Display more information in chat replies (#10950)
This commit is contained in:
@@ -44,12 +44,13 @@ import {useProfileBlockMutationQueue} from '#/state/queries/profile'
|
||||
import {unstableCacheProfileView} from '#/state/queries/unstable-profile-cache'
|
||||
import {useSession} from '#/state/session'
|
||||
import {PreviewableUserAvatar} from '#/view/com/util/UserAvatar'
|
||||
import {atoms as a, native, platform, useTheme, utils} from '#/alf'
|
||||
import {atoms as a, native, platform, tokens, useTheme, utils} from '#/alf'
|
||||
import {isOnlyEmoji} from '#/alf/typography'
|
||||
import {Button} from '#/components/Button'
|
||||
import {ActionsWrapper} from '#/components/dms/ActionsWrapper'
|
||||
import {useMessageDialogs} from '#/components/dms/MessageOverlays'
|
||||
import {useMessageReplies} from '#/components/dms/MessageReplies'
|
||||
import {useReplyPreviewText} from '#/components/dms/replyPreview'
|
||||
import {ArrowCornerDownRight_Stroke2_Corner3_Rounded as ArrowCornerDownRightIcon} from '#/components/icons/ArrowCornerDownRight'
|
||||
import {InlineLinkText} from '#/components/Link'
|
||||
import * as ProfileCard from '#/components/ProfileCard'
|
||||
@@ -834,6 +835,7 @@ function ReplyQuote({
|
||||
}) {
|
||||
const t = useTheme()
|
||||
const {t: l} = useLingui()
|
||||
const getReplyPreviewText = useReplyPreviewText()
|
||||
|
||||
const senderProfile = useMaybeProfileShadow(
|
||||
relatedProfiles.get(replyTo.sender.did),
|
||||
@@ -857,22 +859,15 @@ function ReplyQuote({
|
||||
let text: string
|
||||
let subtle = false
|
||||
if (isBlocked) {
|
||||
text = l`Blocked message hidden`
|
||||
text = l({
|
||||
message: '(blocked message hidden)',
|
||||
comment: 'A reply summary in chat',
|
||||
})
|
||||
subtle = true
|
||||
} else if (ChatBskyConvoDefs.isMessageView(replyTo)) {
|
||||
text = replyTo.text
|
||||
if (!text.trim()) {
|
||||
subtle = true
|
||||
if (ChatBskyEmbedJoinLink.isView(replyTo.embed)) {
|
||||
text = l`(chat invite link)`
|
||||
} else if (AppBskyEmbedRecord.isView(replyTo.embed)) {
|
||||
text = l`(contains embedded content)`
|
||||
} else {
|
||||
text = l`No text`
|
||||
}
|
||||
}
|
||||
;({text, subtle} = getReplyPreviewText(replyTo))
|
||||
} else {
|
||||
text = l`Deleted message`
|
||||
text = l({message: '(deleted message)', comment: 'A reply summary in chat'})
|
||||
subtle = true
|
||||
}
|
||||
|
||||
@@ -888,6 +883,8 @@ function ReplyQuote({
|
||||
a.mb_xs,
|
||||
a.rounded_md,
|
||||
a.p_sm,
|
||||
// The padding above is a little loose, so we tighten it up here.
|
||||
{paddingTop: tokens.space.sm - 2},
|
||||
a.flex_col,
|
||||
a.align_start,
|
||||
a.border,
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
import {
|
||||
AppBskyEmbedExternal,
|
||||
AppBskyEmbedRecord,
|
||||
type ChatBskyConvoDefs,
|
||||
ChatBskyEmbedJoinLink,
|
||||
ChatBskyGroupDefs,
|
||||
} from '@atproto/api'
|
||||
import {useLingui} from '@lingui/react/macro'
|
||||
|
||||
import {BSKY_APP_HOST, toShortUrl} from '#/lib/strings/url-helpers'
|
||||
|
||||
/**
|
||||
* Describes the embed of a quoted message that has no text of its own, so the
|
||||
* reply preview can show what was shared instead of a generic placeholder. For
|
||||
* a link card we surface the URI directly; otherwise we classify the quoted
|
||||
* record (post/feed/list/etc.) so the caller can render a translated label.
|
||||
*/
|
||||
type ReplyEmbedSummary =
|
||||
| {type: 'external'; uri: string}
|
||||
| {type: 'post'}
|
||||
| {type: 'unknown'}
|
||||
|
||||
function summarizeReplyEmbed(
|
||||
embed: ChatBskyConvoDefs.MessageView['embed'],
|
||||
): ReplyEmbedSummary {
|
||||
if (!AppBskyEmbedRecord.isView(embed)) return {type: 'unknown'}
|
||||
const {record} = embed
|
||||
if (AppBskyEmbedRecord.isViewRecord(record)) {
|
||||
const inner = record.embeds?.[0]
|
||||
if (AppBskyEmbedExternal.isView(inner)) {
|
||||
return {type: 'external', uri: inner.external.uri}
|
||||
}
|
||||
return {type: 'post'}
|
||||
}
|
||||
return {type: 'unknown'}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a formatter that computes the preview text for a message being quoted
|
||||
* in a reply, shared between the staged-reply composer and the sent reply
|
||||
* bubble so the two stay in sync. When the message has its own text we use it
|
||||
* verbatim; otherwise we summarize the embed.
|
||||
*
|
||||
* `subtle` indicates the text is a placeholder (not real message content), so
|
||||
* callers can render it in a muted/italic style.
|
||||
*/
|
||||
export function useReplyPreviewText(): (
|
||||
message: ChatBskyConvoDefs.MessageView,
|
||||
) => {text: string; subtle: boolean} {
|
||||
const {t: l} = useLingui()
|
||||
|
||||
return (message: ChatBskyConvoDefs.MessageView) => {
|
||||
const text = message.text
|
||||
if (text.trim()) {
|
||||
return {text, subtle: false}
|
||||
}
|
||||
|
||||
if (ChatBskyEmbedJoinLink.isView(message.embed)) {
|
||||
const {joinLinkPreview} = message.embed
|
||||
if (ChatBskyGroupDefs.isJoinLinkPreviewView(joinLinkPreview)) {
|
||||
return {
|
||||
text: `${BSKY_APP_HOST}/chat/${joinLinkPreview.code}`,
|
||||
subtle: true,
|
||||
}
|
||||
}
|
||||
if (ChatBskyGroupDefs.isDisabledJoinLinkPreviewView(joinLinkPreview)) {
|
||||
return {
|
||||
text: l({
|
||||
message: '(disabled chat invite link)',
|
||||
comment: 'A reply summary in chat',
|
||||
}),
|
||||
subtle: true,
|
||||
}
|
||||
}
|
||||
if (ChatBskyGroupDefs.isInvalidJoinLinkPreviewView(joinLinkPreview)) {
|
||||
return {
|
||||
text: l({
|
||||
message: '(invalid chat invite link)',
|
||||
comment: 'A reply summary in chat',
|
||||
}),
|
||||
subtle: true,
|
||||
}
|
||||
}
|
||||
return {
|
||||
text: l({
|
||||
message: '(chat invite link)',
|
||||
comment: 'A reply summary in chat',
|
||||
}),
|
||||
subtle: true,
|
||||
}
|
||||
}
|
||||
|
||||
const summary = summarizeReplyEmbed(message.embed)
|
||||
switch (summary.type) {
|
||||
case 'external':
|
||||
return {text: toShortUrl(summary.uri), subtle: true}
|
||||
case 'post':
|
||||
return {
|
||||
text: l({
|
||||
message: '(quoted post)',
|
||||
comment: 'A reply summary in chat',
|
||||
}),
|
||||
subtle: true,
|
||||
}
|
||||
default:
|
||||
return {
|
||||
text: l({message: '(no text)', comment: 'A reply summary in chat'}),
|
||||
subtle: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user