diff options
Diffstat (limited to 'src/Main.elm')
| -rw-r--r-- | src/Main.elm | 136 |
1 files changed, 114 insertions, 22 deletions
diff --git a/src/Main.elm b/src/Main.elm index 54352d6..d359eaa 100644 --- a/src/Main.elm +++ b/src/Main.elm @@ -2,8 +2,15 @@ module Main exposing (..) import Browser exposing (Document) import Browser.Navigation exposing (Key) +import Config exposing (makeApiUrl) import Html.Styled exposing (..) -import Types exposing (DisplayableError(..), Model, Msg(..)) +import Http +import Json.Decode exposing (Decoder, field, int, list, map2, map5, string) +import Json.Encode +import Pages.Feed exposing (feedView) +import Task +import Time +import Types exposing (Author, DisplayableError(..), Model, Msg(..), Post) import Url exposing (Url) @@ -13,7 +20,7 @@ main = { init = init , view = view , update = update - , subscriptions = \_ -> Sub.none + , subscriptions = subscriptions , onUrlRequest = \_ -> NoOp , onUrlChange = \_ -> NoOp } @@ -25,18 +32,11 @@ main = init : () -> Url -> Key -> ( Model, Cmd Msg ) init _ _ _ = - ( { posts = - [ { id = "123" - , content = "foobar" - , author = - { id = "456" - , name = "George Technoman" - } - } - ] - , displayError = NoError + ( { posts = [] + , displayError = DNoError + , now = Time.millisToPosix 0 } - , Cmd.none + , Cmd.batch [ getPosts, Task.perform SetNowPosix Time.now ] ) @@ -50,11 +50,108 @@ update msg model = NoOp -> ( model, Cmd.none ) - FetchPostsSuccess posts -> + SetNowPosix now -> + ( { model | now = now }, Cmd.none ) + + GetPosts -> + ( model, getPosts ) + + GotPosts (Result.Ok posts) -> ( { model | posts = posts }, Cmd.none ) - FetchPostsFailure error -> - ( { model | displayError = error }, Cmd.none ) + GotPosts (Result.Err httpErr) -> + ( { model | displayError = DHttpError httpErr } + , Cmd.none + ) + + LikePost post -> + ( model, likePost post ) + + LikedPost (Result.Ok post) -> + ( { model | posts = replaceMatchingPost post model.posts } + , Cmd.none + ) + + LikedPost (Result.Err httpErr) -> + ( { model | displayError = DHttpError httpErr } + , Cmd.none + ) + + +replaceMatchingPost : Post -> List Post -> List Post +replaceMatchingPost post posts = + List.map + (\p -> + if p.id == post.id then + post + + else + p + ) + posts + + +getPosts : Cmd Msg +getPosts = + Http.get + { url = makeApiUrl Config.ApiPosts + , expect = Http.expectJson GotPosts postsDecoder + } + + +likePost : Post -> Cmd Msg +likePost post = + Http.request + { method = "PATCH" + , headers = [] + , url = makeApiUrl (Config.ApiLikePost post.id) + , body = + Http.jsonBody + (Json.Encode.object + [ ( "likes", Json.Encode.int (post.likes + 1) ) ] + ) + , expect = Http.expectJson LikedPost postDecoder + , timeout = Nothing + , tracker = Nothing + } + + +subscriptions : Model -> Sub Msg +subscriptions _ = + Time.every 5000 SetNowPosix + + + +-- JSON + + +decodeTime : Decoder Time.Posix +decodeTime = + int + |> Json.Decode.andThen + (\ms -> + Json.Decode.succeed <| Time.millisToPosix (ms * 1000) + ) + + +postsDecoder : Decoder (List Post) +postsDecoder = + list postDecoder + + +postDecoder : Decoder Post +postDecoder = + map5 Post + (field "id" string) + (field "content" string) + (field "author" + (map2 Author + (field "id" string) + (field "name" string) + ) + ) + (field "createdAt" decodeTime) + (field "likes" int) @@ -64,10 +161,5 @@ update msg model = view : Model -> Document Msg view model = { title = "Shoob book" - , body = [ body model ] |> List.map toUnstyled + , body = feedView model |> List.map toUnstyled } - - -body : Model -> Html Msg -body model = - main_ [] (List.map (\post -> div [] [ text post.id ]) model.posts) |
