Created
May 19, 2016 15:13
-
-
Save szabba/ebc4fb00edbb8db365221762237a1d82 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Html | |
import Html.App as App | |
import Html.Attributes as Attributes | |
import Html.Events as Events | |
import Json.Decode as Json | |
import String | |
main = | |
App.beginnerProgram | |
{ model = | |
{ people = | |
[ ( 1 | |
, { name = "Sanjit" | |
, avatar = Nothing | |
, hearts = 12 | |
} | |
) | |
, ( 2 | |
,{ name = "Anna" | |
, avatar = Nothing | |
, hearts = 9 | |
} | |
) | |
] | |
, form = Nothing | |
} | |
, update = updateList | |
, view = viewList | |
} | |
-- PARENT | |
type alias HeartList = | |
{ people : List (Int, Person) | |
, form : Maybe (Int, Form) | |
} | |
type ListMsg | |
= Delete Int | |
| Forward Int PersonMsg | |
| FormForward FormMsg | |
| Edit Int | |
| Save | |
updateList msg list = | |
let | |
dropIfID idToDrop (id, person) = | |
if idToDrop == id then | |
Nothing | |
else | |
Just (id, person) | |
applyMsgToID target msg (id, person) = | |
if target == id then | |
(id, updatePerson msg person) | |
else | |
(id, person) | |
personToForm (id, { name, avatar }) = | |
( id | |
, { name = name | |
, avatarURL = avatar |> Maybe.withDefault "" | |
} | |
) | |
saveFormTo idFormOpt (id, person) = | |
case idFormOpt of | |
Nothing -> | |
(id, person) | |
Just (target, { name, avatarURL }) -> | |
if target == id then | |
( id | |
, { person | |
| name = name | |
, avatar = | |
if avatarURL /= "" then | |
Just avatarURL | |
else | |
Nothing | |
} | |
) | |
else | |
(id, person) | |
in | |
case msg of | |
Delete idToDrop -> | |
{ list | |
| people = | |
list.people |> List.filterMap (dropIfID idToDrop) | |
} | |
Forward target msg -> | |
{ list | |
| people = | |
list.people |> List.map (applyMsgToID target msg) | |
} | |
FormForward msg -> | |
{ list | |
| form = | |
list.form | |
|> Maybe.map (\(id, form) -> (id, updateForm msg form)) | |
} | |
Edit target -> | |
{ list | |
| form = | |
list.people | |
|> List.filter (fst >> (==) target) | |
|> List.map personToForm | |
|> List.head | |
} | |
Save -> | |
{ list | |
| form = Nothing | |
, people = | |
list.people | |
|> List.map (saveFormTo list.form) | |
} | |
viewList { form, people } = | |
let | |
wrapPerson (id, person) = | |
Html.div | |
[] | |
[ App.map (Forward id) (viewPerson person) | |
, Html.button [ Events.onClick (Delete id) ] [ Html.text "X" ] | |
, Html.button [ Events.onClick (Edit id) ] [ Html.text "E" ] | |
] | |
in | |
Html.div [] <| | |
[ form | |
|> Maybe.map (snd >> viewForm Save FormForward) | |
|> Maybe.withDefault (Html.text "") | |
] | |
++ | |
(List.map wrapPerson people) | |
-- PERSON | |
type alias Person = | |
{ name : String | |
, avatar : Maybe String | |
, hearts : Int | |
} | |
type PersonMsg | |
= SetAvatarAndName { name : String, avatar : Maybe String } | |
| IncrHearts | |
| DecrHearts | |
updatePerson msg person = | |
case msg of | |
SetAvatarAndName { name, avatar } -> | |
{ person | name = name, avatar = avatar } | |
IncrHearts -> | |
{ person | hearts = person.hearts + 1 } | |
DecrHearts -> | |
{ person | hearts = person.hearts - 1 } | |
viewPerson person = | |
Html.div | |
[] | |
[ viewName person | |
, viewAvatar person | |
, viewHearts person | |
] | |
viewAvatar { avatar } = | |
avatar | |
|> Maybe.map (\url -> Html.img [ Attributes.src url ] []) | |
|> Maybe.withDefault (Html.text "") | |
viewName { name } = | |
Html.p [] [ Html.text name ] | |
viewHearts { hearts } = | |
Html.p | |
[] | |
[ Html.button [ Events.onClick DecrHearts ] [ Html.text "-" ] | |
, Html.button [ Events.onClick IncrHearts ] [ Html.text "+" ] | |
, Html.text <| String.repeat hearts " <3 " | |
] | |
-- EDIT FORM | |
type alias Form = | |
{ name : String | |
, avatarURL : String | |
} | |
type FormMsg | |
= FormSetName String | |
| FormSetAvatarURL String | |
updateForm msg form = | |
case msg of | |
FormSetName name -> | |
{ form | name = name } | |
FormSetAvatarURL url -> | |
{ form | avatarURL = url } | |
viewForm onSave wrap { name, avatarURL } = | |
Html.div | |
[] | |
[ Html.p | |
[] | |
[ Html.text "Name:" | |
, Html.input | |
[ Events.onInput (wrap << FormSetName) | |
, Attributes.value name | |
] | |
[] | |
] | |
, Html.p | |
[] | |
[ Html.text "Avatar URL:" | |
, Html.input | |
[ Events.onInput (wrap << FormSetAvatarURL) | |
, Attributes.value avatarURL | |
] | |
[] | |
] | |
, Html.p | |
[] | |
[ Html.button [ Events.onClick onSave ] [ Html.text "Save" ] | |
] | |
] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment