Improvements to notifications screen [APP-520] (#501)
* Refresh or sync notifications when the tab is navigated to * Fix to bad textnode render * Speed up initial session load * Fix lint * Restore updateSessionState() on session resumptionzio/stable
parent
f2fe4abdce
commit
e02c926c8a
|
@ -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])
|
||||||
|
}
|
|
@ -99,14 +99,12 @@ export class MeModel {
|
||||||
this.handle = sess.currentSession?.handle || ''
|
this.handle = sess.currentSession?.handle || ''
|
||||||
await this.fetchProfile()
|
await this.fetchProfile()
|
||||||
this.mainFeed.clear()
|
this.mainFeed.clear()
|
||||||
await Promise.all([
|
/* dont await */ this.mainFeed.setup().catch(e => {
|
||||||
this.mainFeed.setup().catch(e => {
|
this.rootStore.log.error('Failed to setup main feed model', e)
|
||||||
this.rootStore.log.error('Failed to setup main feed model', e)
|
})
|
||||||
}),
|
/* dont await */ this.notifications.setup().catch(e => {
|
||||||
this.notifications.setup().catch(e => {
|
this.rootStore.log.error('Failed to setup notifications model', e)
|
||||||
this.rootStore.log.error('Failed to setup notifications model', e)
|
})
|
||||||
}),
|
|
||||||
])
|
|
||||||
this.rootStore.emitSessionLoaded()
|
this.rootStore.emitSessionLoaded()
|
||||||
await this.fetchInviteCodes()
|
await this.fetchInviteCodes()
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -13,6 +13,7 @@ import {InvitedUsers} from '../com/notifications/InvitedUsers'
|
||||||
import {LoadLatestBtn} from 'view/com/util/load-latest/LoadLatestBtn'
|
import {LoadLatestBtn} from 'view/com/util/load-latest/LoadLatestBtn'
|
||||||
import {useStores} from 'state/index'
|
import {useStores} from 'state/index'
|
||||||
import {useOnMainScroll} from 'lib/hooks/useOnMainScroll'
|
import {useOnMainScroll} from 'lib/hooks/useOnMainScroll'
|
||||||
|
import {useTabFocusEffect} from 'lib/hooks/useTabFocusEffect'
|
||||||
import {s} from 'lib/styles'
|
import {s} from 'lib/styles'
|
||||||
import {useAnalytics} from 'lib/analytics'
|
import {useAnalytics} from 'lib/analytics'
|
||||||
|
|
||||||
|
@ -58,6 +59,27 @@ export const NotificationsScreen = withAuthRequired(
|
||||||
}
|
}
|
||||||
}, [store, screen, onPressLoadLatest]),
|
}, [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 (
|
return (
|
||||||
<View testID="notificationsScreen" style={s.hContentRegion}>
|
<View testID="notificationsScreen" style={s.hContentRegion}>
|
||||||
|
|
|
@ -95,11 +95,11 @@ const NavItem = observer(
|
||||||
<Link href={href} style={styles.navItem}>
|
<Link href={href} style={styles.navItem}>
|
||||||
<View style={[styles.navItemIconWrapper]}>
|
<View style={[styles.navItemIconWrapper]}>
|
||||||
{isCurrent ? iconFilled : icon}
|
{isCurrent ? iconFilled : icon}
|
||||||
{typeof count === 'string' && count && (
|
{typeof count === 'string' && count ? (
|
||||||
<Text type="button" style={styles.navItemCount}>
|
<Text type="button" style={styles.navItemCount}>
|
||||||
{count}
|
{count}
|
||||||
</Text>
|
</Text>
|
||||||
)}
|
) : null}
|
||||||
</View>
|
</View>
|
||||||
<Text type="title" style={[isCurrent ? s.bold : s.normal, pal.text]}>
|
<Text type="title" style={[isCurrent ? s.bold : s.normal, pal.text]}>
|
||||||
{label}
|
{label}
|
||||||
|
|
Loading…
Reference in New Issue