| -- Copyright 2021 The Fuchsia Authors. All rights reserved. |
| -- Use of this source code is governed by a BSD-style license that can be |
| -- found in the LICENSE file. |
| |
| |
| module News exposing |
| ( Model |
| , Msg |
| , decode |
| , encode |
| , init |
| , newSyntax2021Url |
| , update |
| , view |
| ) |
| |
| import Html exposing (Html) |
| import Html.Attributes as Attributes |
| import Html.Events as Events |
| import Json.Decode as Decode |
| import Json.Encode as Encode |
| |
| |
| {-| This module defines news items that display at the top of the page and can |
| be dismissed. Dismissal is remembered across sessions. |
| -} |
| |
| |
| |
| ------------- MODEL ------------------------------------------------------------ |
| |
| |
| type alias Model = |
| { show : List Item } |
| |
| |
| type Item |
| = NewSyntax2021 |
| |
| |
| allItems : List Item |
| allItems = |
| [ NewSyntax2021 ] |
| |
| |
| init : Model |
| init = |
| { show = allItems } |
| |
| |
| {-| Returns all items not in the given list. We can't use the Set library |
| because it doesn't support custom types (Item) nor does it support extracting |
| the smallest element. |
| -} |
| complement : List Item -> List Item |
| complement items = |
| List.filter (\x -> not (List.member x items)) allItems |
| |
| |
| |
| ------------- UPDATE ----------------------------------------------------------- |
| |
| |
| type Msg |
| = Dismiss |
| |
| |
| update : Msg -> Model -> Model |
| update _ model = |
| { show = |
| case model.show of |
| _ :: rest -> |
| rest |
| |
| [] -> |
| [] |
| } |
| |
| |
| |
| ------------- VIEW ------------------------------------------------------------- |
| |
| |
| {-| Creates the news view. The toMsg parameter converts a News.Msg to the |
| top-level Msg type of the app. |
| -} |
| view : (Msg -> msg) -> Model -> Html msg |
| view toMsg model = |
| let |
| dismissButton = |
| Html.button |
| [ Attributes.class "button dismiss-button" |
| , Events.onClick (toMsg Dismiss) |
| ] |
| [ Html.text "dismiss" ] |
| in |
| case model.show of |
| item :: _ -> |
| Html.div |
| [ Attributes.class "news" ] |
| (itemView item ++ [ dismissButton ]) |
| |
| [] -> |
| Html.text "" |
| |
| |
| itemView : Item -> List (Html msg) |
| itemView item = |
| case item of |
| NewSyntax2021 -> |
| [ Html.text "FIDL has a " |
| , Html.a |
| [ Attributes.href newSyntax2021Url ] |
| [ Html.text "new syntax" ] |
| , Html.text "!" |
| ] |
| |
| |
| newSyntax2021Url : String |
| newSyntax2021Url = |
| "https://groups.google.com/a/fuchsia.dev/g/announce/c/D_M8bl_7fEQ/m/I-qhW6iHBAAJ" |
| |
| |
| |
| ------------- ENCODE / DECODE -------------------------------------------------- |
| |
| |
| encode : Model -> Encode.Value |
| encode model = |
| Encode.object |
| [ ( "dismissed", Encode.list encodeItem (complement model.show) ) ] |
| |
| |
| decode : Decode.Decoder Model |
| decode = |
| Decode.field "dismissed" |
| (Decode.list decodeItem |
| |> Decode.map (List.filterMap identity) |
| |> Decode.map complement |
| |> Decode.map Model |
| ) |
| |
| |
| encodeItem : Item -> Encode.Value |
| encodeItem item = |
| case item of |
| NewSyntax2021 -> |
| Encode.string "newSyntax2021" |
| |
| |
| decodeItem : Decode.Decoder (Maybe Item) |
| decodeItem = |
| Decode.string |
| |> Decode.andThen |
| (\string -> |
| case string of |
| "newSyntax2021" -> |
| Decode.succeed (Just NewSyntax2021) |
| |
| -- Ignore unrecognized (old) news items. |
| _ -> |
| Decode.succeed Nothing |
| ) |