summaryrefslogtreecommitdiff
path: root/Main.elm
diff options
context:
space:
mode:
Diffstat (limited to 'Main.elm')
-rw-r--r--Main.elm98
1 files changed, 98 insertions, 0 deletions
diff --git a/Main.elm b/Main.elm
new file mode 100644
index 0000000..961c13a
--- /dev/null
+++ b/Main.elm
@@ -0,0 +1,98 @@
+import Html exposing (..)
+import Html.Attributes exposing (..)
+import Http
+import Task
+import Date
+import Time exposing (..)
+import Json.Decode as Decode
+
+main = Html.program
+ { init = (
+ { lastFetch = 0
+ , state = Fetching
+ , feed = []
+ }, fetch)
+ , view = view
+ , update = update
+ , subscriptions = \_ -> Time.every minute Tick
+ }
+
+
+type alias Article =
+ { title : String
+ , feed : String
+ , ts : Time
+ , url : String
+ }
+
+decodeArticle : Decode.Decoder Article
+decodeArticle = Decode.map4 Article
+ (Decode.field "title" Decode.string)
+ (Decode.field "feed" Decode.string)
+ (Decode.field "ts" Decode.float)
+ (Decode.field "url" Decode.string)
+
+
+type State
+ = Start
+ | Current
+ | Fetching
+ | FetchError
+
+type alias Model =
+ { lastFetch : Time
+ , state : State
+ , feed : List Article
+ }
+
+type Msg
+ = Tick Time
+ | Data (Result Http.Error (List Article))
+ | SetTime Time
+
+
+fetch : Cmd Msg
+fetch = Http.send Data (Http.get "feeds.json" (Decode.list decodeArticle))
+
+
+update : Msg -> Model -> (Model, Cmd Msg)
+update msg model = case msg of
+ Tick _ -> ({ model | state = Fetching }, fetch)
+ Data (Err _) -> ({ model | state = FetchError }, Cmd.none)
+ SetTime t -> ({ model | lastFetch = t }, Cmd.none)
+ Data (Ok r) ->
+ ( { model | state = Current, feed = r }
+ , Task.perform SetTime now
+ )
+
+
+-- Surely there must be an easier way to do this
+fmtts : Time -> String
+fmtts t = let d = Date.fromTime t in
+ toString (Date.day d)
+ ++ " "
+ ++ toString (Date.month d)
+ ++ " "
+ ++ toString (Date.year d)
+ ++ " "
+ ++ String.padLeft 2 '0' (toString (Date.hour d))
+ ++ ":"
+ ++ String.padLeft 2 '0' (toString (Date.minute d))
+
+
+view : Model -> Html Msg
+view model =
+ let
+ state = em [ class (toString model.state) ]
+ [ if model.lastFetch == 0
+ then text "Loading feeds..."
+ else text (fmtts model.lastFetch) ]
+ item n = article []
+ [ a [href n.url] [ text n.title ]
+ , i []
+ [ text (fmtts (n.ts*1000))
+ , text " - "
+ , text n.feed
+ ]
+ ]
+ in div [] (state :: List.map item model.feed)