Update part1
This commit is contained in:
@@ -19,7 +19,7 @@
|
||||
"evancz/url-parser": "2.0.1 <= v < 3.0.0",
|
||||
"lukewestby/elm-http-builder": "5.1.0 <= v < 6.0.0",
|
||||
"mgold/elm-date-format": "1.3.0 <= v < 2.0.0",
|
||||
"rtfeldman/elm-validate": "2.0.0 <= v < 3.0.0",
|
||||
"rtfeldman/elm-validate": "3.0.0 <= v < 4.0.0",
|
||||
"rtfeldman/selectlist": "1.0.0 <= v < 2.0.0"
|
||||
},
|
||||
"elm-version": "0.18.0 <= v < 0.19.0"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"rtfeldman/elm-validate": "2.0.0",
|
||||
"rtfeldman/elm-validate": "3.0.0",
|
||||
"rtfeldman/selectlist": "1.0.0",
|
||||
"elm-lang/navigation": "2.1.0",
|
||||
"elm-lang/virtual-dom": "2.0.4",
|
||||
|
||||
@@ -3,7 +3,7 @@ module Data.Article.Author exposing (Author, decoder)
|
||||
import Data.User as User exposing (Username)
|
||||
import Data.UserPhoto as UserPhoto exposing (UserPhoto)
|
||||
import Json.Decode as Decode exposing (Decoder)
|
||||
import Json.Decode.Pipeline exposing (custom, decode, required)
|
||||
import Json.Decode.Pipeline exposing (custom, decode, optional, required)
|
||||
|
||||
|
||||
decoder : Decoder Author
|
||||
@@ -12,7 +12,7 @@ decoder =
|
||||
|> required "username" User.usernameDecoder
|
||||
|> required "bio" (Decode.nullable Decode.string)
|
||||
|> required "image" UserPhoto.decoder
|
||||
|> required "following" Decode.bool
|
||||
|> optional "following" Decode.bool False
|
||||
|
||||
|
||||
type alias Author =
|
||||
|
||||
@@ -4,7 +4,7 @@ import Data.AuthToken as AuthToken exposing (AuthToken)
|
||||
import Data.UserPhoto as UserPhoto exposing (UserPhoto)
|
||||
import Html exposing (Html)
|
||||
import Json.Decode as Decode exposing (Decoder)
|
||||
import Json.Decode.Pipeline exposing (decode, required)
|
||||
import Json.Decode.Pipeline exposing (decode, optional, required)
|
||||
import Json.Encode as Encode exposing (Value)
|
||||
import Json.Encode.Extra as EncodeExtra
|
||||
import UrlParser
|
||||
@@ -16,8 +16,6 @@ type alias User =
|
||||
, username : Username
|
||||
, bio : Maybe String
|
||||
, image : UserPhoto
|
||||
, createdAt : String
|
||||
, updatedAt : String
|
||||
}
|
||||
|
||||
|
||||
@@ -33,8 +31,6 @@ decoder =
|
||||
|> required "username" usernameDecoder
|
||||
|> required "bio" (Decode.nullable Decode.string)
|
||||
|> required "image" UserPhoto.decoder
|
||||
|> required "createdAt" Decode.string
|
||||
|> required "updatedAt" Decode.string
|
||||
|
||||
|
||||
encode : User -> Value
|
||||
@@ -45,8 +41,6 @@ encode user =
|
||||
, ( "username", encodeUsername user.username )
|
||||
, ( "bio", EncodeExtra.maybe Encode.string user.bio )
|
||||
, ( "image", UserPhoto.encode user.image )
|
||||
, ( "createdAt", Encode.string user.createdAt )
|
||||
, ( "updatedAt", Encode.string user.updatedAt )
|
||||
]
|
||||
|
||||
|
||||
|
||||
@@ -39,7 +39,15 @@ photoToUrl : UserPhoto -> String
|
||||
photoToUrl (UserPhoto maybeUrl) =
|
||||
case maybeUrl of
|
||||
Nothing ->
|
||||
"https://static.productionready.io/images/smiley-cyrus.jpg"
|
||||
defaultPhotoUrl
|
||||
|
||||
Just "" ->
|
||||
defaultPhotoUrl
|
||||
|
||||
Just url ->
|
||||
url
|
||||
|
||||
|
||||
defaultPhotoUrl : String
|
||||
defaultPhotoUrl =
|
||||
"/assets/images/smiley-cyrus.jpg"
|
||||
|
||||
@@ -4,7 +4,7 @@ import Data.Article as Article exposing (Article, Body)
|
||||
import Data.Session exposing (Session)
|
||||
import Data.User exposing (User)
|
||||
import Html exposing (..)
|
||||
import Html.Attributes exposing (attribute, class, disabled, href, id, placeholder, type_, value)
|
||||
import Html.Attributes exposing (attribute, class, defaultValue, disabled, href, id, placeholder, type_)
|
||||
import Html.Events exposing (onInput, onSubmit)
|
||||
import Http
|
||||
import Page.Errored exposing (PageLoadError, pageLoadError)
|
||||
@@ -102,26 +102,26 @@ viewForm model =
|
||||
[ class "form-control-lg"
|
||||
, placeholder "Article Title"
|
||||
, onInput SetTitle
|
||||
, value model.title
|
||||
, defaultValue model.title
|
||||
]
|
||||
[]
|
||||
, Form.input
|
||||
[ placeholder "What's this article about?"
|
||||
, onInput SetDescription
|
||||
, value model.description
|
||||
, defaultValue model.description
|
||||
]
|
||||
[]
|
||||
, Form.textarea
|
||||
[ placeholder "Write your article (in markdown)"
|
||||
, attribute "rows" "8"
|
||||
, onInput SetBody
|
||||
, value model.body
|
||||
, defaultValue model.body
|
||||
]
|
||||
[]
|
||||
, Form.input
|
||||
[ placeholder "Enter tags"
|
||||
, onInput SetTags
|
||||
, value (String.join " " model.tags)
|
||||
, defaultValue (String.join " " model.tags)
|
||||
]
|
||||
[]
|
||||
, button [ class "btn btn-lg pull-xs-right btn-primary", disabled model.isSaving ]
|
||||
|
||||
@@ -186,10 +186,23 @@ modelValidator =
|
||||
Validate.all
|
||||
[ ifBlank .username ( Username, "username can't be blank." )
|
||||
, ifBlank .email ( Email, "email can't be blank." )
|
||||
, ifBlank .password ( Password, "password can't be blank." )
|
||||
, Validate.fromErrors passwordLength
|
||||
]
|
||||
|
||||
|
||||
minPasswordChars : Int
|
||||
minPasswordChars =
|
||||
6
|
||||
|
||||
|
||||
passwordLength : Model -> List Error
|
||||
passwordLength { password } =
|
||||
if String.length password < minPasswordChars then
|
||||
[ ( Password, "password must be at least " ++ toString minPasswordChars ++ " characters long." ) ]
|
||||
else
|
||||
[]
|
||||
|
||||
|
||||
errorsDecoder : Decoder (List String)
|
||||
errorsDecoder =
|
||||
decode (\email username password -> List.concat [ email, username, password ])
|
||||
|
||||
@@ -7,12 +7,22 @@ import Data.Article exposing (Article)
|
||||
import Data.UserPhoto as UserPhoto exposing (UserPhoto)
|
||||
import Date.Format
|
||||
import Html exposing (..)
|
||||
import Html.Attributes exposing (attribute, class, classList, href, id, src)
|
||||
import Html.Attributes exposing (attribute, class, classList, href, id, placeholder, src)
|
||||
import Route exposing (Route)
|
||||
import Views.Article.Favorite as Favorite
|
||||
import Views.Author
|
||||
|
||||
|
||||
-- VIEWS --
|
||||
|
||||
|
||||
{-| Some pages want to view just the timestamp, not the whole article.
|
||||
-}
|
||||
viewTimestamp : Article a -> Html msg
|
||||
viewTimestamp article =
|
||||
span [ class "date" ] [ text (formattedTimestamp article) ]
|
||||
|
||||
|
||||
view : (Article a -> msg) -> Article a -> Html msg
|
||||
view toggleFavorite article =
|
||||
let
|
||||
@@ -25,7 +35,7 @@ view toggleFavorite article =
|
||||
[ img [ UserPhoto.src author.image ] [] ]
|
||||
, div [ class "info" ]
|
||||
[ Views.Author.view author.username
|
||||
, viewTimestamp article
|
||||
, span [ class "date" ] [ text (formattedTimestamp article) ]
|
||||
]
|
||||
, Favorite.button
|
||||
toggleFavorite
|
||||
@@ -41,9 +51,8 @@ view toggleFavorite article =
|
||||
]
|
||||
|
||||
|
||||
viewTimestamp : Article a -> Html msg
|
||||
viewTimestamp article =
|
||||
span [ class "date" ] [ text (formattedTimestamp article) ]
|
||||
|
||||
-- INTERNAL --
|
||||
|
||||
|
||||
formattedTimestamp : Article a -> String
|
||||
|
||||
Reference in New Issue
Block a user