Skip to content

Commit bf95e92

Browse files
committed
fix(mobile): reset navigation stack when switching tab or searching
when it's a page view
1 parent 5b52b68 commit bf95e92

File tree

4 files changed

+77
-36
lines changed

4 files changed

+77
-36
lines changed

ios/App/App/AppDelegate.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,22 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UINavigationControllerDel
134134
// MARK: Navigation operations
135135
// ---------------------------------------------------------
136136

137+
private func emptyNavStack(path: String) {
138+
let path = normalizedPath(path)
139+
guard let nav = navController else { return }
140+
141+
ignoreRoutePopCount = 0
142+
popSnapshotView?.removeFromSuperview()
143+
popSnapshotView = nil
144+
145+
let vc = NativePageViewController(path: path, push: false)
146+
pathStack = [path]
147+
148+
nav.setViewControllers([vc], animated: false)
149+
SharedWebViewController.instance.clearPlaceholder()
150+
SharedWebViewController.instance.attach(to: vc)
151+
}
152+
137153
private func pushIfNeeded(path: String, animated: Bool) {
138154
let path = normalizedPath(path)
139155
guard let nav = navController else { return }
@@ -317,6 +333,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UINavigationControllerDel
317333
let navigationType = (notification.userInfo?["navigationType"] as? String) ?? "push"
318334

319335
switch navigationType {
336+
case "reset":
337+
self.emptyNavStack(path: path)
338+
320339
case "replace":
321340
self.replaceTop(path: path)
322341

src/main/mobile/bottom_tabs.cljs

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
(:require [cljs-bean.core :as bean]
44
[clojure.string :as string]
55
[frontend.handler.editor :as editor-handler]
6-
[frontend.handler.route :as route-handler]
76
[frontend.state :as state]
87
[frontend.util :as util]
98
[logseq.common.util :as common-util]
9+
[mobile.navigation :as mobile-nav]
1010
[mobile.state :as mobile-state]))
1111

1212
;; Capacitor plugin instance:
@@ -79,34 +79,43 @@
7979
(editor-handler/keydown-new-block-handler nil))))
8080
nil)))))
8181

82+
(defonce *previous-tab (atom nil))
8283
(defonce add-tab-listeners!
8384
(do
8485
(add-tab-selected-listener!
8586
(fn [tab]
86-
(reset! mobile-state/*search-input "")
87-
(when-not (= tab "quick-add")
88-
(mobile-state/set-tab! tab))
89-
(case tab
90-
"home"
91-
(do
92-
(route-handler/redirect-to-home!)
93-
(util/scroll-to-top false))
94-
"quick-add"
95-
(editor-handler/show-quick-add)
96-
;; TODO: support longPress detection
97-
;; (if (= "longPress" interaction)
98-
;; (state/pub-event! [:mobile/start-audio-record])
99-
;; (editor-handler/show-quick-add))
100-
nil)))
87+
(let [exit-quick-add? (= @*previous-tab "quick-add")]
88+
(reset! mobile-state/*search-input "")
89+
(when-not (contains? #{"quick-add"} tab)
90+
(when-not exit-quick-add?
91+
(mobile-nav/reset-route!))
92+
(mobile-state/set-tab! tab))
93+
94+
(case tab
95+
"home"
96+
(when-not exit-quick-add?
97+
(util/scroll-to-top false))
98+
"quick-add"
99+
(editor-handler/show-quick-add)
100+
;; TODO: support longPress detection
101+
;; (if (= "longPress" interaction)
102+
;; (state/pub-event! [:mobile/start-audio-record])
103+
;; (editor-handler/show-quick-add))
104+
nil)
105+
106+
(reset! *previous-tab tab))))
107+
101108
(add-watch mobile-state/*tab ::select-tab
102109
(fn [_ _ _old new]
103110
(when new (select! new))))
104111
(add-search-listener!
105112
(fn [q]
106-
;; wire up search handler
113+
;; wire up search handler
107114
(js/console.log "Native search query" q)
108115
(reset! mobile-state/*search-input q)
109-
(reset! mobile-state/*search-last-input-at (common-util/time-ms))))
116+
(reset! mobile-state/*search-last-input-at (common-util/time-ms))
117+
(when (= :page (get-in (state/get-route-match) [:data :name]))
118+
(mobile-nav/reset-route!))))
110119
(add-keyboard-hack-listener!)))
111120

112121
(defn configure

src/main/mobile/components/app.cljs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -87,15 +87,17 @@
8787

8888
(rum/defc other-page
8989
[view tab route-match]
90-
[:div#main-content-container.px-5.ls-layer
91-
(if view
92-
(view route-match)
93-
(case (keyword tab)
94-
:home nil
95-
:favorites (favorites/favorites)
90+
(let [tab' (keyword tab)]
91+
[:div#main-content-container.px-5.ls-layer
92+
(case tab'
9693
:settings (settings/page)
97-
:search (search/search)
98-
nil))])
94+
(if view
95+
(view route-match)
96+
(case tab'
97+
:home nil
98+
:favorites (favorites/favorites)
99+
:search (search/search)
100+
nil)))]))
99101

100102
(rum/defc main-content < rum/static
101103
[tab route-match]

src/main/mobile/navigation.cljs

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
(ns mobile.navigation
22
"Native navigation bridge for mobile (iOS)."
33
(:require [clojure.string :as string]
4+
[frontend.handler.route :as route-handler]
45
[frontend.mobile.util :as mobile-util]
56
[lambdaisland.glogi :as log]
67
[promesa.core :as p]))
@@ -26,6 +27,14 @@
2627
(compare-and-set! initialised? false true) "replace" ;; first load
2728
:else "push")))
2829

30+
(defn- notify-route-payload!
31+
[payload]
32+
(-> (.routeDidChange mobile-util/ui-local (clj->js payload))
33+
(p/catch (fn [err]
34+
(log/warn :mobile-native-navigation/route-report-failed
35+
{:error err
36+
:payload payload})))))
37+
2938
(defn notify-route-change!
3039
"Inform native iOS layer of a route change to keep native stack in sync.
3140
{route {to keyword, path-params map, query-params map}
@@ -35,13 +44,15 @@
3544
(when (and (mobile-util/native-ios?)
3645
mobile-util/ui-local)
3746
(let [nav-type (navigation-type push)
38-
payload (clj->js (cond-> {:navigationType nav-type
39-
:push (not= nav-type "replace")}
40-
route (assoc :route route)
41-
(or path (.-hash js/location))
42-
(assoc :path (strip-fragment (or path (.-hash js/location))))))]
43-
(-> (.routeDidChange mobile-util/ui-local payload)
44-
(p/catch (fn [err]
45-
(log/warn :mobile-native-navigation/route-report-failed
46-
{:error err
47-
:payload payload})))))))
47+
payload (cond-> {:navigationType nav-type
48+
:push (not= nav-type "replace")}
49+
route (assoc :route route)
50+
(or path (.-hash js/location))
51+
(assoc :path (strip-fragment (or path (.-hash js/location)))))]
52+
(notify-route-payload! payload))))
53+
54+
(defn reset-route!
55+
[]
56+
(route-handler/redirect-to-home! false)
57+
(notify-route-payload!
58+
{:navigationType "reset"}))

0 commit comments

Comments
 (0)