pijul nest
guest [sign in]

Fork channel

Create a new channel as a copy of main.

Rename channel

Rename main to:

Delete channel

Delete main? This cannot be undone.

Util.hs
module Frontend.Util where

import Prelude

import Data.Argonaut.Core (Json)
import Data.Argonaut.Decode (JsonDecodeError, decodeJson, (.:))
import Data.Array (filter, length, zip, (..))
import Data.DateTime (DateTime, Time(..), adjust, diff, modifyTime, setMillisecond, setMinute, setSecond)
import Data.DateTime.Instant (fromDateTime, instant, toDateTime, unInstant)
import Data.Either (Either, either, note)
import Data.Formatter.DateTime (formatDateTime)
import Data.Int (floor, toNumber)
import Data.Maybe (Maybe, fromMaybe)
import Data.Newtype (unwrap)
import Data.Time.Duration (Days(..), Hours(..), Milliseconds(..), Seconds(..))
import Data.Traversable (sequence, traverse)
import Data.Tuple (Tuple)
import Effect.Aff (Aff, error, makeAff)
import Graphics.Canvas (CanvasImageSource, tryLoadImage)
import Halogen.HTML as HH
import Halogen.HTML.Properties as HP


classes :: forall r i. Array String -> HH.IProp (class :: String | r) i
classes = HP.classes <<< map HH.ClassName

formatDateTime' :: DateTime -> String
formatDateTime' = either identity identity <<< formatDateTime "YYYY-MM-DD HH:mm:ss.SS"

datetimeToSeconds :: DateTime -> Number
datetimeToSeconds = (_ / 1000.0) <<< unwrap <<< unInstant <<< fromDateTime

secondsToDateTime :: Number -> Maybe DateTime
secondsToDateTime = map toDateTime <<< instant <<< Milliseconds <<< (_ * 1000.0)

-- TODO: convert stuff to local time
-- getTimezoneOffset $ fromDateTime start

midnightBefore :: DateTime -> DateTime
midnightBefore = modifyTime (const $ Time bottom bottom bottom bottom)

hourBefore :: DateTime -> DateTime
hourBefore = modifyTime (setMinute bottom <<< setSecond bottom <<< setMillisecond bottom)

daysInInterval :: DateTime -> DateTime -> Array DateTime
daysInInterval start end = do
  let
    midnight = midnightBefore start
    duration = diff end midnight :: Days
    nDays = floor (unwrap duration)
  fromMaybe [] <<< sequence $
    0 .. nDays <#> \n ->
    adjust (Days (toNumber n)) midnight

hoursInInterval :: DateTime -> DateTime -> DateTime -> Array DateTime
hoursInInterval current start end = do
  let
    midnight = midnightBefore current
    hours = 0 .. 23 <#> Hours <<< toNumber
    hoursDT = fromMaybe [] <<< sequence $ hours <#> \n -> adjust n midnight
  filter (\a -> (unwrap (a `diff` start :: Hours) >= -1.0) && a <= end) hoursDT

decodeTimestamps :: Json -> Either JsonDecodeError (Array Number)
decodeTimestamps json = do
  o <- decodeJson json
  contents <- o .: "Ok"
  decodeJson contents >>= traverse decodeJson

formatDuration :: Seconds -> String
formatDuration (Seconds t) = let
  h = floor $ t / 3600.0
  m = floor (t / 60.0) - h * 60
  s = floor t - h * 3600 - m * 60
  in show h <> "h " <> show m <> "m " <> show s <> "s"


loadImage :: String -> Aff CanvasImageSource
loadImage url = do
  makeAff \cont -> do
    tryLoadImage url \msource ->
      note (error $ "Failed to load image from \"" <> url <> "\"") msource # cont
    mempty

enumerate :: forall a. Array a -> Array (Tuple Int a)
enumerate a = zip (0 .. (length a - 1)) a