import React from 'react' import {GestureResponderEvent, View} from 'react-native' import {AppBskyActorDefs, AppBskyFeedDefs, AtUri} from '@atproto/api' import {msg, plural, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' import {logger} from '#/logger' import { useAddSavedFeedsMutation, usePreferencesQuery, useRemoveFeedMutation, } from '#/state/queries/preferences' import {sanitizeHandle} from 'lib/strings/handles' import {useSession} from 'state/session' import {UserAvatar} from '#/view/com/util/UserAvatar' import * as Toast from 'view/com/util/Toast' import {useTheme} from '#/alf' import {atoms as a} from '#/alf' import {Button, ButtonIcon} from '#/components/Button' import {useRichText} from '#/components/hooks/useRichText' import {PlusLarge_Stroke2_Corner0_Rounded as Plus} from '#/components/icons/Plus' import {Trash_Stroke2_Corner0_Rounded as Trash} from '#/components/icons/Trash' import {Link as InternalLink} from '#/components/Link' import {Loader} from '#/components/Loader' import * as Prompt from '#/components/Prompt' import {RichText} from '#/components/RichText' import {Text} from '#/components/Typography' export function Default({feed}: {feed: AppBskyFeedDefs.GeneratorView}) { return (
) } export function Link({ children, feed, }: { children: React.ReactElement feed: AppBskyFeedDefs.GeneratorView }) { const href = React.useMemo(() => { const urip = new AtUri(feed.uri) const handleOrDid = feed.creator.handle || feed.creator.did return `/profile/${handleOrDid}/feed/${urip.rkey}` }, [feed]) return {children} } export function Outer({children}: {children: React.ReactNode}) { return {children} } export function Header({children}: {children: React.ReactNode}) { return {children} } export function Avatar({src}: {src: string | undefined}) { return } export function TitleAndByline({ title, creator, }: { title: string creator: AppBskyActorDefs.ProfileViewBasic }) { const t = useTheme() return ( {title} Feed by {sanitizeHandle(creator.handle, '@')} ) } export function Description({description}: {description?: string}) { const [rt, isResolving] = useRichText(description || '') if (!description) return null return isResolving ? ( ) : ( ) } export function Likes({count}: {count: number}) { const t = useTheme() return ( {plural(count || 0, { one: 'Liked by # user', other: 'Liked by # users', })} ) } export function Action({uri, pin}: {uri: string; pin?: boolean}) { const {hasSession} = useSession() if (!hasSession) return null return } function ActionInner({uri, pin}: {uri: string; pin?: boolean}) { const {_} = useLingui() const {data: preferences} = usePreferencesQuery() const {isPending: isAddSavedFeedPending, mutateAsync: saveFeeds} = useAddSavedFeedsMutation() const {isPending: isRemovePending, mutateAsync: removeFeed} = useRemoveFeedMutation() const savedFeedConfig = React.useMemo(() => { return preferences?.savedFeeds?.find( feed => feed.type === 'feed' && feed.value === uri, ) }, [preferences?.savedFeeds, uri]) const removePromptControl = Prompt.usePromptControl() const isPending = isAddSavedFeedPending || isRemovePending const toggleSave = React.useCallback( async (e: GestureResponderEvent) => { e.preventDefault() e.stopPropagation() try { if (savedFeedConfig) { await removeFeed(savedFeedConfig) } else { await saveFeeds([ { type: 'feed', value: uri, pinned: pin || false, }, ]) } Toast.show(_(msg`Feeds updated!`)) } catch (e: any) { logger.error(e, {context: `FeedCard: failed to update feeds`, pin}) Toast.show(_(msg`Failed to update feeds`)) } }, [_, pin, saveFeeds, removeFeed, uri, savedFeedConfig], ) const onPrompRemoveFeed = React.useCallback( async (e: GestureResponderEvent) => { e.preventDefault() e.stopPropagation() removePromptControl.open() }, [removePromptControl], ) return ( <> ) }