Bluesky app fork with some witchin' additions 💫
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Conversation-level reporting by reporting most recent message available (#7423)

* report latest message via convo menu

* check all messages we have

* fix types

* rm convo warning

authored by

Samuel Newman and committed by
GitHub
d7f5ee84 42a44682

+84 -50
+1 -3
src/components/ReportDialog/SelectReportOptionView.tsx
··· 25 25 import {Text} from '#/components/Typography' 26 26 import {ReportDialogProps} from './types' 27 27 28 - export function SelectReportOptionView({ 29 - ...props 30 - }: { 28 + export function SelectReportOptionView(props: { 31 29 params: ReportDialogProps['params'] 32 30 labelers: AppBskyLabelerDefs.LabelerViewDetailed[] 33 31 onSelectReportOption: (reportOption: ReportOption) => void
+16 -1
src/components/dms/ConvoMenu.tsx
··· 35 35 import * as Menu from '#/components/Menu' 36 36 import * as Prompt from '#/components/Prompt' 37 37 import {Bubble_Stroke2_Corner2_Rounded as Bubble} from '../icons/Bubble' 38 + import {ReportDialog} from './ReportDialog' 38 39 39 40 let ConvoMenu = ({ 40 41 convo: initialConvo, ··· 44 45 showMarkAsRead, 45 46 hideTrigger, 46 47 blockInfo, 48 + latestReportableMessage, 47 49 style, 48 50 }: { 49 51 convo: ChatBskyConvoDefs.ConvoView ··· 56 58 listBlocks: ModerationCause[] 57 59 userBlock?: ModerationCause 58 60 } 61 + latestReportableMessage?: ChatBskyConvoDefs.MessageView 59 62 style?: ViewStyleProp['style'] 60 63 }): React.ReactNode => { 61 64 const navigation = useNavigation<NavigationProp>() ··· 222 225 convoId={convo.id} 223 226 currentScreen={currentScreen} 224 227 /> 225 - <ReportConversationPrompt control={reportControl} /> 228 + {latestReportableMessage ? ( 229 + <ReportDialog 230 + params={{ 231 + type: 'convoMessage', 232 + convoId: convo.id, 233 + message: latestReportableMessage, 234 + }} 235 + control={reportControl} 236 + /> 237 + ) : ( 238 + <ReportConversationPrompt control={reportControl} /> 239 + )} 240 + 226 241 <BlockedByListDialog 227 242 control={blockedByListControl} 228 243 listBlocks={listBlocks}
+10
src/components/dms/MessagesListHeader.tsx
··· 151 151 moderation.ui('displayName'), 152 152 ) 153 153 154 + const latestMessageFromOther = convoState.items.findLast( 155 + item => item.type === 'message' && item.message.sender.did === profile.did, 156 + ) 157 + 158 + const latestReportableMessage = 159 + latestMessageFromOther?.type === 'message' 160 + ? latestMessageFromOther.message 161 + : undefined 162 + 154 163 return ( 155 164 <View style={[a.flex_1]}> 156 165 <View style={[a.w_full, a.flex_row, a.align_center, a.justify_between]}> ··· 208 217 profile={profile} 209 218 currentScreen="conversation" 210 219 blockInfo={blockInfo} 220 + latestReportableMessage={latestReportableMessage} 211 221 /> 212 222 )} 213 223 </View>
+57 -46
src/screens/Messages/components/ChatListItem.tsx
··· 112 112 113 113 const isDimStyle = convo.muted || moderation.blocked || isDeletedAccount 114 114 115 - const {lastMessage, lastMessageSentAt} = useMemo(() => { 116 - let lastMessage = _(msg`No messages yet`) 117 - let lastMessageSentAt: string | null = null 115 + const {lastMessage, lastMessageSentAt, latestReportableMessage} = 116 + useMemo(() => { 117 + // eslint-disable-next-line @typescript-eslint/no-shadow 118 + let lastMessage = _(msg`No messages yet`) 119 + // eslint-disable-next-line @typescript-eslint/no-shadow 120 + let lastMessageSentAt: string | null = null 121 + // eslint-disable-next-line @typescript-eslint/no-shadow 122 + let latestReportableMessage: ChatBskyConvoDefs.MessageView | undefined 118 123 119 - if (ChatBskyConvoDefs.isMessageView(convo.lastMessage)) { 120 - const isFromMe = convo.lastMessage.sender?.did === currentAccount?.did 124 + if (ChatBskyConvoDefs.isMessageView(convo.lastMessage)) { 125 + const isFromMe = convo.lastMessage.sender?.did === currentAccount?.did 121 126 122 - if (convo.lastMessage.text) { 123 - if (isFromMe) { 124 - lastMessage = _(msg`You: ${convo.lastMessage.text}`) 125 - } else { 126 - lastMessage = convo.lastMessage.text 127 + if (!isFromMe) { 128 + latestReportableMessage = convo.lastMessage 127 129 } 128 - } else if (convo.lastMessage.embed) { 129 - const defaultEmbeddedContentMessage = _( 130 - msg`(contains embedded content)`, 131 - ) 130 + 131 + if (convo.lastMessage.text) { 132 + if (isFromMe) { 133 + lastMessage = _(msg`You: ${convo.lastMessage.text}`) 134 + } else { 135 + lastMessage = convo.lastMessage.text 136 + } 137 + } else if (convo.lastMessage.embed) { 138 + const defaultEmbeddedContentMessage = _( 139 + msg`(contains embedded content)`, 140 + ) 132 141 133 - if (AppBskyEmbedRecord.isView(convo.lastMessage.embed)) { 134 - const embed = convo.lastMessage.embed 142 + if (AppBskyEmbedRecord.isView(convo.lastMessage.embed)) { 143 + const embed = convo.lastMessage.embed 135 144 136 - if (AppBskyEmbedRecord.isViewRecord(embed.record)) { 137 - const record = embed.record 138 - const path = postUriToRelativePath(record.uri, { 139 - handle: record.author.handle, 140 - }) 141 - const href = path ? toBskyAppUrl(path) : undefined 142 - const short = href 143 - ? toShortUrl(href) 144 - : defaultEmbeddedContentMessage 145 + if (AppBskyEmbedRecord.isViewRecord(embed.record)) { 146 + const record = embed.record 147 + const path = postUriToRelativePath(record.uri, { 148 + handle: record.author.handle, 149 + }) 150 + const href = path ? toBskyAppUrl(path) : undefined 151 + const short = href 152 + ? toShortUrl(href) 153 + : defaultEmbeddedContentMessage 154 + if (isFromMe) { 155 + lastMessage = _(msg`You: ${short}`) 156 + } else { 157 + lastMessage = short 158 + } 159 + } 160 + } else { 145 161 if (isFromMe) { 146 - lastMessage = _(msg`You: ${short}`) 162 + lastMessage = _(msg`You: ${defaultEmbeddedContentMessage}`) 147 163 } else { 148 - lastMessage = short 164 + lastMessage = defaultEmbeddedContentMessage 149 165 } 150 166 } 151 - } else { 152 - if (isFromMe) { 153 - lastMessage = _(msg`You: ${defaultEmbeddedContentMessage}`) 154 - } else { 155 - lastMessage = defaultEmbeddedContentMessage 156 - } 157 167 } 168 + 169 + lastMessageSentAt = convo.lastMessage.sentAt 170 + } 171 + if (ChatBskyConvoDefs.isDeletedMessageView(convo.lastMessage)) { 172 + lastMessage = isDeletedAccount 173 + ? _(msg`Conversation deleted`) 174 + : _(msg`Message deleted`) 158 175 } 159 176 160 - lastMessageSentAt = convo.lastMessage.sentAt 161 - } 162 - if (ChatBskyConvoDefs.isDeletedMessageView(convo.lastMessage)) { 163 - lastMessage = isDeletedAccount 164 - ? _(msg`Conversation deleted`) 165 - : _(msg`Message deleted`) 166 - } 167 - 168 - return { 169 - lastMessage, 170 - lastMessageSentAt, 171 - } 172 - }, [_, convo.lastMessage, currentAccount?.did, isDeletedAccount]) 177 + return { 178 + lastMessage, 179 + lastMessageSentAt, 180 + latestReportableMessage, 181 + } 182 + }, [_, convo.lastMessage, currentAccount?.did, isDeletedAccount]) 173 183 174 184 const [showActions, setShowActions] = useState(false) 175 185 ··· 412 422 opacity: !gtMobile || showActions || menuControl.isOpen ? 1 : 0, 413 423 }, 414 424 ]} 425 + latestReportableMessage={latestReportableMessage} 415 426 /> 416 427 <LeaveConvoPrompt 417 428 control={leaveConvoControl}