about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorPaul Frazee <pfrazee@gmail.com>2022-11-17 16:01:29 -0600
committerPaul Frazee <pfrazee@gmail.com>2022-11-17 16:01:29 -0600
commita3bca154c4d8c0c0c42d56d61b2ab2188204710e (patch)
tree56d9eb9be13cf368b9fe2a2845919ae09774526b /src
parentb2160ae15952baf19d7375db2de77ce8d969b44d (diff)
downloadvoidsky-a3bca154c4d8c0c0c42d56d61b2ab2188204710e.tar.zst
Improve reliability of screen titles
Diffstat (limited to 'src')
-rw-r--r--src/state/models/navigation.ts37
-rw-r--r--src/view/routes.ts1
-rw-r--r--src/view/screens/Contacts.tsx4
-rw-r--r--src/view/screens/Home.tsx3
-rw-r--r--src/view/screens/Notifications.tsx4
-rw-r--r--src/view/screens/PostDownvotedBy.tsx4
-rw-r--r--src/view/screens/PostRepostedBy.tsx4
-rw-r--r--src/view/screens/PostThread.tsx4
-rw-r--r--src/view/screens/PostUpvotedBy.tsx4
-rw-r--r--src/view/screens/Profile.tsx4
-rw-r--r--src/view/screens/ProfileFollowers.tsx4
-rw-r--r--src/view/screens/ProfileFollows.tsx4
-rw-r--r--src/view/screens/ProfileMembers.tsx4
-rw-r--r--src/view/screens/Search.tsx4
-rw-r--r--src/view/screens/Settings.tsx7
-rw-r--r--src/view/shell/mobile/index.tsx5
16 files changed, 60 insertions, 37 deletions
diff --git a/src/state/models/navigation.ts b/src/state/models/navigation.ts
index 533336a43..0ec097afc 100644
--- a/src/state/models/navigation.ts
+++ b/src/state/models/navigation.ts
@@ -1,20 +1,23 @@
 import {makeAutoObservable} from 'mobx'
 import {isObj, hasProp} from '../lib/type-guards'
 
-let __tabId = 0
-function genTabId() {
-  return ++__tabId
+let __id = 0
+function genId() {
+  return ++__id
 }
 
 interface HistoryItem {
   url: string
   ts: number
   title?: string
+  id: number
 }
 
+export type HistoryPtr = [number, number]
+
 export class NavigationTabModel {
-  id = genTabId()
-  history: HistoryItem[] = [{url: '/', ts: Date.now()}]
+  id = genId()
+  history: HistoryItem[] = [{url: '/', ts: Date.now(), id: genId()}]
   index = 0
   isNewTab = false
 
@@ -47,6 +50,7 @@ export class NavigationTabModel {
       url: item.url,
       title: item.title,
       index: start + i,
+      id: item.id,
     }))
   }
 
@@ -61,6 +65,7 @@ export class NavigationTabModel {
       url: item.url,
       title: item.title,
       index: start + i,
+      id: item.id,
     }))
   }
 
@@ -78,7 +83,7 @@ export class NavigationTabModel {
       if (this.index < this.history.length - 1) {
         this.history.length = this.index + 1
       }
-      this.history.push({url, title, ts: Date.now()})
+      this.history.push({url, title, ts: Date.now(), id: genId()})
       this.index = this.history.length - 1
     }
   }
@@ -86,7 +91,12 @@ export class NavigationTabModel {
   refresh() {
     this.history = [
       ...this.history.slice(0, this.index),
-      {url: this.current.url, title: this.current.title, ts: Date.now()},
+      {
+        url: this.current.url,
+        title: this.current.title,
+        ts: Date.now(),
+        id: this.current.id,
+      },
       ...this.history.slice(this.index + 1),
     ]
   }
@@ -109,8 +119,13 @@ export class NavigationTabModel {
     }
   }
 
