diff --git a/src/lib/hooks/useTabFocusEffect.ts b/src/lib/hooks/useTabFocusEffect.ts new file mode 100644 index 00000000..e446084c --- /dev/null +++ b/src/lib/hooks/useTabFocusEffect.ts @@ -0,0 +1,27 @@ +import {useEffect, useState} from 'react' +import {useNavigation} from '@react-navigation/native' +import {getTabState, TabState} from 'lib/routes/helpers' + +export function useTabFocusEffect( + tabName: string, + cb: (isInside: boolean) => void, +) { + const [isInside, setIsInside] = useState(false) + + // get root navigator state + let nav = useNavigation() + while (nav.getParent()) { + nav = nav.getParent() + } + const state = nav.getState() + + useEffect(() => { + // check if inside + let v = getTabState(state, tabName) !== TabState.Outside + if (v !== isInside) { + // fire + setIsInside(v) + cb(v) + } + }, [state, isInside, setIsInside, tabName, cb]) +} diff --git a/src/state/models/me.ts b/src/state/models/me.ts index e8b8e1ed..b9936379 100644 --- a/src/state/models/me.ts +++ b/src/state/models/me.ts @@ -99,14 +99,12 @@ export class MeModel { this.handle = sess.currentSession?.handle || '' await this.fetchProfile() this.mainFeed.clear() - await Promise.all([ - this.mainFeed.setup().catch(e => { - this.rootStore.log.error('Failed to setup main feed model', e) - }), - this.notifications.setup().catch(e => { - this.rootStore.log.error('Failed to setup notifications model', e) - }), - ]) + /* dont await */ this.mainFeed.setup().catch(e => { + this.rootStore.log.error('Failed to setup main feed model', e) + }) + /* dont await */ this.notifications.setup().catch(e => { + this.rootStore.log.error('Failed to setup notifications model', e) + }) this.rootStore.emitSessionLoaded() await this.fetchInviteCodes() } else { diff --git a/src/view/screens/Notifications.tsx b/src/view/screens/Notifications.tsx index 3e34a9fa..d93666aa 100644 --- a/src/view/screens/Notifications.tsx +++ b/src/view/screens/Notifications.tsx @@ -13,6 +13,7 @@ import {InvitedUsers} from '../com/notifications/InvitedUsers' import {LoadLatestBtn} from 'view/com/util/load-latest/LoadLatestBtn' import {useStores} from 'state/index' import {useOnMainScroll} from 'lib/hooks/useOnMainScroll' +import {useTabFocusEffect} from 'lib/hooks/useTabFocusEffect' import {s} from 'lib/styles' import {useAnalytics} from 'lib/analytics' @@ -58,6 +59,27 @@ export const NotificationsScreen = withAuthRequired( } }, [store, screen, onPressLoadLatest]), ) + useTabFocusEffect( + 'Notifications', + React.useCallback( + isInside => { + // on mobile: + // fires with `isInside=true` when the user navigates to the root tab + // but not when the user goes back to the screen by pressing back + // on web: + // essentially equivalent to useFocusEffect because we dont used tabbed + // navigation + if (isInside) { + if (store.me.notifications.unreadCount > 0) { + store.me.notifications.refresh() + } else { + store.me.notifications.syncQueue() + } + } + }, + [store], + ), + ) return ( diff --git a/src/view/shell/desktop/LeftNav.tsx b/src/view/shell/desktop/LeftNav.tsx index bcff844f..b4b21902 100644 --- a/src/view/shell/desktop/LeftNav.tsx +++ b/src/view/shell/desktop/LeftNav.tsx @@ -95,11 +95,11 @@ const NavItem = observer( {isCurrent ? iconFilled : icon} - {typeof count === 'string' && count && ( + {typeof count === 'string' && count ? ( {count} - )} + ) : null} {label}