Something went wrong. Try again.
Bluesky app fork with some witchin' additions 💫 forked from jollywhoppers.com/witchsky.app
Something went wrong. Try again.
4.2 kB · 167 lines
TSX
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168import React from 'react'import {View} from 'react-native'import { type AppBskyGraphDefs, AtUri, moderateUserList, type ModerationUI,} from '@atproto/api'import {msg, Trans} from '@lingui/macro'import {useLingui} from '@lingui/react'import {useQueryClient} from '@tanstack/react-query'
import {sanitizeHandle} from '#/lib/strings/handles'import {useModerationOpts} from '#/state/preferences/moderation-opts'import {precacheList} from '#/state/queries/feed'import {useSession} from '#/state/session'import {atoms as a, useTheme} from '#/alf'import { Avatar, Description, Header, Outer, SaveButton,} from '#/components/FeedCard'import {Link as InternalLink, type LinkProps} from '#/components/Link'import * as Hider from '#/components/moderation/Hider'import {Text} from '#/components/Typography'import type * as bsky from '#/types/bsky'
/* * This component is based on `FeedCard` and is tightly coupled with that * component. Please refer to `FeedCard` for more context. */
export { Avatar, AvatarPlaceholder, Description, Header, Outer, SaveButton, TitleAndBylinePlaceholder,} from '#/components/FeedCard'
const CURATELIST = 'app.bsky.graph.defs#curatelist'const MODLIST = 'app.bsky.graph.defs#modlist'
type Props = { view: AppBskyGraphDefs.ListView showPinButton?: boolean}
export function Default( props: Props & Omit<LinkProps, 'to' | 'label' | 'children'>,) { const {view, showPinButton} = props const moderationOpts = useModerationOpts() const moderation = moderationOpts ? moderateUserList(view, moderationOpts) : undefined
return ( <Link {...props}> <Outer> <Header> <Avatar src={view.avatar} /> <TitleAndByline title={view.name} creator={view.creator} purpose={view.purpose} modUi={moderation?.ui('contentView')} /> {showPinButton && view.purpose === CURATELIST && ( <SaveButton view={view} pin /> )} </Header> <Description description={view.description} /> </Outer> </Link> )}
export function Link({ view, children, ...props}: Props & Omit<LinkProps, 'to' | 'label'>) { const queryClient = useQueryClient()
const href = React.useMemo(() => { return createProfileListHref({list: view}) }, [view])
React.useEffect(() => { precacheList(queryClient, view) }, [view, queryClient])
return ( <InternalLink label={view.name} to={href} {...props}> {children} </InternalLink> )}
export function TitleAndByline({ title, creator, purpose = CURATELIST, modUi,}: { title: string creator?: bsky.profile.AnyProfileView purpose?: AppBskyGraphDefs.ListView['purpose'] modUi?: ModerationUI}) { const t = useTheme() const {_} = useLingui() const {currentAccount} = useSession()
return ( <View style={[a.flex_1]}> <Hider.Outer modui={modUi} isContentVisibleInitialState={ creator && currentAccount?.did === creator.did } allowOverride={creator && currentAccount?.did === creator.did}> <Hider.Mask> <Text style={[a.text_md, a.font_semi_bold, a.leading_snug, a.italic]} numberOfLines={1}> <Trans>Hidden list</Trans> </Text> </Hider.Mask> <Hider.Content> <Text emoji style={[a.text_md, a.font_semi_bold, a.leading_snug]} numberOfLines={1}> {title} </Text> </Hider.Content> </Hider.Outer>
{creator && ( <Text emoji style={[a.leading_snug, t.atoms.text_contrast_medium]} numberOfLines={1}> {purpose === MODLIST ? _(msg`Moderation list by ${sanitizeHandle(creator.handle, '@')}`) : _(msg`List by ${sanitizeHandle(creator.handle, '@')}`)} </Text> )} </View> )}
export function createProfileListHref({ list,}: { list: AppBskyGraphDefs.ListView}) { const urip = new AtUri(list.uri) const handleOrDid = list.creator.handle || list.creator.did return `/profile/${handleOrDid}/lists/${urip.rkey}`}