Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extract shell state into separate context #1824

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 17 additions & 14 deletions src/App.native.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import * as analytics from 'lib/analytics/analytics'
import * as Toast from 'view/com/util/Toast'
import {queryClient} from 'lib/react-query'
import {TestCtrls} from 'view/com/testing/TestCtrls'
import {Provider as ShellStateProvider} from 'state/shell'

SplashScreen.preventAutoHideAsync()

Expand All @@ -45,20 +46,22 @@ const App = observer(function AppImpl() {
return null
}
return (
<QueryClientProvider client={queryClient}>
<ThemeProvider theme={rootStore.shell.colorMode}>
<RootSiblingParent>
<analytics.Provider>
<RootStoreProvider value={rootStore}>
<GestureHandlerRootView style={s.h100pct}>
<TestCtrls />
<Shell />
</GestureHandlerRootView>
</RootStoreProvider>
</analytics.Provider>
</RootSiblingParent>
</ThemeProvider>
</QueryClientProvider>
<ShellStateProvider>
<QueryClientProvider client={queryClient}>
<ThemeProvider theme={rootStore.shell.colorMode}>
<RootSiblingParent>
<analytics.Provider>
<RootStoreProvider value={rootStore}>
<GestureHandlerRootView style={s.h100pct}>
<TestCtrls />
<Shell />
</GestureHandlerRootView>
</RootStoreProvider>
</analytics.Provider>
</RootSiblingParent>
</ThemeProvider>
</QueryClientProvider>
</ShellStateProvider>
)
})

Expand Down
31 changes: 17 additions & 14 deletions src/App.web.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {Shell} from 'view/shell/index'
import {ToastContainer} from 'view/com/util/Toast.web'
import {ThemeProvider} from 'lib/ThemeContext'
import {queryClient} from 'lib/react-query'
import {Provider as ShellStateProvider} from 'state/shell'

