diff --git a/src/state/persisted/legacy.ts b/src/state/persisted/legacy.ts index 767faf48..cb4b5b1a 100644 --- a/src/state/persisted/legacy.ts +++ b/src/state/persisted/legacy.ts @@ -111,6 +111,7 @@ export function transform(legacy: Partial): Schema { }, hiddenPosts: defaults.hiddenPosts, externalEmbeds: defaults.externalEmbeds, + lastSelectedHomeFeed: defaults.lastSelectedHomeFeed, } } diff --git a/src/state/persisted/schema.ts b/src/state/persisted/schema.ts index ade97ef7..6771ee6e 100644 --- a/src/state/persisted/schema.ts +++ b/src/state/persisted/schema.ts @@ -56,6 +56,7 @@ export const schema = z.object({ }), hiddenPosts: z.array(z.string()).optional(), // should move to server useInAppBrowser: z.boolean().optional(), + lastSelectedHomeFeed: z.string().optional(), }) export type Schema = z.infer @@ -89,4 +90,5 @@ export const defaults: Schema = { }, hiddenPosts: [], useInAppBrowser: undefined, + lastSelectedHomeFeed: undefined, } diff --git a/src/view/screens/Home.tsx b/src/view/screens/Home.tsx index 1da27648..7228a9e1 100644 --- a/src/view/screens/Home.tsx +++ b/src/view/screens/Home.tsx @@ -16,45 +16,25 @@ import {usePinnedFeedsInfos, FeedSourceInfo} from '#/state/queries/feed' import {UsePreferencesQueryResponse} from '#/state/queries/preferences/types' import {emitSoftReset} from '#/state/events' import {useSession} from '#/state/session' -import {loadString, saveString} from '#/lib/storage' import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries' -import {clamp} from '#/lib/numbers' +import * as persisted from '#/state/persisted' type Props = NativeStackScreenProps export function HomeScreen(props: Props) { const {data: preferences} = usePreferencesQuery() - const {feeds: pinnedFeeds, isLoading: isPinnedFeedsLoading} = + const {feeds: pinnedFeedInfos, isLoading: isPinnedFeedsLoading} = usePinnedFeedsInfos() const {isDesktop} = useWebMediaQueries() - const [initialPage, setInitialPage] = React.useState( - undefined, + const [rawInitialFeed] = React.useState( + () => persisted.get('lastSelectedHomeFeed') ?? 'home', ) - - React.useEffect(() => { - const loadLastActivePage = async () => { - try { - const lastActivePage = - (await loadString('lastActivePage')) ?? 'Following' - setInitialPage(lastActivePage) - } catch { - setInitialPage('Following') - } - } - loadLastActivePage() - }, []) - - if ( - preferences && - pinnedFeeds && - initialPage !== undefined && - !isPinnedFeedsLoading - ) { + if (preferences && pinnedFeedInfos && !isPinnedFeedsLoading) { return ( ) } else { @@ -68,35 +48,17 @@ export function HomeScreen(props: Props) { function HomeScreenReady({ preferences, - pinnedFeeds, - initialPage, + pinnedFeedInfos, + rawInitialFeed, }: Props & { preferences: UsePreferencesQueryResponse - pinnedFeeds: FeedSourceInfo[] - initialPage: string + pinnedFeedInfos: FeedSourceInfo[] + rawInitialFeed: string }) { - const {hasSession} = useSession() - const setMinimalShellMode = useSetMinimalShellMode() - const setDrawerSwipeDisabled = useSetDrawerSwipeDisabled() - const [selectedPage, setSelectedPage] = React.useState(initialPage) - - /** - * Used to ensure that we re-compute `customFeeds` AND force a re-render of - * the pager with the new order of feeds. - */ - const pinnedFeedOrderKey = JSON.stringify(preferences.feeds.pinned) - - const selectedPageIndex = React.useMemo(() => { - const index = ['Following', ...preferences.feeds.pinned].indexOf( - selectedPage, - ) - return Math.max(index, 0) - }, [preferences.feeds.pinned, selectedPage]) - - const customFeeds = React.useMemo(() => { - const pinned = pinnedFeeds + const allFeeds = React.useMemo(() => { const feeds: FeedDescriptor[] = [] - for (const {uri} of pinned) { + feeds.push('home') + for (const {uri} of pinnedFeedInfos) { if (uri.includes('app.bsky.feed.generator')) { feeds.push(`feedgen|${uri}`) } else if (uri.includes('app.bsky.graph.list')) { @@ -104,41 +66,36 @@ function HomeScreenReady({ } } return feeds - }, [pinnedFeeds]) + }, [pinnedFeedInfos]) - const homeFeedParams = React.useMemo(() => { - return { - mergeFeedEnabled: Boolean(preferences.feedViewPrefs.lab_mergeFeedEnabled), - mergeFeedSources: preferences.feedViewPrefs.lab_mergeFeedEnabled - ? preferences.feeds.saved - : [], - } - }, [preferences]) + const [rawSelectedFeed, setSelectedFeed] = + React.useState(rawInitialFeed) + const maybeFoundIndex = allFeeds.indexOf(rawSelectedFeed as FeedDescriptor) + const selectedIndex = Math.max(0, maybeFoundIndex) + const selectedFeed = allFeeds[selectedIndex] + const {hasSession} = useSession() + const setMinimalShellMode = useSetMinimalShellMode() + const setDrawerSwipeDisabled = useSetDrawerSwipeDisabled() useFocusEffect( React.useCallback(() => { setMinimalShellMode(false) - setDrawerSwipeDisabled(selectedPageIndex > 0) + setDrawerSwipeDisabled(selectedIndex > 0) return () => { setDrawerSwipeDisabled(false) } - }, [setDrawerSwipeDisabled, selectedPageIndex, setMinimalShellMode]), + }, [setDrawerSwipeDisabled, selectedIndex, setMinimalShellMode]), ) const onPageSelected = React.useCallback( (index: number) => { setMinimalShellMode(false) setDrawerSwipeDisabled(index > 0) - const page = ['Following', ...preferences.feeds.pinned][index] - setSelectedPage(page) - saveString('lastActivePage', page) + const feed = allFeeds[index] + setSelectedFeed(feed) + persisted.write('lastSelectedHomeFeed', feed) }, - [ - setDrawerSwipeDisabled, - setSelectedPage, - setMinimalShellMode, - preferences.feeds.pinned, - ], + [setDrawerSwipeDisabled, setSelectedFeed, setMinimalShellMode, allFeeds], ) const onPressSelected = React.useCallback(() => { @@ -177,30 +134,40 @@ function HomeScreenReady({ return }, []) + const [homeFeed, ...customFeeds] = allFeeds + const homeFeedParams = React.useMemo(() => { + return { + mergeFeedEnabled: Boolean(preferences.feedViewPrefs.lab_mergeFeedEnabled), + mergeFeedSources: preferences.feedViewPrefs.lab_mergeFeedEnabled + ? preferences.feeds.saved + : [], + } + }, [preferences]) + return hasSession ? ( - {customFeeds.map((f, index) => { + {customFeeds.map(feed => { return ( )