about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/App.web.tsx1
-rw-r--r--src/lib/analytics.tsx1
-rw-r--r--src/lib/analytics.web.tsx1
-rw-r--r--src/platform/urls.tsx9
-rw-r--r--src/state/models/navigation.ts86
5 files changed, 68 insertions, 30 deletions
diff --git a/src/App.web.tsx b/src/App.web.tsx
index 1c6efba8f..84d3b6cd6 100644
--- a/src/App.web.tsx
+++ b/src/App.web.tsx
@@ -16,6 +16,7 @@ function App() {
     view.setup()
     setupState().then(store => {
       setRootStore(store)
+      store.nav.bindWebNavigation()
       getInitialURL().then(url => {
         if (url) {
           store.nav.handleLink(url)
diff --git a/src/lib/analytics.tsx b/src/lib/analytics.tsx
index 441cdc454..e12b8cf7a 100644
--- a/src/lib/analytics.tsx
+++ b/src/lib/analytics.tsx
@@ -7,6 +7,7 @@ const segmentClient = createClient({
   writeKey: '8I6DsgfiSLuoONyaunGoiQM7A6y2ybdI',
   trackAppLifecycleEvents: false,
 })
+export const track = segmentClient.track
 
 export {useAnalytics} from '@segment/analytics-react-native'
 
diff --git a/src/lib/analytics.web.tsx b/src/lib/analytics.web.tsx
index f04d945fe..e2db537f4 100644
--- a/src/lib/analytics.web.tsx
+++ b/src/lib/analytics.web.tsx
@@ -6,6 +6,7 @@ const _analytics = {
   screen(_name: string) {},
   track(_name: string, _opts: any) {},
 }
+export const track = _analytics.track
 export function useAnalytics() {
   return _analytics
 }
diff --git a/src/platform/urls.tsx b/src/platform/urls.tsx
index f544262d7..fd844d933 100644
--- a/src/platform/urls.tsx
+++ b/src/platform/urls.tsx
@@ -1,5 +1,4 @@
 import {Linking} from 'react-native'
-import {createBrowserHistory, createMemoryHistory} from 'history'
 import {isNative, isWeb} from './detection'
 
 export async function getInitialURL(): Promise<string | undefined> {
@@ -24,11 +23,3 @@ export function clearHash() {
     window.location.hash = ''
   }
 }
-
-export function getHistory() {
-  if (isWeb) {
-    return createBrowserHistory()
-  } else {
-    return createMemoryHistory()
-  }
-}
diff --git a/src/state/models/navigation.ts b/src/state/models/navigation.ts
index 9cbc678d0..9836121b4 100644
--- a/src/state/models/navigation.ts
+++ b/src/state/models/navigation.ts
@@ -1,8 +1,8 @@
 import {RootStoreModel} from './root-store'
 import {makeAutoObservable} from 'mobx'
 import {TABS_ENABLED} from 'lib/build-flags'
-import {segmentClient} from 'lib/analytics'
-import {getHistory} from 'platform/urls'
+import * as analytics from 'lib/analytics'
+import {isNative} from 'platform/detection'
 
 let __id = 0
 function genId() {
@@ -42,7 +42,6 @@ export type HistoryPtr = string // `{tabId}-{historyId}`
 export class NavigationTabModel {
   id = genId()
   history: HistoryItem[]
-  browserHistory: any
   index = 0
   isNewTab = false
 
@@ -50,13 +49,11 @@ export class NavigationTabModel {
     this.history = [
       {url: TabPurposeMainPath[fixedTabPurpose], ts: Date.now(), id: genId()},
     ]
-    this.browserHistory = getHistory()
     makeAutoObservable(this, {
       serialize: false,
       hydrate: false,
     })
   }
-
   // accessors
   // =
 
@@ -108,7 +105,7 @@ export class NavigationTabModel {
   navigate(url: string, title?: string) {
     try {
       const path = url.split('/')[1]
-      segmentClient.track('Navigation', {
+      analytics.track('Navigation', {
         path,
       })
     } catch (error) {}
@@ -125,8 +122,10 @@ export class NavigationTabModel {
         this.history.push({url: fixedUrl, ts: Date.now(), id: genId()})
       }
       this.history.push({url, title, ts: Date.now(), id: genId()})
-      this.browserHistory.push(url)
       this.index = this.history.length - 1
+      if (!isNative) {
+        window.history.pushState({hindex: this.index, hurl: url}, '', url)
+      }
     }
   }
 
@@ -146,7 +145,9 @@ export class NavigationTabModel {
   goBack() {
     if (this.canGoBack) {
       this.index--
-      this.browserHistory.back()
+      if (!isNative) {
+        window.history.back()
+      }
     }
   }
 
@@ -160,14 +161,19 @@ export class NavigationTabModel {
   goForward() {
     if (this.canGoForward) {
       this.index++
-      this.browserHistory.forward()
+      if (!isNative) {
+        window.history.forward()
+      }
     }
   }
 
   goToIndex(index: number) {
     if (index >= 0 && index <= this.history.length - 1) {
+      const delta = index - this.index
       this.index = index
-      this.browserHistory.go(index)
+      if (!isNative) {
+        window.history.go(delta)
+      }
     }
   }
 
@@ -184,6 +190,15 @@ export class NavigationTabModel {
     this.isNewTab = v
   }
 
+  // browser only
+  // =
+
+  resetTo(url: string) {
+    this.index = 0
+    this.history.push({url, title: '', ts: Date.now(), id: genId()})
+    this.index = this.history.length - 1
+  }
+
   // persistence
   // =
 
@@ -229,11 +244,13 @@ export class NavigationTabModel {
 }
 
 export class NavigationModel {
-  tabs: NavigationTabModel[] = [
-    new NavigationTabModel(TabPurpose.Default),
-    new NavigationTabModel(TabPurpose.Search),
-    new NavigationTabModel(TabPurpose.Notifs),
-  ]
+  tabs: NavigationTabModel[] = isNative
+    ? [
+        new NavigationTabModel(TabPurpose.Default),
+        new NavigationTabModel(TabPurpose.Search),
+        new NavigationTabModel(TabPurpose.Notifs),
+      ]
+    : [new NavigationTabModel(TabPurpose.Default)]
   tabIndex = 0
 
   constructor(public rootStore: RootStoreModel) {
@@ -244,12 +261,39 @@ export class NavigationModel {
     })
   }
 
+  /**
+   * Used only in the web build to sync with browser history state
+   */
+  bindWebNavigation() {
+    if (!isNative) {
+      window.addEventListener('popstate', e => {
+        const {hindex, hurl} = e.state
+        if (hindex >= 0 && hindex <= this.tab.history.length - 1) {
+          this.tab.index = hindex
+        }
+        if (this.tab.current.url !== hurl) {
+          // desynced because they went back to an old tab session-
+          // do a reset to match that
+          this.tab.resetTo(hurl)
+        }
+
+        // sanity check
+        if (this.tab.current.url !== window.location.pathname) {
+          // state has completely desynced, reload
+          window.location.reload()
+        }
+      })
+    }
+  }
+
   clear() {
-    this.tabs = [
-      new NavigationTabModel(TabPurpose.Default),
-      new NavigationTabModel(TabPurpose.Search),
-      new NavigationTabModel(TabPurpose.Notifs),
-    ]
+    this.tabs = isNative
+      ? [
+          new NavigationTabModel(TabPurpose.Default),
+          new NavigationTabModel(TabPurpose.Search),
+          new NavigationTabModel(TabPurpose.Notifs),
+        ]
+      : [new NavigationTabModel(TabPurpose.Default)]
     this.tabIndex = 0
   }
 
@@ -372,7 +416,7 @@ export class NavigationModel {
   hydrate(_v: unknown) {
     // TODO fixme
     this.clear()
-    /*if (isObj(v)) {
+    /*if (isObj(v)) { 
       if (hasProp(v, 'tabs') && Array.isArray(v.tabs)) {
         for (const tab of v.tabs) {
           const copy = new NavigationTabModel()