Bluesky app fork with some witchin' additions 💫

Compare changes

Choose any two refs to compare.

+146 -12
+1
assets/icons/tealfm.svg
···
··· 1 + <svg xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" clip-rule="evenodd" viewBox="0 0 80 80"><g transform="translate(0 -3)"><circle cx="40" cy="43" r="40" fill="#14B8A6"/><path fill="#fff" fill-rule="nonzero" d="M12.92 48.284c1.105 0 2.065.384 2.833 1.152s1.152 1.68 1.152 2.784-.384 2.064-1.152 2.832-1.728 1.152-2.832 1.152-2.064-.384-2.784-1.152c-.768-.816-1.152-1.776-1.152-2.832s.384-1.968 1.152-2.784c.768-.768 1.68-1.152 2.784-1.152ZM30.843 37.34l-3.12 13.584c-.48 2.16-1.152 4.416-1.968 6.768-1.248 3.456-2.689 6.048-4.369 7.68-1.488 1.488-2.976 2.208-4.463 2.208-.816 0-1.44-.24-1.872-.672-.385-.384-.528-.912-.528-1.536 0-.912.335-1.68 1.056-2.16.287-.192.624-.336 1.008-.336.576 0 1.152.384 1.776 1.2.335.384.576.576.816.576.192 0 .384-.192.624-.624s.575-1.296.912-2.688c.48-1.584.816-3.024 1.055-4.272l3.552-19.728H21.82c-.433 0-.624-.096-.624-.288 0-.048.047-.288.143-.624l.192-.72c.048-.288.145-.432.24-.48.049-.048.24-.048.672-.048h3.264c.145-.72.24-1.2.24-1.392.384-2.16.624-3.552.768-4.128.145-.624.385-1.344.72-2.208 2.305-6 5.665-9.024 10.128-9.024 1.68 0 2.928.432 3.84 1.296q.864.864.864 1.872c0 .576-.191 1.104-.672 1.536-.431.432-.911.672-1.488.672-.432 0-.768-.144-1.104-.384-.288-.192-.623-.672-.96-1.392-.48-1.008-1.008-1.488-1.632-1.488-.335 0-.816.192-1.343.624-.577.384-.96.96-1.297 1.776-.768 2.112-1.488 5.28-2.112 9.408-.096.528-.24 1.488-.431 2.832h4.32c.431 0 .624.048.624.192v.192c-.048.144-.096.24-.096.288l-.193.768c-.047.384-.143.576-.191.624-.097.048-.288.096-.672.096h-4.176ZM36.79 40.844l-1.103-.672a17.4 17.4 0 0 1 2.112-3.552c1.584-1.92 3.12-2.928 4.656-2.928 1.584 0 2.4.96 2.4 2.784 0 1.056-.24 2.496-.672 4.368.336-.384 1.008-1.296 2.112-2.736s2.448-2.592 4.08-3.504c1.056-.576 2.16-.912 3.36-.912.96 0 1.728.288 2.4.816.672.576 1.056 1.344 1.056 2.352 0 .288-.192 1.44-.624 3.456.288-.288 1.296-1.392 3.072-3.264.96-1.056 2.16-1.92 3.552-2.592a9.2 9.2 0 0 1 3.648-.768c.864 0 1.536.288 2.112.816.672.624 1.008 1.44 1.008 2.4q0 2.016-2.304 7.776c-1.296 3.168-1.92 5.232-1.92 6.144 0 .768.288 1.104.912 1.104q1.008 0 3.312-3.168l1.056 1.104c-3.12 4.224-5.952 6.384-8.352 6.384-.864 0-1.488-.288-1.968-.864-.48-.48-.672-1.104-.672-1.872 0-1.152.816-3.648 2.4-7.536 1.632-4.032 2.448-6.48 2.448-7.488q0-.648-.432-1.008c-.336-.288-.672-.432-1.104-.432-.96 0-2.16.72-3.6 2.112-1.632 1.632-3.168 4.128-4.656 7.584-1.104 2.64-1.968 4.896-2.592 6.72q-.648 1.944-.864 2.16c-.24.24-.72.336-1.392.336-1.056 0-1.92-.096-2.496-.336-.288-.144-.432-.288-.432-.528 0-.192.096-.528.24-.96l3.6-10.272c.768-2.304 1.2-3.936 1.2-4.944 0-.528-.144-.96-.48-1.296-.288-.384-.72-.576-1.2-.576-.912 0-1.92.576-2.928 1.776-1.344 1.488-2.88 4.272-4.656 8.448-.096.24-.72 1.824-1.824 4.656-.624 1.584-.96 2.448-1.008 2.64-.192.624-.48 1.008-.72 1.152-.288.192-.72.24-1.296.24-1.824 0-2.784-.336-2.784-1.056q0-.576.288-1.296l3.024-7.68c.24-.528.624-1.776 1.248-3.792.336-1.056.528-1.776.528-2.208 0-.384-.096-.672-.288-.912a.92.92 0 0 0-.768-.432c-.864 0-1.776.768-2.688 2.256Z"/></g></svg>
+42
src/components/icons/Tealfm.tsx
···
··· 1 + import Svg, {Path} from 'react-native-svg' 2 + 3 + import {type Props, useCommonSVGProps} from './common' 4 + import {createSinglePathSVG} from './TEMPLATE' 5 + 6 + export const Mark = createSinglePathSVG({ 7 + path: 'M6.335 4.212c2.293 1.76 4.76 5.327 5.665 7.241.906-1.914 3.372-5.482 5.665-7.241C19.319 2.942 22 1.96 22 5.086c0 .624-.35 5.244-.556 5.994-.713 2.608-3.315 3.273-5.629 2.87 4.045.704 5.074 3.035 2.852 5.366-4.22 4.426-6.066-1.111-6.54-2.53-.086-.26-.126-.382-.127-.278 0-.104-.041.018-.128.278-.473 1.419-2.318 6.956-6.539 2.53-2.222-2.331-1.193-4.662 2.852-5.366-2.314.403-4.916-.262-5.63-2.87C2.35 10.33 2 5.71 2 5.086c0-3.126 2.68-2.144 4.335-.874Z', 8 + }) 9 + 10 + export function Full( 11 + props: Omit<Props, 'fill' | 'size' | 'height'> & { 12 + markFill?: Props['fill'] 13 + textFill?: Props['fill'] 14 + }, 15 + ) { 16 + const {fill, size, style, gradient, ...rest} = useCommonSVGProps(props) 17 + const ratio = 123 / 555 18 + 19 + return ( 20 + <Svg 21 + fill="none" 22 + {...rest} 23 + viewBox="0 0 555 123" 24 + width={size} 25 + height={size * ratio} 26 + style={[style]}> 27 + {gradient} 28 + <Path 29 + fill={props.markFill ?? fill} 30 + fillRule="evenodd" 31 + clipRule="evenodd" 32 + d="M101.821 7.673C112.575-.367 130-6.589 130 13.21c0 3.953-2.276 33.214-3.611 37.965-4.641 16.516-21.549 20.729-36.591 18.179 26.292 4.457 32.979 19.218 18.535 33.98-27.433 28.035-39.428-7.034-42.502-16.02-.563-1.647-.827-2.418-.831-1.763-.004-.655-.268.116-.831 1.763-3.074 8.986-15.07 44.055-42.502 16.02C7.223 88.571 13.91 73.81 40.202 69.353c-15.041 2.55-31.95-1.663-36.59-18.179C2.275 46.424 0 17.162 0 13.21 0-6.59 17.426-.368 28.18 7.673 43.084 18.817 59.114 41.413 65 53.54c5.886-12.125 21.917-34.722 36.821-45.866Z" 33 + /> 34 + <Path 35 + fill={props.textFill ?? fill} 36 + fillRule="evenodd" 37 + clipRule="evenodd" 38 + d="m454.459 63.823 24.128-25.056h32.638l4.825 15.104c3.561 11.357 6.664 22.598 9.422 33.72 2.527-9.6 5.744-20.84 9.536-33.603l4.826-15.221H555l-22.864 65.335c-2.413 6.673-5.4 11.475-9.192 14.168-3.791 2.693-9.192 3.98-16.315 3.98-2.413 0-4.481-.117-6.319-.352v-11.59h5.514c6.549 0 9.767-4.099 9.767-9.719 0-2.81-.92-6.908-2.758-12.177l-17.177-49.478-22.239 22.665L497.2 99.184h-16.545l-17.234-28.101-8.962 9.133v18.968h-14.246V15.817h14.246v48.006Zm-48.373-26.46c16.889 0 25.622 6.79 26.196 20.49h-13.673c-.344-7.377-4.595-9.954-12.523-9.954-6.894 0-10.341 2.342-10.341 7.026 0 4.215 2.987 6.089 9.881 7.377l7.469 1.17c14.361 2.694 20.566 8.08 20.566 18.384 0 12.176-9.652 18.967-26.311 18.967-17.235 0-26.311-6.908-27.116-20.842h14.132c.804 7.494 4.481 10.304 13.213 10.304 7.813 0 11.72-2.459 11.72-7.26 0-4.332-2.758-6.44-11.605-7.962l-6.778-1.17c-12.983-2.224-19.418-8.313-19.418-18.265 0-11.358 8.847-18.266 24.588-18.266ZM270.534 76.351c0 7.61 3.677 11.474 11.145 11.474 7.008 0 13.212-5.268 13.213-15.22v-33.84h14.476v60.418h-14.016v-8.782c-4.481 6.791-10.686 10.187-18.614 10.187-12.523 0-20.68-7.728-20.68-21.778V38.767h14.476v37.585Zm75.432-38.99c8.961 0 16.085 3.045 21.37 9.016s7.928 13.933 7.928 23.651v3.513h-44.35c1.034 10.42 6.664 15.572 15.396 15.572 6.663 0 11.144-2.927 13.557-8.664h13.903c-3.103 12.294-13.443 20.139-27.575 20.139-8.847 0-15.971-2.927-21.371-8.664-5.4-5.737-8.157-13.348-8.157-22.95 0-9.483 2.643-17.094 8.043-22.949 5.4-5.737 12.409-8.664 21.256-8.664ZM195.628 15.817c17.809 0 26.426 9.251 26.426 21.545 0 8.196-3.677 14.168-10.915 17.914 9.306 3.396 14.247 11.24 14.247 20.022 0 14.87-9.767 23.886-28.494 23.886h-38.26V15.817h36.996Zm51.264 83.367h-14.477V15.817h14.477v83.367ZM174.143 86.07h21.944c8.732 0 13.443-4.098 13.443-11.474 0-7.728-4.481-11.592-13.443-11.592h-21.944V86.07Zm171.708-37.233c-7.928 0-13.443 4.683-14.822 14.401h29.758c-1.264-8.781-6.549-14.401-14.936-14.401Zm-171.708 1.756h20.336c7.927 0 12.178-4.215 12.178-11.24 0-6.44-4.366-10.539-12.178-10.539h-20.336v21.779Z" 39 + /> 40 + </Svg> 41 + ) 42 + }
+30 -3
src/screens/Profile/Header/ProfileHeaderStandard.tsx
··· 1 import {memo, useMemo, useState} from 'react' 2 import {View} from 'react-native' 3 import { 4 type AppBskyActorDefs, 5 moderateProfile, ··· 18 import {type Shadow, useProfileShadow} from '#/state/cache/profile-shadow' 19 import {useDisableFollowedByMetrics} from '#/state/preferences/disable-followed-by-metrics' 20 import { 21 useProfileBlockMutationQueue, 22 useProfileFollowMutationQueue, 23 } from '#/state/queries/profile' ··· 30 import {useDialogControl} from '#/components/Dialog' 31 import {MessageProfileButton} from '#/components/dms/MessageProfileButton' 32 import {PlusLarge_Stroke2_Corner0_Rounded as Plus} from '#/components/icons/Plus' 33 import { 34 KnownFollowers, 35 shouldShowKnownFollowers, ··· 47 import {AnimatedProfileHeaderSuggestedFollows} from './SuggestedFollows' 48 49 interface Props { 50 - profile: AppBskyActorDefs.ProfileViewDetailed 51 descriptionRT: RichTextAPI | null 52 moderationOpts: ModerationOpts 53 hideBackButton?: boolean ··· 63 }: Props): React.ReactNode => { 64 const t = useTheme() 65 const {gtMobile} = useBreakpoints() 66 - const profile = 67 - useProfileShadow<AppBskyActorDefs.ProfileViewDetailed>(profileUnshadowed) 68 const {currentAccount} = useSession() 69 const {_} = useLingui() 70 const moderation = useMemo( ··· 167 </View> 168 ) : undefined} 169 170 {!isMe && 171 !disableFollowedByMetrics && 172 !isBlockedUser &&
··· 1 import {memo, useMemo, useState} from 'react' 2 import {View} from 'react-native' 3 + import {Image} from 'expo-image' 4 import { 5 type AppBskyActorDefs, 6 moderateProfile, ··· 19 import {type Shadow, useProfileShadow} from '#/state/cache/profile-shadow' 20 import {useDisableFollowedByMetrics} from '#/state/preferences/disable-followed-by-metrics' 21 import { 22 + type TealActorStatus, 23 useProfileBlockMutationQueue, 24 useProfileFollowMutationQueue, 25 } from '#/state/queries/profile' ··· 32 import {useDialogControl} from '#/components/Dialog' 33 import {MessageProfileButton} from '#/components/dms/MessageProfileButton' 34 import {PlusLarge_Stroke2_Corner0_Rounded as Plus} from '#/components/icons/Plus' 35 + import {tealfm} from '#/components/icons/tealfm' 36 import { 37 KnownFollowers, 38 shouldShowKnownFollowers, ··· 50 import {AnimatedProfileHeaderSuggestedFollows} from './SuggestedFollows' 51 52 interface Props { 53 + profile: AppBskyActorDefs.ProfileViewDetailed & { 54 + tealStatus: TealActorStatus | undefined 55 + } 56 descriptionRT: RichTextAPI | null 57 moderationOpts: ModerationOpts 58 hideBackButton?: boolean ··· 68 }: Props): React.ReactNode => { 69 const t = useTheme() 70 const {gtMobile} = useBreakpoints() 71 + const profile = useProfileShadow< 72 + AppBskyActorDefs.ProfileViewDetailed & { 73 + tealStatus: TealActorStatus | undefined 74 + } 75 + >(profileUnshadowed) 76 const {currentAccount} = useSession() 77 const {_} = useLingui() 78 const moderation = useMemo( ··· 175 </View> 176 ) : undefined} 177 178 + {profile.tealStatus && ( 179 + <View style={[a.flex_row, a.align_center, a.gap_sm]}> 180 + <Image 181 + source={{ 182 + uri: `https://coverartarchive.org/release/${profile.tealStatus.item.releaseMbId}/front-250`, 183 + }} 184 + style={[{width: 30, height: 30, borderRadius: 4}]} 185 + loading={'eager'} 186 + accessibilityIgnoresInvertColors 187 + /> 188 + <Text> 189 + Listening to {profile.tealStatus.item.trackName} by{' '} 190 + {profile.tealStatus.item.artists 191 + .map(artist => artist.artistName) 192 + .join(', ')} 193 + </Text> 194 + </View> 195 + )} 196 + 197 {!isMe && 198 !disableFollowedByMetrics && 199 !isBlockedUser &&
+7 -2
src/screens/Profile/Header/index.tsx
··· 19 import {sanitizeHandle} from '#/lib/strings/handles' 20 import {useProfileShadow} from '#/state/cache/profile-shadow' 21 import {useModerationOpts} from '#/state/preferences/moderation-opts' 22 import {useSetLightStatusBar} from '#/state/shell/light-status-bar' 23 import {usePagerHeaderContext} from '#/view/com/pager/PagerHeaderContext' 24 import {LoadingPlaceholder} from '#/view/com/util/LoadingPlaceholder' ··· 60 export {ProfileHeaderLoading} 61 62 interface Props { 63 - profile: AppBskyActorDefs.ProfileViewDetailed 64 labeler: AppBskyLabelerDefs.LabelerViewDetailed | undefined 65 descriptionRT: RichTextAPI | null 66 moderationOpts: ModerationOpts ··· 105 hideBackButton = false, 106 }: { 107 onLayout: (e: LayoutChangeEvent) => void 108 - profile: AppBskyActorDefs.ProfileViewDetailed 109 labeler?: AppBskyLabelerDefs.LabelerViewDetailed 110 hideBackButton?: boolean 111 }) {
··· 19 import {sanitizeHandle} from '#/lib/strings/handles' 20 import {useProfileShadow} from '#/state/cache/profile-shadow' 21 import {useModerationOpts} from '#/state/preferences/moderation-opts' 22 + import {type TealActorStatus} from '#/state/queries/profile' 23 import {useSetLightStatusBar} from '#/state/shell/light-status-bar' 24 import {usePagerHeaderContext} from '#/view/com/pager/PagerHeaderContext' 25 import {LoadingPlaceholder} from '#/view/com/util/LoadingPlaceholder' ··· 61 export {ProfileHeaderLoading} 62 63 interface Props { 64 + profile: AppBskyActorDefs.ProfileViewDetailed & { 65 + tealStatus: TealActorStatus | undefined 66 + } 67 labeler: AppBskyLabelerDefs.LabelerViewDetailed | undefined 68 descriptionRT: RichTextAPI | null 69 moderationOpts: ModerationOpts ··· 108 hideBackButton = false, 109 }: { 110 onLayout: (e: LayoutChangeEvent) => void 111 + profile: AppBskyActorDefs.ProfileViewDetailed & { 112 + tealStatus: TealActorStatus | undefined 113 + } 114 labeler?: AppBskyLabelerDefs.LabelerViewDetailed 115 hideBackButton?: boolean 116 }) {
+7 -2
src/state/cache/profile-shadow.ts
··· 21 import {findAllProfilesInQueryData as findAllProfilesInPostLikedByQueryData} from '#/state/queries/post-liked-by' 22 import {findAllProfilesInQueryData as findAllProfilesInPostQuotesQueryData} from '#/state/queries/post-quotes' 23 import {findAllProfilesInQueryData as findAllProfilesInPostRepostedByQueryData} from '#/state/queries/post-reposted-by' 24 - import {findAllProfilesInQueryData as findAllProfilesInProfileQueryData} from '#/state/queries/profile' 25 import {findAllProfilesInQueryData as findAllProfilesInProfileFollowersQueryData} from '#/state/queries/profile-followers' 26 import {findAllProfilesInQueryData as findAllProfilesInProfileFollowsQueryData} from '#/state/queries/profile-follows' 27 import {findAllProfilesInQueryData as findAllProfilesInSuggestedFollowsQueryData} from '#/state/queries/suggested-follows' ··· 49 const emitter = new EventEmitter() 50 51 export function useProfileShadow< 52 - TProfileView extends bsky.profile.AnyProfileView, 53 >(profile: TProfileView): Shadow<TProfileView> { 54 const [shadow, setShadow] = useState(() => shadows.get(profile)) 55 const [prevPost, setPrevPost] = useState(profile)
··· 21 import {findAllProfilesInQueryData as findAllProfilesInPostLikedByQueryData} from '#/state/queries/post-liked-by' 22 import {findAllProfilesInQueryData as findAllProfilesInPostQuotesQueryData} from '#/state/queries/post-quotes' 23 import {findAllProfilesInQueryData as findAllProfilesInPostRepostedByQueryData} from '#/state/queries/post-reposted-by' 24 + import { 25 + findAllProfilesInQueryData as findAllProfilesInProfileQueryData, 26 + type TealActorStatus, 27 + } from '#/state/queries/profile' 28 import {findAllProfilesInQueryData as findAllProfilesInProfileFollowersQueryData} from '#/state/queries/profile-followers' 29 import {findAllProfilesInQueryData as findAllProfilesInProfileFollowsQueryData} from '#/state/queries/profile-follows' 30 import {findAllProfilesInQueryData as findAllProfilesInSuggestedFollowsQueryData} from '#/state/queries/suggested-follows' ··· 52 const emitter = new EventEmitter() 53 54 export function useProfileShadow< 55 + TProfileView extends bsky.profile.AnyProfileView & { 56 + tealStatus: TealActorStatus | undefined 57 + }, 58 >(profile: TProfileView): Shadow<TProfileView> { 59 const [shadow, setShadow] = useState(() => shadows.get(profile)) 60 const [prevPost, setPrevPost] = useState(profile)
+55 -3
src/state/queries/profile.ts
··· 55 const RQKEY_ROOT = 'profile' 56 export const RQKEY = (did: string) => [RQKEY_ROOT, did] 57 58 export const profilesQueryKeyRoot = 'profiles' 59 export const profilesQueryKey = (handles: string[]) => [ 60 profilesQueryKeyRoot, ··· 70 }) { 71 const agent = useAgent() 72 const {getUnstableProfile} = useUnstableProfileViewCache() 73 - return useQuery<AppBskyActorDefs.ProfileViewDetailed>({ 74 // WARNING 75 // this staleTime is load-bearing 76 // if you remove it, the UI infinite-loops ··· 80 queryKey: RQKEY(did ?? ''), 81 queryFn: async () => { 82 const res = await agent.getProfile({actor: did ?? ''}) 83 - return res.data 84 }, 85 placeholderData: () => { 86 if (!did) return 87 - return getUnstableProfile(did) as AppBskyActorDefs.ProfileViewDetailed 88 }, 89 enabled: !!did, 90 })
··· 55 const RQKEY_ROOT = 'profile' 56 export const RQKEY = (did: string) => [RQKEY_ROOT, did] 57 58 + export type TealArtist = { 59 + artistName: string 60 + artistMbId?: string 61 + } 62 + 63 + export type TealPlayView = { 64 + trackName: string 65 + trackMbId?: string 66 + recordingMbId?: string 67 + duration?: number 68 + artists: TealArtist[] 69 + releaseName?: string 70 + releaseMbId?: string 71 + isrc?: string 72 + originUrl?: string 73 + musicServiceBaseDomain?: string 74 + submissionClientAgent?: string 75 + playedTime?: string // datetime 76 + } 77 + 78 + export type TealActorStatus = { 79 + time: string // datetime 80 + expiry?: string // datetime 81 + item: TealPlayView 82 + } 83 + 84 export const profilesQueryKeyRoot = 'profiles' 85 export const profilesQueryKey = (handles: string[]) => [ 86 profilesQueryKeyRoot, ··· 96 }) { 97 const agent = useAgent() 98 const {getUnstableProfile} = useUnstableProfileViewCache() 99 + return useQuery< 100 + AppBskyActorDefs.ProfileViewDetailed & { 101 + tealStatus: TealActorStatus | undefined 102 + } 103 + >({ 104 // WARNING 105 // this staleTime is load-bearing 106 // if you remove it, the UI infinite-loops ··· 110 queryKey: RQKEY(did ?? ''), 111 queryFn: async () => { 112 const res = await agent.getProfile({actor: did ?? ''}) 113 + try { 114 + const teal = await fetch( 115 + `https://slingshot.microcosm.blue/xrpc/com.atproto.repo.getRecord?repo=${did ?? ''}&collection=fm.teal.alpha.actor.status&rkey=self`, 116 + { 117 + method: 'GET', 118 + }, 119 + ) 120 + const tealData = await teal.json() 121 + 122 + return { 123 + ...res.data, 124 + tealStatus: tealData.value as TealActorStatus | undefined, 125 + } 126 + } catch (e) { 127 + return { 128 + ...res.data, 129 + tealStatus: undefined as TealActorStatus | undefined, 130 + } 131 + } 132 }, 133 placeholderData: () => { 134 if (!did) return 135 + const profile = getUnstableProfile(did) as AppBskyActorDefs.ProfileViewDetailed 136 + return profile ? { 137 + ...profile, 138 + tealStatus: undefined, 139 + } : undefined 140 }, 141 enabled: !!did, 142 })
+4 -2
src/view/screens/Profile.tsx
··· 30 import {useModerationOpts} from '#/state/preferences/moderation-opts' 31 import {useLabelerInfoQuery} from '#/state/queries/labeler' 32 import {resetProfilePostsQueries} from '#/state/queries/post-feed' 33 - import {useProfileQuery} from '#/state/queries/profile' 34 import {useResolveDidQuery} from '#/state/queries/resolve-uri' 35 import {useAgent, useSession} from '#/state/session' 36 import {useSetMinimalShellMode} from '#/state/shell' ··· 167 moderationOpts, 168 hideBackButton, 169 }: { 170 - profile: AppBskyActorDefs.ProfileViewDetailed 171 moderationOpts: ModerationOpts 172 hideBackButton: boolean 173 isPlaceholderProfile: boolean
··· 30 import {useModerationOpts} from '#/state/preferences/moderation-opts' 31 import {useLabelerInfoQuery} from '#/state/queries/labeler' 32 import {resetProfilePostsQueries} from '#/state/queries/post-feed' 33 + import {type TealActorStatus, useProfileQuery} from '#/state/queries/profile' 34 import {useResolveDidQuery} from '#/state/queries/resolve-uri' 35 import {useAgent, useSession} from '#/state/session' 36 import {useSetMinimalShellMode} from '#/state/shell' ··· 167 moderationOpts, 168 hideBackButton, 169 }: { 170 + profile: AppBskyActorDefs.ProfileViewDetailed & { 171 + tealStatus: TealActorStatus | undefined 172 + } 173 moderationOpts: ModerationOpts 174 hideBackButton: boolean 175 isPlaceholderProfile: boolean