diff options
author | dan <dan.abramov@gmail.com> | 2024-02-08 20:37:08 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-08 12:37:08 -0800 |
commit | 06f81d69486f2e6e8ffd65da5a4bfdcd7d8a2655 (patch) | |
tree | 041b9ddf0c44c871c6de14e96a65371c9c6c416d /src/state/shell/selected-feed.tsx | |
parent | 80c482b026ad956e3a2bbfba864821a736e413f6 (diff) | |
download | voidsky-06f81d69486f2e6e8ffd65da5a4bfdcd7d8a2655.tar.zst |
Keep pager feeds in sync with the right pane (#2775)
* Hoist selected feed state * Seed state from params * Refine and fix logic * Fix scroll restoration * Soft reset on second click
Diffstat (limited to 'src/state/shell/selected-feed.tsx')
-rw-r--r-- | src/state/shell/selected-feed.tsx | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/src/state/shell/selected-feed.tsx b/src/state/shell/selected-feed.tsx new file mode 100644 index 000000000..a05d8661b --- /dev/null +++ b/src/state/shell/selected-feed.tsx @@ -0,0 +1,61 @@ +import React from 'react' +import * as persisted from '#/state/persisted' +import {isWeb} from '#/platform/detection' + +type StateContext = string +type SetContext = (v: string) => void + +const stateContext = React.createContext<StateContext>('home') +const setContext = React.createContext<SetContext>((_: string) => {}) + +function getInitialFeed() { + if (isWeb) { + if (window.location.pathname === '/') { + const params = new URLSearchParams(window.location.search) + const feedFromUrl = params.get('feed') + if (feedFromUrl) { + // If explicitly booted from a link like /?feed=..., prefer that. + return feedFromUrl + } + } + const feedFromSession = sessionStorage.getItem('lastSelectedHomeFeed') + if (feedFromSession) { + // Fall back to a previously chosen feed for this browser tab. + return feedFromSession + } + } + const feedFromPersisted = persisted.get('lastSelectedHomeFeed') + if (feedFromPersisted) { + // Fall back to the last chosen one across all tabs. + return feedFromPersisted + } + return 'home' +} + +export function Provider({children}: React.PropsWithChildren<{}>) { + const [state, setState] = React.useState(getInitialFeed) + + const saveState = React.useCallback((feed: string) => { + setState(feed) + if (isWeb) { + try { + sessionStorage.setItem('lastSelectedHomeFeed', feed) + } catch {} + } + persisted.write('lastSelectedHomeFeed', feed) + }, []) + + return ( + <stateContext.Provider value={state}> + <setContext.Provider value={saveState}>{children}</setContext.Provider> + </stateContext.Provider> + ) +} + +export function useSelectedFeed() { + return React.useContext(stateContext) +} + +export function useSetSelectedFeed() { + return React.useContext(setContext) +} |