[Chat] Sync convo agent with shadow cache (#10827)

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: DS Boyce <260543580+ds-boyce@users.noreply.github.com>
Co-authored-by: Samuel Newman <mozzius@protonmail.com>
This commit is contained in:
Eric Bailey
2026-06-10 10:16:58 -05:00
committed by GitHub
parent 17ff9af200
commit 8b4a5238be
12 changed files with 195 additions and 58 deletions
+10 -21
View File
@@ -1,4 +1,4 @@
import {useEffect, useMemo} from 'react'
import {useEffect} from 'react'
import {View} from 'react-native'
import Animated, {
Easing,
@@ -8,12 +8,10 @@ import Animated, {
withDelay,
withTiming,
} from 'react-native-reanimated'
import {
moderateProfile,
type ModerationOpts,
type ModerationUI,
} from '@atproto/api'
import {moderateProfile} from '@atproto/api'
import {useMaybeProfileShadow} from '#/state/cache/profile-shadow'
import {useModerationOpts} from '#/state/preferences/moderation-opts'
import {useSession} from '#/state/session'
import {UserAvatar} from '#/view/com/util/UserAvatar'
import {atoms as a, useTheme} from '#/alf'
@@ -33,7 +31,6 @@ export function AvatarBubbles({
profiles: allProfiles,
self = false,
size = 120,
moderationOpts,
}: {
animate?: boolean
profiles: (bsky.profile.AnyProfileView | undefined)[]
@@ -45,19 +42,12 @@ export function AvatarBubbles({
*/
self?: boolean
size?: number
moderationOpts?: ModerationOpts
}) {
const {currentAccount} = useSession()
const profiles =
!self && allProfiles.length > 2
? allProfiles.filter(p => !p || p.did !== currentAccount?.did)
: allProfiles
const moderations = useMemo(() => {
if (!moderationOpts) return []
return profiles.map(p => {
return p && moderateProfile(p, moderationOpts)
})
}, [profiles, moderationOpts])
const scale = size / 120
const marginOffset = size < 120 ? -2 : 0
@@ -110,7 +100,6 @@ export function AvatarBubbles({
y={layout.y}
zIndex={layout.zIndex}
includeProfileBorder={layout.border}
moderation={moderations[i]?.ui('avatar')}
/>
))}
</View>
@@ -119,14 +108,13 @@ export function AvatarBubbles({
}
function AvatarBubble({
profile,
profile: profileUnshadowed,
scale,
size,
x,
y,
zIndex,
includeProfileBorder,
moderation,
}: {
profile?: bsky.profile.AnyProfileView
scale: SharedValue<number>
@@ -135,14 +123,15 @@ function AvatarBubble({
y: number
zIndex?: number
includeProfileBorder?: boolean
moderation?: ModerationUI
}) {
const t = useTheme()
const animatedStyle = useAnimatedStyle(() => ({
transform: [{translateX: x}, {translateY: y}, {scale: scale.get()}],
}))
const profile = useMaybeProfileShadow(profileUnshadowed)
const moderationOpts = useModerationOpts()
return (
<Animated.View
style={[
@@ -156,14 +145,14 @@ function AvatarBubble({
zIndex != null && {zIndex},
animatedStyle,
]}>
{profile ? (
{profile && moderationOpts ? (
<UserAvatar
avatar={profile.avatar}
size={size}
type="user"
hideLiveBadge
noBorder
moderation={moderation}
moderation={moderateProfile(profile, moderationOpts).ui('avatar')}
/>
) : (
<AvatarPlaceholder size={size} />
@@ -152,11 +152,7 @@ function RecentChatItem({
a.align_center,
]}>
{convo.kind === 'group' ? (
<AvatarBubbles
profiles={convo.members}
size={WIDTH - 8}
moderationOpts={moderationOpts}
/>
<AvatarBubbles profiles={convo.members} size={WIDTH - 8} />
) : (
<UserAvatar
avatar={primaryProfile.avatar}
@@ -514,11 +514,7 @@ function ExistingChatCard({
]}>
<ProfileCard.Header>
{convo.kind === 'group' ? (
<AvatarBubbles
profiles={convo.members}
size={40}
moderationOpts={moderationOpts}
/>
<AvatarBubbles profiles={convo.members} size={40} />
) : (
<ProfileCard.Avatar
profile={convo.primaryMember}
+2 -8
View File
@@ -42,7 +42,7 @@ export function MessagesListHeader({convo}: {convo?: ConvoWithDetails | null}) {
convo.kind === 'direct' ? (
<ProfileHeaderReady convo={convo} moderationOpts={moderationOpts} />
) : (
<GroupHeaderReady convo={convo} moderationOpts={moderationOpts} />
<GroupHeaderReady convo={convo} />
)
) : (
<>
@@ -152,10 +152,8 @@ function ProfileHeaderReady({
function GroupHeaderReady({
convo,
moderationOpts,
}: {
convo: Extract<ConvoWithDetails, {kind: 'group'}>
moderationOpts: ModerationOpts
}) {
const {t: l} = useLingui()
@@ -178,11 +176,7 @@ function GroupHeaderReady({
},
}
}>
<AvatarBubbles
size={40}
profiles={convo.members}
moderationOpts={moderationOpts}
/>
<AvatarBubbles size={40} profiles={convo.members} />
<View style={[a.flex_row, a.flex_1, a.align_center]}>
<Text
style={[a.text_lg, a.font_semi_bold, a.flex_shrink]}