mirror of
https://github.com/jhillyerd/inbucket.git
synced 2025-12-17 17:47:03 +00:00
ui: Refactor Mailbox states to reduce cases.
This commit is contained in:
@@ -38,10 +38,14 @@ type Body
|
|||||||
|
|
||||||
type State
|
type State
|
||||||
= LoadingList (Maybe MessageID)
|
= LoadingList (Maybe MessageID)
|
||||||
| ShowingList MessageList (Maybe MessageID)
|
| ShowingList MessageList MessageState
|
||||||
| LoadingMessage MessageList MessageID
|
|
||||||
| ShowingMessage MessageList VisibleMessage
|
|
||||||
| Transitioning MessageList VisibleMessage MessageID
|
type MessageState
|
||||||
|
= NoMessage
|
||||||
|
| LoadingMessage MessageID
|
||||||
|
| ShowingMessage VisibleMessage
|
||||||
|
| Transitioning VisibleMessage MessageID
|
||||||
|
|
||||||
|
|
||||||
type alias MessageID =
|
type alias MessageID =
|
||||||
@@ -88,7 +92,7 @@ load mailboxName =
|
|||||||
subscriptions : Model -> Sub Msg
|
subscriptions : Model -> Sub Msg
|
||||||
subscriptions model =
|
subscriptions model =
|
||||||
case model.state of
|
case model.state of
|
||||||
ShowingMessage _ { message } ->
|
ShowingList _ (ShowingMessage { message }) ->
|
||||||
if message.seen then
|
if message.seen then
|
||||||
Sub.none
|
Sub.none
|
||||||
else
|
else
|
||||||
@@ -122,7 +126,7 @@ update session msg model =
|
|||||||
ClickMessage id ->
|
ClickMessage id ->
|
||||||
( updateSelected model id
|
( updateSelected model id
|
||||||
, Cmd.batch
|
, Cmd.batch
|
||||||
[ -- Update browser location
|
[ -- Update browser location.
|
||||||
Route.newUrl (Route.Message model.mailboxName id)
|
Route.newUrl (Route.Message model.mailboxName id)
|
||||||
, getMessage model.mailboxName id
|
, getMessage model.mailboxName id
|
||||||
]
|
]
|
||||||
@@ -149,7 +153,7 @@ update session msg model =
|
|||||||
LoadingList selection ->
|
LoadingList selection ->
|
||||||
let
|
let
|
||||||
newModel =
|
newModel =
|
||||||
{ model | state = ShowingList (MessageList headers "") selection }
|
{ model | state = ShowingList (MessageList headers "") NoMessage }
|
||||||
in
|
in
|
||||||
case selection of
|
case selection of
|
||||||
Just id ->
|
Just id ->
|
||||||
@@ -181,21 +185,23 @@ update session msg model =
|
|||||||
( { model | bodyMode = bodyMode }, Cmd.none, Session.none )
|
( { model | bodyMode = bodyMode }, Cmd.none, Session.none )
|
||||||
|
|
||||||
SearchInput searchInput ->
|
SearchInput searchInput ->
|
||||||
updateSearch model searchInput
|
updateSearchInput model searchInput
|
||||||
|
|
||||||
OpenedTime time ->
|
OpenedTime time ->
|
||||||
case model.state of
|
case model.state of
|
||||||
ShowingMessage list visible ->
|
ShowingList list (ShowingMessage visible) ->
|
||||||
if visible.message.seen then
|
if visible.message.seen then
|
||||||
( model, Cmd.none, Session.none )
|
( model, Cmd.none, Session.none )
|
||||||
else
|
else
|
||||||
-- Set delay to report message as seen to backend.
|
-- Set delay before reporting message as seen to backend.
|
||||||
( { model
|
( { model
|
||||||
| state =
|
| state =
|
||||||
ShowingMessage list
|
ShowingList list
|
||||||
|
(ShowingMessage
|
||||||
{ visible
|
{ visible
|
||||||
| markSeenAt = Just (time + (1.5 * Time.second))
|
| markSeenAt = Just (time + (1.5 * Time.second))
|
||||||
}
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
, Cmd.none
|
, Cmd.none
|
||||||
, Session.none
|
, Session.none
|
||||||
@@ -206,7 +212,7 @@ update session msg model =
|
|||||||
|
|
||||||
Tick now ->
|
Tick now ->
|
||||||
case model.state of
|
case model.state of
|
||||||
ShowingMessage _ { message, markSeenAt } ->
|
ShowingList _ (ShowingMessage { message, markSeenAt }) ->
|
||||||
case markSeenAt of
|
case markSeenAt of
|
||||||
Just deadline ->
|
Just deadline ->
|
||||||
if now >= deadline then
|
if now >= deadline then
|
||||||
@@ -221,6 +227,8 @@ update session msg model =
|
|||||||
( model, Cmd.none, Session.none )
|
( model, Cmd.none, Session.none )
|
||||||
|
|
||||||
|
|
||||||
|
{-| Replace the currently displayed message.
|
||||||
|
-}
|
||||||
updateMessageResult : Model -> Message -> ( Model, Cmd Msg, Session.Msg )
|
updateMessageResult : Model -> Message -> ( Model, Cmd Msg, Session.Msg )
|
||||||
updateMessageResult model message =
|
updateMessageResult model message =
|
||||||
let
|
let
|
||||||
@@ -229,80 +237,58 @@ updateMessageResult model message =
|
|||||||
TextBody
|
TextBody
|
||||||
else
|
else
|
||||||
model.bodyMode
|
model.bodyMode
|
||||||
|
in
|
||||||
|
case model.state of
|
||||||
|
LoadingList _ ->
|
||||||
|
( model, Cmd.none, Session.none )
|
||||||
|
|
||||||
updateMessage list message =
|
ShowingList list _ ->
|
||||||
( { model
|
( { model
|
||||||
| state = ShowingMessage list { message = message, markSeenAt = Nothing }
|
| state = ShowingList list (ShowingMessage (VisibleMessage message Nothing))
|
||||||
, bodyMode = bodyMode
|
, bodyMode = bodyMode
|
||||||
}
|
}
|
||||||
, Task.perform OpenedTime Time.now
|
, Task.perform OpenedTime Time.now
|
||||||
, Session.none
|
, Session.none
|
||||||
)
|
)
|
||||||
in
|
|
||||||
case model.state of
|
|
||||||
LoadingList _ ->
|
|
||||||
( model, Cmd.none, Session.none )
|
|
||||||
|
|
||||||
ShowingList list _ ->
|
|
||||||
updateMessage list message
|
|
||||||
|
|
||||||
LoadingMessage list _ ->
|
|
||||||
updateMessage list message
|
|
||||||
|
|
||||||
ShowingMessage list _ ->
|
|
||||||
updateMessage list message
|
|
||||||
|
|
||||||
Transitioning list _ _ ->
|
|
||||||
updateMessage list message
|
|
||||||
|
|
||||||
|
|
||||||
updateSearch : Model -> String -> ( Model, Cmd Msg, Session.Msg )
|
updateSearchInput : Model -> String -> ( Model, Cmd Msg, Session.Msg )
|
||||||
updateSearch model searchInput =
|
updateSearchInput model searchInput =
|
||||||
let
|
let
|
||||||
updateList list =
|
searchFilter =
|
||||||
{ list
|
|
||||||
| searchFilter =
|
|
||||||
if String.length searchInput > 1 then
|
if String.length searchInput > 1 then
|
||||||
String.toLower searchInput
|
String.toLower searchInput
|
||||||
else
|
else
|
||||||
""
|
""
|
||||||
}
|
|
||||||
|
|
||||||
updateModel state =
|
|
||||||
( { model | searchInput = searchInput, state = state }
|
|
||||||
, Cmd.none
|
|
||||||
, Session.none
|
|
||||||
)
|
|
||||||
in
|
in
|
||||||
case model.state of
|
case model.state of
|
||||||
LoadingList _ ->
|
LoadingList _ ->
|
||||||
( model, Cmd.none, Session.none )
|
( model, Cmd.none, Session.none )
|
||||||
|
|
||||||
ShowingList list selection ->
|
ShowingList list messageState ->
|
||||||
updateModel (ShowingList (updateList list) selection)
|
( { model
|
||||||
|
| searchInput = searchInput
|
||||||
LoadingMessage list id ->
|
, state = ShowingList { list | searchFilter = searchFilter } messageState
|
||||||
updateModel (LoadingMessage (updateList list) id)
|
}
|
||||||
|
, Cmd.none
|
||||||
ShowingMessage list visible ->
|
, Session.none
|
||||||
updateModel (ShowingMessage (updateList list) visible)
|
)
|
||||||
|
|
||||||
Transitioning list visible id ->
|
|
||||||
updateModel (Transitioning (updateList list) visible id)
|
|
||||||
|
|
||||||
|
|
||||||
|
{-| Set the selected message in our model.
|
||||||
|
-}
|
||||||
updateSelected : Model -> MessageID -> Model
|
updateSelected : Model -> MessageID -> Model
|
||||||
updateSelected model id =
|
updateSelected model id =
|
||||||
case model.state of
|
case model.state of
|
||||||
ShowingList list _ ->
|
ShowingList list NoMessage ->
|
||||||
{ model | state = LoadingMessage list id }
|
{ model | state = ShowingList list (LoadingMessage id) }
|
||||||
|
|
||||||
ShowingMessage list visible ->
|
ShowingList list (ShowingMessage visible) ->
|
||||||
-- Use Transitioning state to prevent message flicker.
|
-- Use Transitioning state to prevent blank message flicker.
|
||||||
{ model | state = Transitioning list visible id }
|
{ model | state = ShowingList list (Transitioning visible id) }
|
||||||
|
|
||||||
Transitioning list visible _ ->
|
ShowingList list (Transitioning visible _) ->
|
||||||
{ model | state = Transitioning list visible id }
|
{ model | state = ShowingList list (Transitioning visible id) }
|
||||||
|
|
||||||
_ ->
|
_ ->
|
||||||
model
|
model
|
||||||
@@ -322,9 +308,10 @@ updateDeleteMessage model message =
|
|||||||
{ messageList | headers = List.filter f messageList.headers }
|
{ messageList | headers = List.filter f messageList.headers }
|
||||||
in
|
in
|
||||||
case model.state of
|
case model.state of
|
||||||
ShowingMessage list _ ->
|
ShowingList list _ ->
|
||||||
( { model
|
( { model
|
||||||
| state = ShowingList (filter (\x -> x.id /= message.id) list) Nothing
|
| state =
|
||||||
|
ShowingList (filter (\x -> x.id /= message.id) list) NoMessage
|
||||||
}
|
}
|
||||||
, cmd
|
, cmd
|
||||||
, Session.none
|
, Session.none
|
||||||
@@ -337,11 +324,8 @@ updateDeleteMessage model message =
|
|||||||
updateMarkMessageSeen : Model -> Message -> ( Model, Cmd Msg, Session.Msg )
|
updateMarkMessageSeen : Model -> Message -> ( Model, Cmd Msg, Session.Msg )
|
||||||
updateMarkMessageSeen model message =
|
updateMarkMessageSeen model message =
|
||||||
case model.state of
|
case model.state of
|
||||||
ShowingMessage list visible ->
|
ShowingList list (ShowingMessage visible) ->
|
||||||
let
|
let
|
||||||
message =
|
|
||||||
visible.message
|
|
||||||
|
|
||||||
updateSeen header =
|
updateSeen header =
|
||||||
if header.id == message.id then
|
if header.id == message.id then
|
||||||
{ header | seen = True }
|
{ header | seen = True }
|
||||||
@@ -364,11 +348,13 @@ updateMarkMessageSeen model message =
|
|||||||
in
|
in
|
||||||
( { model
|
( { model
|
||||||
| state =
|
| state =
|
||||||
ShowingMessage (map updateSeen list)
|
ShowingList (map updateSeen list)
|
||||||
|
(ShowingMessage
|
||||||
{ visible
|
{ visible
|
||||||
| message = { message | seen = True }
|
| message = { message | seen = True }
|
||||||
, markSeenAt = Nothing
|
, markSeenAt = Nothing
|
||||||
}
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
, command
|
, command
|
||||||
, Session.None
|
, Session.None
|
||||||
@@ -407,36 +393,43 @@ view session model =
|
|||||||
div [ id "page", class "mailbox" ]
|
div [ id "page", class "mailbox" ]
|
||||||
[ aside [ id "message-list" ]
|
[ aside [ id "message-list" ]
|
||||||
[ div []
|
[ div []
|
||||||
[ input [ type_ "search", placeholder "search", onInput SearchInput, value model.searchInput ] [] ]
|
[ input
|
||||||
|
[ type_ "search"
|
||||||
|
, placeholder "search"
|
||||||
|
, onInput SearchInput
|
||||||
|
, value model.searchInput
|
||||||
|
]
|
||||||
|
[]
|
||||||
|
]
|
||||||
, case model.state of
|
, case model.state of
|
||||||
LoadingList _ ->
|
LoadingList _ ->
|
||||||
div [] []
|
div [] []
|
||||||
|
|
||||||
ShowingList list selection ->
|
ShowingList list NoMessage ->
|
||||||
messageList list selection
|
messageList list Nothing
|
||||||
|
|
||||||
LoadingMessage list selection ->
|
ShowingList list (LoadingMessage id) ->
|
||||||
messageList list (Just selection)
|
messageList list (Just id)
|
||||||
|
|
||||||
ShowingMessage list visible ->
|
ShowingList list (ShowingMessage visible) ->
|
||||||
messageList list (Just visible.message.id)
|
messageList list (Just visible.message.id)
|
||||||
|
|
||||||
Transitioning list _ selection ->
|
ShowingList list (Transitioning _ id) ->
|
||||||
messageList list (Just selection)
|
messageList list (Just id)
|
||||||
]
|
]
|
||||||
, main_
|
, main_
|
||||||
[ id "message" ]
|
[ id "message" ]
|
||||||
[ case model.state of
|
[ case model.state of
|
||||||
ShowingList _ _ ->
|
ShowingList _ NoMessage ->
|
||||||
text
|
text
|
||||||
("Select a message on the left,"
|
("Select a message on the left,"
|
||||||
++ " or enter a different username into the box on upper right."
|
++ " or enter a different username into the box on upper right."
|
||||||
)
|
)
|
||||||
|
|
||||||
ShowingMessage _ { message } ->
|
ShowingList _ (ShowingMessage { message }) ->
|
||||||
viewMessage message model.bodyMode
|
viewMessage message model.bodyMode
|
||||||
|
|
||||||
Transitioning _ { message } _ ->
|
ShowingList _ (Transitioning { message } _) ->
|
||||||
viewMessage message model.bodyMode
|
viewMessage message model.bodyMode
|
||||||
|
|
||||||
_ ->
|
_ ->
|
||||||
|
|||||||
Reference in New Issue
Block a user