Show which list caused a mute

This commit is contained in:
Paul Frazee
2023-05-07 21:25:59 -05:00
parent 2482f41ffb
commit 1dc633b07c
9 changed files with 73 additions and 18 deletions
+24 -3
View File
@@ -1,5 +1,6 @@
import { import {
AppBskyActorDefs, AppBskyActorDefs,
AppBskyGraphDefs,
AppBskyEmbedRecordWithMedia, AppBskyEmbedRecordWithMedia,
AppBskyEmbedRecord, AppBskyEmbedRecord,
AppBskyEmbedImages, AppBskyEmbedImages,
@@ -127,11 +128,15 @@ export function getPostModeration(
// muting // muting
if (postInfo.isMuted) { if (postInfo.isMuted) {
let msg = 'Post from an account you muted.'
if (postInfo.mutedByList) {
msg = `Muted by ${postInfo.mutedByList.name}`
}
return { return {
avatar, avatar,
list: hide('Post from an account you muted.'), list: hide(msg),
thread: warn('Post from an account you muted.'), thread: warn(msg),
view: warn('Post from an account you muted.'), view: warn(msg),
} }
} }
@@ -273,6 +278,7 @@ export function getProfileViewBasicLabelInfo(
profileLabels: filterProfileLabels(profile.labels), profileLabels: filterProfileLabels(profile.labels),
isMuted: profile.viewer?.muted || false, isMuted: profile.viewer?.muted || false,
isBlocking: !!profile.viewer?.blocking || false, isBlocking: !!profile.viewer?.blocking || false,
isBlockedBy: !!profile.viewer?.blockedBy || false,
} }
} }
@@ -302,6 +308,21 @@ export function getEmbedMuted(embed?: Embed): boolean {
return false return false
} }
export function getEmbedMutedByList(
embed?: Embed,
): AppBskyGraphDefs.ListViewBasic | undefined {
if (!embed) {
return undefined
}
if (
AppBskyEmbedRecord.isView(embed) &&
AppBskyEmbedRecord.isViewRecord(embed.record)
) {
return embed.record.author.viewer?.mutedByList
}
return undefined
}
export function getEmbedBlocking(embed?: Embed): boolean { export function getEmbedBlocking(embed?: Embed): boolean {
if (!embed) { if (!embed) {
return false return false
+2 -1
View File
@@ -1,4 +1,4 @@
import {ComAtprotoLabelDefs} from '@atproto/api' import {ComAtprotoLabelDefs, AppBskyGraphDefs} from '@atproto/api'
import {LabelPreferencesModel} from 'state/models/ui/preferences' import {LabelPreferencesModel} from 'state/models/ui/preferences'
export type Label = ComAtprotoLabelDefs.Label export type Label = ComAtprotoLabelDefs.Label
@@ -22,6 +22,7 @@ export interface PostLabelInfo {
accountLabels: Label[] accountLabels: Label[]
profileLabels: Label[] profileLabels: Label[]
isMuted: boolean isMuted: boolean
mutedByList?: AppBskyGraphDefs.ListViewBasic
isBlocking: boolean isBlocking: boolean
isBlockedBy: boolean isBlockedBy: boolean
} }
+9
View File
@@ -90,6 +90,15 @@ export function convertBskyAppUrlIfNeeded(url: string): string {
return url return url
} }
export function listUriToHref(url: string): string {
try {
const {hostname, rkey} = new AtUri(url)
return `/profile/${hostname}/lists/${rkey}`
} catch {
return ''
}
}
export function getYoutubeVideoId(link: string): string | undefined { export function getYoutubeVideoId(link: string): string | undefined {
let url let url
try { try {
+4
View File
@@ -14,6 +14,7 @@ import {PostLabelInfo, PostModeration} from 'lib/labeling/types'
import { import {
getEmbedLabels, getEmbedLabels,
getEmbedMuted, getEmbedMuted,
getEmbedMutedByList,
getEmbedBlocking, getEmbedBlocking,
getEmbedBlockedBy, getEmbedBlockedBy,
filterAccountLabels, filterAccountLabels,
@@ -70,6 +71,9 @@ export class PostThreadItemModel {
this.post.author.viewer?.muted || this.post.author.viewer?.muted ||
getEmbedMuted(this.post.embed) || getEmbedMuted(this.post.embed) ||
false, false,
mutedByList:
this.post.author.viewer?.mutedByList ||
getEmbedMutedByList(this.post.embed),
isBlocking: isBlocking:
!!this.post.author.viewer?.blocking || !!this.post.author.viewer?.blocking ||
getEmbedBlocking(this.post.embed) || getEmbedBlocking(this.post.embed) ||
+2
View File
@@ -2,6 +2,7 @@ import {makeAutoObservable, runInAction} from 'mobx'
import { import {
AtUri, AtUri,
ComAtprotoLabelDefs, ComAtprotoLabelDefs,
AppBskyGraphDefs,
AppBskyActorGetProfile as GetProfile, AppBskyActorGetProfile as GetProfile,
AppBskyActorProfile, AppBskyActorProfile,
RichText, RichText,
@@ -20,6 +21,7 @@ import {
export class ProfileViewerModel { export class ProfileViewerModel {
muted?: boolean muted?: boolean
mutedByList?: AppBskyGraphDefs.ListViewBasic
following?: string following?: string
followedBy?: string followedBy?: string
blockedBy?: boolean blockedBy?: boolean
+1
View File
@@ -111,6 +111,7 @@ export class NotificationsFeedItemModel {
addedInfo?.profileLabels || [], addedInfo?.profileLabels || [],
), ),
isMuted: this.author.viewer?.muted || addedInfo?.isMuted || false, isMuted: this.author.viewer?.muted || addedInfo?.isMuted || false,
mutedByList: this.author.viewer?.mutedByList || addedInfo.mutedByList,
isBlocking: isBlocking:
!!this.author.viewer?.blocking || addedInfo?.isBlocking || false, !!this.author.viewer?.blocking || addedInfo?.isBlocking || false,
isBlockedBy: isBlockedBy:
+4
View File
@@ -24,6 +24,7 @@ import {PostLabelInfo, PostModeration} from 'lib/labeling/types'
import { import {
getEmbedLabels, getEmbedLabels,
getEmbedMuted, getEmbedMuted,
getEmbedMutedByList,
getEmbedBlocking, getEmbedBlocking,
getEmbedBlockedBy, getEmbedBlockedBy,
getPostModeration, getPostModeration,
@@ -105,6 +106,9 @@ export class PostsFeedItemModel {
this.post.author.viewer?.muted || this.post.author.viewer?.muted ||
getEmbedMuted(this.post.embed) || getEmbedMuted(this.post.embed) ||
false, false,
mutedByList:
this.post.author.viewer?.mutedByList ||
getEmbedMutedByList(this.post.embed),
isBlocking: isBlocking:
!!this.post.author.viewer?.blocking || !!this.post.author.viewer?.blocking ||
getEmbedBlocking(this.post.embed) || getEmbedBlocking(this.post.embed) ||
+1 -1
View File
@@ -156,7 +156,7 @@ export const ListItems = observer(
} }
return <View /> return <View />
} else if (item === HEADER_ITEM) { } else if (item === HEADER_ITEM) {
return list.hasLoaded ? ( return list.list ? (
<ListHeader <ListHeader
list={list.list} list={list.list}
isOwner={list.isOwner} isOwner={list.isOwner}
+26 -13
View File
@@ -23,6 +23,7 @@ import {DropdownButton, DropdownItem} from '../util/forms/DropdownButton'
import * as Toast from '../util/Toast' import * as Toast from '../util/Toast'
import {LoadingPlaceholder} from '../util/LoadingPlaceholder' import {LoadingPlaceholder} from '../util/LoadingPlaceholder'
import {Text} from '../util/text/Text' import {Text} from '../util/text/Text'
import {TextLink} from '../util/Link'
import {RichText} from '../util/text/RichText' import {RichText} from '../util/text/RichText'
import {UserAvatar} from '../util/UserAvatar' import {UserAvatar} from '../util/UserAvatar'
import {UserBanner} from '../util/UserBanner' import {UserBanner} from '../util/UserBanner'
@@ -30,6 +31,7 @@ import {ProfileHeaderWarnings} from '../util/moderation/ProfileHeaderWarnings'
import {usePalette} from 'lib/hooks/usePalette' import {usePalette} from 'lib/hooks/usePalette'
import {useAnalytics} from 'lib/analytics' import {useAnalytics} from 'lib/analytics'
import {NavigationProp} from 'lib/routes/types' import {NavigationProp} from 'lib/routes/types'
import {listUriToHref} from 'lib/strings/url-helpers'
import {isDesktopWeb} from 'platform/detection' import {isDesktopWeb} from 'platform/detection'
import {FollowState} from 'state/models/cache/my-follows' import {FollowState} from 'state/models/cache/my-follows'
import {shareUrl} from 'lib/sharing' import {shareUrl} from 'lib/sharing'
@@ -436,31 +438,42 @@ const ProfileHeaderLoaded = observer(
{view.viewer.blocking ? ( {view.viewer.blocking ? (
<View <View
testID="profileHeaderBlockedNotice" testID="profileHeaderBlockedNotice"
style={[styles.moderationNotice, pal.view, pal.border]}> style={[styles.moderationNotice, pal.viewLight]}>
<FontAwesomeIcon icon="ban" style={[pal.text, s.mr5]} /> <FontAwesomeIcon icon="ban" style={[pal.text]} />
<Text type="md" style={[s.mr2, pal.text]}> <Text type="lg-medium" style={pal.text}>
Account blocked Account blocked
</Text> </Text>
</View> </View>
) : view.viewer.muted ? ( ) : view.viewer.muted ? (
<View <View
testID="profileHeaderMutedNotice" testID="profileHeaderMutedNotice"
style={[styles.moderationNotice, pal.view, pal.border]}> style={[styles.moderationNotice, pal.viewLight]}>
<FontAwesomeIcon <FontAwesomeIcon
icon={['far', 'eye-slash']} icon={['far', 'eye-slash']}
style={[pal.text, s.mr5]} style={[pal.text]}
/> />
<Text type="md" style={[s.mr2, pal.text]}> <Text type="lg-medium" style={pal.text}>
Account muted Account muted{' '}
{view.viewer.mutedByList && (
<Text type="lg-medium" style={pal.text}>
by{' '}
<TextLink
type="lg-medium"
style={pal.link}
href={listUriToHref(view.viewer.mutedByList.uri)}
text={view.viewer.mutedByList.name}
/>
</Text>
)}
</Text> </Text>
</View> </View>
) : undefined} ) : undefined}
{view.viewer.blockedBy && ( {view.viewer.blockedBy && (
<View <View
testID="profileHeaderBlockedNotice" testID="profileHeaderBlockedNotice"
style={[styles.moderationNotice, pal.view, pal.border]}> style={[styles.moderationNotice, pal.viewLight]}>
<FontAwesomeIcon icon="ban" style={[pal.text, s.mr5]} /> <FontAwesomeIcon icon="ban" style={[pal.text]} />
<Text type="md" style={[s.mr2, pal.text]}> <Text type="lg-medium" style={pal.text}>
This account has blocked you This account has blocked you
</Text> </Text>
</View> </View>
@@ -600,10 +613,10 @@ const styles = StyleSheet.create({
moderationNotice: { moderationNotice: {
flexDirection: 'row', flexDirection: 'row',
alignItems: 'center', alignItems: 'center',
borderWidth: 1,
borderRadius: 8, borderRadius: 8,
paddingHorizontal: 12, paddingHorizontal: 16,
paddingVertical: 10, paddingVertical: 14,
gap: 8,
}, },
br40: {borderRadius: 40}, br40: {borderRadius: 40},