Use consistent avatar shape/defaults for labelers (#3257)
* Add type: labeler to easy spots * Search and ProfileCard * Filter out of suggested follows * ComposeReplyTo * PReviewable avatar in posts * Lists * PostMeta * Notifications * Autocomplete * Straggler * Bump sdkzio/stable
parent
b9474a5d55
commit
dfe88e1656
|
@ -46,7 +46,7 @@
|
|||
"make-deploy-bundle": "bash scripts/bundleUpdate.sh"
|
||||
},
|
||||
"dependencies": {
|
||||
"@atproto/api": "^0.12.0",
|
||||
"@atproto/api": "^0.12.1",
|
||||
"@bam.tech/react-native-image-resizer": "^3.0.4",
|
||||
"@braintree/sanitize-url": "^6.0.2",
|
||||
"@emoji-mart/react": "^1.1.1",
|
||||
|
|
|
@ -101,13 +101,7 @@ function computeSuggestions(
|
|||
}
|
||||
for (const item of searched) {
|
||||
if (!items.find(item2 => item2.handle === item.handle)) {
|
||||
items.push({
|
||||
did: item.did,
|
||||
handle: item.handle,
|
||||
displayName: item.displayName,
|
||||
avatar: item.avatar,
|
||||
labels: item.labels,
|
||||
})
|
||||
items.push(item)
|
||||
}
|
||||
}
|
||||
return items.filter(profile => {
|
||||
|
|
|
@ -3,6 +3,7 @@ import {
|
|||
AppBskyEmbedRecord,
|
||||
AppBskyRichtextFacet,
|
||||
ModerationDecision,
|
||||
AppBskyActorDefs,
|
||||
} from '@atproto/api'
|
||||
import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback'
|
||||
|
||||
|
@ -10,11 +11,7 @@ export interface ComposerOptsPostRef {
|
|||
uri: string
|
||||
cid: string
|
||||
text: string
|
||||
author: {
|
||||
handle: string
|
||||
displayName?: string
|
||||
avatar?: string
|
||||
}
|
||||
author: AppBskyActorDefs.ProfileViewBasic
|
||||
embed?: AppBskyEmbedRecord.ViewRecord['embed']
|
||||
moderation?: ModerationDecision
|
||||
}
|
||||
|
|
|
@ -45,7 +45,11 @@ function AccountItem({
|
|||
accessibilityHint={_(msg`Double tap to sign in`)}>
|
||||
<View style={[pal.borderDark, styles.groupContent, styles.noTopBorder]}>
|
||||
<View style={s.p10}>
|
||||
<UserAvatar avatar={profile?.avatar} size={30} />
|
||||
<UserAvatar
|
||||
avatar={profile?.avatar}
|
||||
size={30}
|
||||
type={profile?.associated?.labeler ? 'labeler' : 'user'}
|
||||
/>
|
||||
</View>
|
||||
<Text style={styles.accountText}>
|
||||
<Text type="lg-bold" style={pal.text}>
|
||||
|
|
|
@ -415,7 +415,11 @@ export const ComposePost = observer(function ComposePost({
|
|||
styles.textInputLayout,
|
||||
isNative && styles.textInputLayoutMobile,
|
||||
]}>
|
||||
<UserAvatar avatar={currentProfile?.avatar} size={50} />
|
||||
<UserAvatar
|
||||
avatar={currentProfile?.avatar}
|
||||
size={50}
|
||||
type={currentProfile?.associated?.labeler ? 'labeler' : 'user'}
|
||||
/>
|
||||
<TextInput
|
||||
ref={textInput}
|
||||
richtext={richtext}
|
||||
|
|
|
@ -87,6 +87,7 @@ export function ComposerReplyTo({replyTo}: {replyTo: ComposerOptsPostRef}) {
|
|||
avatar={replyTo.author.avatar}
|
||||
size={50}
|
||||
moderation={replyTo.moderation?.ui('avatar')}
|
||||
type={replyTo.author.associated?.labeler ? 'labeler' : 'user'}
|
||||
/>
|
||||
<View style={styles.replyToPost}>
|
||||
<Text type="xl-medium" style={[pal.text]}>
|
||||
|
|
|
@ -23,7 +23,11 @@ export function ComposePrompt({onPressCompose}: {onPressCompose: () => void}) {
|
|||
accessibilityRole="button"
|
||||
accessibilityLabel={_(msg`Compose reply`)}
|
||||
accessibilityHint={_(msg`Opens composer`)}>
|
||||
<UserAvatar avatar={profile?.avatar} size={38} />
|
||||
<UserAvatar
|
||||
avatar={profile?.avatar}
|
||||
size={38}
|
||||
type={profile?.associated?.labeler ? 'labeler' : 'user'}
|
||||
/>
|
||||
<Text
|
||||
type="xl"
|
||||
style={[
|
||||
|
|
|
@ -78,7 +78,11 @@ export function Autocomplete({
|
|||
accessibilityLabel={`Select ${item.handle}`}
|
||||
accessibilityHint="">
|
||||
<View style={styles.avatarAndHandle}>
|
||||
<UserAvatar avatar={item.avatar ?? null} size={24} />
|
||||
<UserAvatar
|
||||
avatar={item.avatar ?? null}
|
||||
size={24}
|
||||
type={item.associated?.labeler ? 'labeler' : 'user'}
|
||||
/>
|
||||
<Text type="md-medium" style={pal.text}>
|
||||
{displayName}
|
||||
</Text>
|
||||
|
|
|
@ -175,7 +175,11 @@ const MentionList = forwardRef<MentionListRef, SuggestionProps>(
|
|||
}}
|
||||
accessibilityRole="button">
|
||||
<View style={styles.avatarAndDisplayName}>
|
||||
<UserAvatar avatar={item.avatar ?? null} size={26} />
|
||||
<UserAvatar
|
||||
avatar={item.avatar ?? null}
|
||||
size={26}
|
||||
type={item.associated?.labeler ? 'labeler' : 'user'}
|
||||
/>
|
||||
<Text style={pal.text} numberOfLines={1}>
|
||||
{displayName}
|
||||
</Text>
|
||||
|
|
|
@ -231,7 +231,11 @@ function UserResult({
|
|||
width: 54,
|
||||
paddingLeft: 4,
|
||||
}}>
|
||||
<UserAvatar size={40} avatar={profile.avatar} />
|
||||
<UserAvatar
|
||||
size={40}
|
||||
avatar={profile.avatar}
|
||||
type={profile.associated?.labeler ? 'labeler' : 'user'}
|
||||
/>
|
||||
</View>
|
||||
<View
|
||||
style={{
|
||||
|
|
|
@ -45,7 +45,11 @@ function SwitchAccountCard({account}: {account: SessionAccount}) {
|
|||
const contents = (
|
||||
<View style={[pal.view, styles.linkCard]}>
|
||||
<View style={styles.avi}>
|
||||
<UserAvatar size={40} avatar={profile?.avatar} />
|
||||
<UserAvatar
|
||||
size={40}
|
||||
avatar={profile?.avatar}
|
||||
type={profile?.associated?.labeler ? 'labeler' : 'user'}
|
||||
/>
|
||||
</View>
|
||||
<View style={[s.flex1]}>
|
||||
<Text type="md-bold" style={pal.text} numberOfLines={1}>
|
||||
|
|
|
@ -180,7 +180,7 @@ function ListItem({
|
|||
},
|
||||
]}>
|
||||
<View style={styles.listItemAvi}>
|
||||
<UserAvatar size={40} avatar={list.avatar} />
|
||||
<UserAvatar size={40} avatar={list.avatar} type="list" />
|
||||
</View>
|
||||
<View style={styles.listItemContent}>
|
||||
<Text
|
||||
|
|
|
@ -14,6 +14,7 @@ import {
|
|||
ModerationDecision,
|
||||
moderateProfile,
|
||||
AppBskyEmbedRecordWithMedia,
|
||||
AppBskyActorDefs,
|
||||
} from '@atproto/api'
|
||||
import {AtUri} from '@atproto/api'
|
||||
import {
|
||||
|
@ -55,6 +56,7 @@ interface Author {
|
|||
displayName?: string
|
||||
avatar?: string
|
||||
moderation: ModerationDecision
|
||||
associated?: AppBskyActorDefs.ProfileAssociated
|
||||
}
|
||||
|
||||
let FeedItem = ({
|
||||
|
@ -100,6 +102,7 @@ let FeedItem = ({
|
|||
displayName: item.notification.author.displayName,
|
||||
avatar: item.notification.author.avatar,
|
||||
moderation: moderateProfile(item.notification.author, moderationOpts),
|
||||
associated: item.notification.author.associated,
|
||||
},
|
||||
...(item.additional?.map(({author}) => {
|
||||
return {
|
||||
|
@ -109,6 +112,7 @@ let FeedItem = ({
|
|||
displayName: author.displayName,
|
||||
avatar: author.avatar,
|
||||
moderation: moderateProfile(author, moderationOpts),
|
||||
associated: author.associated,
|
||||
}
|
||||
}) || []),
|
||||
]
|
||||
|
@ -337,6 +341,7 @@ function CondensedAuthorsList({
|
|||
handle={authors[0].handle}
|
||||
avatar={authors[0].avatar}
|
||||
moderation={authors[0].moderation.ui('avatar')}
|
||||
type={authors[0].associated?.labeler ? 'labeler' : 'user'}
|
||||
/>
|
||||
</View>
|
||||
)
|
||||
|
@ -355,6 +360,7 @@ function CondensedAuthorsList({
|
|||
size={35}
|
||||
avatar={author.avatar}
|
||||
moderation={author.moderation.ui('avatar')}
|
||||
type={author.associated?.labeler ? 'labeler' : 'user'}
|
||||
/>
|
||||
</View>
|
||||
))}
|
||||
|
@ -413,6 +419,7 @@ function ExpandedAuthorsList({
|
|||
size={35}
|
||||
avatar={author.avatar}
|
||||
moderation={author.moderation.ui('avatar')}
|
||||
type={author.associated?.labeler ? 'labeler' : 'user'}
|
||||
/>
|
||||
</View>
|
||||
<View style={s.flex1}>
|
||||
|
|
|
@ -205,11 +205,7 @@ let PostThreadItemLoaded = ({
|
|||
uri: post.uri,
|
||||
cid: post.cid,
|
||||
text: record.text,
|
||||
author: {
|
||||
handle: post.author.handle,
|
||||
displayName: post.author.displayName,
|
||||
avatar: post.author.avatar,
|
||||
},
|
||||
author: post.author,
|
||||
embed: post.embed,
|
||||
moderation,
|
||||
},
|
||||
|
@ -256,6 +252,7 @@ let PostThreadItemLoaded = ({
|
|||
handle={post.author.handle}
|
||||
avatar={post.author.avatar}
|
||||
moderation={moderation.ui('avatar')}
|
||||
type={post.author.associated?.labeler ? 'labeler' : 'user'}
|
||||
/>
|
||||
</View>
|
||||
<View style={styles.layoutContent}>
|
||||
|
@ -452,6 +449,7 @@ let PostThreadItemLoaded = ({
|
|||
handle={post.author.handle}
|
||||
avatar={post.author.avatar}
|
||||
moderation={moderation.ui('avatar')}
|
||||
type={post.author.associated?.labeler ? 'labeler' : 'user'}
|
||||
/>
|
||||
|
||||
{showChildReplyLine && (
|
||||
|
|
|
@ -118,11 +118,7 @@ function PostInner({
|
|||
uri: post.uri,
|
||||
cid: post.cid,
|
||||
text: record.text,
|
||||
author: {
|
||||
handle: post.author.handle,
|
||||
displayName: post.author.displayName,
|
||||
avatar: post.author.avatar,
|
||||
},
|
||||
author: post.author,
|
||||
embed: post.embed,
|
||||
moderation,
|
||||
},
|
||||
|
@ -144,6 +140,7 @@ function PostInner({
|
|||
handle={post.author.handle}
|
||||
avatar={post.author.avatar}
|
||||
moderation={moderation.ui('avatar')}
|
||||
type={post.author.associated?.labeler ? 'labeler' : 'user'}
|
||||
/>
|
||||
</View>
|
||||
<View style={styles.layoutContent}>
|
||||
|
|
|
@ -126,11 +126,7 @@ let FeedItemInner = ({
|
|||
uri: post.uri,
|
||||
cid: post.cid,
|
||||
text: record.text || '',
|
||||
author: {
|
||||
handle: post.author.handle,
|
||||
displayName: post.author.displayName,
|
||||
avatar: post.author.avatar,
|
||||
},
|
||||
author: post.author,
|
||||
embed: post.embed,
|
||||
moderation,
|
||||
},
|
||||
|
@ -243,6 +239,7 @@ let FeedItemInner = ({
|
|||
handle={post.author.handle}
|
||||
avatar={post.author.avatar}
|
||||
moderation={moderation.ui('avatar')}
|
||||
type={post.author.associated?.labeler ? 'labeler' : 'user'}
|
||||
/>
|
||||
{isThreadParent && (
|
||||
<View
|
||||
|
|
|
@ -49,6 +49,7 @@ export function ProfileCard({
|
|||
const pal = usePalette('default')
|
||||
const profile = useProfileShadow(profileUnshadowed)
|
||||
const moderationOpts = useModerationOpts()
|
||||
const isLabeler = profile?.associated?.labeler
|
||||
if (!moderationOpts) {
|
||||
return null
|
||||
}
|
||||
|
@ -79,6 +80,7 @@ export function ProfileCard({
|
|||
size={40}
|
||||
avatar={profile.avatar}
|
||||
moderation={moderation.ui('avatar')}
|
||||
type={isLabeler ? 'labeler' : 'user'}
|
||||
/>
|
||||
</View>
|
||||
<View style={styles.layoutContent}>
|
||||
|
@ -101,7 +103,7 @@ export function ProfileCard({
|
|||
/>
|
||||
{!!profile.viewer?.followedBy && <View style={s.flexRow} />}
|
||||
</View>
|
||||
{renderButton ? (
|
||||
{renderButton && !isLabeler ? (
|
||||
<View style={styles.layoutButton}>{renderButton(profile)}</View>
|
||||
) : undefined}
|
||||
</View>
|
||||
|
@ -223,6 +225,7 @@ function FollowersList({
|
|||
avatar={f.avatar}
|
||||
size={32}
|
||||
moderation={mod.ui('avatar')}
|
||||
type={f.associated?.labeler ? 'labeler' : 'user'}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
|
|
|
@ -98,7 +98,9 @@ export function ProfileHeaderSuggestedFollows({
|
|||
<SuggestedFollowSkeleton />
|
||||
</>
|
||||
) : data ? (
|
||||
data.suggestions.map(profile => (
|
||||
data.suggestions
|
||||
.filter(s => (s.associated?.labeler ? false : true))
|
||||
.map(profile => (
|
||||
<SuggestedFollow key={profile.did} profile={profile} />
|
||||
))
|
||||
) : (
|
||||
|
|
|
@ -11,16 +11,11 @@ import {sanitizeHandle} from 'lib/strings/handles'
|
|||
import {isAndroid, isWeb} from 'platform/detection'
|
||||
import {TimeElapsed} from './TimeElapsed'
|
||||
import {makeProfileLink} from 'lib/routes/links'
|
||||
import {ModerationDecision, ModerationUI} from '@atproto/api'
|
||||
import {AppBskyActorDefs, ModerationDecision, ModerationUI} from '@atproto/api'
|
||||
import {usePrefetchProfileQuery} from '#/state/queries/profile'
|
||||
|
||||
interface PostMetaOpts {
|
||||
author: {
|
||||
avatar?: string
|
||||
did: string
|
||||
handle: string
|
||||
displayName?: string | undefined
|
||||
}
|
||||
author: AppBskyActorDefs.ProfileViewBasic
|
||||
moderation: ModerationDecision | undefined
|
||||
authorHasWarning: boolean
|
||||
postHref: string
|
||||
|
@ -47,6 +42,7 @@ let PostMeta = (opts: PostMetaOpts): React.ReactNode => {
|
|||
avatar={opts.author.avatar}
|
||||
size={opts.avatarSize || 16}
|
||||
moderation={opts.avatarModeration}
|
||||
type={opts.author.associated?.labeler ? 'labeler' : 'user'}
|
||||
/>
|
||||
</View>
|
||||
)}
|
||||
|
|
|
@ -59,11 +59,7 @@ export function PostThreadScreen({route}: Props) {
|
|||
uri: thread.post.uri,
|
||||
cid: thread.post.cid,
|
||||
text: thread.record.text,
|
||||
author: {
|
||||
handle: thread.post.author.handle,
|
||||
displayName: thread.post.author.displayName,
|
||||
avatar: thread.post.author.avatar,
|
||||
},
|
||||
author: thread.post.author,
|
||||
embed: thread.post.embed,
|
||||
},
|
||||
onPost: () =>
|
||||
|
|
|
@ -141,6 +141,7 @@ function SearchScreenSuggestedFollows() {
|
|||
friends.slice(0, 4).map(friend =>
|
||||
getSuggestedFollowsByActor(friend.did).then(foafsRes => {
|
||||
for (const user of foafsRes.suggestions) {
|
||||
if (user.associated?.labeler) continue
|
||||
friendsOfFriends.set(user.did, user)
|
||||
}
|
||||
}),
|
||||
|
|
|
@ -82,7 +82,11 @@ function SettingsAccountCard({account}: {account: SessionAccount}) {
|
|||
const contents = (
|
||||
<View style={[pal.view, styles.linkCard]}>
|
||||
<View style={styles.avi}>
|
||||
<UserAvatar size={40} avatar={profile?.avatar} />
|
||||
<UserAvatar
|
||||
size={40}
|
||||
avatar={profile?.avatar}
|
||||
type={profile?.associated?.labeler ? 'labeler' : 'user'}
|
||||
/>
|
||||
</View>
|
||||
<View style={[s.flex1]}>
|
||||
<Text type="md-bold" style={pal.text}>
|
||||
|
|
|
@ -75,6 +75,7 @@ let DrawerProfileCard = ({
|
|||
avatar={profile?.avatar}
|
||||
// See https://github.com/bluesky-social/social-app/pull/1801:
|
||||
usePlainRNImage={true}
|
||||
type={profile?.associated?.labeler ? 'labeler' : 'user'}
|
||||
/>
|
||||
<Text
|
||||
type="title-lg"
|
||||
|
|
|
@ -229,6 +229,7 @@ export function BottomBar({navigation}: BottomTabBarProps) {
|
|||
size={27}
|
||||
// See https://github.com/bluesky-social/social-app/pull/1801:
|
||||
usePlainRNImage={true}
|
||||
type={profile?.associated?.labeler ? 'labeler' : 'user'}
|
||||
/>
|
||||
</View>
|
||||
) : (
|
||||
|
@ -238,6 +239,7 @@ export function BottomBar({navigation}: BottomTabBarProps) {
|
|||
size={28}
|
||||
// See https://github.com/bluesky-social/social-app/pull/1801:
|
||||
usePlainRNImage={true}
|
||||
type={profile?.associated?.labeler ? 'labeler' : 'user'}
|
||||
/>
|
||||
</View>
|
||||
)}
|
||||
|
|
|
@ -64,7 +64,11 @@ function ProfileCard() {
|
|||
style={[styles.profileCard, !isDesktop && styles.profileCardTablet]}
|
||||
title={_(msg`My Profile`)}
|
||||
asAnchor>
|
||||
<UserAvatar avatar={profile.avatar} size={size} />
|
||||
<UserAvatar
|
||||
avatar={profile.avatar}
|
||||
size={size}
|
||||
type={profile?.associated?.labeler ? 'labeler' : 'user'}
|
||||
/>
|
||||
</Link>
|
||||
) : (
|
||||
<View style={[styles.profileCard, !isDesktop && styles.profileCardTablet]}>
|
||||
|
|
|
@ -112,6 +112,7 @@ export function SearchProfileCard({
|
|||
size={40}
|
||||
avatar={profile.avatar}
|
||||
moderation={moderation.ui('avatar')}
|
||||
type={profile.associated?.labeler ? 'labeler' : 'user'}
|
||||
/>
|
||||
<View style={{flex: 1}}>
|
||||
<Text
|
||||
|
|
|
@ -34,10 +34,10 @@
|
|||
jsonpointer "^5.0.0"
|
||||
leven "^3.1.0"
|
||||
|
||||
"@atproto/api@^0.12.0":
|
||||
version "0.12.0"
|
||||
resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.12.0.tgz#69e52f8761dc7d76c675fa7284bd49240bb0df64"
|
||||
integrity sha512-nSWiad1Z6IC/oVFSVxD5gZLhkD+J4EW2CFqAqIhklJNc0cjFKdmf8D56Pac6Ktm1sJoM6TVZ8GEeuEG6bJS/aQ==
|
||||
"@atproto/api@^0.12.1":
|
||||
version "0.12.1"
|
||||
resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.12.1.tgz#3340cbbd6a51a8c2f3248dae55a01415ab71084e"
|
||||
integrity sha512-Grigs9neuQxytXr2yHq/IfNlgXQVptWDO9KTQr5FDmgMY4Zly2X7Sa99u9c1CW9auwUTbcd+yRFBNEtbA3n3qg==
|
||||
dependencies:
|
||||
"@atproto/common-web" "^0.3.0"
|
||||
"@atproto/lexicon" "^0.4.0"
|
||||
|
|
Loading…
Reference in New Issue