1
0
mirror of https://github.com/jhillyerd/inbucket.git synced 2025-12-17 17:47:03 +00:00

ui: Friendly date format for mailbox list, monitor

This commit is contained in:
James Hillyerd
2018-11-06 20:47:15 -08:00
parent 9e2f138279
commit d05eb10851
5 changed files with 104 additions and 29 deletions

View File

@@ -29,7 +29,8 @@
"elm-lang/svg": "2.0.0 <= v < 3.0.0", "elm-lang/svg": "2.0.0 <= v < 3.0.0",
"elm-lang/websocket": "1.0.2 <= v < 2.0.0", "elm-lang/websocket": "1.0.2 <= v < 2.0.0",
"evancz/url-parser": "2.0.1 <= v < 3.0.0", "evancz/url-parser": "2.0.1 <= v < 3.0.0",
"jweir/sparkline": "3.0.0 <= v < 4.0.0" "jweir/sparkline": "3.0.0 <= v < 4.0.0",
"ryannhg/elm-date-format": "2.1.2 <= v < 3.0.0"
}, },
"elm-version": "0.18.0 <= v < 0.19.0" "elm-version": "0.18.0 <= v < 0.19.0"
} }

View File

@@ -1,5 +1,6 @@
module Data.MessageHeader exposing (..) module Data.MessageHeader exposing (..)
import Date exposing (Date)
import Json.Decode as Decode exposing (..) import Json.Decode as Decode exposing (..)
import Json.Decode.Pipeline exposing (..) import Json.Decode.Pipeline exposing (..)
@@ -10,7 +11,7 @@ type alias MessageHeader =
, from : String , from : String
, to : List String , to : List String
, subject : String , subject : String
, date : String , date : Date
, size : Int , size : Int
, seen : Bool , seen : Bool
} }
@@ -24,6 +25,21 @@ decoder =
|> optional "from" string "" |> optional "from" string ""
|> required "to" (list string) |> required "to" (list string)
|> optional "subject" string "" |> optional "subject" string ""
|> required "date" string |> required "date" date
|> required "size" int |> required "size" int
|> required "seen" bool |> required "seen" bool
date : Decoder Date
date =
let
convert : String -> Decoder Date
convert raw =
case Date.fromString raw of
Ok date ->
succeed date
Err error ->
fail error
in
string |> andThen convert

View File

