about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPaul Frazee <pfrazee@gmail.com>2023-04-20 17:36:25 -0500
committerGitHub <noreply@github.com>2023-04-20 17:36:25 -0500
commite02c926c8a18f9cf296544b23ad343a59919acff (patch)
tree95eb2afa59595b74564c36178ad019c67a058e83
parentf2fe4abdce71fffa36419b8642289b7b86af7377 (diff)
downloadvoidsky-e02c926c8a18f9cf296544b23ad343a59919acff.tar.zst
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 resumption
-rw-r--r--src/lib/hooks/useTabFocusEffect.ts27
-rw-r--r--src/state/models/me.ts14
-rw-r--r--src/view/screens/Notifications.tsx22
-rw-r--r--src/view/shell/desktop/LeftNav.tsx4
4 files changed, 57 insertions, 10 deletions
diff --git a/src/lib/hooks/useTabFocusEffect.ts b/src/lib/hooks/useTabFocusEffect.ts
new file mode 100644
index 000000000..e446084c5
--- /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 e8b8e1ed0..b99363790 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 3e34a9fab..d93666aa8 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 (
       <View testID="notificationsScreen" style={s.hContentRegion}>
diff --git a/src/view/shell/desktop/LeftNav.tsx b/src/view/shell/desktop/LeftNav.tsx
index bcff844f1..b4b219023 100644
--- a/src/view/shell/desktop/LeftNav.tsx
+++ b/src/view/shell/desktop/LeftNav.tsx
@@ -95,11 +95,11 @@ const NavItem = observer(
         <Link href={href} style={styles.navItem}>
           <View style={[styles.navItemIconWrapper]}>
             {isCurrent ? iconFilled : icon}
-            {typeof count === 'string' && count && (
+            {typeof count === 'string' && count ? (
               <Text type="button" style={styles.navItemCount}>
                 {count}
               </Text>
-            )}
+            ) : null}
           </View>
           <Text type="title" style={[isCurrent ? s.bold : s.normal, pal.text]}>
             {label}