From b52dabab4975ce732e9419acafb89bfb76472707 Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Fri, 13 Feb 2026 11:04:04 -0600 Subject: [PATCH] Move actor-status into liveNow --- src/components/AccountList.tsx | 2 +- src/components/ProfileCard.tsx | 2 +- src/components/ProfileHoverCard/index.web.tsx | 2 +- src/features/liveNow/index.tsx | 89 ++++++++++++++++++ src/lib/actor-status.ts | 92 ------------------- .../components/ThreadItemAnchor.tsx | 2 +- .../PostThread/components/ThreadItemPost.tsx | 2 +- .../Profile/Header/ProfileHeaderStandard.tsx | 2 +- src/screens/Profile/Header/Shell.tsx | 2 +- src/screens/Settings/Settings.tsx | 2 +- src/view/com/posts/PostFeed.tsx | 7 +- src/view/com/posts/PostFeedItem.tsx | 2 +- src/view/com/profile/ProfileMenu.tsx | 3 +- src/view/com/util/PostMeta.tsx | 2 +- src/view/com/util/UserAvatar.tsx | 2 +- src/view/shell/Drawer.tsx | 2 +- src/view/shell/bottom-bar/BottomBar.tsx | 2 +- src/view/shell/desktop/LeftNav.tsx | 2 +- 18 files changed, 109 insertions(+), 110 deletions(-) delete mode 100644 src/lib/actor-status.ts diff --git a/src/components/AccountList.tsx b/src/components/AccountList.tsx index 70fc29d5b6..2fd56eabb8 100644 --- a/src/components/AccountList.tsx +++ b/src/components/AccountList.tsx @@ -4,7 +4,6 @@ import {type AppBskyActorDefs} from '@atproto/api' import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' -import {useActorStatus} from '#/lib/actor-status' import {isJwtExpired} from '#/lib/jwt' import {sanitizeDisplayName} from '#/lib/strings/display-names' import {sanitizeHandle} from '#/lib/strings/handles' @@ -19,6 +18,7 @@ import {PlusLarge_Stroke2_Corner0_Rounded as PlusIcon} from '#/components/icons/ import {Text} from '#/components/Typography' import {useSimpleVerificationState} from '#/components/verification' import {VerificationCheck} from '#/components/verification/VerificationCheck' +import {useActorStatus} from '#/features/liveNow' export function AccountList({ onSelectAccount, diff --git a/src/components/ProfileCard.tsx b/src/components/ProfileCard.tsx index b932517170..e184ebf514 100644 --- a/src/components/ProfileCard.tsx +++ b/src/components/ProfileCard.tsx @@ -14,7 +14,6 @@ import { import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' -import {useActorStatus} from '#/lib/actor-status' import {getModerationCauseKey} from '#/lib/moderation' import {forceLTR} from '#/lib/strings/bidi' import {NON_BREAKING_SPACE} from '#/lib/strings/constants' @@ -47,6 +46,7 @@ import {Text} from '#/components/Typography' import {useSimpleVerificationState} from '#/components/verification' import {VerificationCheck} from '#/components/verification/VerificationCheck' import {type Metrics} from '#/analytics' +import {useActorStatus} from '#/features/liveNow' import type * as bsky from '#/types/bsky' export function Default({ diff --git a/src/components/ProfileHoverCard/index.web.tsx b/src/components/ProfileHoverCard/index.web.tsx index 12246387fd..fe35b1911e 100644 --- a/src/components/ProfileHoverCard/index.web.tsx +++ b/src/components/ProfileHoverCard/index.web.tsx @@ -10,7 +10,6 @@ import {msg, plural} from '@lingui/macro' import {useLingui} from '@lingui/react' import {useNavigation} from '@react-navigation/native' -import {useActorStatus} from '#/lib/actor-status' import {getModerationCauseKey} from '#/lib/moderation' import {makeProfileLink} from '#/lib/routes/links' import {type NavigationProp} from '#/lib/routes/types' @@ -43,6 +42,7 @@ import {Text} from '#/components/Typography' import {useSimpleVerificationState} from '#/components/verification' import {VerificationCheck} from '#/components/verification/VerificationCheck' import {IS_WEB_TOUCH_DEVICE} from '#/env' +import {useActorStatus} from '#/features/liveNow' import {type ProfileHoverCardProps} from './types' const floatingMiddlewares = [ diff --git a/src/features/liveNow/index.tsx b/src/features/liveNow/index.tsx index 09c5ddbc8c..cc36009c02 100644 --- a/src/features/liveNow/index.tsx +++ b/src/features/liveNow/index.tsx @@ -1,8 +1,18 @@ import {useMemo} from 'react' +import { + type $Typed, + type AppBskyActorDefs, + AppBskyEmbedExternal, + AtUri, +} from '@atproto/api' +import {isAfter, parseISO} from 'date-fns' import {useAppConfig} from '#/state/appConfig' +import {useMaybeProfileShadow} from '#/state/cache/profile-shadow' import {useSession} from '#/state/session' +import {useTickEveryMinute} from '#/state/shell' import {useAnalytics} from '#/analytics' +import type * as bsky from '#/types/bsky' export const DEFAULT_ALLOWED_DOMAINS = [ 'twitch.tv', @@ -59,3 +69,82 @@ export function useLiveNowConfig(): LiveNowConfig { } }, [ax, liveNow, currentAccount]) } + +export function useActorStatus(actor?: bsky.profile.AnyProfileView) { + const shadowed = useMaybeProfileShadow(actor) + const tick = useTickEveryMinute() + const config = useLiveNowConfig() + + return useMemo(() => { + void tick // revalidate every minute + + if (shadowed && 'status' in shadowed && shadowed.status) { + const isValid = isStatusValidForViewers(shadowed.status, config) + const isDisabled = shadowed.status.isDisabled || false + const isActive = isStatusStillActive(shadowed.status.expiresAt) + if (isValid && !isDisabled && isActive) { + return { + uri: shadowed.status.uri, + cid: shadowed.status.cid, + isDisabled: false, + isActive: true, + status: 'app.bsky.actor.status#live', + embed: shadowed.status.embed as $Typed, // temp_isStatusValid asserts this + expiresAt: shadowed.status.expiresAt!, // isStatusStillActive asserts this + record: shadowed.status.record, + } satisfies AppBskyActorDefs.StatusView + } + return { + uri: shadowed.status.uri, + cid: shadowed.status.cid, + isDisabled, + isActive: false, + status: 'app.bsky.actor.status#live', + embed: shadowed.status.embed as $Typed, // temp_isStatusValid asserts this + expiresAt: shadowed.status.expiresAt!, // isStatusStillActive asserts this + record: shadowed.status.record, + } satisfies AppBskyActorDefs.StatusView + } else { + return { + status: '', + isDisabled: false, + isActive: false, + record: {}, + } satisfies AppBskyActorDefs.StatusView + } + }, [shadowed, config, tick]) +} + +export function isStatusStillActive(timeStr: string | undefined) { + if (!timeStr) return false + const now = new Date() + const expiry = parseISO(timeStr) + + return isAfter(expiry, now) +} + +/** + * Validates whether the live status is valid for display in the app. Does NOT + * validate if the status is valid for the acting user e.g. as they go live. + */ +export function isStatusValidForViewers( + status: AppBskyActorDefs.StatusView, + config: LiveNowConfig, +) { + if (status.status !== 'app.bsky.actor.status#live') return false + if (!status.uri) return false // should not happen, just backwards compat + try { + const {host: liveDid} = new AtUri(status.uri) + if (AppBskyEmbedExternal.isView(status.embed)) { + const url = new URL(status.embed.external.uri) + const exception = config.allowedHostsExceptionsByDid.get(liveDid) + const isValidException = exception ? exception.has(url.hostname) : false + const isValidForAnyone = config.defaultAllowedHosts.has(url.hostname) + return isValidException || isValidForAnyone + } else { + return false + } + } catch { + return false + } +} diff --git a/src/lib/actor-status.ts b/src/lib/actor-status.ts deleted file mode 100644 index b66fe68a92..0000000000 --- a/src/lib/actor-status.ts +++ /dev/null @@ -1,92 +0,0 @@ -import {useMemo} from 'react' -import { - type $Typed, - type AppBskyActorDefs, - AppBskyEmbedExternal, - AtUri, -} from '@atproto/api' -import {isAfter, parseISO} from 'date-fns' - -import {useMaybeProfileShadow} from '#/state/cache/profile-shadow' -import {useTickEveryMinute} from '#/state/shell' -import {type LiveNowConfig, useLiveNowConfig} from '#/features/liveNow' -import type * as bsky from '#/types/bsky' - -export function useActorStatus(actor?: bsky.profile.AnyProfileView) { - const shadowed = useMaybeProfileShadow(actor) - const tick = useTickEveryMinute() - const config = useLiveNowConfig() - - return useMemo(() => { - void tick // revalidate every minute - - if (shadowed && 'status' in shadowed && shadowed.status) { - const isValid = isStatusValidForViewers(shadowed.status, config) - const isDisabled = shadowed.status.isDisabled || false - const isActive = isStatusStillActive(shadowed.status.expiresAt) - if (isValid && !isDisabled && isActive) { - return { - uri: shadowed.status.uri, - cid: shadowed.status.cid, - isDisabled: false, - isActive: true, - status: 'app.bsky.actor.status#live', - embed: shadowed.status.embed as $Typed, // temp_isStatusValid asserts this - expiresAt: shadowed.status.expiresAt!, // isStatusStillActive asserts this - record: shadowed.status.record, - } satisfies AppBskyActorDefs.StatusView - } - return { - uri: shadowed.status.uri, - cid: shadowed.status.cid, - isDisabled, - isActive: false, - status: 'app.bsky.actor.status#live', - embed: shadowed.status.embed as $Typed, // temp_isStatusValid asserts this - expiresAt: shadowed.status.expiresAt!, // isStatusStillActive asserts this - record: shadowed.status.record, - } satisfies AppBskyActorDefs.StatusView - } else { - return { - status: '', - isDisabled: false, - isActive: false, - record: {}, - } satisfies AppBskyActorDefs.StatusView - } - }, [shadowed, config, tick]) -} - -export function isStatusStillActive(timeStr: string | undefined) { - if (!timeStr) return false - const now = new Date() - const expiry = parseISO(timeStr) - - return isAfter(expiry, now) -} - -/** - * Validates whether the live status is valid for display in the app. Does NOT - * validate if the status is valid for the acting user e.g. as they go live. - */ -export function isStatusValidForViewers( - status: AppBskyActorDefs.StatusView, - config: LiveNowConfig, -) { - if (status.status !== 'app.bsky.actor.status#live') return false - if (!status.uri) return false // should not happen, just backwards compat - try { - const {host: liveDid} = new AtUri(status.uri) - if (AppBskyEmbedExternal.isView(status.embed)) { - const url = new URL(status.embed.external.uri) - const exception = config.allowedHostsExceptionsByDid.get(liveDid) - const isValidException = exception ? exception.has(url.hostname) : false - const isValidForAnyone = config.defaultAllowedHosts.has(url.hostname) - return isValidException || isValidForAnyone - } else { - return false - } - } catch { - return false - } -} diff --git a/src/screens/PostThread/components/ThreadItemAnchor.tsx b/src/screens/PostThread/components/ThreadItemAnchor.tsx index e475b42de1..27fcaf0fa8 100644 --- a/src/screens/PostThread/components/ThreadItemAnchor.tsx +++ b/src/screens/PostThread/components/ThreadItemAnchor.tsx @@ -10,7 +10,6 @@ import { import {msg, Plural, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' -import {useActorStatus} from '#/lib/actor-status' import {useOpenComposer} from '#/lib/hooks/useOpenComposer' import {useTranslate} from '#/lib/hooks/useTranslate' import {makeProfileLink} from '#/lib/routes/links' @@ -60,6 +59,7 @@ import {Text} from '#/components/Typography' import {VerificationCheckButton} from '#/components/verification/VerificationCheckButton' import {WhoCanReply} from '#/components/WhoCanReply' import {useAnalytics} from '#/analytics' +import {useActorStatus} from '#/features/liveNow' import * as bsky from '#/types/bsky' export function ThreadItemAnchor({ diff --git a/src/screens/PostThread/components/ThreadItemPost.tsx b/src/screens/PostThread/components/ThreadItemPost.tsx index ea0d5631bb..4fe78785b8 100644 --- a/src/screens/PostThread/components/ThreadItemPost.tsx +++ b/src/screens/PostThread/components/ThreadItemPost.tsx @@ -8,7 +8,6 @@ import { } from '@atproto/api' import {Trans} from '@lingui/macro' -import {useActorStatus} from '#/lib/actor-status' import {MAX_POST_LINES} from '#/lib/constants' import {useOpenComposer} from '#/lib/hooks/useOpenComposer' import {makeProfileLink} from '#/lib/routes/links' @@ -44,6 +43,7 @@ import {RichText} from '#/components/RichText' import * as Skele from '#/components/Skeleton' import {SubtleHover} from '#/components/SubtleHover' import {Text} from '#/components/Typography' +import {useActorStatus} from '#/features/liveNow' export type ThreadItemPostProps = { item: Extract diff --git a/src/screens/Profile/Header/ProfileHeaderStandard.tsx b/src/screens/Profile/Header/ProfileHeaderStandard.tsx index c60fcd032a..fc2061b5db 100644 --- a/src/screens/Profile/Header/ProfileHeaderStandard.tsx +++ b/src/screens/Profile/Header/ProfileHeaderStandard.tsx @@ -10,7 +10,6 @@ import { import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' -import {useActorStatus} from '#/lib/actor-status' import {useHaptics} from '#/lib/haptics' import {sanitizeDisplayName} from '#/lib/strings/display-names' import {sanitizeHandle} from '#/lib/strings/handles' @@ -39,6 +38,7 @@ import * as Toast from '#/components/Toast' import {Text} from '#/components/Typography' import {VerificationCheckButton} from '#/components/verification/VerificationCheckButton' import {IS_IOS} from '#/env' +import {useActorStatus} from '#/features/liveNow' import {GermButton} from '../components/GermButton' import {EditProfileDialog} from './EditProfileDialog' import {ProfileHeaderHandle} from './Handle' diff --git a/src/screens/Profile/Header/Shell.tsx b/src/screens/Profile/Header/Shell.tsx index 8543d45bd1..d195a668dd 100644 --- a/src/screens/Profile/Header/Shell.tsx +++ b/src/screens/Profile/Header/Shell.tsx @@ -14,7 +14,6 @@ import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' import {useNavigation} from '@react-navigation/native' -import {useActorStatus} from '#/lib/actor-status' import {BACK_HITSLOP} from '#/lib/constants' import {useHaptics} from '#/lib/haptics' import {type NavigationProp} from '#/lib/routes/types' @@ -35,6 +34,7 @@ import {LabelsOnMe} from '#/components/moderation/LabelsOnMe' import {ProfileHeaderAlerts} from '#/components/moderation/ProfileHeaderAlerts' import {useAnalytics} from '#/analytics' import {IS_IOS} from '#/env' +import {useActorStatus} from '#/features/liveNow' import {GrowableAvatar} from './GrowableAvatar' import {GrowableBanner} from './GrowableBanner' import {StatusBarShadow} from './StatusBarShadow' diff --git a/src/screens/Settings/Settings.tsx b/src/screens/Settings/Settings.tsx index 4f6fbb602b..c79386d05b 100644 --- a/src/screens/Settings/Settings.tsx +++ b/src/screens/Settings/Settings.tsx @@ -7,7 +7,6 @@ import {useLingui} from '@lingui/react' import {useNavigation} from '@react-navigation/native' import {type NativeStackScreenProps} from '@react-navigation/native-stack' -import {useActorStatus} from '#/lib/actor-status' import {HELP_DESK_URL} from '#/lib/constants' import {useAccountSwitcher} from '#/lib/hooks/useAccountSwitcher' import {useApplyPullRequestOTAUpdate} from '#/lib/hooks/useOTAUpdates' @@ -70,6 +69,7 @@ import { } from '#/components/verification/VerificationCheckButton' import {useAnalytics} from '#/analytics' import {IS_INTERNAL, IS_IOS, IS_NATIVE} from '#/env' +import {useActorStatus} from '#/features/liveNow' import {device, useStorage} from '#/storage' import {useActivitySubscriptionsNudged} from '#/storage/hooks/activity-subscriptions-nudged' diff --git a/src/view/com/posts/PostFeed.tsx b/src/view/com/posts/PostFeed.tsx index cb1e367b4f..2648b3ed47 100644 --- a/src/view/com/posts/PostFeed.tsx +++ b/src/view/com/posts/PostFeed.tsx @@ -27,7 +27,6 @@ import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' import {useQueryClient} from '@tanstack/react-query' -import {isStatusStillActive, isStatusValidForViewers} from '#/lib/actor-status' import {DISCOVER_FEED_URI, KNOWN_SHUTDOWN_FEEDS} from '#/lib/constants' import {useInitialNumToRender} from '#/lib/hooks/useInitialNumToRender' import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback' @@ -70,7 +69,11 @@ import {TrendingVideos as TrendingVideosInterstitial} from '#/components/interst import {useAnalytics} from '#/analytics' import {IS_IOS, IS_NATIVE, IS_WEB} from '#/env' import {DiscoverFeedLiveEventFeedsAndTrendingBanner} from '#/features/liveEvents/components/DiscoverFeedLiveEventFeedsAndTrendingBanner' -import {useLiveNowConfig} from '#/features/liveNow' +import { + isStatusStillActive, + isStatusValidForViewers, + useLiveNowConfig, +} from '#/features/liveNow' import {ComposerPrompt} from '../feeds/ComposerPrompt' import {DiscoverFallbackHeader} from './DiscoverFallbackHeader' import {FeedShutdownMsg} from './FeedShutdownMsg' diff --git a/src/view/com/posts/PostFeedItem.tsx b/src/view/com/posts/PostFeedItem.tsx index 0961004952..064c94d2c3 100644 --- a/src/view/com/posts/PostFeedItem.tsx +++ b/src/view/com/posts/PostFeedItem.tsx @@ -11,7 +11,6 @@ import { } from '@atproto/api' import {useQueryClient} from '@tanstack/react-query' -import {useActorStatus} from '#/lib/actor-status' import {type ReasonFeedSource} from '#/lib/api/feed/types' import {MAX_POST_LINES} from '#/lib/constants' import {useOpenComposer} from '#/lib/hooks/useOpenComposer' @@ -48,6 +47,7 @@ import {DiscoverDebug} from '#/components/PostControls/DiscoverDebug' import {RichText} from '#/components/RichText' import {SubtleHover} from '#/components/SubtleHover' import {useAnalytics} from '#/analytics' +import {useActorStatus} from '#/features/liveNow' import * as bsky from '#/types/bsky' import {PostFeedReason} from './PostFeedReason' diff --git a/src/view/com/profile/ProfileMenu.tsx b/src/view/com/profile/ProfileMenu.tsx index 25601b0228..e4ac1ccaaf 100644 --- a/src/view/com/profile/ProfileMenu.tsx +++ b/src/view/com/profile/ProfileMenu.tsx @@ -5,7 +5,6 @@ import {useLingui} from '@lingui/react' import {useNavigation} from '@react-navigation/native' import {useQueryClient} from '@tanstack/react-query' -import {useActorStatus} from '#/lib/actor-status' import {HITSLOP_20} from '#/lib/constants' import {makeProfileLink} from '#/lib/routes/links' import {type NavigationProp} from '#/lib/routes/types' @@ -60,7 +59,7 @@ import {VerificationCreatePrompt} from '#/components/verification/VerificationCr import {VerificationRemovePrompt} from '#/components/verification/VerificationRemovePrompt' import {useAnalytics} from '#/analytics' import {IS_WEB} from '#/env' -import {useLiveNowConfig} from '#/features/liveNow' +import {useActorStatus, useLiveNowConfig} from '#/features/liveNow' import {Dot} from '#/features/nuxs/components/Dot' import {Gradient} from '#/features/nuxs/components/Gradient' import {useDevMode} from '#/storage/hooks/dev-mode' diff --git a/src/view/com/util/PostMeta.tsx b/src/view/com/util/PostMeta.tsx index ca40ef5f42..1a37e55cbd 100644 --- a/src/view/com/util/PostMeta.tsx +++ b/src/view/com/util/PostMeta.tsx @@ -5,7 +5,6 @@ import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' import {useQueryClient} from '@tanstack/react-query' -import {useActorStatus} from '#/lib/actor-status' import {makeProfileLink} from '#/lib/routes/links' import {forceLTR} from '#/lib/strings/bidi' import {NON_BREAKING_SPACE} from '#/lib/strings/constants' @@ -21,6 +20,7 @@ import {Text} from '#/components/Typography' import {useSimpleVerificationState} from '#/components/verification' import {VerificationCheck} from '#/components/verification/VerificationCheck' import {IS_ANDROID} from '#/env' +import {useActorStatus} from '#/features/liveNow' import {TimeElapsed} from './TimeElapsed' import {PreviewableUserAvatar} from './UserAvatar' diff --git a/src/view/com/util/UserAvatar.tsx b/src/view/com/util/UserAvatar.tsx index 529a6ed52f..4c2ca2c528 100644 --- a/src/view/com/util/UserAvatar.tsx +++ b/src/view/com/util/UserAvatar.tsx @@ -15,7 +15,6 @@ import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' import {useQueryClient} from '@tanstack/react-query' -import {useActorStatus} from '#/lib/actor-status' import {useHaptics} from '#/lib/haptics' import { useCameraPermission, @@ -54,6 +53,7 @@ import * as Menu from '#/components/Menu' import {ProfileHoverCard} from '#/components/ProfileHoverCard' import {useAnalytics} from '#/analytics' import {IS_ANDROID, IS_NATIVE, IS_WEB, IS_WEB_TOUCH_DEVICE} from '#/env' +import {useActorStatus} from '#/features/liveNow' import type * as bsky from '#/types/bsky' export type UserAvatarType = 'user' | 'algo' | 'list' | 'labeler' diff --git a/src/view/shell/Drawer.tsx b/src/view/shell/Drawer.tsx index 42a5fe417c..d46e1e44e5 100644 --- a/src/view/shell/Drawer.tsx +++ b/src/view/shell/Drawer.tsx @@ -5,7 +5,6 @@ import {msg, Plural, plural, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' import {StackActions, useNavigation} from '@react-navigation/native' -import {useActorStatus} from '#/lib/actor-status' import {FEEDBACK_FORM_URL, HELP_DESK_URL} from '#/lib/constants' import {type PressableScale} from '#/lib/custom-animations/PressableScale' import {useNavigationTabState} from '#/lib/hooks/useNavigationTabState' @@ -57,6 +56,7 @@ import {Text} from '#/components/Typography' import {useSimpleVerificationState} from '#/components/verification' import {VerificationCheck} from '#/components/verification/VerificationCheck' import {IS_WEB} from '#/env' +import {useActorStatus} from '#/features/liveNow' const iconWidth = 26 diff --git a/src/view/shell/bottom-bar/BottomBar.tsx b/src/view/shell/bottom-bar/BottomBar.tsx index 7c2a010ab1..ef0ceaba97 100644 --- a/src/view/shell/bottom-bar/BottomBar.tsx +++ b/src/view/shell/bottom-bar/BottomBar.tsx @@ -7,7 +7,6 @@ import {useLingui} from '@lingui/react' import {type BottomTabBarProps} from '@react-navigation/bottom-tabs' import {StackActions} from '@react-navigation/native' -import {useActorStatus} from '#/lib/actor-status' import {PressableScale} from '#/lib/custom-animations/PressableScale' import {BOTTOM_BAR_AVI} from '#/lib/demo' import {useHaptics} from '#/lib/haptics' @@ -49,6 +48,7 @@ import { Message_Stroke2_Corner0_Rounded_Filled as MessageFilled, } from '#/components/icons/Message' import {Text} from '#/components/Typography' +import {useActorStatus} from '#/features/liveNow' import {useDemoMode} from '#/storage/hooks/demo-mode' import {styles} from './BottomBarStyles' diff --git a/src/view/shell/desktop/LeftNav.tsx b/src/view/shell/desktop/LeftNav.tsx index 3e9ccea647..a9d1942051 100644 --- a/src/view/shell/desktop/LeftNav.tsx +++ b/src/view/shell/desktop/LeftNav.tsx @@ -5,7 +5,6 @@ import {msg, plural, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' import {useNavigation, useNavigationState} from '@react-navigation/native' -import {useActorStatus} from '#/lib/actor-status' import {useAccountSwitcher} from '#/lib/hooks/useAccountSwitcher' import {useOpenComposer} from '#/lib/hooks/useOpenComposer' import {usePalette} from '#/lib/hooks/usePalette' @@ -74,6 +73,7 @@ import {CENTER_COLUMN_OFFSET} from '#/components/Layout' import * as Menu from '#/components/Menu' import * as Prompt from '#/components/Prompt' import {Text} from '#/components/Typography' +import {useActorStatus} from '#/features/liveNow' import {PlatformInfo} from '../../../../modules/expo-bluesky-swiss-army' import {router} from '../../../routes'