diff --git a/src/components/Post/Embed/StandardSiteEmbed/PublicationMetaRow.tsx b/src/components/Post/Embed/StandardSiteEmbed/PublicationMetaRow.tsx index 01e39bce90..5b63e34062 100644 --- a/src/components/Post/Embed/StandardSiteEmbed/PublicationMetaRow.tsx +++ b/src/components/Post/Embed/StandardSiteEmbed/PublicationMetaRow.tsx @@ -1,33 +1,39 @@ import {Fragment, type ReactNode} from 'react' import {View} from 'react-native' -import {type AppBskyEmbedExternal} from '@atproto/api' +import {type AppBskyEmbedExternal, AtUri} from '@atproto/api' import {Trans, useLingui} from '@lingui/react/macro' import {makeProfileLink} from '#/lib/routes/links' import {toNiceDomain} from '#/lib/strings/url-helpers' -import {useProfileQuery} from '#/state/queries/profile' import {atoms as a, useTheme} from '#/alf' +import {StandardSite} from '#/components/icons/community/StandardSite' import {InlineLinkText} from '#/components/Link' import {matchStandardSitePublisher} from '#/components/Post/Embed/StandardSiteEmbed/publishers' +import {isStandardSiteDocumentUri} from '#/components/Post/Embed/StandardSiteEmbed/utils' import {Text} from '#/components/Typography' export function PublicationMetaRow({ view, - author, onInteractWithin, onInteractWithout, }: { view: AppBskyEmbedExternal.ViewExternal - author: {did: string | null | undefined} onInteractWithin: () => void onInteractWithout: () => void }) { const t = useTheme() const {t: l} = useLingui() - const profileQuery = useProfileQuery({did: author.did ?? undefined}) - const handle = author.did ? profileQuery.data?.handle : undefined const highlightedPublisher = !!matchStandardSitePublisher(view) - + const didsFromRecords = + view.associatedRefs + ?.filter(isStandardSiteDocumentUri) + .map(ref => new AtUri(ref.uri).host) || [] + // atm should only be one docment + const authorDid = didsFromRecords.at(0) + const authorProfile = authorDid + ? view.associatedProfiles?.find(p => p.did === authorDid) + : undefined + const articleDomain = toNiceDomain(view.uri) const metaTextStyle = [ a.text_xs, a.leading_snug, @@ -36,18 +42,21 @@ export function PublicationMetaRow({ const items: {key: string; node: ReactNode}[] = [] - if (!highlightedPublisher && view.source?.uri) { + if (!highlightedPublisher) { items.push({ key: 'domain', node: ( - - {toNiceDomain(view.source.uri)} - + + + + {articleDomain} + + ), }) } - if (author.did && handle) { + if (authorProfile) { items.push({ key: 'author', node: ( @@ -55,8 +64,8 @@ export function PublicationMetaRow({ by{' '} { // this link is nested, yes it's not ideal @@ -64,7 +73,7 @@ export function PublicationMetaRow({ }} onMouseEnter={onInteractWithin} onMouseLeave={onInteractWithout}> - @{handle} + @{authorProfile.handle} diff --git a/src/components/Post/Embed/StandardSiteEmbed/index.tsx b/src/components/Post/Embed/StandardSiteEmbed/index.tsx index 9eacb9aafd..53bcf6a6be 100644 --- a/src/components/Post/Embed/StandardSiteEmbed/index.tsx +++ b/src/components/Post/Embed/StandardSiteEmbed/index.tsx @@ -14,8 +14,6 @@ import {ButtonIcon, ButtonText} from '#/components/Button' import {Divider} from '#/components/Divider' import {useInteractionState} from '#/components/hooks/useInteractionState' import {Clock_Stroke2_Corner0_Rounded as Clock} from '#/components/icons/Clock' -import {StandardSite} from '#/components/icons/community/StandardSite' -import {Earth_Stroke2_Corner0_Rounded as Globe} from '#/components/icons/Globe' import {Link} from '#/components/Link' import {MediaInsetBorder} from '#/components/MediaInsetBorder' import {PublicationMetaRow} from '#/components/Post/Embed/StandardSiteEmbed/PublicationMetaRow' @@ -74,12 +72,11 @@ export const StandardSiteEmbed = ({ } } - // Embeds are expected to associate with at most one publication; if multiple - // refs are ever present, the byline silently uses the first one. - const publicationUri = view.associatedRefs?.find( - ref => new AtUri(ref.uri).collection === 'site.standard.publication', - )?.uri - const maybeAuthorDid = publicationUri ? new AtUri(publicationUri)?.did : null + const { + state: interactedWithin, + onIn: onInteractWithin, + onOut: onInteractWithout, + } = useInteractionState() const onPress = () => { playHaptic('Light') @@ -96,7 +93,6 @@ export const StandardSiteEmbed = ({ if (isStandardPublication) { return ( - {({hovered}) => ( - - {imageUri ? ( - - ) : undefined} + {({hovered: maybeHovered}) => { + const hovered = maybeHovered && !interactedWithin + return ( + + {imageUri ? ( + + ) : undefined} - - - {view.title} - - {view.description ? ( - {view.description} - - ) : undefined} - - {isStandard && (view.createdAt || view.readingTime) && ( - - {view.createdAt && ( - - {niceDate(i18n, view.createdAt, 'medium', 'none')} - - )} - {view.readingTime && ( - - + {view.title} + + {view.description ? ( + + {view.description} + + ) : undefined} + + {isStandard && (view.createdAt || view.readingTime) && ( + + {view.createdAt && ( - {l({ - message: plural(view.readingTime, { - one: '#m', - other: '#m', - }), - comment: `How long it takes to read an article, in minutes. Displayed in a short form, e.g. "5m" for 5 minutes.`, - })} + {niceDate(i18n, view.createdAt, 'medium', 'none')} - - )} + )} + {view.readingTime && ( + + + + {l({ + message: plural(view.readingTime, { + one: '#m', + other: '#m', + }), + comment: `How long it takes to read an article, in minutes. Displayed in a short form, e.g. "5m" for 5 minutes.`, + })} + + + )} + + )} + + + {!view.source && ( + + + + + )} - - {!view.source && ( - - - - - - {toNiceDomain(view.uri)} - - - - )} - - )} + ) + }} {view.source && ( @@ -268,7 +242,6 @@ export const StandardSiteEmbed = ({ onPress={onPress} onLongPress={onLongPress} themeColors={themeColors} - author={{did: maybeAuthorDid}} /> )} @@ -283,7 +256,6 @@ export function PublicationCard({ onLongPress, themeColors, style, - author, }: { view: AppBskyEmbedExternal.ViewExternal hideSubscribe?: boolean @@ -291,7 +263,6 @@ export function PublicationCard({ onLongPress?: () => void themeColors: ThemeColors style?: StyleProp - author: {did: string | null | undefined} }) { const t = useTheme() const {t: l} = useLingui() @@ -361,7 +332,6 @@ export function PublicationCard({ @@ -450,6 +420,7 @@ function PublicationIcon({ themeColors: ThemeColors }) { const opacity = hovered ? 0.6 : 0.2 + if (!view.source) return null return view.source?.icon ? ( - + + {[...view.source.title][0] ?? ''} + void onLongPress?: () => void - author: {did: string | null | undefined} }) { const t = useTheme() const {t: l} = useLingui() @@ -573,7 +546,6 @@ export function PublicationFooter({ diff --git a/src/components/Post/Embed/StandardSiteEmbed/utils.ts b/src/components/Post/Embed/StandardSiteEmbed/utils.ts index 5985667e65..2338ca59a3 100644 --- a/src/components/Post/Embed/StandardSiteEmbed/utils.ts +++ b/src/components/Post/Embed/StandardSiteEmbed/utils.ts @@ -1,9 +1,25 @@ -import {type AppBskyEmbedExternal, AtUri} from '@atproto/api' +import { + type AppBskyEmbedExternal, + AtUri, + type ComAtprotoRepoStrongRef, +} from '@atproto/api' + +export function isStandardSiteDocumentUri(ref: ComAtprotoRepoStrongRef.Main) { + return new AtUri(ref.uri).collection.startsWith('site.standard.document') +} + +export function isStandardSitePublicationUri( + ref: ComAtprotoRepoStrongRef.Main, +) { + return new AtUri(ref.uri).collection.startsWith('site.standard.publication') +} + +export function isStandardSiteUri(ref: ComAtprotoRepoStrongRef.Main) { + return new AtUri(ref.uri).collection.startsWith('site.standard.') +} export function isStandardSiteEmbed(view: AppBskyEmbedExternal.ViewExternal) { - return view.associatedRefs?.some(ref => - new AtUri(ref.uri).collection.startsWith('site.standard.'), - ) + return view.associatedRefs?.some(ref => isStandardSiteUri(ref)) } export function isStandardSitePublicationEmbed(