lue-bird / elm-state-interface / Web.Time

Helpers for elm/time primitives as part of an Interface.

posixRequest : Web.Interface Time.Posix

An Interface for getting the current POSIX time.

Replacement for elm/time's Time.now.

zoneRequest : Web.Interface Time.Zone

An Interface for getting a Time.Zone based on the current UTC offset.

Replacement for elm/time's Time.here.

zoneNameRequest : Web.Interface String

Intended for package authors. An Interface for using Intl.DateTimeFormat().resolvedOptions().timeZone to get names like Europe/Moscow or America/Havana. From there you can look it up in any IANA data you loaded yourself.

Replacement for elm/time's Time.getZoneName.

periodicallyListen : Duration -> Web.Interface Time.Posix

An Interface for getting the current time every time a given Duration has passed.

Note: Do not use it for animations. Web.Window.animationFrameListen syncs up with repaints and will end up being much smoother for any moving visuals.

onceAt : Time.Posix -> Web.Interface Time.Posix

An Interface for getting a reminder once a given point in time has been reached.

This lets you for example wait until it's 15 minutes before the event, timeout a request or schedule a certain action to a specific time.

import Web

type RequestState result
    = NotAsked
    | BeforeTimeout { start : Time.Posix }
    | TimedOut
    | GotResult result

{ initialState = NotAsked
, interface =
    \state ->
        [ case state of
            NotAsked ->
                [ Web.Time.posixRequest
                    |> Web.interfaceFutureMap BeforeTimeout
                , ..request.. |> Web.futureMap GotResult
                ]

            BeforeTimeout requestTime ->
                -- timeout after 10 seconds
                Web.Time.onceAt (Duration.addTo requestTime (Duration.seconds 10))
                    |> Web.interfaceFutureMap (\_ -> TimedOut)

            TimedOut ->
                ...

            GotResult result ->
                ...
        ]
}

You can abstract this in various ways like adding a

withTimeout :
    ..Request result..
    -> Web.Interface (RequestState result)

where the result can be put into the "main state" and therefore cased on.