const App = observer(function AppImpl() {
const [rootStore, setRootStore] = useState<RootStoreModel | undefined>(
Expand All @@ -34,20 +35,22 @@ const App = observer(function AppImpl() {
}

return (
<QueryClientProvider client={queryClient}>
<ThemeProvider theme={rootStore.shell.colorMode}>
<RootSiblingParent>
<analytics.Provider>
<RootStoreProvider value={rootStore}>
<SafeAreaProvider>
<Shell />
</SafeAreaProvider>
<ToastContainer />
</RootStoreProvider>
</analytics.Provider>
</RootSiblingParent>
</ThemeProvider>
</QueryClientProvider>
<ShellStateProvider>
<QueryClientProvider client={queryClient}>
<ThemeProvider theme={rootStore.shell.colorMode}>
<RootSiblingParent>
<analytics.Provider>
<RootStoreProvider value={rootStore}>
<SafeAreaProvider>
<Shell />
</SafeAreaProvider>
<ToastContainer />
</RootStoreProvider>
</analytics.Provider>
</RootSiblingParent>
</ThemeProvider>
</QueryClientProvider>
</ShellStateProvider>
)
})

Expand Down
6 changes: 4 additions & 2 deletions src/lib/hooks/useAccountSwitcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,16 @@ import {NavigationProp} from 'lib/routes/types'
import {AccountData} from 'state/models/session'
import {reset as resetNavigation} from '../../Navigation'
import * as Toast from 'view/com/util/Toast'
import {useSetDrawerOpen} from '#/state/shell/drawer-open'

export function useAccountSwitcher(): [
boolean,
(v: boolean) => void,
(acct: AccountData) => Promise<void>,
] {
const {track} = useAnalytics()

const store = useStores()
const setDrawerOpen = useSetDrawerOpen()
const [isSwitching, setIsSwitching] = useState(false)
const navigation = useNavigation<NavigationProp>()

Expand All @@ -23,6 +24,7 @@ export function useAccountSwitcher(): [
track('Settings:SwitchAccountButtonClicked')
setIsSwitching(true)
const success = await store.session.resumeSession(acct)
setDrawerOpen(false)
store.shell.closeAllActiveElements()
if (success) {
resetNavigation()
Expand All @@ -34,7 +36,7 @@ export function useAccountSwitcher(): [
store.session.clear()
}
},
[track, setIsSwitching, navigation, store],
[track, setIsSwitching, navigation, store, setDrawerOpen],
)

return [isSwitching, setIsSwitching, onPressSwitchAccount]
Expand Down
10 changes: 6 additions & 4 deletions src/lib/hooks/useMinimalShellMode.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React from 'react'
import {autorun} from 'mobx'
import {useStores} from 'state/index'
import {
Easing,
interpolate,
Expand All @@ -9,8 +8,10 @@ import {
withTiming,
} from 'react-native-reanimated'

import {useMinimalShellMode as useMinimalShellModeState} from '#/state/shell/minimal-mode'

export function useMinimalShellMode() {
const store = useStores()
const minimalShellMode = useMinimalShellModeState()
const minimalShellInterp = useSharedValue(0)
const footerMinimalShellTransform = useAnimatedStyle(() => {
return {
Expand Down Expand Up @@ -38,7 +39,7 @@ export function useMinimalShellMode() {

React.useEffect(() => {
return autorun(() => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The autorun here doesn't make sense anymore.

if (store.shell.minimalShellMode) {
if (minimalShellMode) {
minimalShellInterp.value = withTiming(1, {
duration: 125,
easing: Easing.bezier(0.25, 0.1, 0.25, 1),
Expand All @@ -50,9 +51,10 @@ export function useMinimalShellMode() {
})
}
})
}, [minimalShellInterp, store.shell.minimalShellMode])
}, [minimalShellInterp, minimalShellMode])
gaearon marked this conversation as resolved.
Show resolved Hide resolved

return {
minimalShellMode,
footerMinimalShellTransform,
headerMinimalShellTransform,
fabMinimalShellTransform,
Expand Down
31 changes: 17 additions & 14 deletions src/lib/hooks/useOnMainScroll.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import {useState, useCallback, useRef} from 'react'
import {NativeSyntheticEvent, NativeScrollEvent} from 'react-native'
import {RootStoreModel} from 'state/index'
import {s} from 'lib/styles'
import {useWebMediaQueries} from './useWebMediaQueries'
import {useSetMinimalShellMode, useMinimalShellMode} from '#/state/shell'

const Y_LIMIT = 10

Expand All @@ -19,12 +19,12 @@ export type OnScrollCb = (
) => void
export type ResetCb = () => void

export function useOnMainScroll(
store: RootStoreModel,
): [OnScrollCb, boolean, ResetCb] {
export function useOnMainScroll(): [OnScrollCb, boolean, ResetCb] {
let lastY = useRef(0)
let [isScrolledDown, setIsScrolledDown] = useState(false)
const {dyLimitUp, dyLimitDown} = useDeviceLimits()
const minimalShellMode = useMinimalShellMode()
const setMinimalShellMode = useSetMinimalShellMode()

return [
useCallback(
Expand All @@ -33,13 +33,10 @@ export function useOnMainScroll(
const dy = y - (lastY.current || 0)
lastY.current = y

if (!store.shell.minimalShellMode && dy > dyLimitDown && y > Y_LIMIT) {
store.shell.setMinimalShellMode(true)
} else if (
store.shell.minimalShellMode &&
(dy < dyLimitUp * -1 || y <= Y_LIMIT)
) {
store.shell.setMinimalShellMode(false)
if (!minimalShellMode && dy > dyLimitDown && y > Y_LIMIT) {
setMinimalShellMode(true)
} else if (minimalShellMode && (dy < dyLimitUp * -1 || y <= Y_LIMIT)) {
setMinimalShellMode(false)
}

if (
Expand All @@ -54,13 +51,19 @@ export function useOnMainScroll(
setIsScrolledDown(false)
}
},
[store.shell, dyLimitDown, dyLimitUp, isScrolledDown],
[
dyLimitDown,
dyLimitUp,
isScrolledDown,
minimalShellMode,
setMinimalShellMode,
],
),
isScrolledDown,
useCallback(() => {
setIsScrolledDown(false)
store.shell.setMinimalShellMode(false)
setMinimalShellMode(false)
lastY.current = 1e8 // NOTE we set this very high so that the onScroll logic works right -prf
}, [store, setIsScrolledDown]),
}, [setIsScrolledDown, setMinimalShellMode]),
]
}
19 changes: 0 additions & 19 deletions src/lib/routes/back-handler.ts

This file was deleted.

26 changes: 0 additions & 26 deletions src/state/models/ui/shell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -266,9 +266,6 @@ export interface ComposerOpts {

export class ShellUiModel {
colorMode: ColorMode = 'system'
minimalShellMode = false
isDrawerOpen = false
isDrawerSwipeDisabled = false
isModalActive = false
activeModals: Modal[] = []
isLightboxActive = false
Expand Down Expand Up @@ -313,10 +310,6 @@ export class ShellUiModel {
}
}

setMinimalShellMode(v: boolean) {
this.minimalShellMode = v
}

/**
* returns true if something was closed
* (used by the android hardware back btn)
Expand All @@ -334,10 +327,6 @@ export class ShellUiModel {
this.closeComposer()
return true
}
if (this.isDrawerOpen) {
this.closeDrawer()
return true
}
return false
}

Expand All @@ -354,21 +343,6 @@ export class ShellUiModel {
if (this.isComposerActive) {
this.closeComposer()
}
if (this.isDrawerOpen) {
this.closeDrawer()
}
}

openDrawer() {
this.isDrawerOpen = true
}

closeDrawer() {
this.isDrawerOpen = false
}

setIsDrawerSwipeDisabled(v: boolean) {
this.isDrawerSwipeDisabled = v
}

openModal(modal: Modal) {
Expand Down
24 changes: 24 additions & 0 deletions src/state/shell/drawer-open.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import React from 'react'

type StateContext = boolean
type SetContext = (v: boolean) => void

const stateContext = React.createContext<StateContext>(false)
const setContext = React.createContext<SetContext>((_: boolean) => {})

export function Provider({children}: React.PropsWithChildren<{}>) {
const [state, setState] = React.useState(false)
return (
<stateContext.Provider value={state}>
<setContext.Provider value={setState}>{children}</setContext.Provider>
</stateContext.Provider>
)
}

export function useIsDrawerOpen() {
return React.useContext(stateContext)
}

export function useSetDrawerOpen() {
return React.useContext(setContext)
}
24 changes: 24 additions & 0 deletions src/state/shell/drawer-swipe-disabled.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import React from 'react'

type StateContext = boolean
type SetContext = (v: boolean) => void

const stateContext = React.createContext<StateContext>(false)
const setContext = React.createContext<SetContext>((_: boolean) => {})

export function Provider({children}: React.PropsWithChildren<{}>) {
const [state, setState] = React.useState(false)
return (
<stateContext.Provider value={state}>
<setContext.Provider value={setState}>{children}</setContext.Provider>
</stateContext.Provider>
)
}

export function useIsDrawerSwipeDisabled() {
return React.useContext(stateContext)
}

export function useSetDrawerSwipeDisabled() {
return React.useContext(setContext)
}
21 changes: 21 additions & 0 deletions src/state/shell/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from 'react'
import {Provider as DrawerOpenProvider} from './drawer-open'
import {Provider as DrawerSwipableProvider} from './drawer-swipe-disabled'
import {Provider as MinimalModeProvider} from './minimal-mode'

export {useIsDrawerOpen, useSetDrawerOpen} from './drawer-open'
export {
useIsDrawerSwipeDisabled,
useSetDrawerSwipeDisabled,
} from './drawer-swipe-disabled'
export {useMinimalShellMode, useSetMinimalShellMode} from './minimal-mode'

export function Provider({children}: React.PropsWithChildren<{}>) {
return (
<DrawerOpenProvider>
<DrawerSwipableProvider>
<MinimalModeProvider>{children}</MinimalModeProvider>
</DrawerSwipableProvider>
</DrawerOpenProvider>
)
}
Loading