@@ -4,6 +4,7 @@ import Bridge
44import Browser
55import FFI exposing (getBridge, sendBridge)
66import Html exposing (..)
7+import List.Nonempty as Nonempty exposing (Nonempty(..))
78import Notification
89import Pages.Cipher as Cipher
910import Pages.Ciphers as Ciphers
@@ -32,6 +33,7 @@ type Msg
3233 | CipherMsg Cipher.Msg
3334 | ShowCipherPage Bridge.Sub_LoadCipher
3435 | RequestCipher CipherId
36+ | PopView
3537
3638
3739type alias CipherId =
@@ -40,7 +42,7 @@ type alias CipherId =
4042
4143type alias Model =
4244 { notifications : List Notification.Config
43− , page : PageModel
45+ , pageStack : Navigation.PageStack PageModel
4446 }
4547
4648
@@ -134,7 +136,7 @@ init : ( Model, Cmd Msg )
134136init =
135137 -- Cipher.init |> Tuple.mapBoth (\p -> { notifications = [], page = CipherModel p }) (Cmd.map CipherMsg)
136138 ( { notifications = []
137− , page = LoadingPage
139+ , pageStack = Nonempty.singleton LoadingPage
138140 }
139141 , FFI.sendBridge Bridge.Init
140142 )
@@ -142,15 +144,38 @@ init =
142144
143145view : Model -> Html Msg
144146view model =
145− let
146− ( title, body ) =
147− showPage model.page
148− in
149− div []
150− [ Navigation.navigation { back = False, title = title }
151− , main_ []
152− (maybeList (List.head model.notifications) (Notification.notification CloseNotification) ++ body)
153− ]
147+ Navigation.showNavigationView { popStack = PopView }
148+ model.pageStack
149+ (\page ->
150+ let
151+ ( title, body ) =
152+ showPage page
153+ in
154+ ( title
155+ , maybeList (List.head model.notifications) (Notification.notification CloseNotification) ++ body
156+ )
157+ )
158+
159+
160+mapHead : (a -> a) -> Nonempty a -> Nonempty a
161+mapHead f (Nonempty x xx) =
162+ Nonempty (f x) xx
163+
164+
165+doNotStoreInHistory : PageModel -> Bool
166+doNotStoreInHistory page =
167+ case page of
168+ LoginModel _ ->
169+ True
170+
171+ MasterPasswordModel _ ->
172+ True
173+
174+ LoadingPage ->
175+ True
176+
177+ _ ->
178+ False
154179
155180
156181update : Msg -> Model -> ( Model, Cmd Msg )
@@ -160,7 +185,7 @@ update msg model =
160185 processPage liftModel ( resultModel, cmd ) =
161186 case resultModel of
162187 Ok mdl ->
163− ( { model | page = liftModel mdl }, cmd )
188+ ( { model | pageStack = mapHead (always (liftModel mdl)) model.pageStack }, cmd )
164189
165190 Err err ->
166191 ( appendNotification
@@ -171,6 +196,13 @@ update msg model =
171196 model
172197 , cmd
173198 )
199+
200+ appendPageStack : PageModel -> Model
201+ appendPageStack mdl =
202+ { model | pageStack = model.pageStack |> Nonempty.toList |> List.filter (doNotStoreInHistory >> not) |> Nonempty mdl }
203+
204+ currentPage =
205+ model.pageStack |> Nonempty.head
174206 in
175207 case msg of
176208 RecieveMessage x ->
@@ -204,7 +236,7 @@ update msg model =
204236 )
205237
206238 LoginMsg imsg ->
207− case model.page of
239+ case currentPage of
208240 LoginModel page ->
209241 (Login.page loginCallbacks LoginMsg).update imsg page |> processPage LoginModel
210242
@@ -212,7 +244,7 @@ update msg model =
212244 ( model, Cmd.none )
213245
214246 CiphersMsg imsg ->
215− case model.page of
247+ case currentPage of
216248 CiphersModel page ->
217249 (Ciphers.page ciphersCallbacks CiphersMsg).update imsg page |> processPage CiphersModel
218250
@@ -221,30 +253,30 @@ update msg model =
221253
222254 ShowLoginPage ->
223255 (Login.page loginCallbacks LoginMsg).init ()
224− |> Tuple.mapFirst (\pageModel -> { model | page = LoginModel pageModel })
256+ |> Tuple.mapFirst (\pageModel -> appendPageStack <| LoginModel pageModel)
225257
226258 LoadCiphers ciphers ->
227259 (Ciphers.page ciphersCallbacks CiphersMsg).init ciphers
228− |> Tuple.mapFirst (\pageModel -> { model | page = CiphersModel pageModel })
260+ |> Tuple.mapFirst (\pageModel -> appendPageStack <| CiphersModel pageModel)
229261
230262 OpenCiphersScreen ->
231− ( { model | page = LoadingPage }, sendBridge Bridge.NeedCiphersList )
263+ ( appendPageStack <| LoadingPage, sendBridge Bridge.NeedCiphersList )
232264
233265 Reset ->
234266 init
235267
236268 ShowMasterPasswordPage { server, login } ->
237269 (MasterPassword.page masterPasswordCallbacks MasterPasswordMsg).init { server = server, login = login }
238− |> Tuple.mapFirst (\pageModel -> { model | page = MasterPasswordModel pageModel })
270+ |> Tuple.mapFirst (\pageModel -> appendPageStack <| MasterPasswordModel pageModel)
239271
240272 NeedsReset ->
241− ( { model | page = LoadingPage }, sendBridge Bridge.NeedsReset )
273+ ( appendPageStack <| LoadingPage, sendBridge Bridge.NeedsReset )
242274
243275 SendMasterPassword { password } ->
244− ( { model | page = LoadingPage }, sendBridge (Bridge.SendMasterPassword password) )
276+ ( appendPageStack <| LoadingPage, sendBridge (Bridge.SendMasterPassword password) )
245277
246278 MasterPasswordMsg imsg ->
247− case model.page of
279+ case currentPage of
248280 MasterPasswordModel page ->
249281 (MasterPassword.page masterPasswordCallbacks MasterPasswordMsg).update imsg page |> processPage MasterPasswordModel
250282
@@ -252,7 +284,7 @@ update msg model =
252284 ( model, Cmd.none )
253285
254286 CipherMsg imsg ->
255− case model.page of
287+ case currentPage of
256288 CipherModel page ->
257289 (Cipher.page cipherCallbacks CipherMsg).update imsg page |> processPage CipherModel
258290
@@ -261,10 +293,15 @@ update msg model =
261293
262294 ShowCipherPage cipher ->
263295 (Cipher.page cipherCallbacks CipherMsg).init cipher
264− |> Tuple.mapFirst (\pageModel -> { model | page = CipherModel pageModel })
296+ |> Tuple.mapFirst (\pageModel -> appendPageStack <| CipherModel pageModel)
265297
266298 RequestCipher id ->
267− ( { model | page = LoadingPage }, sendBridge (Bridge.RequestCipher id) )
299+ ( appendPageStack <| LoadingPage, sendBridge (Bridge.RequestCipher id) )
300+
301+ PopView ->
302+ ( { model | pageStack = Navigation.popView model.pageStack }
303+ , Cmd.none
304+ )
268305
269306
270307loginCallbacks : Login.Callbacks Msg