@@ -188,16 +188,24 @@ setRoute route model =
) )
Route.Mailbox name -> Route.Mailbox name ->
( { model | page = Mailbox (Mailbox.init name Nothing) } let
, Cmd.map MailboxMsg (Mailbox.load name) ( subModel, subCmd ) =
, Session.none Mailbox.init name Nothing
) in
( { model | page = Mailbox subModel }
, Cmd.map MailboxMsg subCmd
, Session.none
)
Route.Message mailbox id -> Route.Message mailbox id ->
( { model | page = Mailbox (Mailbox.init mailbox (Just id)) } let
, Cmd.map MailboxMsg (Mailbox.load mailbox) ( subModel, subCmd ) =
, Session.none Mailbox.init mailbox (Just id)
) in
( { model | page = Mailbox subModel }
, Cmd.map MailboxMsg subCmd
, Session.none
)
Route.Monitor -> Route.Monitor ->
( { model | page = Monitor (Monitor.init model.session.host) } ( { model | page = Monitor (Monitor.init model.session.host) }

View File

@@ -3,6 +3,8 @@ module Page.Mailbox exposing (Model, Msg, init, load, subscriptions, update, vie
import Data.Message as Message exposing (Message) import Data.Message as Message exposing (Message)
import Data.MessageHeader as MessageHeader exposing (MessageHeader) import Data.MessageHeader as MessageHeader exposing (MessageHeader)
import Data.Session as Session exposing (Session) import Data.Session as Session exposing (Session)
import Date exposing (Date)
import DateFormat.Relative as Relative
import Json.Decode as Decode exposing (Decoder) import Json.Decode as Decode exposing (Decoder)
import Html exposing (..) import Html exposing (..)
import Html.Attributes import Html.Attributes
@@ -70,18 +72,22 @@ type alias Model =
, state : State , state : State
, bodyMode : Body , bodyMode : Body
, searchInput : String , searchInput : String
, now : Date
} }
init : String -> Maybe MessageID -> Model init : String -> Maybe MessageID -> ( Model, Cmd Msg )
init mailboxName selection = init mailboxName selection =
Model mailboxName (LoadingList selection) SafeHtmlBody "" ( Model mailboxName (LoadingList selection) SafeHtmlBody "" (Date.fromTime 0)
, load mailboxName
)
load : String -> Cmd Msg load : String -> Cmd Msg
load mailboxName = load mailboxName =
Cmd.batch Cmd.batch
[ Ports.windowTitle (mailboxName ++ " - Inbucket") [ Ports.windowTitle (mailboxName ++ " - Inbucket")
, Task.perform Tick Time.now
, getList mailboxName , getList mailboxName
] ]
@@ -92,15 +98,22 @@ load mailboxName =
subscriptions : Model -> Sub Msg subscriptions : Model -> Sub Msg
subscriptions model = subscriptions model =
case model.state of let
ShowingList _ (ShowingMessage { message }) -> subSeen =
if message.seen then case model.state of
Sub.none ShowingList _ (ShowingMessage { message }) ->
else if message.seen then
Time.every (250 * Time.millisecond) Tick Sub.none
else
Time.every (250 * Time.millisecond) SeenTick
_ -> _ ->
Sub.none Sub.none
in
Sub.batch
[ Time.every (30 * Time.second) Tick
, subSeen
]
@@ -119,6 +132,7 @@ type Msg
| Purge | Purge
| PurgeResult (Result Http.Error ()) | PurgeResult (Result Http.Error ())
| SearchInput String | SearchInput String
| SeenTick Time
| Tick Time | Tick Time
| ViewMessage MessageID | ViewMessage MessageID
@@ -224,7 +238,7 @@ update session msg model =
PurgeResult (Err err) -> PurgeResult (Err err) ->
( model, Cmd.none, Session.SetFlash (HttpUtil.errorString err) ) ( model, Cmd.none, Session.SetFlash (HttpUtil.errorString err) )
Tick now -> SeenTick now ->
case model.state of case model.state of
ShowingList _ (ShowingMessage { message, markSeenAt }) -> ShowingList _ (ShowingMessage { message, markSeenAt }) ->
case markSeenAt of case markSeenAt of
@@ -240,6 +254,9 @@ update session msg model =
_ -> _ ->
( model, Cmd.none, Session.none ) ( model, Cmd.none, Session.none )
Tick now ->
( { model | now = Date.fromTime now }, Cmd.none, Session.none )
{-| Replace the currently displayed message. {-| Replace the currently displayed message.
-} -}
@@ -481,13 +498,13 @@ viewMessageList session model =
(list (list
|> filterMessageList |> filterMessageList
|> List.reverse |> List.reverse
|> List.map (messageChip list.selected) |> List.map (messageChip model list.selected)
) )
] ]
messageChip : Maybe MessageID -> MessageHeader -> Html Msg messageChip : Model -> Maybe MessageID -> MessageHeader -> Html Msg
messageChip selected message = messageChip model selected message =
div div
[ classList [ classList
[ ( "message-list-entry", True ) [ ( "message-list-entry", True )
@@ -498,7 +515,7 @@ messageChip selected message =
] ]
[ div [ class "subject" ] [ text message.subject ] [ div [ class "subject" ] [ text message.subject ]
, div [ class "from" ] [ text message.from ] , div [ class "from" ] [ text message.from ]
, div [ class "date" ] [ text message.date ] , div [ class "date" ] [ relativeDate model message.date ]
] ]
@@ -593,6 +610,11 @@ attachmentRow baseUrl attach =
] ]
relativeDate : Model -> Date -> Html Msg
relativeDate model date =
Relative.relativeTime model.now date |> text
-- UTILITY -- UTILITY

View File

@@ -2,6 +2,16 @@ module Page.Monitor exposing (Model, Msg, init, subscriptions, update, view)
import Data.MessageHeader as MessageHeader exposing (MessageHeader) import Data.MessageHeader as MessageHeader exposing (MessageHeader)
import Data.Session as Session exposing (Session) import Data.Session as Session exposing (Session)
import Date exposing (Date)
import DateFormat
exposing
( format
, monthNameFirstThree
, dayOfMonthFixed
, hourNumber
, minuteFixed
, amPmUppercase
)
import Json.Decode exposing (decodeString) import Json.Decode exposing (decodeString)
import Html exposing (..) import Html exposing (..)
import Html.Attributes exposing (..) import Html.Attributes exposing (..)
@@ -32,8 +42,7 @@ init host =
subscriptions : Model -> Sub Msg subscriptions : Model -> Sub Msg
subscriptions model = subscriptions model =
WebSocket.listen model.wsUrl WebSocket.listen model.wsUrl (decodeString MessageHeader.decoder >> NewMessage)
(decodeString MessageHeader.decoder >> NewMessage)
@@ -85,8 +94,27 @@ view session model =
viewMessage : MessageHeader -> Html Msg viewMessage : MessageHeader -> Html Msg
viewMessage message = viewMessage message =
tr [ Events.onClick (OpenMessage message) ] tr [ Events.onClick (OpenMessage message) ]
[ td [] [ text message.date ] [ td [] [ text (timestamp message.date) ]
, td [ class "desktop" ] [ text message.from ] , td [ class "desktop" ] [ text message.from ]
, td [] [ text message.mailbox ] , td [] [ text message.mailbox ]
, td [] [ text message.subject ] , td [] [ text message.subject ]
] ]
-- UTILITY
timestamp : Date -> String
timestamp =
format
[ dayOfMonthFixed
, DateFormat.text "-"
, monthNameFirstThree
, DateFormat.text " "
, hourNumber
, DateFormat.text ":"
, minuteFixed
, DateFormat.text " "
, amPmUppercase
]