-  setTitle(title: string) {
-    this.current.title = title
+  setTitle(id: number, title: string) {
+    this.history = this.history.map(h => {
+      if (h.id === id) {
+        return {...h, title}
+      }
+      return h
+    })
   }
 
   setIsNewTab(v: boolean) {
@@ -203,8 +218,8 @@ export class NavigationModel {
     this.tab.refresh()
   }
 
-  setTitle(title: string) {
-    this.tab.setTitle(title)
+  setTitle(ptr: HistoryPtr, title: string) {
+    this.tabs.find(t => t.id === ptr[0])?.setTitle(ptr[1], title)
   }
 
   // tab management
diff --git a/src/view/routes.ts b/src/view/routes.ts
index c49297071..272a1b096 100644
--- a/src/view/routes.ts
+++ b/src/view/routes.ts
@@ -17,6 +17,7 @@ import {ProfileMembers} from './screens/ProfileMembers'
 import {Settings} from './screens/Settings'
 
 export type ScreenParams = {
+  navIdx: [number, number]
   params: Record<string, any>
   visible: boolean
   scrollElRef?: MutableRefObject<FlatList<any> | undefined>
diff --git a/src/view/screens/Contacts.tsx b/src/view/screens/Contacts.tsx
index 65c933b38..c0e265ca7 100644
--- a/src/view/screens/Contacts.tsx
+++ b/src/view/screens/Contacts.tsx
@@ -8,13 +8,13 @@ import {colors} from '../lib/styles'
 import {ScreenParams} from '../routes'
 import {useStores} from '../../state'
 
-export const Contacts = ({visible, params}: ScreenParams) => {
+export const Contacts = ({navIdx, visible, params}: ScreenParams) => {
   const store = useStores()
   const selectorInterp = useSharedValue(0)
 
   useEffect(() => {
     if (visible) {
-      store.nav.setTitle(`Contacts`)
+      store.nav.setTitle(navIdx, `Contacts`)
     }
   }, [store, visible])
 
diff --git a/src/view/screens/Home.tsx b/src/view/screens/Home.tsx
index 668ec3a75..609b1ca38 100644
--- a/src/view/screens/Home.tsx
+++ b/src/view/screens/Home.tsx
@@ -12,6 +12,7 @@ import {ScreenParams} from '../routes'
 import {s, colors} from '../lib/styles'
 
 export const Home = observer(function Home({
+  navIdx,
   visible,
   scrollElRef,
 }: ScreenParams) {
@@ -51,7 +52,7 @@ export const Home = observer(function Home({
       console.log('Updating home feed')
       defaultFeedView.update()
     } else {
-      store.nav.setTitle('Home')
+      store.nav.setTitle(navIdx, 'Home')
       console.log('Fetching home feed')
       defaultFeedView.setup().then(() => {
         if (aborted) return
diff --git a/src/view/screens/Notifications.tsx b/src/view/screens/Notifications.tsx
index 71eda34de..7e4de497e 100644
--- a/src/view/screens/Notifications.tsx
+++ b/src/view/screens/Notifications.tsx
@@ -7,7 +7,7 @@ import {useStores} from '../../state'
 import {NotificationsViewModel} from '../../state/models/notifications-view'
 import {ScreenParams} from '../routes'
 
-export const Notifications = ({visible}: ScreenParams) => {
+export const Notifications = ({navIdx, visible}: ScreenParams) => {
   const [hasSetup, setHasSetup] = useState<boolean>(false)
   const [notesView, setNotesView] = useState<
     NotificationsViewModel | undefined
@@ -24,7 +24,7 @@ export const Notifications = ({visible}: ScreenParams) => {
       console.log('Updating notifications feed')
       notesView?.update()
     } else {
-      store.nav.setTitle('Notifications')
+      store.nav.setTitle(navIdx, 'Notifications')
       const newNotesView = new NotificationsViewModel(store, {})
       setNotesView(newNotesView)
       newNotesView.setup().then(() => {
diff --git a/src/view/screens/PostDownvotedBy.tsx b/src/view/screens/PostDownvotedBy.tsx
index a77476834..4d9752799 100644
--- a/src/view/screens/PostDownvotedBy.tsx
+++ b/src/view/screens/PostDownvotedBy.tsx
@@ -6,14 +6,14 @@ import {ScreenParams} from '../routes'
 import {useStores} from '../../state'
 import {makeRecordUri} from '../lib/strings'
 
-export const PostDownvotedBy = ({visible, params}: ScreenParams) => {
+export const PostDownvotedBy = ({navIdx, visible, params}: ScreenParams) => {
   const store = useStores()
   const {name, rkey} = params
   const uri = makeRecordUri(name, 'app.bsky.feed.post', rkey)
 
   useEffect(() => {
     if (visible) {
-      store.nav.setTitle('Downvoted by')
+      store.nav.setTitle(navIdx, 'Downvoted by')
     }
   }, [store, visible])
 
diff --git a/src/view/screens/PostRepostedBy.tsx b/src/view/screens/PostRepostedBy.tsx
index 263af195d..8e8346693 100644
--- a/src/view/screens/PostRepostedBy.tsx
+++ b/src/view/screens/PostRepostedBy.tsx
@@ -6,14 +6,14 @@ import {ScreenParams} from '../routes'
 import {useStores} from '../../state'
 import {makeRecordUri} from '../lib/strings'
 
-export const PostRepostedBy = ({visible, params}: ScreenParams) => {
+export const PostRepostedBy = ({navIdx, visible, params}: ScreenParams) => {
   const store = useStores()
   const {name, rkey} = params
   const uri = makeRecordUri(name, 'app.bsky.feed.post', rkey)
 
   useEffect(() => {
     if (visible) {
-      store.nav.setTitle('Reposted by')
+      store.nav.setTitle(navIdx, 'Reposted by')
     }
   }, [store, visible])
 
diff --git a/src/view/screens/PostThread.tsx b/src/view/screens/PostThread.tsx
index fc804f61e..69dda7426 100644
--- a/src/view/screens/PostThread.tsx
+++ b/src/view/screens/PostThread.tsx
@@ -6,14 +6,14 @@ import {PostThread as PostThreadComponent} from '../com/post-thread/PostThread'
 import {ScreenParams} from '../routes'
 import {useStores} from '../../state'
 
-export const PostThread = ({visible, params}: ScreenParams) => {
+export const PostThread = ({navIdx, visible, params}: ScreenParams) => {
   const store = useStores()
   const {name, rkey} = params
   const uri = makeRecordUri(name, 'app.bsky.feed.post', rkey)
 
   useEffect(() => {
     if (visible) {
-      store.nav.setTitle(`Post by ${name}`)
+      store.nav.setTitle(navIdx, `Post by ${name}`)
     }
   }, [visible, store.nav, name])
 
diff --git a/src/view/screens/PostUpvotedBy.tsx b/src/view/screens/PostUpvotedBy.tsx
index 0bf662def..d87fa548d 100644
--- a/src/view/screens/PostUpvotedBy.tsx
+++ b/src/view/screens/PostUpvotedBy.tsx
@@ -6,14 +6,14 @@ import {ScreenParams} from '../routes'
 import {useStores} from '../../state'
 import {makeRecordUri} from '../lib/strings'
 
-export const PostUpvotedBy = ({visible, params}: ScreenParams) => {
+export const PostUpvotedBy = ({navIdx, visible, params}: ScreenParams) => {
   const store = useStores()
   const {name, rkey} = params
   const uri = makeRecordUri(name, 'app.bsky.feed.post', rkey)
 
   useEffect(() => {
     if (visible) {
-      store.nav.setTitle('Upvoted by')
+      store.nav.setTitle(navIdx, 'Upvoted by')
     }
   }, [store, visible])
 
diff --git a/src/view/screens/Profile.tsx b/src/view/screens/Profile.tsx
index 0edb503da..e637c6ad8 100644
--- a/src/view/screens/Profile.tsx
+++ b/src/view/screens/Profile.tsx
@@ -23,7 +23,7 @@ const LOADING_ITEM = {_reactKey: '__loading__'}
 const END_ITEM = {_reactKey: '__end__'}
 const EMPTY_ITEM = {_reactKey: '__empty__'}
 
-export const Profile = observer(({visible, params}: ScreenParams) => {
+export const Profile = observer(({navIdx, visible, params}: ScreenParams) => {
   const store = useStores()
   const [hasSetup, setHasSetup] = useState<boolean>(false)
   const uiState = useMemo(
@@ -41,7 +41,7 @@ export const Profile = observer(({visible, params}: ScreenParams) => {
       uiState.update()
     } else {
       console.log('Fetching profile for', params.name)
-      store.nav.setTitle(params.name)
+      store.nav.setTitle(navIdx, params.name)
       uiState.setup().then(() => {
         if (aborted) return
         setHasSetup(true)
diff --git a/src/view/screens/ProfileFollowers.tsx b/src/view/screens/ProfileFollowers.tsx
index ac776a056..b19a5bc37 100644
--- a/src/view/screens/ProfileFollowers.tsx
+++ b/src/view/screens/ProfileFollowers.tsx
@@ -5,13 +5,13 @@ import {ProfileFollowers as ProfileFollowersComponent} from '../com/profile/Prof
 import {ScreenParams} from '../routes'
 import {useStores} from '../../state'
 
-export const ProfileFollowers = ({visible, params}: ScreenParams) => {
+export const ProfileFollowers = ({navIdx, visible, params}: ScreenParams) => {
   const store = useStores()
   const {name} = params
 
   useEffect(() => {
     if (visible) {
-      store.nav.setTitle(`Followers of ${name}`)
+      store.nav.setTitle(navIdx, `Followers of ${name}`)
     }
   }, [store, visible, name])
 
diff --git a/src/view/screens/ProfileFollows.tsx b/src/view/screens/ProfileFollows.tsx
index c075851c6..e54b562e7 100644
--- a/src/view/screens/ProfileFollows.tsx
+++ b/src/view/screens/ProfileFollows.tsx
@@ -5,13 +5,13 @@ import {ProfileFollows as ProfileFollowsComponent} from '../com/profile/ProfileF
 import {ScreenParams} from '../routes'
 import {useStores} from '../../state'
 
-export const ProfileFollows = ({visible, params}: ScreenParams) => {
+export const ProfileFollows = ({navIdx, visible, params}: ScreenParams) => {
   const store = useStores()
   const {name} = params
 
   useEffect(() => {
     if (visible) {
-      store.nav.setTitle(`Followed by ${name}`)
+      store.nav.setTitle(navIdx, `Followed by ${name}`)
     }
   }, [store, visible, name])
 
diff --git a/src/view/screens/ProfileMembers.tsx b/src/view/screens/ProfileMembers.tsx
index dd2221091..b4b6c7e50 100644
--- a/src/view/screens/ProfileMembers.tsx
+++ b/src/view/screens/ProfileMembers.tsx
@@ -5,13 +5,13 @@ import {ProfileMembers as ProfileMembersComponent} from '../com/profile/ProfileM
 import {ScreenParams} from '../routes'
 import {useStores} from '../../state'
 
-export const ProfileMembers = ({visible, params}: ScreenParams) => {
+export const ProfileMembers = ({navIdx, visible, params}: ScreenParams) => {
   const store = useStores()
   const {name} = params
 
   useEffect(() => {
     if (visible) {
-      store.nav.setTitle(`Members of ${name}`)
+      store.nav.setTitle(navIdx, `Members of ${name}`)
     }
   }, [store, visible, name])
 
diff --git a/src/view/screens/Search.tsx b/src/view/screens/Search.tsx
index 7f3dd966b..71bac4ad7 100644
--- a/src/view/screens/Search.tsx
+++ b/src/view/screens/Search.tsx
@@ -7,13 +7,13 @@ import {ScreenParams} from '../routes'
 import {useStores} from '../../state'
 import {colors} from '../lib/styles'
 
-export const Search = ({visible, params}: ScreenParams) => {
+export const Search = ({navIdx, visible, params}: ScreenParams) => {
   const store = useStores()
   const {name} = params
 
   useEffect(() => {
     if (visible) {
-      store.nav.setTitle(`Search`)
+      store.nav.setTitle(navIdx, `Search`)
     }
   }, [store, visible, name])
   const onComposePress = () => {
diff --git a/src/view/screens/Settings.tsx b/src/view/screens/Settings.tsx
index a0aec89f3..b7344cf0d 100644
--- a/src/view/screens/Settings.tsx
+++ b/src/view/screens/Settings.tsx
@@ -8,14 +8,17 @@ import {ViewHeader} from '../com/util/ViewHeader'
 import {Link} from '../com/util/Link'
 import {UserAvatar} from '../com/util/UserAvatar'
 
-export const Settings = observer(function Settings({visible}: ScreenParams) {
+export const Settings = observer(function Settings({
+  navIdx,
+  visible,
+}: ScreenParams) {
   const store = useStores()
 
   useEffect(() => {
     if (!visible) {
       return
     }
-    store.nav.setTitle('Settings')
+    store.nav.setTitle(navIdx, 'Settings')
   }, [visible, store])
 
   const onPressSignout = () => {
diff --git a/src/view/shell/mobile/index.tsx b/src/view/shell/mobile/index.tsx
index cad681bd6..b4b98e35e 100644
--- a/src/view/shell/mobile/index.tsx
+++ b/src/view/shell/mobile/index.tsx
@@ -268,7 +268,7 @@ export const MobileShell: React.FC = observer(() => {
         <GestureDetector gesture={swipeGesture}>
           <ScreenContainer style={styles.screenContainer}>
             {screenRenderDesc.screens.map(
-              ({Com, params, key, current, previous}) => {
+              ({Com, navIdx, params, key, current, previous}) => {
                 return (
                   <Screen
                     key={key}
@@ -293,6 +293,7 @@ export const MobileShell: React.FC = observer(() => {
                       ]}>
                       <Com
                         params={params}
+                        navIdx={navIdx}
                         visible={current}
                         scrollElRef={current ? scrollElRef : undefined}
                       />
@@ -361,6 +362,7 @@ export const MobileShell: React.FC = observer(() => {
  */
 type ScreenRenderDesc = MatchResult & {
   key: string
+  navIdx: [number, number]
   current: boolean
   previous: boolean
   isNewTab: boolean
@@ -388,6 +390,7 @@ function constructScreenRenderDesc(nav: NavigationModel): {
       hasNewTab = hasNewTab || tab.isNewTab
       return Object.assign(matchRes, {
         key: `t${tab.id}-s${screen.index}`,
+        navIdx: [tab.id, screen.id],
         current: isCurrent,
         previous: isPrevious,
         isNewTab: tab.isNewTab,