@@ -4,6 +4,7 @@ import Bridge
4import Browser
4import Browser
5import FFI exposing (getBridge, sendBridge)
5import FFI exposing (getBridge, sendBridge)
6import Html exposing (..)
6import Html exposing (..)
7+import List.Nonempty as Nonempty exposing (Nonempty(..))
7import Notification
8import Notification
8import Pages.Cipher as Cipher
9import Pages.Cipher as Cipher
9import Pages.Ciphers as Ciphers
10import Pages.Ciphers as Ciphers
@@ -32,6 +33,7 @@ type Msg
32 | CipherMsg Cipher.Msg
33 | CipherMsg Cipher.Msg
33 | ShowCipherPage Bridge.Sub_LoadCipher
34 | ShowCipherPage Bridge.Sub_LoadCipher
34 | RequestCipher CipherId
35 | RequestCipher CipherId
37type alias CipherId =
39type alias CipherId =
@@ -40,7 +42,7 @@ type alias CipherId =
41type alias Model =
43type alias Model =
42 { notifications : List Notification.Config
44 { notifications : List Notification.Config
43− , page : PageModel
45+ , pageStack : Navigation.PageStack PageModel
@@ -134,7 +136,7 @@ init : ( Model, Cmd Msg )
135 -- Cipher.init |> Tuple.mapBoth (\p -> { notifications = [], page = CipherModel p }) (Cmd.map CipherMsg)
137 -- Cipher.init |> Tuple.mapBoth (\p -> { notifications = [], page = CipherModel p }) (Cmd.map CipherMsg)
136 ( { notifications = []
138 ( { notifications = []
137− , page = LoadingPage
139+ , pageStack = Nonempty.singleton LoadingPage
139 , FFI.sendBridge Bridge.Init
141 , FFI.sendBridge Bridge.Init
@@ -142,15 +144,38 @@ init =
143view : Model -> Html Msg
145view : Model -> Html Msg
144view model =
146view model =
145− let
147+ Navigation.showNavigationView { popStack = PopView }
146− ( title, body ) =
148+ model.pageStack
147− showPage model.page
149+ (\page ->
149− div []
151+ ( title, body ) =
150− [ Navigation.navigation { back = False, title = title }
152+ showPage page
152− (maybeList (List.head model.notifications) (Notification.notification CloseNotification) ++ body)
155+ , maybeList (List.head model.notifications) (Notification.notification CloseNotification) ++ body
160+mapHead : (a -> a) -> Nonempty a -> Nonempty a
161+mapHead f (Nonempty x xx) =
165+doNotStoreInHistory : PageModel -> Bool
166+doNotStoreInHistory page =
171+ MasterPasswordModel _ ->
156update : Msg -> Model -> ( Model, Cmd Msg )
181update : Msg -> Model -> ( Model, Cmd Msg )
@@ -160,7 +185,7 @@ update msg model =
160 processPage liftModel ( resultModel, cmd ) =
185 processPage liftModel ( resultModel, cmd ) =
161 case resultModel of
186 case resultModel of
162 Ok mdl ->
187 Ok mdl ->
163− ( { model | page = liftModel mdl }, cmd )
188+ ( { model | pageStack = mapHead (always (liftModel mdl)) model.pageStack }, cmd )
165 Err err ->
190 Err err ->
166 ( appendNotification
191 ( appendNotification
@@ -171,6 +196,13 @@ update msg model =
200+ appendPageStack : PageModel -> Model
201+ appendPageStack mdl =
202+ { model | pageStack = model.pageStack |> Nonempty.toList |> List.filter (doNotStoreInHistory >> not) |> Nonempty mdl }
205+ model.pageStack |> Nonempty.head
175 case msg of
207 case msg of
176 RecieveMessage x ->
208 RecieveMessage x ->
@@ -204,7 +236,7 @@ update msg model =
206 LoginMsg imsg ->
238 LoginMsg imsg ->
207− case model.page of
239+ case currentPage of
208 LoginModel page ->
240 LoginModel page ->
209 (Login.page loginCallbacks LoginMsg).update imsg page |> processPage LoginModel
241 (Login.page loginCallbacks LoginMsg).update imsg page |> processPage LoginModel
@@ -212,7 +244,7 @@ update msg model =
212 ( model, Cmd.none )
244 ( model, Cmd.none )
214 CiphersMsg imsg ->
246 CiphersMsg imsg ->
215− case model.page of
247+ case currentPage of
216 CiphersModel page ->
248 CiphersModel page ->
217 (Ciphers.page ciphersCallbacks CiphersMsg).update imsg page |> processPage CiphersModel
249 (Ciphers.page ciphersCallbacks CiphersMsg).update imsg page |> processPage CiphersModel
@@ -221,30 +253,30 @@ update msg model =
222 ShowLoginPage ->
254 ShowLoginPage ->
223 (Login.page loginCallbacks LoginMsg).init ()
255 (Login.page loginCallbacks LoginMsg).init ()
224− |> Tuple.mapFirst (\pageModel -> { model | page = LoginModel pageModel })
256+ |> Tuple.mapFirst (\pageModel -> appendPageStack <| LoginModel pageModel)
226 LoadCiphers ciphers ->
258 LoadCiphers ciphers ->
227 (Ciphers.page ciphersCallbacks CiphersMsg).init ciphers
259 (Ciphers.page ciphersCallbacks CiphersMsg).init ciphers
228− |> Tuple.mapFirst (\pageModel -> { model | page = CiphersModel pageModel })
260+ |> Tuple.mapFirst (\pageModel -> appendPageStack <| CiphersModel pageModel)
230 OpenCiphersScreen ->
262 OpenCiphersScreen ->
231− ( { model | page = LoadingPage }, sendBridge Bridge.NeedCiphersList )
263+ ( appendPageStack <| LoadingPage, sendBridge Bridge.NeedCiphersList )
236 ShowMasterPasswordPage { server, login } ->
268 ShowMasterPasswordPage { server, login } ->
237 (MasterPassword.page masterPasswordCallbacks MasterPasswordMsg).init { server = server, login = login }
269 (MasterPassword.page masterPasswordCallbacks MasterPasswordMsg).init { server = server, login = login }
238− |> Tuple.mapFirst (\pageModel -> { model | page = MasterPasswordModel pageModel })
270+ |> Tuple.mapFirst (\pageModel -> appendPageStack <| MasterPasswordModel pageModel)
240 NeedsReset ->
272 NeedsReset ->
241− ( { model | page = LoadingPage }, sendBridge Bridge.NeedsReset )
273+ ( appendPageStack <| LoadingPage, sendBridge Bridge.NeedsReset )
243 SendMasterPassword { password } ->
275 SendMasterPassword { password } ->
244− ( { model | page = LoadingPage }, sendBridge (Bridge.SendMasterPassword password) )
276+ ( appendPageStack <| LoadingPage, sendBridge (Bridge.SendMasterPassword password) )
246 MasterPasswordMsg imsg ->
278 MasterPasswordMsg imsg ->
247− case model.page of
279+ case currentPage of
248 MasterPasswordModel page ->
280 MasterPasswordModel page ->
249 (MasterPassword.page masterPasswordCallbacks MasterPasswordMsg).update imsg page |> processPage MasterPasswordModel
281 (MasterPassword.page masterPasswordCallbacks MasterPasswordMsg).update imsg page |> processPage MasterPasswordModel
@@ -252,7 +284,7 @@ update msg model =
252 ( model, Cmd.none )
284 ( model, Cmd.none )
254 CipherMsg imsg ->
286 CipherMsg imsg ->
255− case model.page of
287+ case currentPage of
256 CipherModel page ->
288 CipherModel page ->
257 (Cipher.page cipherCallbacks CipherMsg).update imsg page |> processPage CipherModel
289 (Cipher.page cipherCallbacks CipherMsg).update imsg page |> processPage CipherModel
@@ -261,10 +293,15 @@ update msg model =
262 ShowCipherPage cipher ->
294 ShowCipherPage cipher ->
263 (Cipher.page cipherCallbacks CipherMsg).init cipher
295 (Cipher.page cipherCallbacks CipherMsg).init cipher
264− |> Tuple.mapFirst (\pageModel -> { model | page = CipherModel pageModel })
296+ |> Tuple.mapFirst (\pageModel -> appendPageStack <| CipherModel pageModel)
266 RequestCipher id ->
298 RequestCipher id ->
267− ( { model | page = LoadingPage }, sendBridge (Bridge.RequestCipher id) )
299+ ( appendPageStack <| LoadingPage, sendBridge (Bridge.RequestCipher id) )
302+ ( { model | pageStack = Navigation.popView model.pageStack }
270loginCallbacks : Login.Callbacks Msg
307loginCallbacks : Login.Callbacks Msg