diff --git a/src/Api.elm b/src/Api.elm index adce6e82be..dae5a0da17 100644 --- a/src/Api.elm +++ b/src/Api.elm @@ -37,18 +37,13 @@ This token should never be rendered to the end user, and with this API, it can't be! -} -type Cred - = Cred Username String +type Cred = Cred Username String -username : Cred -> Username -username (Cred val _) = - val +username (Cred val _) = val -credHeader : Cred -> Http.Header -credHeader (Cred _ str) = - Http.header "authorization" ("Token " ++ str) +credHeader (Cred _ str) = Http.header "authorization" ("Token " ++ str) {-| It's important that this is never exposed! @@ -58,7 +53,6 @@ ever has access to a `Cred` value, it came from either the login API endpoint or was passed in via flags. -} -credDecoder : Decoder Cred credDecoder = Decode.succeed Cred |> required "username" Username.decoder @@ -69,7 +63,6 @@ credDecoder = -- PERSISTENCE -decode : Decoder (Cred -> viewer) -> Value -> Result Decode.Error viewer decode decoder value = -- It's stored in localStorage as a JSON String; -- first decode the Value as a String, then @@ -81,12 +74,9 @@ decode decoder value = port onStoreChange : (Value -> msg) -> Sub msg -viewerChanges : (Maybe viewer -> msg) -> Decoder (Cred -> viewer) -> Sub msg -viewerChanges toMsg decoder = - onStoreChange (\value -> toMsg (decodeFromChange decoder value)) +viewerChanges toMsg decoder = onStoreChange (\value -> toMsg (decodeFromChange decoder value)) -decodeFromChange : Decoder (Cred -> viewer) -> Value -> Maybe viewer decodeFromChange viewerDecoder val = -- It's stored in localStorage as a JSON String; -- first decode the Value as a String, then @@ -95,7 +85,6 @@ decodeFromChange viewerDecoder val = |> Result.toMaybe -storeCredWith : Cred -> Avatar -> Cmd msg storeCredWith (Cred uname token) avatar = let json = @@ -112,7 +101,6 @@ storeCredWith (Cred uname token) avatar = storeCache (Just json) -logout : Cmd msg logout = storeCache Nothing @@ -157,16 +145,13 @@ application viewerDecoder config = } -storageDecoder : Decoder (Cred -> viewer) -> Decoder viewer -storageDecoder viewerDecoder = - Decode.field "user" (decoderFromCred viewerDecoder) +storageDecoder viewerDecoder = Decode.field "user" (decoderFromCred viewerDecoder) -- HTTP -get : Endpoint -> Maybe Cred -> Decoder a -> Http.Request a get url maybeCred decoder = Endpoint.request { method = "GET" @@ -174,18 +159,15 @@ get url maybeCred decoder = , expect = Http.expectJson decoder , headers = case maybeCred of - Just cred -> - [ credHeader cred ] + Just cred -> [ credHeader cred ] - Nothing -> - [] + Nothing -> [] , body = Http.emptyBody , timeout = Nothing , withCredentials = False } -put : Endpoint -> Cred -> Body -> Decoder a -> Http.Request a put url cred body decoder = Endpoint.request { method = "PUT" @@ -198,7 +180,6 @@ put url cred body decoder = } -post : Endpoint -> Maybe Cred -> Body -> Decoder a -> Http.Request a post url maybeCred body decoder = Endpoint.request { method = "POST" @@ -206,18 +187,15 @@ post url maybeCred body decoder = , expect = Http.expectJson decoder , headers = case maybeCred of - Just cred -> - [ credHeader cred ] + Just cred -> [ credHeader cred ] - Nothing -> - [] + Nothing -> [] , body = body , timeout = Nothing , withCredentials = False } -delete : Endpoint -> Cred -> Body -> Decoder a -> Http.Request a delete url cred body decoder = Endpoint.request { method = "DELETE" @@ -230,40 +208,27 @@ delete url cred body decoder = } -login : Http.Body -> Decoder (Cred -> a) -> Http.Request a -login body decoder = - post Endpoint.login Nothing body (Decode.field "user" (decoderFromCred decoder)) +login body decoder = post Endpoint.login Nothing body (Decode.field "user" (decoderFromCred decoder)) -register : Http.Body -> Decoder (Cred -> a) -> Http.Request a -register body decoder = - post Endpoint.users Nothing body (Decode.field "user" (decoderFromCred decoder)) +register body decoder = post Endpoint.users Nothing body (Decode.field "user" (decoderFromCred decoder)) -settings : Cred -> Http.Body -> Decoder (Cred -> a) -> Http.Request a -settings cred body decoder = - put Endpoint.user cred body (Decode.field "user" (decoderFromCred decoder)) +settings cred body decoder = put Endpoint.user cred body (Decode.field "user" (decoderFromCred decoder)) -decoderFromCred : Decoder (Cred -> a) -> Decoder a -decoderFromCred decoder = - Decode.map2 (\fromCred cred -> fromCred cred) - decoder - credDecoder +decoderFromCred decoder = Decode.map2 (\fromCred cred -> fromCred cred) decoder credDecoder -- ERRORS -addServerError : List String -> List String -addServerError list = - "Server error" :: list +addServerError list = "Server error" :: list {-| Many API endpoints include an "errors" field in their BadStatus responses. -} -decodeErrors : Http.Error -> List String decodeErrors error = case error of Http.BadStatus response -> @@ -271,30 +236,22 @@ decodeErrors error = |> decodeString (field "errors" errorsDecoder) |> Result.withDefault [ "Server error" ] - err -> - [ "Server error" ] + err -> [ "Server error" ] -errorsDecoder : Decoder (List String) errorsDecoder = Decode.keyValuePairs (Decode.list Decode.string) |> Decode.map (List.concatMap fromPair) -fromPair : ( String, List String ) -> List String -fromPair ( field, errors ) = - List.map (\error -> field ++ " " ++ error) errors +fromPair ( field, errors ) = List.map (\error -> field ++ " " ++ error) errors -- LOCALSTORAGE KEYS -cacheStorageKey : String -cacheStorageKey = - "cache" +cacheStorageKey = "cache" -credStorageKey : String -credStorageKey = - "cred" +credStorageKey = "cred" diff --git a/src/Api/Endpoint.elm b/src/Api/Endpoint.elm index 7812fdb2d9..94adee543e 100644 --- a/src/Api/Endpoint.elm +++ b/src/Api/Endpoint.elm @@ -9,16 +9,6 @@ import Username exposing (Username) {-| Http.request, except it takes an Endpoint instead of a Url. -} -request : - { body : Http.Body - , expect : Http.Expect a - , headers : List Http.Header - , method : String - , timeout : Maybe Float - , url : Endpoint - , withCredentials : Bool - } - -> Http.Request a request config = Http.request { body = config.body @@ -44,12 +34,10 @@ type Endpoint = Endpoint String -unwrap : Endpoint -> String unwrap (Endpoint str) = str -url : List String -> List QueryParameter -> Endpoint url paths queryParams = -- NOTE: Url.Builder takes care of percent-encoding special URL characters. -- See https://package.elm-lang.org/packages/elm/url/latest/Url#percentEncode @@ -63,22 +51,18 @@ url paths queryParams = -- ENDPOINTS -login : Endpoint login = url [ "users", "login" ] [] -user : Endpoint user = url [ "user" ] [] -users : Endpoint users = url [ "users" ] [] -follow : Username -> Endpoint follow uname = url [ "profiles", Username.toString uname, "follow" ] [] @@ -87,41 +71,33 @@ follow uname = -- ARTICLE ENDPOINTS -article : Slug -> Endpoint article slug = url [ "articles", Slug.toString slug ] [] -comments : Slug -> Endpoint comments slug = url [ "articles", Slug.toString slug, "comments" ] [] -comment : Slug -> CommentId -> Endpoint comment slug commentId = url [ "articles", Slug.toString slug, "comments", CommentId.toString commentId ] [] -favorite : Slug -> Endpoint favorite slug = url [ "articles", Slug.toString slug, "favorite" ] [] -articles : List QueryParameter -> Endpoint articles params = url [ "articles" ] params -profiles : Username -> Endpoint profiles uname = url [ "profiles", Username.toString uname ] [] -feed : List QueryParameter -> Endpoint feed params = url [ "articles", "feed" ] params -tags : Endpoint tags = url [ "tags" ] [] diff --git a/src/Article.elm b/src/Article.elm index fc65faa822..550c4b2c94 100644 --- a/src/Article.elm +++ b/src/Article.elm @@ -45,8 +45,6 @@ which displays multiple articles, but without bodies. This definition for `Article` means we can write: -viewArticle : Article Full -> Html msg -viewFeed : List (Article Preview) -> Html msg This indicates that `viewArticle` requires an article _with a `body` present_, wereas `viewFeed` accepts articles with no bodies. (We could also have written @@ -71,8 +69,7 @@ not to alter it. This is read-only information! If we find ourselves using any particular piece of metadata often, for example `title`, we could expose a convenience function like this: -Article.title : Article a -> String - +Article. If you like, it's totally reasonable to expose a function like that for every one of these fields! @@ -110,36 +107,26 @@ type alias Internals = } -type Preview - = Preview +type Preview = Preview -type Full - = Full Body +type Full = Full Body -- INFO -author : Article a -> Author -author (Article internals _) = - internals.author +author (Article internals _) = internals.author -metadata : Article a -> Metadata -metadata (Article internals _) = - internals.metadata +metadata (Article internals _) = internals.metadata -slug : Article a -> Slug -slug (Article internals _) = - internals.slug +slug (Article internals _) = internals.slug -body : Article Full -> Body -body (Article _ (Full extraInfo)) = - extraInfo +body (Article _ (Full extraInfo)) = extraInfo @@ -154,35 +141,28 @@ We can tell this for sure by looking at the types of the exposed functions in this module. -} -mapAuthor : (Author -> Author) -> Article a -> Article a -mapAuthor transform (Article info extras) = - Article { info | author = transform info.author } extras +mapAuthor transform (Article info extras) = Article { info | author = transform info.author } extras -fromPreview : Body -> Article Preview -> Article Full -fromPreview newBody (Article info Preview) = - Article info (Full newBody) +fromPreview newBody (Article info Preview) = Article info (Full newBody) -- SERIALIZATION -previewDecoder : Maybe Cred -> Decoder (Article Preview) previewDecoder maybeCred = Decode.succeed Article |> custom (internalsDecoder maybeCred) |> hardcoded Preview -fullDecoder : Maybe Cred -> Decoder (Article Full) fullDecoder maybeCred = Decode.succeed Article |> custom (internalsDecoder maybeCred) |> required "body" (Decode.map Full Body.decoder) -internalsDecoder : Maybe Cred -> Decoder Internals internalsDecoder maybeCred = Decode.succeed Internals |> required "slug" Slug.decoder @@ -190,7 +170,6 @@ internalsDecoder maybeCred = |> custom metadataDecoder -metadataDecoder : Decoder Metadata metadataDecoder = Decode.succeed Metadata |> required "description" (Decode.map (Maybe.withDefault "") (Decode.nullable Decode.string)) @@ -205,7 +184,6 @@ metadataDecoder = -- SINGLE -fetch : Maybe Cred -> Slug -> Http.Request (Article Full) fetch maybeCred articleSlug = Decode.field "article" (fullDecoder maybeCred) |> Api.get (Endpoint.article articleSlug) maybeCred @@ -215,19 +193,11 @@ fetch maybeCred articleSlug = -- FAVORITE -favorite : Slug -> Cred -> Http.Request (Article Preview) -favorite articleSlug cred = - Api.post (Endpoint.favorite articleSlug) (Just cred) Http.emptyBody (faveDecoder cred) - - -unfavorite : Slug -> Cred -> Http.Request (Article Preview) -unfavorite articleSlug cred = - Api.delete (Endpoint.favorite articleSlug) cred Http.emptyBody (faveDecoder cred) +favorite articleSlug cred = Api.post (Endpoint.favorite articleSlug) (Just cred) Http.emptyBody (faveDecoder cred) +unfavorite articleSlug cred = Api.delete (Endpoint.favorite articleSlug) cred Http.emptyBody (faveDecoder cred) -faveDecoder : Cred -> Decoder (Article Preview) -faveDecoder cred = - Decode.field "article" (previewDecoder (Just cred)) +faveDecoder cred = Decode.field "article" (previewDecoder (Just cred)) {-| This is a "build your own element" API. @@ -236,39 +206,14 @@ You pass it some configuration, followed by a `List (Attribute msg)` and a `List (Html msg)`, just like any standard Html element. -} -favoriteButton : - Cred - -> msg - -> List (Attribute msg) - -> List (Html msg) - -> Html msg -favoriteButton _ msg attrs kids = - toggleFavoriteButton "btn btn-sm btn-outline-primary" msg attrs kids - - -unfavoriteButton : - Cred - -> msg - -> List (Attribute msg) - -> List (Html msg) - -> Html msg -unfavoriteButton _ msg attrs kids = - toggleFavoriteButton "btn btn-sm btn-primary" msg attrs kids - - -toggleFavoriteButton : - String - -> msg - -> List (Attribute msg) - -> List (Html msg) - -> Html msg +favoriteButton _ msg attrs kids = toggleFavoriteButton "btn btn-sm btn-outline-primary" msg attrs kids + +unfavoriteButton _ msg attrs kids = toggleFavoriteButton "btn btn-sm btn-primary" msg attrs kids + toggleFavoriteButton classStr msg attrs kids = Html.button (class classStr :: onClickStopPropagation msg :: attrs) (i [ class "ion-heart" ] [] :: kids) - -onClickStopPropagation : msg -> Attribute msg onClickStopPropagation msg = - stopPropagationOn "click" - (Decode.succeed ( msg, True )) + stopPropagationOn "click" (Decode.succeed ( msg, True )) diff --git a/src/Article/Body.elm b/src/Article/Body.elm index b1c55f150f..10887a2607 100644 --- a/src/Article/Body.elm +++ b/src/Article/Body.elm @@ -23,16 +23,13 @@ type alias MarkdownString = -- CONVERSIONS -toHtml : Body -> List (Attribute msg) -> Html msg toHtml (Body markdown) attributes = Markdown.toHtml attributes markdown -toMarkdownString : Body -> MarkdownString toMarkdownString (Body markdown) = markdown -decoder : Decoder Body decoder = Decode.map Body Decode.string diff --git a/src/Article/Comment.elm b/src/Article/Comment.elm index 301799d11e..cd6797f7ce 100644 --- a/src/Article/Comment.elm +++ b/src/Article/Comment.elm @@ -35,22 +35,18 @@ type alias Internals = -- INFO -id : Comment -> CommentId id (Comment comment) = comment.id -body : Comment -> String body (Comment comment) = comment.body -createdAt : Comment -> Time.Posix createdAt (Comment comment) = comment.createdAt -author : Comment -> Author author (Comment comment) = comment.author @@ -59,7 +55,6 @@ author (Comment comment) = -- LIST -list : Maybe Cred -> Slug -> Http.Request (List Comment) list maybeCred articleSlug = Decode.field "comments" (Decode.list (decoder maybeCred)) |> Api.get (Endpoint.comments articleSlug) maybeCred @@ -69,7 +64,6 @@ list maybeCred articleSlug = -- POST -post : Slug -> String -> Cred -> Http.Request Comment post articleSlug commentBody cred = let bod = @@ -80,7 +74,6 @@ post articleSlug commentBody cred = |> Api.post (Endpoint.comments articleSlug) (Just cred) bod -encodeCommentBody : String -> Value encodeCommentBody str = Encode.object [ ( "comment", Encode.object [ ( "body", Encode.string str ) ] ) ] @@ -89,7 +82,6 @@ encodeCommentBody str = -- DELETE -delete : Slug -> CommentId -> Cred -> Http.Request () delete articleSlug commentId cred = Api.delete (Endpoint.comment articleSlug commentId) cred Http.emptyBody (Decode.succeed ()) @@ -98,7 +90,6 @@ delete articleSlug commentId cred = -- SERIALIZATION -decoder : Maybe Cred -> Decoder Comment decoder maybeCred = Decode.succeed Internals |> required "id" CommentId.decoder diff --git a/src/Article/Feed.elm b/src/Article/Feed.elm index 8e4f4bd1a0..cad1ed3443 100644 --- a/src/Article/Feed.elm +++ b/src/Article/Feed.elm @@ -61,7 +61,6 @@ type alias Internals = } -init : Session -> PaginatedList (Article Preview) -> Model init session articles = Model { session = session @@ -75,7 +74,6 @@ init session articles = -- VIEW -viewArticles : Time.Zone -> Model -> List (Html Msg) viewArticles timeZone (Model { articles, session, errors }) = let maybeCred = @@ -88,7 +86,6 @@ viewArticles timeZone (Model { articles, session, errors }) = Page.viewErrors ClickedDismissErrors errors :: articlesHtml -viewPreview : Maybe Cred -> Time.Zone -> Article Preview -> Html Msg viewPreview maybeCred timeZone article = let slug = @@ -169,7 +166,6 @@ viewTab attrs ( name, msg ) = ] -viewPagination : (Int -> msg) -> Int -> Model -> Html msg viewPagination toMsg page (Model feed) = let viewPageLink currentPage = @@ -187,7 +183,6 @@ viewPagination toMsg page (Model feed) = Html.text "" -pageLink : (Int -> msg) -> Int -> Bool -> Html msg pageLink toMsg targetPage isActive = li [ classList [ ( "page-item", True ), ( "active", isActive ) ] ] [ a @@ -201,7 +196,6 @@ pageLink toMsg targetPage isActive = ] -viewTag : String -> Html msg viewTag tagName = li [ class "tag-default tag-pill tag-outline" ] [ text tagName ] @@ -240,7 +234,6 @@ update maybeCred msg (Model model) = ) -replaceArticle : Article a -> Article a -> Article a replaceArticle newArticle oldArticle = if Article.slug newArticle == Article.slug oldArticle then newArticle @@ -253,14 +246,12 @@ replaceArticle newArticle oldArticle = -- SERIALIZATION -decoder : Maybe Cred -> Int -> Decoder (PaginatedList (Article Preview)) decoder maybeCred resultsPerPage = Decode.succeed PaginatedList.fromList |> required "articlesCount" (pageCountDecoder resultsPerPage) |> required "articles" (Decode.list (Article.previewDecoder maybeCred)) -pageCountDecoder : Int -> Decoder Int pageCountDecoder resultsPerPage = Decode.int |> Decode.map (\total -> ceiling (toFloat total / toFloat resultsPerPage)) diff --git a/src/Article/Slug.elm b/src/Article/Slug.elm index 723f5f9db0..8699243841 100644 --- a/src/Article/Slug.elm +++ b/src/Article/Slug.elm @@ -16,12 +16,10 @@ type Slug -- CREATE -urlParser : Parser (Slug -> a) a urlParser = Url.Parser.custom "SLUG" (\str -> Just (Slug str)) -decoder : Decoder Slug decoder = Decode.map Slug Decode.string @@ -30,6 +28,5 @@ decoder = -- TRANSFORM -toString : Slug -> String toString (Slug str) = str diff --git a/src/Article/Tag.elm b/src/Article/Tag.elm index 2d2c713dc3..f063d6d44e 100644 --- a/src/Article/Tag.elm +++ b/src/Article/Tag.elm @@ -18,7 +18,6 @@ type Tag -- TRANSFORM -toString : Tag -> String toString (Tag slug) = slug @@ -27,7 +26,6 @@ toString (Tag slug) = -- LIST -list : Http.Request (List Tag) list = Decode.field "tags" (Decode.list decoder) |> Api.get Endpoint.tags Nothing @@ -37,6 +35,5 @@ list = -- SERIALIZATION -decoder : Decoder Tag decoder = Decode.map Tag Decode.string diff --git a/src/Asset.elm b/src/Asset.elm index 72b396d11d..ff8f5a303e 100644 --- a/src/Asset.elm +++ b/src/Asset.elm @@ -19,30 +19,20 @@ type Image -- IMAGES -error : Image -error = - image "error.jpg" +error = image "error.jpg" -loading : Image -loading = - image "loading.svg" +loading = image "loading.svg" -defaultAvatar : Image -defaultAvatar = - image "smiley-cyrus.jpg" +defaultAvatar = image "smiley-cyrus.jpg" -image : String -> Image -image filename = - Image ("/assets/images/" ++ filename) +image filename = Image ("/assets/images/" ++ filename) -- USING IMAGES -src : Image -> Attribute msg -src (Image url) = - Attr.src url +src (Image url) = Attr.src url diff --git a/src/Author.elm b/src/Author.elm index 5a19fd912a..2fddb95368 100644 --- a/src/Author.elm +++ b/src/Author.elm @@ -18,8 +18,6 @@ help me keep track of which operations are supported. For example, consider these functions: -requestFollow : UnfollowedAuthor -> Cred -> Http.Request Author -requestUnfollow : FollowedAuthor -> Cred -> Http.Request Author These types help the compiler prevent several mistakes: @@ -62,51 +60,40 @@ type Author {-| An author we're following. -} -type FollowedAuthor - = FollowedAuthor Username Profile +type FollowedAuthor = FollowedAuthor Username Profile {-| An author we're not following. -} -type UnfollowedAuthor - = UnfollowedAuthor Username Profile +type UnfollowedAuthor = UnfollowedAuthor Username Profile {-| Return an Author's username. -} -username : Author -> Username username author = case author of - IsViewer cred _ -> - Api.username cred + IsViewer cred _ -> Api.username cred - IsFollowing (FollowedAuthor val _) -> - val + IsFollowing (FollowedAuthor val _) -> val - IsNotFollowing (UnfollowedAuthor val _) -> - val + IsNotFollowing (UnfollowedAuthor val _) -> val {-| Return an Author's profile. -} -profile : Author -> Profile profile author = case author of - IsViewer _ val -> - val + IsViewer _ val -> val - IsFollowing (FollowedAuthor _ val) -> - val + IsFollowing (FollowedAuthor _ val) -> val - IsNotFollowing (UnfollowedAuthor _ val) -> - val + IsNotFollowing (UnfollowedAuthor _ val) -> val -- FETCH -fetch : Username -> Maybe Cred -> Http.Request Author fetch uname maybeCred = Decode.field "profile" (decoder maybeCred) |> Api.get (Endpoint.profiles uname) maybeCred @@ -116,78 +103,43 @@ fetch uname maybeCred = -- FOLLOWING -follow : UnfollowedAuthor -> FollowedAuthor -follow (UnfollowedAuthor uname prof) = - FollowedAuthor uname prof +follow (UnfollowedAuthor uname prof) = FollowedAuthor uname prof -unfollow : FollowedAuthor -> UnfollowedAuthor -unfollow (FollowedAuthor uname prof) = - UnfollowedAuthor uname prof +unfollow (FollowedAuthor uname prof) = UnfollowedAuthor uname prof -requestFollow : UnfollowedAuthor -> Cred -> Http.Request Author -requestFollow (UnfollowedAuthor uname _) cred = - Api.post (Endpoint.follow uname) (Just cred) Http.emptyBody (followDecoder cred) +requestFollow (UnfollowedAuthor uname _) cred = Api.post (Endpoint.follow uname) (Just cred) Http.emptyBody (followDecoder cred) -requestUnfollow : FollowedAuthor -> Cred -> Http.Request Author requestUnfollow (FollowedAuthor uname _) cred = - Api.delete (Endpoint.follow uname) - cred - Http.emptyBody - (followDecoder cred) + Api.delete (Endpoint.follow uname) cred Http.emptyBody (followDecoder cred) -followDecoder : Cred -> Decoder Author -followDecoder cred = - Decode.field "profile" (decoder (Just cred)) +followDecoder cred = Decode.field "profile" (decoder (Just cred)) -followButton : - (Cred -> UnfollowedAuthor -> msg) - -> Cred - -> UnfollowedAuthor - -> Html msg followButton toMsg cred ((UnfollowedAuthor uname _) as author) = - toggleFollowButton "Follow" - [ "btn-outline-secondary" ] - (toMsg cred author) - uname + toggleFollowButton "Follow" [ "btn-outline-secondary" ] (toMsg cred author) uname -unfollowButton : - (Cred -> FollowedAuthor -> msg) - -> Cred - -> FollowedAuthor - -> Html msg unfollowButton toMsg cred ((FollowedAuthor uname _) as author) = - toggleFollowButton "Unfollow" - [ "btn-secondary" ] - (toMsg cred author) - uname + toggleFollowButton "Unfollow" [ "btn-secondary" ] (toMsg cred author) uname -toggleFollowButton : String -> List String -> msg -> Username -> Html msg toggleFollowButton txt extraClasses msgWhenClicked uname = - let - classStr = - "btn btn-sm " ++ String.join " " extraClasses ++ " action-btn" + let classStr = "btn btn-sm " ++ String.join " " extraClasses ++ " action-btn" - caption = - "\u{00A0}" ++ txt ++ " " ++ Username.toString uname + caption = "\u{00A0}" ++ txt ++ " " ++ Username.toString uname in Html.button [ class classStr, onClick msgWhenClicked ] - [ i [ class "ion-plus-round" ] [] - , text caption - ] + [ i [ class "ion-plus-round" ] [], text caption ] -- SERIALIZATION -decoder : Maybe Cred -> Decoder Author decoder maybeCred = Decode.succeed Tuple.pair |> custom Profile.decoder @@ -195,40 +147,29 @@ decoder maybeCred = |> Decode.andThen (decodeFromPair maybeCred) -decodeFromPair : Maybe Cred -> ( Profile, Username ) -> Decoder Author decodeFromPair maybeCred ( prof, uname ) = case maybeCred of - Nothing -> - -- If you're logged out, you can't be following anyone! - Decode.succeed (IsNotFollowing (UnfollowedAuthor uname prof)) + Nothing -> Decode.succeed (IsNotFollowing (UnfollowedAuthor uname prof)) Just cred -> - if uname == Api.username cred then - Decode.succeed (IsViewer cred prof) + if uname == Api.username cred + then Decode.succeed (IsViewer cred prof) + else nonViewerDecoder prof uname - else - nonViewerDecoder prof uname - -nonViewerDecoder : Profile -> Username -> Decoder Author nonViewerDecoder prof uname = Decode.succeed (authorFromFollowing prof uname) |> optional "following" Decode.bool False -authorFromFollowing : Profile -> Username -> Bool -> Author authorFromFollowing prof uname isFollowing = - if isFollowing then - IsFollowing (FollowedAuthor uname prof) - - else - IsNotFollowing (UnfollowedAuthor uname prof) + if isFollowing + then IsFollowing (FollowedAuthor uname prof) + else IsNotFollowing (UnfollowedAuthor uname prof) {-| View an author. We basically render their username and a link to their profile, and that's it. -} -view : Username -> Html msg view uname = - a [ class "author", Route.href (Route.Profile uname) ] - [ Username.toHtml uname ] + a [ class "author", Route.href (Route.Profile uname) ] [ Username.toHtml uname ] diff --git a/src/Avatar.elm b/src/Avatar.elm index 7ecafb3b66..9e83ac801e 100644 --- a/src/Avatar.elm +++ b/src/Avatar.elm @@ -11,46 +11,34 @@ import Json.Encode as Encode exposing (Value) -- TYPES -type Avatar - = Avatar (Maybe String) +type Avatar = Avatar (Maybe String) -- CREATE -decoder : Decoder Avatar -decoder = - Decode.map Avatar (Decode.nullable Decode.string) +decoder = Decode.map Avatar (Decode.nullable Decode.string) -- TRANSFORM -encode : Avatar -> Value encode (Avatar maybeUrl) = case maybeUrl of - Just url -> - Encode.string url + Just url -> Encode.string url - Nothing -> - Encode.null + Nothing -> Encode.null -src : Avatar -> Attribute msg src (Avatar maybeUrl) = case maybeUrl of - Nothing -> - Asset.src Asset.defaultAvatar + Nothing -> Asset.src Asset.defaultAvatar - Just "" -> - Asset.src Asset.defaultAvatar + Just "" -> Asset.src Asset.defaultAvatar - Just url -> - Html.Attributes.src url + Just url -> Html.Attributes.src url -toMaybeString : Avatar -> Maybe String -toMaybeString (Avatar maybeUrl) = - maybeUrl +toMaybeString (Avatar maybeUrl) = maybeUrl diff --git a/src/CommentId.elm b/src/CommentId.elm index f136e1b0d2..3d2a5350cb 100644 --- a/src/CommentId.elm +++ b/src/CommentId.elm @@ -7,23 +7,18 @@ import Json.Decode as Decode exposing (Decoder) -- TYPES -type CommentId - = CommentId Int +type CommentId = CommentId Int -- CREATE -decoder : Decoder CommentId -decoder = - Decode.map CommentId Decode.int +decoder = Decode.map CommentId Decode.int -- TRANSFORM -toString : CommentId -> String -toString (CommentId id) = - String.fromInt id +toString (CommentId id) = String.fromInt id diff --git a/src/Email.elm b/src/Email.elm index f696c01abb..f317b9ccda 100644 --- a/src/Email.elm +++ b/src/Email.elm @@ -9,7 +9,6 @@ import Json.Encode as Encode exposing (Value) Having this as a custom type that's separate from String makes certain mistakes impossible. Consider this function: -updateEmailAddress : Email -> String -> Http.Request updateEmailAddress email password = ... (The server needs your password to confirm that you should be allowed @@ -30,16 +29,10 @@ type Email = Email String -toString : Email -> String -toString (Email str) = - str +toString (Email str) = str -encode : Email -> Value -encode (Email str) = - Encode.string str +encode (Email str) = Encode.string str -decoder : Decoder Email -decoder = - Decode.map Email Decode.string +decoder = Decode.map Email Decode.string diff --git a/src/Loading.elm b/src/Loading.elm index 2eba30199c..d4eddff8f0 100644 --- a/src/Loading.elm +++ b/src/Loading.elm @@ -10,7 +10,6 @@ import Process import Task exposing (Task) -icon : Html msg icon = Html.img [ Asset.src Asset.loading @@ -21,11 +20,7 @@ icon = [] -error : String -> Html msg -error str = - Html.text ("Error loading " ++ str ++ ".") +error str = Html.text ("Error loading " ++ str ++ ".") -slowThreshold : Task x () -slowThreshold = - Process.sleep 500 +slowThreshold = Process.sleep 500 diff --git a/src/Log.elm b/src/Log.elm index fe6111ec7b..7303319e0d 100644 --- a/src/Log.elm +++ b/src/Log.elm @@ -15,6 +15,4 @@ diagnostic info, authentication tokens, etc.) -} -error : Cmd msg -error = - Cmd.none +error = Cmd.none diff --git a/src/Main.elm b/src/Main.elm index 70c62ad026..e1674797dd 100644 --- a/src/Main.elm +++ b/src/Main.elm @@ -50,61 +50,42 @@ type Model -- MODEL -init : Maybe Viewer -> Url -> Nav.Key -> ( Model, Cmd Msg ) init maybeViewer url navKey = - changeRouteTo (Route.fromUrl url) - (Redirect (Session.fromViewer navKey maybeViewer)) + changeRouteTo (Route.fromUrl url) (Redirect (Session.fromViewer navKey maybeViewer)) -- VIEW -view : Model -> Document Msg view model = let - viewer = - Session.viewer (toSession model) + viewer = Session.viewer (toSession model) viewPage page toMsg config = - let - { title, body } = - Page.view viewer page config - in - { title = title - , body = List.map (Html.map toMsg) body - } + let { title, body } = Page.view viewer page config in + { title = title, body = List.map (Html.map toMsg) body } in case model of - Redirect _ -> - Page.view viewer Page.Other Blank.view + Redirect _ -> Page.view viewer Page.Other Blank.view - NotFound _ -> - Page.view viewer Page.Other NotFound.view + NotFound _ -> Page.view viewer Page.Other NotFound.view - Settings settings -> - viewPage Page.Other GotSettingsMsg (Settings.view settings) + Settings settings -> viewPage Page.Other GotSettingsMsg (Settings.view settings) - Home home -> - viewPage Page.Home GotHomeMsg (Home.view home) + Home home -> viewPage Page.Home GotHomeMsg (Home.view home) - Login login -> - viewPage Page.Other GotLoginMsg (Login.view login) + Login login -> viewPage Page.Other GotLoginMsg (Login.view login) - Register register -> - viewPage Page.Other GotRegisterMsg (Register.view register) + Register register -> viewPage Page.Other GotRegisterMsg (Register.view register) - Profile username profile -> - viewPage (Page.Profile username) GotProfileMsg (Profile.view profile) + Profile username profile -> viewPage (Page.Profile username) GotProfileMsg (Profile.view profile) - Article article -> - viewPage Page.Other GotArticleMsg (Article.view article) + Article article -> viewPage Page.Other GotArticleMsg (Article.view article) - Editor Nothing editor -> - viewPage Page.NewArticle GotEditorMsg (Editor.view editor) + Editor Nothing editor -> viewPage Page.NewArticle GotEditorMsg (Editor.view editor) - Editor (Just _) editor -> - viewPage Page.Other GotEditorMsg (Editor.view editor) + Editor (Just _) editor -> viewPage Page.Other GotEditorMsg (Editor.view editor) @@ -124,202 +105,121 @@ type Msg | GotSession Session -toSession : Model -> Session toSession page = case page of - Redirect session -> - session + Redirect session -> session - NotFound session -> - session + NotFound session -> session - Home home -> - Home.toSession home + Home home -> Home.toSession home - Settings settings -> - Settings.toSession settings + Settings settings -> Settings.toSession settings - Login login -> - Login.toSession login + Login login -> Login.toSession login - Register register -> - Register.toSession register + Register register -> Register.toSession register - Profile _ profile -> - Profile.toSession profile + Profile _ profile -> Profile.toSession profile - Article article -> - Article.toSession article + Article article -> Article.toSession article - Editor _ editor -> - Editor.toSession editor + Editor _ editor -> Editor.toSession editor -changeRouteTo : Maybe Route -> Model -> ( Model, Cmd Msg ) changeRouteTo maybeRoute model = let session = toSession model in case maybeRoute of - Nothing -> - ( NotFound session, Cmd.none ) + Nothing -> ( NotFound session, Cmd.none ) - Just Route.Root -> - ( model, Route.replaceUrl (Session.navKey session) Route.Home ) + Just Route.Root -> ( model, Route.replaceUrl (Session.navKey session) Route.Home ) - Just Route.Logout -> - ( model, Api.logout ) + Just Route.Logout -> ( model, Api.logout ) - Just Route.NewArticle -> - Editor.initNew session - |> updateWith (Editor Nothing) GotEditorMsg model + Just Route.NewArticle -> Editor.initNew session |> updateWith (Editor Nothing) GotEditorMsg model - Just (Route.EditArticle slug) -> - Editor.initEdit session slug - |> updateWith (Editor (Just slug)) GotEditorMsg model + Just (Route.EditArticle slug) -> Editor.initEdit session slug |> updateWith (Editor (Just slug)) GotEditorMsg model - Just Route.Settings -> - Settings.init session - |> updateWith Settings GotSettingsMsg model + Just Route.Settings -> Settings.init session |> updateWith Settings GotSettingsMsg model - Just Route.Home -> - Home.init session - |> updateWith Home GotHomeMsg model + Just Route.Home -> Home.init session |> updateWith Home GotHomeMsg model - Just Route.Login -> - Login.init session - |> updateWith Login GotLoginMsg model + Just Route.Login -> Login.init session |> updateWith Login GotLoginMsg model - Just Route.Register -> - Register.init session - |> updateWith Register GotRegisterMsg model + Just Route.Register -> Register.init session |> updateWith Register GotRegisterMsg model - Just (Route.Profile username) -> - Profile.init session username - |> updateWith (Profile username) GotProfileMsg model + Just (Route.Profile username) -> Profile.init session username |> updateWith (Profile username) GotProfileMsg model - Just (Route.Article slug) -> - Article.init session slug - |> updateWith Article GotArticleMsg model + Just (Route.Article slug) -> Article.init session slug |> updateWith Article GotArticleMsg model -update : Msg -> Model -> ( Model, Cmd Msg ) update msg model = case ( msg, model ) of ( ClickedLink urlRequest, _ ) -> case urlRequest of Browser.Internal url -> case url.fragment of - Nothing -> - -- If we got a link that didn't include a fragment, - -- it's from one of those (href "") attributes that - -- we have to include to make the RealWorld CSS work. - -- - -- In an application doing path routing instead of - -- fragment-based routing, this entire - -- `case url.fragment of` expression this comment - -- is inside would be unnecessary. - ( model, Cmd.none ) + Nothing -> ( model, Cmd.none ) - Just _ -> - ( model - , Nav.pushUrl (Session.navKey (toSession model)) (Url.toString url) - ) + Just _ -> ( model, Nav.pushUrl (Session.navKey (toSession model)) (Url.toString url) ) - Browser.External href -> - ( model - , Nav.load href - ) + Browser.External href -> ( model, Nav.load href ) - ( ChangedUrl url, _ ) -> - changeRouteTo (Route.fromUrl url) model + ( ChangedUrl url, _ ) -> changeRouteTo (Route.fromUrl url) model - ( GotSettingsMsg subMsg, Settings settings ) -> - Settings.update subMsg settings - |> updateWith Settings GotSettingsMsg model + ( GotSettingsMsg subMsg, Settings settings ) -> Settings.update subMsg settings |> updateWith Settings GotSettingsMsg model - ( GotLoginMsg subMsg, Login login ) -> - Login.update subMsg login - |> updateWith Login GotLoginMsg model + ( GotLoginMsg subMsg, Login login ) -> Login.update subMsg login |> updateWith Login GotLoginMsg model - ( GotRegisterMsg subMsg, Register register ) -> - Register.update subMsg register - |> updateWith Register GotRegisterMsg model + ( GotRegisterMsg subMsg, Register register ) -> Register.update subMsg register |> updateWith Register GotRegisterMsg model - ( GotHomeMsg subMsg, Home home ) -> - Home.update subMsg home - |> updateWith Home GotHomeMsg model + ( GotHomeMsg subMsg, Home home ) -> Home.update subMsg home |> updateWith Home GotHomeMsg model - ( GotProfileMsg subMsg, Profile username profile ) -> - Profile.update subMsg profile - |> updateWith (Profile username) GotProfileMsg model + ( GotProfileMsg subMsg, Profile username profile ) -> Profile.update subMsg profile |> updateWith (Profile username) GotProfileMsg model - ( GotArticleMsg subMsg, Article article ) -> - Article.update subMsg article - |> updateWith Article GotArticleMsg model + ( GotArticleMsg subMsg, Article article ) -> Article.update subMsg article |> updateWith Article GotArticleMsg model - ( GotEditorMsg subMsg, Editor slug editor ) -> - Editor.update subMsg editor - |> updateWith (Editor slug) GotEditorMsg model + ( GotEditorMsg subMsg, Editor slug editor ) -> Editor.update subMsg editor |> updateWith (Editor slug) GotEditorMsg model - ( GotSession session, Redirect _ ) -> - ( Redirect session - , Route.replaceUrl (Session.navKey session) Route.Home - ) + ( GotSession session, Redirect _ ) -> ( Redirect session, Route.replaceUrl (Session.navKey session) Route.Home ) - ( _, _ ) -> - -- Disregard messages that arrived for the wrong page. - ( model, Cmd.none ) + ( _, _ ) -> ( model, Cmd.none ) -updateWith : (subModel -> Model) -> (subMsg -> Msg) -> Model -> ( subModel, Cmd subMsg ) -> ( Model, Cmd Msg ) -updateWith toModel toMsg model ( subModel, subCmd ) = - ( toModel subModel - , Cmd.map toMsg subCmd - ) +updateWith toModel toMsg model ( subModel, subCmd ) = ( toModel subModel, Cmd.map toMsg subCmd ) -- SUBSCRIPTIONS -subscriptions : Model -> Sub Msg subscriptions model = case model of - NotFound _ -> - Sub.none + NotFound _ -> Sub.none - Redirect _ -> - Session.changes GotSession (Session.navKey (toSession model)) + Redirect _ -> Session.changes GotSession (Session.navKey (toSession model)) - Settings settings -> - Sub.map GotSettingsMsg (Settings.subscriptions settings) + Settings settings -> Sub.map GotSettingsMsg (Settings.subscriptions settings) - Home home -> - Sub.map GotHomeMsg (Home.subscriptions home) + Home home -> Sub.map GotHomeMsg (Home.subscriptions home) - Login login -> - Sub.map GotLoginMsg (Login.subscriptions login) + Login login -> Sub.map GotLoginMsg (Login.subscriptions login) - Register register -> - Sub.map GotRegisterMsg (Register.subscriptions register) + Register register -> Sub.map GotRegisterMsg (Register.subscriptions register) - Profile _ profile -> - Sub.map GotProfileMsg (Profile.subscriptions profile) + Profile _ profile -> Sub.map GotProfileMsg (Profile.subscriptions profile) - Article article -> - Sub.map GotArticleMsg (Article.subscriptions article) + Article article -> Sub.map GotArticleMsg (Article.subscriptions article) - Editor _ editor -> - Sub.map GotEditorMsg (Editor.subscriptions editor) + Editor _ editor -> Sub.map GotEditorMsg (Editor.subscriptions editor) -- MAIN -main : Program Value Model Msg main = Api.application Viewer.decoder { init = init diff --git a/src/Page.elm b/src/Page.elm index f1790bff6f..7c40442ff2 100644 --- a/src/Page.elm +++ b/src/Page.elm @@ -39,14 +39,12 @@ isLoading is for determining whether we should show a loading spinner in the header. (This comes up during slow page transitions.) -} -view : Maybe Viewer -> Page -> { title : String, content : Html msg } -> Document msg view maybeViewer page { title, content } = { title = title ++ " - Conduit" , body = viewHeader page maybeViewer :: content :: [ viewFooter ] } -viewHeader : Page -> Maybe Viewer -> Html msg viewHeader page maybeViewer = nav [ class "navbar navbar-light" ] [ div [ class "container" ] @@ -59,20 +57,14 @@ viewHeader page maybeViewer = ] -viewMenu : Page -> Maybe Viewer -> List (Html msg) viewMenu page maybeViewer = - let - linkTo = - navbarLink page - in + let linkTo = navbarLink page in case maybeViewer of Just viewer -> let - username = - Viewer.username viewer + username = Viewer.username viewer - avatar = - Viewer.avatar viewer + avatar = Viewer.avatar viewer in [ linkTo Route.NewArticle [ i [ class "ion-compose" ] [], text "\u{00A0}New Post" ] , linkTo Route.Settings [ i [ class "ion-gear-a" ] [], text "\u{00A0}Settings" ] @@ -90,7 +82,6 @@ viewMenu page maybeViewer = ] -viewFooter : Html msg viewFooter = footer [] [ div [ class "container" ] @@ -104,44 +95,32 @@ viewFooter = ] -navbarLink : Page -> Route -> List (Html msg) -> Html msg navbarLink page route linkContent = li [ classList [ ( "nav-item", True ), ( "active", isActive page route ) ] ] [ a [ class "nav-link", Route.href route ] linkContent ] -isActive : Page -> Route -> Bool isActive page route = case ( page, route ) of - ( Home, Route.Home ) -> - True + ( Home, Route.Home ) -> True - ( Login, Route.Login ) -> - True + ( Login, Route.Login ) -> True - ( Register, Route.Register ) -> - True + ( Register, Route.Register ) -> True - ( Settings, Route.Settings ) -> - True + ( Settings, Route.Settings ) -> True - ( Profile pageUsername, Route.Profile routeUsername ) -> - pageUsername == routeUsername + ( Profile pageUsername, Route.Profile routeUsername ) -> pageUsername == routeUsername - ( NewArticle, Route.NewArticle ) -> - True + ( NewArticle, Route.NewArticle ) -> True - _ -> - False + _ -> False {-| Render dismissable errors. We use this all over the place! -} -viewErrors : msg -> List String -> Html msg viewErrors dismissErrors errors = - if List.isEmpty errors then - Html.text "" - + if List.isEmpty errors then Html.text "" else div [ class "error-messages" diff --git a/src/Page/Article.elm b/src/Page/Article.elm index 1ef0d6e16f..872ae42a3a 100644 --- a/src/Page/Article.elm +++ b/src/Page/Article.elm @@ -58,7 +58,6 @@ type CommentText | Sending String -init : Session -> Slug -> ( Model, Cmd Msg ) init session slug = let maybeCred = @@ -85,7 +84,6 @@ init session slug = -- VIEW -view : Model -> { title : String, content : Html Msg } view model = case model.article of Loaded article -> @@ -185,7 +183,6 @@ view model = { title = "Article", content = Loading.error "article" } -viewAddComment : Slug -> CommentText -> Maybe Viewer -> Html Msg viewAddComment slug commentText maybeViewer = case maybeViewer of Just viewer -> @@ -232,7 +229,6 @@ viewAddComment slug commentText maybeViewer = ] -viewButtons : Cred -> Article Full -> Author -> List (Html Msg) viewButtons cred article author = case author of IsFollowing followedAuthor -> @@ -254,7 +250,6 @@ viewButtons cred article author = ] -viewComment : Time.Zone -> Slug -> Comment -> Html Msg viewComment timeZone slug comment = let author = @@ -329,7 +324,6 @@ type Msg | PassedSlowLoadThreshold -update : Msg -> Model -> ( Model, Cmd Msg ) update msg model = case msg of ClickedDismissErrors -> @@ -508,7 +502,6 @@ update msg model = -- SUBSCRIPTIONS -subscriptions : Model -> Sub Msg subscriptions model = Session.changes GotSession (Session.navKey model.session) @@ -517,7 +510,6 @@ subscriptions model = -- HTTP -delete : Slug -> Cred -> Http.Request () delete slug cred = Api.delete (Endpoint.article slug) cred Http.emptyBody (Decode.succeed ()) @@ -526,7 +518,6 @@ delete slug cred = -- EXPORT -toSession : Model -> Session toSession model = model.session @@ -535,7 +526,6 @@ toSession model = -- INTERNAL -fave : (Slug -> Cred -> Http.Request (Article Preview)) -> Cred -> Slug -> Body -> Cmd Msg fave toRequest cred slug body = toRequest slug cred |> Http.toTask @@ -543,12 +533,10 @@ fave toRequest cred slug body = |> Task.attempt CompletedFavoriteChange -withoutComment : CommentId -> List Comment -> List Comment withoutComment id list = List.filter (\comment -> Comment.id comment /= id) list -favoriteButton : Cred -> Article Full -> Html Msg favoriteButton cred article = let { favoritesCount, favorited } = @@ -570,7 +558,6 @@ favoriteButton cred article = Article.favoriteButton cred (ClickedFavorite cred slug body) [] kids -deleteButton : Cred -> Article a -> Html Msg deleteButton cred article = let msg = @@ -580,7 +567,6 @@ deleteButton cred article = [ i [ class "ion-trash-a" ] [], text " Delete Article" ] -editButton : Article a -> Html Msg editButton article = a [ class "btn btn-outline-secondary btn-sm", Route.href (Route.EditArticle (Article.slug article)) ] [ i [ class "ion-edit" ] [], text " Edit Article" ] diff --git a/src/Page/Article/Editor.elm b/src/Page/Article/Editor.elm index d339cbfd26..9b7c482552 100644 --- a/src/Page/Article/Editor.elm +++ b/src/Page/Article/Editor.elm @@ -57,7 +57,6 @@ type alias Form = } -initNew : Session -> ( Model, Cmd msg ) initNew session = ( { session = session , status = @@ -72,7 +71,6 @@ initNew session = ) -initEdit : Session -> Slug -> ( Model, Cmd Msg ) initEdit session slug = ( { session = session , status = Loading slug @@ -93,7 +91,6 @@ initEdit session slug = -- VIEW -view : Model -> { title : String, content : Html Msg } view model = { title = case getSlug model.status of @@ -112,13 +109,11 @@ view model = } -viewProblems : List Problem -> Html msg viewProblems problems = ul [ class "error-messages" ] (List.map viewProblem problems) -viewProblem : Problem -> Html msg viewProblem problem = let errorMessage = @@ -132,7 +127,6 @@ viewProblem problem = li [] [ text errorMessage ] -viewAuthenticated : Cred -> Model -> Html Msg viewAuthenticated cred model = let formHtml = @@ -172,7 +166,6 @@ viewAuthenticated cred model = ] -viewForm : Cred -> Form -> Html Msg -> Html Msg viewForm cred fields saveButton = Html.form [ onSubmit (ClickedSave cred) ] [ fieldset [] @@ -218,17 +211,12 @@ viewForm cred fields saveButton = ] -editArticleSaveButton : List (Attribute msg) -> Html msg -editArticleSaveButton extraAttrs = - saveArticleButton "Update Article" extraAttrs +editArticleSaveButton extraAttrs = saveArticleButton "Update Article" extraAttrs -newArticleSaveButton : List (Attribute msg) -> Html msg -newArticleSaveButton extraAttrs = - saveArticleButton "Publish Article" extraAttrs +newArticleSaveButton extraAttrs = saveArticleButton "Publish Article" extraAttrs -saveArticleButton : String -> List (Attribute msg) -> Html msg saveArticleButton caption extraAttrs = button (class "btn btn-lg pull-xs-right btn-primary" :: extraAttrs) [ text caption ] @@ -251,7 +239,6 @@ type Msg | PassedSlowLoadThreshold -update : Msg -> Model -> ( Model, Cmd Msg ) update msg model = case msg of ClickedSave cred -> @@ -336,7 +323,6 @@ update msg model = ( { model | status = status }, Cmd.none ) -save : Cred -> Status -> ( Status, Cmd Msg ) save cred status = case status of Editing slug _ form -> @@ -375,7 +361,6 @@ save cred status = ( status, Cmd.none ) -savingError : Http.Error -> Status -> Status savingError error status = let problems = @@ -401,7 +386,6 @@ This could also log errors to the server if we are trying to record things in the form and we don't actually have a form. -} -updateForm : (Form -> Form) -> Model -> ( Model, Cmd Msg ) updateForm transform model = let newModel = @@ -434,7 +418,6 @@ updateForm transform model = -- SUBSCRIPTIONS -subscriptions : Model -> Sub Msg subscriptions model = Session.changes GotSession (Session.navKey model.session) @@ -457,7 +440,6 @@ type ValidatedField | Body -fieldsToValidate : List ValidatedField fieldsToValidate = [ Title , Body @@ -466,7 +448,6 @@ fieldsToValidate = {-| Trim the form and validate its fields. If there are problems, report them! -} -validate : Form -> Result (List Problem) TrimmedForm validate form = let trimmedForm = @@ -480,7 +461,6 @@ validate form = Err problems -validateField : TrimmedForm -> ValidatedField -> List Problem validateField (Trimmed form) field = List.map (InvalidEntry field) <| case field of @@ -502,7 +482,6 @@ validateField (Trimmed form) field = {-| Don't trim while the user is typing! That would be super annoying. Instead, trim only on submit. -} -trimFields : Form -> TrimmedForm trimFields form = Trimmed { title = String.trim form.title @@ -516,7 +495,6 @@ trimFields form = -- HTTP -create : TrimmedForm -> Cred -> Http.Request (Article Full) create (Trimmed form) cred = let article = @@ -535,14 +513,12 @@ create (Trimmed form) cred = |> Api.post (Endpoint.articles []) (Just cred) body -tagsFromString : String -> List String tagsFromString str = String.split " " str |> List.map String.trim |> List.filter (not << String.isEmpty) -edit : Slug -> TrimmedForm -> Cred -> Http.Request (Article Full) edit articleSlug (Trimmed form) cred = let article = @@ -564,7 +540,6 @@ edit articleSlug (Trimmed form) cred = -- EXPORT -toSession : Model -> Session toSession model = model.session @@ -575,7 +550,6 @@ toSession model = {-| Used for setting the page's title. -} -getSlug : Status -> Maybe Slug getSlug status = case status of Loading slug -> diff --git a/src/Page/Home.elm b/src/Page/Home.elm index 9008a8311c..e4ed83ab05 100644 --- a/src/Page/Home.elm +++ b/src/Page/Home.elm @@ -53,7 +53,6 @@ type FeedTab | TagFeed Tag -init : Session -> ( Model, Cmd Msg ) init session = let feedTab = @@ -89,7 +88,6 @@ init session = -- VIEW -view : Model -> { title : String, content : Html Msg } view model = { title = "Conduit" , content = @@ -143,7 +141,6 @@ view model = } -viewBanner : Html msg viewBanner = div [ class "banner" ] [ div [ class "container" ] @@ -157,7 +154,6 @@ viewBanner = -- TABS -viewTabs : Maybe Cred -> FeedTab -> Html Msg viewTabs maybeCred tab = case tab of YourFeed cred -> @@ -188,31 +184,22 @@ viewTabs maybeCred tab = Feed.viewTabs otherTabs (tagFeed tag) [] -yourFeed : Cred -> ( String, Msg ) -yourFeed cred = - ( "Your Feed", ClickedTab (YourFeed cred) ) +yourFeed cred = ( "Your Feed", ClickedTab (YourFeed cred) ) -globalFeed : ( String, Msg ) -globalFeed = - ( "Global Feed", ClickedTab GlobalFeed ) +globalFeed = ( "Global Feed", ClickedTab GlobalFeed ) -tagFeed : Tag -> ( String, Msg ) -tagFeed tag = - ( "#" ++ Tag.toString tag, ClickedTab (TagFeed tag) ) +tagFeed tag = ( "#" ++ Tag.toString tag, ClickedTab (TagFeed tag) ) -- TAGS -viewTags : List Tag -> Html Msg -viewTags tags = - div [ class "tag-list" ] (List.map viewTag tags) +viewTags tags = div [ class "tag-list" ] (List.map viewTag tags) -viewTag : Tag -> Html Msg viewTag tagName = a [ class "tag-pill tag-default" @@ -240,7 +227,6 @@ type Msg | PassedSlowLoadThreshold -update : Msg -> Model -> ( Model, Cmd Msg ) update msg model = case msg of ClickedTag tag -> @@ -333,7 +319,6 @@ update msg model = -- HTTP -fetchFeed : Session -> FeedTab -> Int -> Task Http.Error Feed.Model fetchFeed session feedTabs page = let maybeCred = @@ -364,12 +349,9 @@ fetchFeed session feedTabs page = |> Task.map (Feed.init session) -articlesPerPage : Int -articlesPerPage = - 10 +articlesPerPage = 10 -scrollToTop : Task x () scrollToTop = Dom.setViewport 0 0 -- It's not worth showing the user anything special if scrolling fails. @@ -381,15 +363,11 @@ scrollToTop = -- SUBSCRIPTIONS -subscriptions : Model -> Sub Msg -subscriptions model = - Session.changes GotSession (Session.navKey model.session) +subscriptions model = Session.changes GotSession (Session.navKey model.session) -- EXPORT -toSession : Model -> Session -toSession model = - model.session +toSession model = model.session diff --git a/src/Page/Login.elm b/src/Page/Login.elm index 31bab51450..57928b042d 100644 --- a/src/Page/Login.elm +++ b/src/Page/Login.elm @@ -63,7 +63,6 @@ type alias Form = } -init : Session -> ( Model, Cmd msg ) init session = ( { session = session , problems = [] @@ -80,7 +79,6 @@ init session = -- VIEW -view : Model -> { title : String, content : Html Msg } view model = { title = "Login" , content = @@ -103,7 +101,6 @@ view model = } -viewProblem : Problem -> Html msg viewProblem problem = let errorMessage = @@ -117,7 +114,6 @@ viewProblem problem = li [] [ text errorMessage ] -viewForm : Form -> Html Msg viewForm form = Html.form [ onSubmit SubmittedForm ] [ fieldset [ class "form-group" ] @@ -156,7 +152,6 @@ type Msg | GotSession Session -update : Msg -> Model -> ( Model, Cmd Msg ) update msg model = case msg of SubmittedForm -> @@ -201,7 +196,6 @@ update msg model = {-| Helper function for `update`. Updates the form and returns Cmd.none. Useful for recording form fields! -} -updateForm : (Form -> Form) -> Model -> ( Model, Cmd Msg ) updateForm transform model = ( { model | form = transform model.form }, Cmd.none ) @@ -210,7 +204,6 @@ updateForm transform model = -- SUBSCRIPTIONS -subscriptions : Model -> Sub Msg subscriptions model = Session.changes GotSession (Session.navKey model.session) @@ -233,7 +226,6 @@ type ValidatedField | Password -fieldsToValidate : List ValidatedField fieldsToValidate = [ Email , Password @@ -242,7 +234,6 @@ fieldsToValidate = {-| Trim the form and validate its fields. If there are problems, report them! -} -validate : Form -> Result (List Problem) TrimmedForm validate form = let trimmedForm = @@ -256,7 +247,6 @@ validate form = Err problems -validateField : TrimmedForm -> ValidatedField -> List Problem validateField (Trimmed form) field = List.map (InvalidEntry field) <| case field of @@ -278,7 +268,6 @@ validateField (Trimmed form) field = {-| Don't trim while the user is typing! That would be super annoying. Instead, trim only on submit. -} -trimFields : Form -> TrimmedForm trimFields form = Trimmed { email = String.trim form.email @@ -290,7 +279,6 @@ trimFields form = -- HTTP -login : TrimmedForm -> Http.Request Viewer login (Trimmed form) = let user = @@ -310,6 +298,5 @@ login (Trimmed form) = -- EXPORT -toSession : Model -> Session toSession model = model.session diff --git a/src/Page/Profile.elm b/src/Page/Profile.elm index 906b5270d2..c25c5a9909 100644 --- a/src/Page/Profile.elm +++ b/src/Page/Profile.elm @@ -55,7 +55,6 @@ type Status a | Failed Username -init : Session -> Username -> ( Model, Cmd Msg ) init session username = let maybeCred = @@ -81,7 +80,6 @@ init session username = ) -currentUsername : Model -> Username currentUsername model = case model.author of Loading username -> @@ -97,16 +95,13 @@ currentUsername model = username -defaultFeedTab : FeedTab -defaultFeedTab = - MyArticles +defaultFeedTab = MyArticles -- HTTP -fetchFeed : Session -> FeedTab -> Username -> Int -> Cmd Msg fetchFeed session feedTabs username page = let maybeCred = @@ -133,16 +128,13 @@ fetchFeed session feedTabs username page = |> Task.attempt CompletedFeedLoad -articlesPerPage : Int -articlesPerPage = - 5 +articlesPerPage = 5 -- VIEW -view : Model -> { title : String, content : Html Msg } view model = let title = @@ -249,12 +241,10 @@ view model = -- PAGE TITLE -titleForOther : Username -> String titleForOther otherUsername = "Profile — " ++ Username.toString otherUsername -titleForMe : Maybe Cred -> Username -> String titleForMe maybeCred username = case maybeCred of Just cred -> @@ -268,21 +258,16 @@ titleForMe maybeCred username = defaultTitle -myProfileTitle : String -myProfileTitle = - "My Profile" +myProfileTitle = "My Profile" -defaultTitle : String -defaultTitle = - "Profile" +defaultTitle = "Profile" -- TABS -viewTabs : FeedTab -> Html Msg viewTabs tab = case tab of MyArticles -> @@ -292,14 +277,10 @@ viewTabs tab = Feed.viewTabs [ myArticles ] favoritedArticles [] -myArticles : ( String, Msg ) -myArticles = - ( "My Articles", ClickedTab MyArticles ) +myArticles = ( "My Articles", ClickedTab MyArticles ) -favoritedArticles : ( String, Msg ) -favoritedArticles = - ( "Favorited Articles", ClickedTab FavoritedArticles ) +favoritedArticles = ( "Favorited Articles", ClickedTab FavoritedArticles ) @@ -321,7 +302,6 @@ type Msg | PassedSlowLoadThreshold -update : Msg -> Model -> ( Model, Cmd Msg ) update msg model = case msg of ClickedDismissErrors -> @@ -424,15 +404,11 @@ update msg model = -- SUBSCRIPTIONS -subscriptions : Model -> Sub Msg -subscriptions model = - Session.changes GotSession (Session.navKey model.session) +subscriptions model = Session.changes GotSession (Session.navKey model.session) -- EXPORT -toSession : Model -> Session -toSession model = - model.session +toSession model = model.session diff --git a/src/Page/Register.elm b/src/Page/Register.elm index f1078e9329..d3e876038b 100644 --- a/src/Page/Register.elm +++ b/src/Page/Register.elm @@ -37,7 +37,6 @@ type Problem | ServerError String -init : Session -> ( Model, Cmd msg ) init session = ( { session = session , problems = [] @@ -55,7 +54,6 @@ init session = -- VIEW -view : Model -> { title : String, content : Html Msg } view model = { title = "Register" , content = @@ -78,7 +76,6 @@ view model = } -viewForm : Form -> Html Msg viewForm form = Html.form [ onSubmit SubmittedForm ] [ fieldset [ class "form-group" ] @@ -114,7 +111,6 @@ viewForm form = ] -viewProblem : Problem -> Html msg viewProblem problem = let errorMessage = @@ -141,7 +137,6 @@ type Msg | GotSession Session -update : Msg -> Model -> ( Model, Cmd Msg ) update msg model = case msg of SubmittedForm -> @@ -156,21 +151,14 @@ update msg model = , Cmd.none ) - EnteredUsername username -> - updateForm (\form -> { form | username = username }) model + EnteredUsername username -> updateForm (\form -> { form | username = username }) model - EnteredEmail email -> - updateForm (\form -> { form | email = email }) model + EnteredEmail email -> updateForm (\form -> { form | email = email }) model - EnteredPassword password -> - updateForm (\form -> { form | password = password }) model + EnteredPassword password -> updateForm (\form -> { form | password = password }) model CompletedRegister (Err error) -> - let - serverErrors = - Api.decodeErrors error - |> List.map ServerError - in + let serverErrors = List.map ServerError (Api.decodeErrors error) in ( { model | problems = List.append model.problems serverErrors } , Cmd.none ) @@ -189,27 +177,21 @@ update msg model = {-| Helper function for `update`. Updates the form and returns Cmd.none. Useful for recording form fields! -} -updateForm : (Form -> Form) -> Model -> ( Model, Cmd Msg ) -updateForm transform model = - ( { model | form = transform model.form }, Cmd.none ) +updateForm transform model = ( { model | form = transform model.form }, Cmd.none ) -- SUBSCRIPTIONS -subscriptions : Model -> Sub Msg -subscriptions model = - Session.changes GotSession (Session.navKey model.session) +subscriptions model = Session.changes GotSession (Session.navKey model.session) -- EXPORT -toSession : Model -> Session -toSession model = - model.session +toSession model = model.session @@ -231,7 +213,6 @@ type ValidatedField | Password -fieldsToValidate : List ValidatedField fieldsToValidate = [ Username , Email @@ -241,21 +222,14 @@ fieldsToValidate = {-| Trim the form and validate its fields. If there are problems, report them! -} -validate : Form -> Result (List Problem) TrimmedForm validate form = - let - trimmedForm = - trimFields form - in + let trimmedForm = trimFields form in case List.concatMap (validateField trimmedForm) fieldsToValidate of - [] -> - Ok trimmedForm + [] -> Ok trimmedForm - problems -> - Err problems + problems -> Err problems -validateField : TrimmedForm -> ValidatedField -> List Problem validateField (Trimmed form) field = List.map (InvalidEntry field) <| case field of @@ -287,7 +261,6 @@ validateField (Trimmed form) field = {-| Don't trim while the user is typing! That would be super annoying. Instead, trim only on submit. -} -trimFields : Form -> TrimmedForm trimFields form = Trimmed { username = String.trim form.username @@ -300,7 +273,6 @@ trimFields form = -- HTTP -register : TrimmedForm -> Http.Request Viewer register (Trimmed form) = let user = diff --git a/src/Page/Settings.elm b/src/Page/Settings.elm index dc188a905d..dd9fb19d98 100644 --- a/src/Page/Settings.elm +++ b/src/Page/Settings.elm @@ -54,7 +54,6 @@ type Problem | ServerError String -init : Session -> ( Model, Cmd Msg ) init session = ( { session = session , problems = [] @@ -68,7 +67,6 @@ init session = ) -formDecoder : Decoder Form formDecoder = Decode.succeed Form |> required "image" (Decode.map (Maybe.withDefault "") (Decode.nullable Decode.string)) @@ -94,7 +92,6 @@ type ValidForm -- VIEW -view : Model -> { title : String, content : Html Msg } view model = { title = "Settings" , content = @@ -108,17 +105,13 @@ view model = , ul [ class "error-messages" ] (List.map viewProblem model.problems) , case model.status of - Loaded form -> - viewForm cred form + Loaded form -> viewForm cred form - Loading -> - text "" + Loading -> text "" - LoadingSlowly -> - Loading.icon + LoadingSlowly -> Loading.icon - Failed -> - text "Error loading page." + Failed -> text "Error loading page." ] ] ] @@ -129,7 +122,6 @@ view model = } -viewForm : Cred -> Form -> Html Msg viewForm cred form = Html.form [ onSubmit (SubmittedForm cred form) ] [ fieldset [] @@ -187,16 +179,13 @@ viewForm cred form = ] -viewProblem : Problem -> Html msg viewProblem problem = let errorMessage = case problem of - InvalidEntry _ message -> - message + InvalidEntry _ message -> message - ServerError message -> - message + ServerError message -> message in li [] [ text errorMessage ] @@ -218,25 +207,17 @@ type Msg | PassedSlowLoadThreshold -update : Msg -> Model -> ( Model, Cmd Msg ) update msg model = case msg of - CompletedFormLoad (Ok form) -> - ( { model | status = Loaded form } - , Cmd.none - ) + CompletedFormLoad (Ok form) -> ( { model | status = Loaded form }, Cmd.none ) - CompletedFormLoad (Err _) -> - ( { model | status = Failed } - , Cmd.none - ) + CompletedFormLoad (Err _) -> ( { model | status = Failed }, Cmd.none ) SubmittedForm cred form -> case validate form of Ok validForm -> ( { model | status = Loaded form } - , edit cred validForm - |> Http.send CompletedSave + , edit cred validForm |> Http.send CompletedSave ) Err problems -> @@ -244,35 +225,24 @@ update msg model = , Cmd.none ) - EnteredEmail email -> - updateForm (\form -> { form | email = email }) model + EnteredEmail email -> updateForm (\form -> { form | email = email }) model - EnteredUsername username -> - updateForm (\form -> { form | username = username }) model + EnteredUsername username -> updateForm (\form -> { form | username = username }) model - EnteredPassword password -> - updateForm (\form -> { form | password = password }) model + EnteredPassword password -> updateForm (\form -> { form | password = password }) model - EnteredBio bio -> - updateForm (\form -> { form | bio = bio }) model + EnteredBio bio -> updateForm (\form -> { form | bio = bio }) model - EnteredAvatar avatar -> - updateForm (\form -> { form | avatar = avatar }) model + EnteredAvatar avatar -> updateForm (\form -> { form | avatar = avatar }) model CompletedSave (Err error) -> - let - serverErrors = - Api.decodeErrors error - |> List.map ServerError - in + let serverErrors = Api.decodeErrors error |> List.map ServerError in ( { model | problems = List.append model.problems serverErrors } , Cmd.none ) CompletedSave (Ok viewer) -> - ( model - , Viewer.store viewer - ) + ( model, Viewer.store viewer ) GotSession session -> ( { model | session = session } @@ -281,44 +251,33 @@ update msg model = PassedSlowLoadThreshold -> case model.status of - Loading -> - ( { model | status = LoadingSlowly } - , Cmd.none - ) + Loading -> ( { model | status = LoadingSlowly }, Cmd.none ) - _ -> - ( model, Cmd.none ) + _ -> ( model, Cmd.none ) {-| Helper function for `update`. Updates the form and returns Cmd.none. Useful for recording form fields! -} -updateForm : (Form -> Form) -> Model -> ( Model, Cmd msg ) updateForm transform model = case model.status of - Loaded form -> - ( { model | status = Loaded (transform form) }, Cmd.none ) + Loaded form -> ( { model | status = Loaded (transform form) }, Cmd.none ) - _ -> - ( model, Log.error ) + _ -> ( model, Log.error ) -- SUBSCRIPTIONS -subscriptions : Model -> Sub Msg -subscriptions model = - Session.changes GotSession (Session.navKey model.session) +subscriptions model = Session.changes GotSession (Session.navKey model.session) -- EXPORT -toSession : Model -> Session -toSession model = - model.session +toSession model = model.session @@ -328,8 +287,7 @@ toSession model = {-| Marks that we've trimmed the form's fields, so we don't accidentally send it to the server without having trimmed it! -} -type TrimmedForm - = Trimmed Form +type TrimmedForm = Trimmed Form {-| When adding a variant here, add it to `fieldsToValidate` too! @@ -343,7 +301,6 @@ type ValidatedField | Password -fieldsToValidate : List ValidatedField fieldsToValidate = [ Username , Email @@ -353,54 +310,33 @@ fieldsToValidate = {-| Trim the form and validate its fields. If there are problems, report them! -} -validate : Form -> Result (List Problem) TrimmedForm validate form = - let - trimmedForm = - trimFields form - in + let trimmedForm = trimFields form in case List.concatMap (validateField trimmedForm) fieldsToValidate of - [] -> - Ok trimmedForm + [] -> Ok trimmedForm - problems -> - Err problems + problems -> Err problems -validateField : TrimmedForm -> ValidatedField -> List Problem validateField (Trimmed form) field = List.map (InvalidEntry field) <| case field of Username -> - if String.isEmpty form.username then - [ "username can't be blank." ] - - else - [] + if String.isEmpty form.username then [ "username can't be blank." ] else [] Email -> - if String.isEmpty form.email then - [ "email can't be blank." ] - - else - [] + if String.isEmpty form.email then [ "email can't be blank." ] else [] Password -> - let - passwordLength = - String.length form.password - in - if passwordLength > 0 && passwordLength < Viewer.minPasswordChars then - [ "password must be at least " ++ String.fromInt Viewer.minPasswordChars ++ " characters long." ] - - else - [] + let passwordLength = String.length form.password in + if passwordLength > 0 && passwordLength < Viewer.minPasswordChars + then [ "password must be at least " ++ String.fromInt Viewer.minPasswordChars ++ " characters long." ] + else [] {-| Don't trim while the user is typing! That would be super annoying. Instead, trim only on submit. -} -trimFields : Form -> TrimmedForm trimFields form = Trimmed { avatar = String.trim form.avatar @@ -418,16 +354,13 @@ trimFields form = {-| This takes a Valid Form as a reminder that it needs to have been validated first. -} -edit : Cred -> TrimmedForm -> Http.Request Viewer edit cred (Trimmed form) = let encodedAvatar = case form.avatar of - "" -> - Encode.null + "" -> Encode.null - avatar -> - Encode.string avatar + avatar -> Encode.string avatar updates = [ ( "username", Encode.string form.username ) @@ -439,23 +372,13 @@ edit cred (Trimmed form) = encodedUser = Encode.object <| case form.password of - "" -> - updates + "" -> updates - password -> - ( "password", Encode.string password ) :: updates + password -> ( "password", Encode.string password ) :: updates - body = - Encode.object [ ( "user", encodedUser ) ] - |> Http.jsonBody + body = Encode.object [ ( "user", encodedUser ) ] |> Http.jsonBody in Api.settings cred body Viewer.decoder -nothingIfEmpty : String -> Maybe String -nothingIfEmpty str = - if String.isEmpty str then - Nothing - - else - Just str +nothingIfEmpty str = if String.isEmpty str then Nothing else Just str diff --git a/src/PaginatedList.elm b/src/PaginatedList.elm index 55512c53b7..2383e46f39 100644 --- a/src/PaginatedList.elm +++ b/src/PaginatedList.elm @@ -23,21 +23,16 @@ type PaginatedList a -- INFO -values : PaginatedList a -> List a -values (PaginatedList info) = - info.values +values (PaginatedList info) = info.values -total : PaginatedList a -> Int -total (PaginatedList info) = - info.total +total (PaginatedList info) = info.total -- CREATE -fromList : Int -> List a -> PaginatedList a fromList totalCount list = PaginatedList { values = list, total = totalCount } @@ -46,7 +41,6 @@ fromList totalCount list = -- TRANSFORM -map : (a -> a) -> PaginatedList a -> PaginatedList a map transform (PaginatedList info) = PaginatedList { info | values = List.map transform info.values } @@ -57,14 +51,8 @@ map transform (PaginatedList info) = {-| I decided to accept a record here so I don't mess up the argument order of the two Ints. -} -params : - { page : Int, resultsPerPage : Int } - -> List QueryParameter params { page, resultsPerPage } = - let - offset = - (page - 1) * resultsPerPage - in + let offset = (page - 1) * resultsPerPage in [ Url.Builder.string "limit" (String.fromInt resultsPerPage) , Url.Builder.string "offset" (String.fromInt offset) ] diff --git a/src/Profile.elm b/src/Profile.elm index 536582a165..96ff85d125 100644 --- a/src/Profile.elm +++ b/src/Profile.elm @@ -32,21 +32,16 @@ type alias Internals = -- INFO -bio : Profile -> Maybe String -bio (Profile info) = - info.bio +bio (Profile info) = info.bio -avatar : Profile -> Avatar -avatar (Profile info) = - info.avatar +avatar (Profile info) = info.avatar -- SERIALIZATION -decoder : Decoder Profile decoder = Decode.succeed Internals |> required "bio" (Decode.nullable Decode.string) diff --git a/src/Route.elm b/src/Route.elm index 03568fbb4d..54baa75bb2 100644 --- a/src/Route.elm +++ b/src/Route.elm @@ -27,7 +27,6 @@ type Route | EditArticle Slug -parser : Parser (Route -> a) a parser = oneOf [ Parser.map Home Parser.top @@ -46,17 +45,12 @@ parser = -- PUBLIC HELPERS -href : Route -> Attribute msg -href targetRoute = - Attr.href (routeToString targetRoute) +href targetRoute = Attr.href (routeToString targetRoute) -replaceUrl : Nav.Key -> Route -> Cmd msg -replaceUrl key route = - Nav.replaceUrl key (routeToString route) +replaceUrl key route = Nav.replaceUrl key (routeToString route) -fromUrl : Url -> Maybe Route fromUrl url = -- The RealWorld spec treats the fragment like a path. -- This makes it *literally* the path, so we can proceed @@ -69,40 +63,27 @@ fromUrl url = -- INTERNAL -routeToString : Route -> String -routeToString page = - "#/" ++ String.join "/" (routeToPieces page) +routeToString page = "#/" ++ String.join "/" (routeToPieces page) -routeToPieces : Route -> List String routeToPieces page = case page of - Home -> - [] + Home -> [] - Root -> - [] + Root -> [] - Login -> - [ "login" ] + Login -> [ "login" ] - Logout -> - [ "logout" ] + Logout -> [ "logout" ] - Register -> - [ "register" ] + Register -> [ "register" ] - Settings -> - [ "settings" ] + Settings -> [ "settings" ] - Article slug -> - [ "article", Slug.toString slug ] + Article slug -> [ "article", Slug.toString slug ] - Profile username -> - [ "profile", Username.toString username ] + Profile username -> [ "profile", Username.toString username ] - NewArticle -> - [ "editor" ] + NewArticle -> [ "editor" ] - EditArticle slug -> - [ "editor", Slug.toString slug ] + EditArticle slug -> [ "editor", Slug.toString slug ] diff --git a/src/Session.elm b/src/Session.elm index 8b5436e504..2f9a65d24b 100644 --- a/src/Session.elm +++ b/src/Session.elm @@ -24,53 +24,39 @@ type Session -- INFO -viewer : Session -> Maybe Viewer viewer session = case session of - LoggedIn _ val -> - Just val + LoggedIn _ val -> Just val - Guest _ -> - Nothing + Guest _ -> Nothing -cred : Session -> Maybe Cred cred session = case session of - LoggedIn _ val -> - Just (Viewer.cred val) + LoggedIn _ val -> Just (Viewer.cred val) - Guest _ -> - Nothing + Guest _ -> Nothing -navKey : Session -> Nav.Key navKey session = case session of - LoggedIn key _ -> - key + LoggedIn key _ -> key - Guest key -> - key + Guest key -> key -- CHANGES -changes : (Session -> msg) -> Nav.Key -> Sub msg -changes toMsg key = - Api.viewerChanges (\maybeViewer -> toMsg (fromViewer key maybeViewer)) Viewer.decoder +changes toMsg key = Api.viewerChanges (\maybeViewer -> toMsg (fromViewer key maybeViewer)) Viewer.decoder -fromViewer : Nav.Key -> Maybe Viewer -> Session fromViewer key maybeViewer = -- It's stored in localStorage as a JSON String; -- first decode the Value as a String, then -- decode that String as JSON. case maybeViewer of - Just viewerVal -> - LoggedIn key viewerVal + Just viewerVal -> LoggedIn key viewerVal - Nothing -> - Guest key + Nothing -> Guest key diff --git a/src/Timestamp.elm b/src/Timestamp.elm index 07982d692a..3d510a5da9 100644 --- a/src/Timestamp.elm +++ b/src/Timestamp.elm @@ -10,7 +10,6 @@ import Time exposing (Month(..)) -- VIEW -view : Time.Zone -> Time.Posix -> Html msg view timeZone timestamp = span [ class "date" ] [ text (format timeZone timestamp) ] @@ -27,51 +26,36 @@ For more complex date formatting scenarios, here's a nice package: -} -format : Time.Zone -> Time.Posix -> String format zone time = let month = case Time.toMonth zone time of - Jan -> - "January" + Jan -> "January" - Feb -> - "February" + Feb -> "February" - Mar -> - "March" + Mar -> "March" - Apr -> - "April" + Apr -> "April" - May -> - "May" + May -> "May" - Jun -> - "June" + Jun -> "June" - Jul -> - "July" + Jul -> "July" - Aug -> - "August" + Aug -> "August" - Sep -> - "September" + Sep -> "September" - Oct -> - "October" + Oct -> "October" - Nov -> - "November" + Nov -> "November" - Dec -> - "December" + Dec -> "December" - day = - String.fromInt (Time.toDay zone time) + day = String.fromInt (Time.toDay zone time) - year = - String.fromInt (Time.toYear zone time) + year = String.fromInt (Time.toYear zone time) in month ++ " " ++ day ++ ", " ++ year diff --git a/src/Username.elm b/src/Username.elm index a7f17ec62c..57c01fd706 100644 --- a/src/Username.elm +++ b/src/Username.elm @@ -10,38 +10,27 @@ import Url.Parser -- TYPES -type Username - = Username String +type Username = Username String -- CREATE -decoder : Decoder Username -decoder = - Decode.map Username Decode.string +decoder = Decode.map Username Decode.string -- TRANSFORM -encode : Username -> Value -encode (Username username) = - Encode.string username +encode (Username username) = Encode.string username -toString : Username -> String -toString (Username username) = - username +toString (Username username) = username -urlParser : Url.Parser.Parser (Username -> a) a -urlParser = - Url.Parser.custom "USERNAME" (\str -> Just (Username str)) +urlParser = Url.Parser.custom "USERNAME" (\str -> Just (Username str)) -toHtml : Username -> Html msg -toHtml (Username username) = - Html.text username +toHtml (Username username) = Html.text username diff --git a/src/Viewer.elm b/src/Viewer.elm index 58ec00552e..69b02b28a1 100644 --- a/src/Viewer.elm +++ b/src/Viewer.elm @@ -19,48 +19,34 @@ import Username exposing (Username) -- TYPES -type Viewer - = Viewer Avatar Cred +type Viewer = Viewer Avatar Cred -- INFO -cred : Viewer -> Cred -cred (Viewer _ val) = - val +cred (Viewer _ val) = val -username : Viewer -> Username -username (Viewer _ val) = - Api.username val +username (Viewer _ val) = Api.username val -avatar : Viewer -> Avatar -avatar (Viewer val _) = - val +avatar (Viewer val _) = val {-| Passwords must be at least this many characters long! -} -minPasswordChars : Int -minPasswordChars = - 6 +minPasswordChars = 6 -- SERIALIZATION -decoder : Decoder (Cred -> Viewer) decoder = Decode.succeed Viewer |> custom (Decode.field "image" Avatar.decoder) -store : Viewer -> Cmd msg -store (Viewer avatarVal credVal) = - Api.storeCredWith - credVal - avatarVal +store (Viewer avatarVal credVal) = Api.storeCredWith credVal avatarVal