[Chat] Fix assumption that every chat has an owner (#10373)
This commit is contained in:
@@ -14,7 +14,11 @@ import {useHaptics} from '#/lib/haptics'
|
||||
import {createSanitizedDisplayName} from '#/lib/moderation/create-sanitized-display-name'
|
||||
import {decrementBadgeCount} from '#/lib/notifications/notifications'
|
||||
import {sanitizeHandle} from '#/lib/strings/handles'
|
||||
import {type Shadow, useProfileShadow} from '#/state/cache/profile-shadow'
|
||||
import {
|
||||
type Shadow,
|
||||
useMaybeProfileShadow,
|
||||
useProfileShadow,
|
||||
} from '#/state/cache/profile-shadow'
|
||||
import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
||||
import {
|
||||
precacheConvoQuery,
|
||||
@@ -120,7 +124,7 @@ function DirectChatItem({
|
||||
|
||||
return (
|
||||
<BaseChatItem
|
||||
convo={convo.view}
|
||||
convo={convo}
|
||||
avatar={
|
||||
<PreviewableUserAvatar
|
||||
profile={profile}
|
||||
@@ -167,10 +171,11 @@ function GroupChatItem({
|
||||
children?: React.ReactNode
|
||||
}) {
|
||||
const {t: l} = useLingui()
|
||||
const groupOwner = useProfileShadow(convo.primaryMember)
|
||||
const groupOwner = useMaybeProfileShadow(convo.primaryMember)
|
||||
|
||||
const moderation = useMemo(
|
||||
() => moderateProfile(groupOwner, moderationOpts),
|
||||
() =>
|
||||
groupOwner ? moderateProfile(groupOwner, moderationOpts) : undefined,
|
||||
[groupOwner, moderationOpts],
|
||||
)
|
||||
|
||||
@@ -178,7 +183,7 @@ function GroupChatItem({
|
||||
|
||||
return (
|
||||
<BaseChatItem
|
||||
convo={convo.view}
|
||||
convo={convo}
|
||||
avatar={<AvatarBubbles profiles={convo.members} size={52} />}
|
||||
title={chatName}
|
||||
accessibilityHint={l`Go to the group chat named "${chatName}"`}
|
||||
@@ -208,15 +213,15 @@ function BaseChatItem({
|
||||
postAlerts,
|
||||
children,
|
||||
}: {
|
||||
convo: ChatBskyConvoDefs.ConvoView
|
||||
convo: ConvoWithDetails
|
||||
avatar: React.ReactNode
|
||||
title: string
|
||||
subtitle?: string
|
||||
accessibilityHint: string
|
||||
isDeletedAccount: boolean
|
||||
isBlockedAccount: boolean
|
||||
primaryProfile: Shadow<bsky.profile.AnyProfileView>
|
||||
primaryProfileModeration: ModerationDecision
|
||||
primaryProfile?: Shadow<bsky.profile.AnyProfileView>
|
||||
primaryProfileModeration?: ModerationDecision
|
||||
showMenu?: boolean
|
||||
showProfileBadges: boolean
|
||||
postAlerts?: React.ReactNode
|
||||
@@ -233,9 +238,16 @@ function BaseChatItem({
|
||||
|
||||
const playHaptic = useHaptics()
|
||||
const queryClient = useQueryClient()
|
||||
const hasUnread = convo.unreadCount > 0 && !isDeletedAccount
|
||||
const hasUnread =
|
||||
convo.view.unreadCount > 0 &&
|
||||
!isDeletedAccount &&
|
||||
!(
|
||||
convo.kind === 'group' &&
|
||||
convo.details.lockStatus === 'locked-permanently'
|
||||
)
|
||||
|
||||
const blockInfo = useMemo(() => {
|
||||
if (!primaryProfileModeration) return {listBlocks: [], userBlock: undefined}
|
||||
const modui = primaryProfileModeration.ui('profileView')
|
||||
const blocks = modui.alerts.filter(alert => alert.type === 'blocking')
|
||||
const listBlocks = blocks.filter(alert => alert.source.type === 'list')
|
||||
@@ -246,7 +258,11 @@ function BaseChatItem({
|
||||
}
|
||||
}, [primaryProfileModeration])
|
||||
|
||||
const isDimStyle = convo.muted || isBlockedAccount || isDeletedAccount
|
||||
const isDimStyle =
|
||||
convo.view.muted ||
|
||||
isBlockedAccount ||
|
||||
isDeletedAccount ||
|
||||
(convo.kind === 'group' && convo.details.lockStatus !== 'unlocked')
|
||||
|
||||
const {lastMessage, lastMessageSentAt, latestReportableMessage} =
|
||||
useMemo(() => {
|
||||
@@ -257,8 +273,8 @@ function BaseChatItem({
|
||||
let latestReportableMessage: ChatBskyConvoDefs.MessageView | undefined
|
||||
|
||||
// Deleted message
|
||||
if (ChatBskyConvoDefs.isDeletedMessageView(convo.lastMessage)) {
|
||||
lastMessageSentAt = convo.lastMessage.sentAt
|
||||
if (ChatBskyConvoDefs.isDeletedMessageView(convo.view.lastMessage)) {
|
||||
lastMessageSentAt = convo.view.lastMessage.sentAt
|
||||
|
||||
lastMessage = isDeletedAccount
|
||||
? l`Conversation deleted`
|
||||
@@ -266,9 +282,9 @@ function BaseChatItem({
|
||||
}
|
||||
|
||||
// Message
|
||||
if (ChatBskyConvoDefs.isMessageView(convo.lastMessage)) {
|
||||
if (ChatBskyConvoDefs.isMessageView(convo.view.lastMessage)) {
|
||||
const info = getMessageInfo({
|
||||
convo,
|
||||
convo: convo.view,
|
||||
currentAccountDid: currentAccount?.did,
|
||||
i18n,
|
||||
})
|
||||
@@ -280,9 +296,9 @@ function BaseChatItem({
|
||||
}
|
||||
|
||||
// Reaction
|
||||
if (ChatBskyConvoDefs.isMessageAndReactionView(convo.lastReaction)) {
|
||||
if (ChatBskyConvoDefs.isMessageAndReactionView(convo.view.lastReaction)) {
|
||||
const info = getReactionInfo({
|
||||
convo,
|
||||
convo: convo.view,
|
||||
currentAccountDid: currentAccount?.did,
|
||||
i18n,
|
||||
})
|
||||
@@ -297,14 +313,14 @@ function BaseChatItem({
|
||||
}
|
||||
|
||||
// System message
|
||||
if (ChatBskyConvoDefs.isSystemMessageView(convo.lastMessage)) {
|
||||
if (ChatBskyConvoDefs.isSystemMessageView(convo.view.lastMessage)) {
|
||||
const info = getSystemMessageInfo(
|
||||
convo.lastMessage.data,
|
||||
new Map(convo.members.map(m => [m.did, m])),
|
||||
convo.view.lastMessage.data,
|
||||
new Map(convo.view.members.map(m => [m.did, m])),
|
||||
)
|
||||
if (info) {
|
||||
lastMessage = i18n._(info.message)
|
||||
lastMessageSentAt = convo.lastMessage.sentAt
|
||||
lastMessageSentAt = convo.view.lastMessage.sentAt
|
||||
}
|
||||
}
|
||||
|
||||
@@ -332,11 +348,11 @@ function BaseChatItem({
|
||||
|
||||
const onPress = useCallback(
|
||||
(e: GestureResponderEvent) => {
|
||||
for (const member of convo.members) {
|
||||
for (const member of convo.view.members) {
|
||||
unstableCacheProfileView(queryClient, member)
|
||||
}
|
||||
precacheConvoQuery(queryClient, convo)
|
||||
void decrementBadgeCount(convo.unreadCount)
|
||||
precacheConvoQuery(queryClient, convo.view)
|
||||
void decrementBadgeCount(convo.view.unreadCount)
|
||||
if (isDeletedAccount) {
|
||||
e.preventDefault()
|
||||
menuControl.open()
|
||||
@@ -359,7 +375,7 @@ function BaseChatItem({
|
||||
icon: EnvelopeOpen,
|
||||
action: () => {
|
||||
markAsRead({
|
||||
convoId: convo.id,
|
||||
convoId: convo.view.id,
|
||||
})
|
||||
},
|
||||
}
|
||||
@@ -402,7 +418,7 @@ function BaseChatItem({
|
||||
</View>
|
||||
|
||||
<Link
|
||||
to={`/messages/${convo.id}`}
|
||||
to={`/messages/${convo.view.id}`}
|
||||
label={title}
|
||||
accessibilityHint={accessibilityHint}
|
||||
accessibilityActions={
|
||||
@@ -419,7 +435,7 @@ function BaseChatItem({
|
||||
]
|
||||
: undefined
|
||||
}
|
||||
onPressIn={() => precacheConvoQuery(queryClient, convo)}
|
||||
onPressIn={() => precacheConvoQuery(queryClient, convo.view)}
|
||||
onPress={onPress}
|
||||
onLongPress={showMenu && IS_NATIVE ? onLongPress : undefined}
|
||||
onAccessibilityAction={showMenu ? onLongPress : undefined}>
|
||||
@@ -455,7 +471,7 @@ function BaseChatItem({
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
{showProfileBadges && (
|
||||
{showProfileBadges && primaryProfile && (
|
||||
<ProfileBadges
|
||||
profile={primaryProfile}
|
||||
size="md"
|
||||
@@ -480,7 +496,7 @@ function BaseChatItem({
|
||||
</TimeElapsed>
|
||||
</View>
|
||||
)}
|
||||
{(convo.muted || isBlockedAccount) && (
|
||||
{(convo.view.muted || isBlockedAccount) && (
|
||||
<Text
|
||||
style={[
|
||||
a.text_sm,
|
||||
@@ -550,13 +566,14 @@ function BaseChatItem({
|
||||
|
||||
<ChatListItemPortal.Outlet />
|
||||
|
||||
{showMenu && (
|
||||
{/* TODO: Allow showing menu for groups where the owner has left! */}
|
||||
{showMenu && primaryProfile && (
|
||||
<ConvoMenu
|
||||
convo={convo}
|
||||
convo={convo.view}
|
||||
profile={primaryProfile}
|
||||
control={menuControl}
|
||||
currentScreen="list"
|
||||
showMarkAsRead={convo.unreadCount > 0}
|
||||
showMarkAsRead={convo.view.unreadCount > 0}
|
||||
hideTrigger={IS_NATIVE}
|
||||
blockInfo={blockInfo}
|
||||
style={[
|
||||
@@ -576,7 +593,7 @@ function BaseChatItem({
|
||||
|
||||
<LeaveConvoPrompt
|
||||
control={leaveConvoControl}
|
||||
convoId={convo.id}
|
||||
convoId={convo.view.id}
|
||||
currentScreen="list"
|
||||
/>
|
||||
</View>
|
||||
|
||||
Reference in New Issue
Block a user