mirror of
https://github.com/jhillyerd/inbucket.git
synced 2025-12-17 17:47:03 +00:00
ui: Refactor Mailbox model states
This commit is contained in:
@@ -24,22 +24,29 @@ type Body
|
|||||||
| SafeHtmlBody
|
| SafeHtmlBody
|
||||||
|
|
||||||
|
|
||||||
|
type State
|
||||||
|
= NoSelection
|
||||||
|
| Selected String
|
||||||
|
| Viewing Visible
|
||||||
|
|
||||||
|
|
||||||
|
type alias Visible =
|
||||||
|
{ message : Message
|
||||||
|
, markSeenAt : Maybe Time
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
type alias Model =
|
type alias Model =
|
||||||
{ name : String
|
{ name : String
|
||||||
, selected : Maybe String
|
, state : State
|
||||||
, headers : List MessageHeader
|
, headers : List MessageHeader
|
||||||
, visible :
|
|
||||||
Maybe
|
|
||||||
{ message : Message
|
|
||||||
, markSeenAt : Maybe Time
|
|
||||||
}
|
|
||||||
, bodyMode : Body
|
, bodyMode : Body
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
init : String -> Maybe String -> Model
|
init : String -> Maybe String -> Model
|
||||||
init name id =
|
init name id =
|
||||||
Model name id [] Nothing SafeHtmlBody
|
Model name NoSelection [] SafeHtmlBody
|
||||||
|
|
||||||
|
|
||||||
load : String -> Cmd Msg
|
load : String -> Cmd Msg
|
||||||
@@ -56,16 +63,14 @@ load name =
|
|||||||
|
|
||||||
subscriptions : Model -> Sub Msg
|
subscriptions : Model -> Sub Msg
|
||||||
subscriptions model =
|
subscriptions model =
|
||||||
case model.visible of
|
case model.state of
|
||||||
Just { message, markSeenAt } ->
|
Viewing { message } ->
|
||||||
case markSeenAt of
|
if message.seen then
|
||||||
Just time ->
|
Sub.none
|
||||||
Time.every (250 * Time.millisecond) Tick
|
else
|
||||||
|
Time.every (250 * Time.millisecond) Tick
|
||||||
|
|
||||||
Nothing ->
|
_ ->
|
||||||
Sub.none
|
|
||||||
|
|
||||||
Nothing ->
|
|
||||||
Sub.none
|
Sub.none
|
||||||
|
|
||||||
|
|
||||||
@@ -90,7 +95,7 @@ update : Session -> Msg -> Model -> ( Model, Cmd Msg, Session.Msg )
|
|||||||
update session msg model =
|
update session msg model =
|
||||||
case msg of
|
case msg of
|
||||||
ClickMessage id ->
|
ClickMessage id ->
|
||||||
( { model | selected = Just id }
|
( { model | state = Selected id }
|
||||||
, Cmd.batch
|
, Cmd.batch
|
||||||
[ Route.newUrl (Route.Message model.name id)
|
[ Route.newUrl (Route.Message model.name id)
|
||||||
, getMessage model.name id
|
, getMessage model.name id
|
||||||
@@ -99,7 +104,7 @@ update session msg model =
|
|||||||
)
|
)
|
||||||
|
|
||||||
ViewMessage id ->
|
ViewMessage id ->
|
||||||
( { model | selected = Just id }
|
( { model | state = Selected id }
|
||||||
, getMessage model.name id
|
, getMessage model.name id
|
||||||
, Session.AddRecent model.name
|
, Session.AddRecent model.name
|
||||||
)
|
)
|
||||||
@@ -118,14 +123,14 @@ update session msg model =
|
|||||||
newModel =
|
newModel =
|
||||||
{ model | headers = headers }
|
{ model | headers = headers }
|
||||||
in
|
in
|
||||||
case model.selected of
|
case model.state of
|
||||||
Nothing ->
|
Selected id ->
|
||||||
( newModel, Cmd.none, Session.AddRecent model.name )
|
|
||||||
|
|
||||||
Just id ->
|
|
||||||
-- Recurse to select message id.
|
-- Recurse to select message id.
|
||||||
update session (ViewMessage id) newModel
|
update session (ViewMessage id) newModel
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
( newModel, Cmd.none, Session.AddRecent model.name )
|
||||||
|
|
||||||
MailboxResult (Err err) ->
|
MailboxResult (Err err) ->
|
||||||
( model, Cmd.none, Session.SetFlash (HttpUtil.errorString err) )
|
( model, Cmd.none, Session.SetFlash (HttpUtil.errorString err) )
|
||||||
|
|
||||||
@@ -144,7 +149,7 @@ update session msg model =
|
|||||||
model.bodyMode
|
model.bodyMode
|
||||||
in
|
in
|
||||||
( { model
|
( { model
|
||||||
| visible = Just { message = msg, markSeenAt = Nothing }
|
| state = Viewing { message = msg, markSeenAt = Nothing }
|
||||||
, bodyMode = bodyMode
|
, bodyMode = bodyMode
|
||||||
}
|
}
|
||||||
, Task.perform OpenedTime Time.now
|
, Task.perform OpenedTime Time.now
|
||||||
@@ -158,15 +163,15 @@ update session msg model =
|
|||||||
( { model | bodyMode = bodyMode }, Cmd.none, Session.none )
|
( { model | bodyMode = bodyMode }, Cmd.none, Session.none )
|
||||||
|
|
||||||
OpenedTime time ->
|
OpenedTime time ->
|
||||||
case model.visible of
|
case model.state of
|
||||||
Just visible ->
|
Viewing 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 to report message as seen to backend.
|
||||||
( { model
|
( { model
|
||||||
| visible =
|
| state =
|
||||||
Just
|
Viewing
|
||||||
{ visible
|
{ visible
|
||||||
| markSeenAt = Just (time + (1.5 * Time.second))
|
| markSeenAt = Just (time + (1.5 * Time.second))
|
||||||
}
|
}
|
||||||
@@ -175,12 +180,12 @@ update session msg model =
|
|||||||
, Session.none
|
, Session.none
|
||||||
)
|
)
|
||||||
|
|
||||||
Nothing ->
|
_ ->
|
||||||
( model, Cmd.none, Session.none )
|
( model, Cmd.none, Session.none )
|
||||||
|
|
||||||
Tick now ->
|
Tick now ->
|
||||||
case model.visible of
|
case model.state of
|
||||||
Just { message, markSeenAt } ->
|
Viewing { message, markSeenAt } ->
|
||||||
case markSeenAt of
|
case markSeenAt of
|
||||||
Just deadline ->
|
Just deadline ->
|
||||||
if now >= deadline then
|
if now >= deadline then
|
||||||
@@ -191,7 +196,7 @@ update session msg model =
|
|||||||
Nothing ->
|
Nothing ->
|
||||||
( model, Cmd.none, Session.none )
|
( model, Cmd.none, Session.none )
|
||||||
|
|
||||||
Nothing ->
|
_ ->
|
||||||
( model, Cmd.none, Session.none )
|
( model, Cmd.none, Session.none )
|
||||||
|
|
||||||
|
|
||||||
@@ -216,8 +221,7 @@ deleteMessage model msg =
|
|||||||
|> Http.send DeleteMessageResult
|
|> Http.send DeleteMessageResult
|
||||||
in
|
in
|
||||||
( { model
|
( { model
|
||||||
| visible = Nothing
|
| state = NoSelection
|
||||||
, selected = Nothing
|
|
||||||
, headers = List.filter (\x -> x.id /= msg.id) model.headers
|
, headers = List.filter (\x -> x.id /= msg.id) model.headers
|
||||||
}
|
}
|
||||||
, cmd
|
, cmd
|
||||||
@@ -237,9 +241,12 @@ getMessage mailbox id =
|
|||||||
|
|
||||||
markMessageSeen : Model -> Message -> ( Model, Cmd Msg, Session.Msg )
|
markMessageSeen : Model -> Message -> ( Model, Cmd Msg, Session.Msg )
|
||||||
markMessageSeen model message =
|
markMessageSeen model message =
|
||||||
case model.visible of
|
case model.state of
|
||||||
Just visible ->
|
Viewing 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 }
|
||||||
@@ -258,14 +265,19 @@ markMessageSeen model message =
|
|||||||
|> Http.send MarkSeenResult
|
|> Http.send MarkSeenResult
|
||||||
in
|
in
|
||||||
( { model
|
( { model
|
||||||
| visible = Just { visible | markSeenAt = Nothing }
|
| state =
|
||||||
|
Viewing
|
||||||
|
{ visible
|
||||||
|
| message = { message | seen = True }
|
||||||
|
, markSeenAt = Nothing
|
||||||
|
}
|
||||||
, headers = List.map updateSeen model.headers
|
, headers = List.map updateSeen model.headers
|
||||||
}
|
}
|
||||||
, command
|
, command
|
||||||
, Session.None
|
, Session.None
|
||||||
)
|
)
|
||||||
|
|
||||||
Nothing ->
|
_ ->
|
||||||
( model, Cmd.none, Session.none )
|
( model, Cmd.none, Session.none )
|
||||||
|
|
||||||
|
|
||||||
@@ -279,22 +291,37 @@ view session model =
|
|||||||
[ aside [ id "message-list" ] [ messageList model ]
|
[ aside [ id "message-list" ] [ messageList model ]
|
||||||
, main_
|
, main_
|
||||||
[ id "message" ]
|
[ id "message" ]
|
||||||
[ case model.visible of
|
[ case model.state of
|
||||||
Just { message } ->
|
NoSelection ->
|
||||||
viewMessage message model.bodyMode
|
|
||||||
|
|
||||||
Nothing ->
|
|
||||||
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."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Viewing { message } ->
|
||||||
|
viewMessage message model.bodyMode
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
text ""
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
messageList : Model -> Html Msg
|
messageList : Model -> Html Msg
|
||||||
messageList model =
|
messageList model =
|
||||||
div [] (List.map (messageChip model.selected) (List.reverse model.headers))
|
let
|
||||||
|
selected =
|
||||||
|
case model.state of
|
||||||
|
Selected id ->
|
||||||
|
Just id
|
||||||
|
|
||||||
|
Viewing { message } ->
|
||||||
|
Just message.id
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
Nothing
|
||||||
|
in
|
||||||
|
div [] (List.map (messageChip selected) (List.reverse model.headers))
|
||||||
|
|
||||||
|
|
||||||
messageChip : Maybe String -> MessageHeader -> Html Msg
|
messageChip : Maybe String -> MessageHeader -> Html Msg
|
||||||
|
|||||||
Reference in New Issue
Block a user