Refactor post meta to return PostView (#5645)
This commit is contained in:
+3
-12
@@ -1,6 +1,5 @@
|
|||||||
import {
|
import {
|
||||||
AppBskyActorDefs,
|
AppBskyFeedDefs,
|
||||||
AppBskyFeedPost,
|
|
||||||
AppBskyGraphStarterpack,
|
AppBskyGraphStarterpack,
|
||||||
ComAtprotoRepoStrongRef,
|
ComAtprotoRepoStrongRef,
|
||||||
} from '@atproto/api'
|
} from '@atproto/api'
|
||||||
@@ -41,11 +40,7 @@ type ResolvedPostRecord = {
|
|||||||
type: 'record'
|
type: 'record'
|
||||||
record: ComAtprotoRepoStrongRef.Main
|
record: ComAtprotoRepoStrongRef.Main
|
||||||
kind: 'post'
|
kind: 'post'
|
||||||
meta: {
|
meta: AppBskyFeedDefs.PostView
|
||||||
text: string
|
|
||||||
indexedAt: string
|
|
||||||
author: AppBskyActorDefs.ProfileViewBasic
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type ResolvedOtherRecord = {
|
type ResolvedOtherRecord = {
|
||||||
@@ -92,11 +87,7 @@ export async function resolveLink(
|
|||||||
uri: post.uri,
|
uri: post.uri,
|
||||||
},
|
},
|
||||||
kind: 'post',
|
kind: 'post',
|
||||||
meta: {
|
meta: post,
|
||||||
text: AppBskyFeedPost.isRecord(post.record) ? post.record.text : '',
|
|
||||||
indexedAt: post.indexedAt,
|
|
||||||
author: post.author,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isBskyCustomFeedUrl(uri)) {
|
if (isBskyCustomFeedUrl(uri)) {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import React from 'react'
|
|||||||
import {
|
import {
|
||||||
AppBskyActorDefs,
|
AppBskyActorDefs,
|
||||||
AppBskyEmbedRecord,
|
AppBskyEmbedRecord,
|
||||||
AppBskyRichtextFacet,
|
AppBskyFeedDefs,
|
||||||
ModerationDecision,
|
ModerationDecision,
|
||||||
} from '@atproto/api'
|
} from '@atproto/api'
|
||||||
import {msg} from '@lingui/macro'
|
import {msg} from '@lingui/macro'
|
||||||
@@ -23,20 +23,11 @@ export interface ComposerOptsPostRef {
|
|||||||
embed?: AppBskyEmbedRecord.ViewRecord['embed']
|
embed?: AppBskyEmbedRecord.ViewRecord['embed']
|
||||||
moderation?: ModerationDecision
|
moderation?: ModerationDecision
|
||||||
}
|
}
|
||||||
export interface ComposerOptsQuote {
|
|
||||||
uri: string
|
|
||||||
cid: string
|
|
||||||
text: string
|
|
||||||
facets?: AppBskyRichtextFacet.Main[]
|
|
||||||
indexedAt: string
|
|
||||||
author: AppBskyActorDefs.ProfileViewBasic
|
|
||||||
embeds?: AppBskyEmbedRecord.ViewRecord['embeds']
|
|
||||||
}
|
|
||||||
export interface ComposerOpts {
|
export interface ComposerOpts {
|
||||||
replyTo?: ComposerOptsPostRef
|
replyTo?: ComposerOptsPostRef
|
||||||
onPost?: (postUri: string | undefined) => void
|
onPost?: (postUri: string | undefined) => void
|
||||||
quote?: ComposerOptsQuote
|
quote?: AppBskyFeedDefs.PostView
|
||||||
quoteCount?: number
|
|
||||||
mention?: string // handle of user to mention
|
mention?: string // handle of user to mention
|
||||||
openEmojiPicker?: (pos: DOMRect | undefined) => void
|
openEmojiPicker?: (pos: DOMRect | undefined) => void
|
||||||
text?: string
|
text?: string
|
||||||
@@ -75,11 +66,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
|
|||||||
cid: opts.quote.cid,
|
cid: opts.quote.cid,
|
||||||
uri: opts.quote.uri,
|
uri: opts.quote.uri,
|
||||||
},
|
},
|
||||||
meta: {
|
meta: opts.quote,
|
||||||
author: opts.quote.author,
|
|
||||||
indexedAt: opts.quote.indexedAt,
|
|
||||||
text: opts.quote.text,
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -129,7 +129,6 @@ export const ComposePost = ({
|
|||||||
replyTo,
|
replyTo,
|
||||||
onPost,
|
onPost,
|
||||||
quote: initQuote,
|
quote: initQuote,
|
||||||
quoteCount: initQuoteCount,
|
|
||||||
mention: initMention,
|
mention: initMention,
|
||||||
openEmojiPicker,
|
openEmojiPicker,
|
||||||
text: initText,
|
text: initText,
|
||||||
@@ -425,13 +424,13 @@ export const ComposePost = ({
|
|||||||
emitPostCreated()
|
emitPostCreated()
|
||||||
}
|
}
|
||||||
setLangPrefs.savePostLanguageToHistory()
|
setLangPrefs.savePostLanguageToHistory()
|
||||||
if (initQuote && initQuoteCount !== undefined) {
|
if (initQuote) {
|
||||||
// We want to wait for the quote count to update before we call `onPost`, which will refetch data
|
// We want to wait for the quote count to update before we call `onPost`, which will refetch data
|
||||||
whenAppViewReady(agent, initQuote.uri, res => {
|
whenAppViewReady(agent, initQuote.uri, res => {
|
||||||
const thread = res.data.thread
|
const thread = res.data.thread
|
||||||
if (
|
if (
|
||||||
AppBskyFeedDefs.isThreadViewPost(thread) &&
|
AppBskyFeedDefs.isThreadViewPost(thread) &&
|
||||||
thread.post.quoteCount !== initQuoteCount
|
thread.post.quoteCount !== initQuote.quoteCount
|
||||||
) {
|
) {
|
||||||
onPost?.(postUri)
|
onPost?.(postUri)
|
||||||
return true
|
return true
|
||||||
@@ -463,7 +462,6 @@ export const ComposePost = ({
|
|||||||
onPost,
|
onPost,
|
||||||
quote,
|
quote,
|
||||||
initQuote,
|
initQuote,
|
||||||
initQuoteCount,
|
|
||||||
replyTo,
|
replyTo,
|
||||||
richtext.text,
|
richtext.text,
|
||||||
setLangPrefs,
|
setLangPrefs,
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import {useLingui} from '@lingui/react'
|
|||||||
import {sanitizeDisplayName} from '#/lib/strings/display-names'
|
import {sanitizeDisplayName} from '#/lib/strings/display-names'
|
||||||
import {sanitizeHandle} from '#/lib/strings/handles'
|
import {sanitizeHandle} from '#/lib/strings/handles'
|
||||||
import {ComposerOptsPostRef} from '#/state/shell/composer'
|
import {ComposerOptsPostRef} from '#/state/shell/composer'
|
||||||
import {QuoteEmbed} from '#/view/com/util/post-embeds/QuoteEmbed'
|
import {MaybeQuoteEmbed} from '#/view/com/util/post-embeds/QuoteEmbed'
|
||||||
import {Text} from '#/view/com/util/text/Text'
|
import {Text} from '#/view/com/util/text/Text'
|
||||||
import {PreviewableUserAvatar} from '#/view/com/util/UserAvatar'
|
import {PreviewableUserAvatar} from '#/view/com/util/UserAvatar'
|
||||||
import {atoms as a, useTheme} from '#/alf'
|
import {atoms as a, useTheme} from '#/alf'
|
||||||
@@ -33,33 +33,21 @@ export function ComposerReplyTo({replyTo}: {replyTo: ComposerOptsPostRef}) {
|
|||||||
})
|
})
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const quote = React.useMemo(() => {
|
const quoteEmbed = React.useMemo(() => {
|
||||||
if (
|
if (
|
||||||
AppBskyEmbedRecord.isView(embed) &&
|
AppBskyEmbedRecord.isView(embed) &&
|
||||||
AppBskyEmbedRecord.isViewRecord(embed.record) &&
|
AppBskyEmbedRecord.isViewRecord(embed.record) &&
|
||||||
AppBskyFeedPost.isRecord(embed.record.value)
|
AppBskyFeedPost.isRecord(embed.record.value)
|
||||||
) {
|
) {
|
||||||
// Not going to include the images right now
|
return embed
|
||||||
return {
|
|
||||||
author: embed.record.author,
|
|
||||||
cid: embed.record.cid,
|
|
||||||
uri: embed.record.uri,
|
|
||||||
indexedAt: embed.record.indexedAt,
|
|
||||||
text: embed.record.value.text,
|
|
||||||
}
|
|
||||||
} else if (
|
} else if (
|
||||||
AppBskyEmbedRecordWithMedia.isView(embed) &&
|
AppBskyEmbedRecordWithMedia.isView(embed) &&
|
||||||
AppBskyEmbedRecord.isViewRecord(embed.record.record) &&
|
AppBskyEmbedRecord.isViewRecord(embed.record.record) &&
|
||||||
AppBskyFeedPost.isRecord(embed.record.record.value)
|
AppBskyFeedPost.isRecord(embed.record.record.value)
|
||||||
) {
|
) {
|
||||||
return {
|
return embed.record
|
||||||
author: embed.record.record.author,
|
|
||||||
cid: embed.record.record.cid,
|
|
||||||
uri: embed.record.record.uri,
|
|
||||||
indexedAt: embed.record.record.indexedAt,
|
|
||||||
text: embed.record.record.value.text,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return null
|
||||||
}, [embed])
|
}, [embed])
|
||||||
|
|
||||||
const images = React.useMemo(() => {
|
const images = React.useMemo(() => {
|
||||||
@@ -110,7 +98,7 @@ export function ComposerReplyTo({replyTo}: {replyTo: ComposerOptsPostRef}) {
|
|||||||
<ComposerReplyToImages images={images} showFull={showFull} />
|
<ComposerReplyToImages images={images} showFull={showFull} />
|
||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
{showFull && quote && <QuoteEmbed quote={quote} />}
|
{showFull && quoteEmbed && <MaybeQuoteEmbed embed={quoteEmbed} />}
|
||||||
</View>
|
</View>
|
||||||
</Pressable>
|
</Pressable>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -199,27 +199,15 @@ let PostCtrls = ({
|
|||||||
feedContext,
|
feedContext,
|
||||||
})
|
})
|
||||||
openComposer({
|
openComposer({
|
||||||
quote: {
|
quote: post,
|
||||||
uri: post.uri,
|
|
||||||
cid: post.cid,
|
|
||||||
text: record.text,
|
|
||||||
author: post.author,
|
|
||||||
indexedAt: post.indexedAt,
|
|
||||||
},
|
|
||||||
quoteCount: post.quoteCount,
|
|
||||||
onPost: onPostReply,
|
onPost: onPostReply,
|
||||||
})
|
})
|
||||||
}, [
|
}, [
|
||||||
_,
|
_,
|
||||||
sendInteraction,
|
sendInteraction,
|
||||||
post.uri,
|
post,
|
||||||
post.cid,
|
|
||||||
post.author,
|
|
||||||
post.indexedAt,
|
|
||||||
post.quoteCount,
|
|
||||||
feedContext,
|
feedContext,
|
||||||
openComposer,
|
openComposer,
|
||||||
record.text,
|
|
||||||
onPostReply,
|
onPostReply,
|
||||||
isBlocked,
|
isBlocked,
|
||||||
])
|
])
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
|||||||
import {precacheProfile} from '#/state/queries/profile'
|
import {precacheProfile} from '#/state/queries/profile'
|
||||||
import {useResolveLinkQuery} from '#/state/queries/resolve-link'
|
import {useResolveLinkQuery} from '#/state/queries/resolve-link'
|
||||||
import {useSession} from '#/state/session'
|
import {useSession} from '#/state/session'
|
||||||
import {ComposerOptsQuote} from '#/state/shell/composer'
|
|
||||||
import {atoms as a, useTheme} from '#/alf'
|
import {atoms as a, useTheme} from '#/alf'
|
||||||
import {RichText} from '#/components/RichText'
|
import {RichText} from '#/components/RichText'
|
||||||
import {ContentHider} from '../../../../components/moderation/ContentHider'
|
import {ContentHider} from '../../../../components/moderation/ContentHider'
|
||||||
@@ -68,7 +67,6 @@ export function MaybeQuoteEmbed({
|
|||||||
return (
|
return (
|
||||||
<QuoteEmbedModerated
|
<QuoteEmbedModerated
|
||||||
viewRecord={embed.record}
|
viewRecord={embed.record}
|
||||||
postRecord={embed.record.value}
|
|
||||||
onOpen={onOpen}
|
onOpen={onOpen}
|
||||||
style={style}
|
style={style}
|
||||||
allowNestedQuotes={allowNestedQuotes}
|
allowNestedQuotes={allowNestedQuotes}
|
||||||
@@ -118,39 +116,31 @@ export function MaybeQuoteEmbed({
|
|||||||
|
|
||||||
function QuoteEmbedModerated({
|
function QuoteEmbedModerated({
|
||||||
viewRecord,
|
viewRecord,
|
||||||
postRecord,
|
|
||||||
onOpen,
|
onOpen,
|
||||||
style,
|
style,
|
||||||
allowNestedQuotes,
|
allowNestedQuotes,
|
||||||
viewContext,
|
viewContext,
|
||||||
}: {
|
}: {
|
||||||
viewRecord: AppBskyEmbedRecord.ViewRecord
|
viewRecord: AppBskyEmbedRecord.ViewRecord
|
||||||
postRecord: AppBskyFeedPost.Record
|
|
||||||
onOpen?: () => void
|
onOpen?: () => void
|
||||||
style?: StyleProp<ViewStyle>
|
style?: StyleProp<ViewStyle>
|
||||||
allowNestedQuotes?: boolean
|
allowNestedQuotes?: boolean
|
||||||
viewContext?: QuoteEmbedViewContext
|
viewContext?: QuoteEmbedViewContext
|
||||||
}) {
|
}) {
|
||||||
const moderationOpts = useModerationOpts()
|
const moderationOpts = useModerationOpts()
|
||||||
|
const postView = React.useMemo(
|
||||||
|
() => viewRecordToPostView(viewRecord),
|
||||||
|
[viewRecord],
|
||||||
|
)
|
||||||
const moderation = React.useMemo(() => {
|
const moderation = React.useMemo(() => {
|
||||||
return moderationOpts
|
return moderationOpts
|
||||||
? moderatePost_wrapped(viewRecordToPostView(viewRecord), moderationOpts)
|
? moderatePost_wrapped(postView, moderationOpts)
|
||||||
: undefined
|
: undefined
|
||||||
}, [viewRecord, moderationOpts])
|
}, [postView, moderationOpts])
|
||||||
|
|
||||||
const quote = {
|
|
||||||
author: viewRecord.author,
|
|
||||||
cid: viewRecord.cid,
|
|
||||||
uri: viewRecord.uri,
|
|
||||||
indexedAt: viewRecord.indexedAt,
|
|
||||||
text: postRecord.text,
|
|
||||||
facets: postRecord.facets,
|
|
||||||
embeds: viewRecord.embeds,
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<QuoteEmbed
|
<QuoteEmbed
|
||||||
quote={quote}
|
quote={postView}
|
||||||
moderation={moderation}
|
moderation={moderation}
|
||||||
onOpen={onOpen}
|
onOpen={onOpen}
|
||||||
style={style}
|
style={style}
|
||||||
@@ -167,7 +157,7 @@ export function QuoteEmbed({
|
|||||||
style,
|
style,
|
||||||
allowNestedQuotes,
|
allowNestedQuotes,
|
||||||
}: {
|
}: {
|
||||||
quote: ComposerOptsQuote
|
quote: AppBskyFeedDefs.PostView
|
||||||
moderation?: ModerationDecision
|
moderation?: ModerationDecision
|
||||||
onOpen?: () => void
|
onOpen?: () => void
|
||||||
style?: StyleProp<ViewStyle>
|
style?: StyleProp<ViewStyle>
|
||||||
@@ -181,16 +171,18 @@ export function QuoteEmbed({
|
|||||||
const itemHref = makeProfileLink(quote.author, 'post', itemUrip.rkey)
|
const itemHref = makeProfileLink(quote.author, 'post', itemUrip.rkey)
|
||||||
const itemTitle = `Post by ${quote.author.handle}`
|
const itemTitle = `Post by ${quote.author.handle}`
|
||||||
|
|
||||||
const richText = React.useMemo(
|
const richText = React.useMemo(() => {
|
||||||
() =>
|
const text = AppBskyFeedPost.isRecord(quote.record) ? quote.record.text : ''
|
||||||
quote.text.trim()
|
const facets = AppBskyFeedPost.isRecord(quote.record)
|
||||||
? new RichTextAPI({text: quote.text, facets: quote.facets})
|
? quote.record.facets
|
||||||
: undefined,
|
: undefined
|
||||||
[quote.text, quote.facets],
|
return text.trim()
|
||||||
)
|
? new RichTextAPI({text: text, facets: facets})
|
||||||
|
: undefined
|
||||||
|
}, [quote.record])
|
||||||
|
|
||||||
const embed = React.useMemo(() => {
|
const embed = React.useMemo(() => {
|
||||||
const e = quote.embeds?.[0]
|
const e = quote.embed
|
||||||
|
|
||||||
if (allowNestedQuotes) {
|
if (allowNestedQuotes) {
|
||||||
return e
|
return e
|
||||||
@@ -210,7 +202,7 @@ export function QuoteEmbed({
|
|||||||
return e.media
|
return e.media
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [quote.embeds, allowNestedQuotes])
|
}, [quote.embed, allowNestedQuotes])
|
||||||
|
|
||||||
const onBeforePress = React.useCallback(() => {
|
const onBeforePress = React.useCallback(() => {
|
||||||
precacheProfile(queryClient, quote.author)
|
precacheProfile(queryClient, quote.author)
|
||||||
@@ -292,17 +284,7 @@ export function LazyQuoteEmbed({uri}: {uri: string}) {
|
|||||||
if (!data || data.type !== 'record' || data.kind !== 'post') {
|
if (!data || data.type !== 'record' || data.kind !== 'post') {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
return (
|
return <QuoteEmbed quote={data.meta} />
|
||||||
<QuoteEmbed
|
|
||||||
quote={{
|
|
||||||
cid: data.record.cid,
|
|
||||||
uri: data.record.uri,
|
|
||||||
author: data.meta.author,
|
|
||||||
indexedAt: data.meta.indexedAt,
|
|
||||||
text: data.meta.text,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function viewRecordToPostView(
|
function viewRecordToPostView(
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ export function Composer({}: {winHeight: number}) {
|
|||||||
replyTo={state?.replyTo}
|
replyTo={state?.replyTo}
|
||||||
onPost={state?.onPost}
|
onPost={state?.onPost}
|
||||||
quote={state?.quote}
|
quote={state?.quote}
|
||||||
quoteCount={state?.quoteCount}
|
|
||||||
mention={state?.mention}
|
mention={state?.mention}
|
||||||
text={state?.text}
|
text={state?.text}
|
||||||
imageUris={state?.imageUris}
|
imageUris={state?.imageUris}
|
||||||
|
|||||||
@@ -50,7 +50,6 @@ export function Composer({winHeight}: {winHeight: number}) {
|
|||||||
replyTo={state.replyTo}
|
replyTo={state.replyTo}
|
||||||
onPost={state.onPost}
|
onPost={state.onPost}
|
||||||
quote={state.quote}
|
quote={state.quote}
|
||||||
quoteCount={state.quoteCount}
|
|
||||||
mention={state.mention}
|
mention={state.mention}
|
||||||
text={state.text}
|
text={state.text}
|
||||||
imageUris={state.imageUris}
|
imageUris={state.imageUris}
|
||||||
|
|||||||
@@ -94,7 +94,6 @@ function Inner({state}: {state: ComposerOpts}) {
|
|||||||
cancelRef={ref}
|
cancelRef={ref}
|
||||||
replyTo={state.replyTo}
|
replyTo={state.replyTo}
|
||||||
quote={state.quote}
|
quote={state.quote}
|
||||||
quoteCount={state?.quoteCount}
|
|
||||||
onPost={state.onPost}
|
onPost={state.onPost}
|
||||||
mention={state.mention}
|
mention={state.mention}
|
||||||
openEmojiPicker={onOpenPicker}
|
openEmojiPicker={onOpenPicker}
|
||||||
|
|||||||
Reference in New Issue
Block a user