|
|
@@ -4,7 +4,7 @@ import Browser exposing (Document)
|
|
|
import Draft exposing (Draft)
|
|
|
import Html exposing (Html, button, div, img, span, text)
|
|
|
import Html.Attributes exposing (alt, attribute, class, classList, disabled, src)
|
|
|
-import Html.Events exposing (onClick)
|
|
|
+import Html.Events as Events exposing (onClick)
|
|
|
import Html.Keyed as Keyed
|
|
|
import Json.Decode exposing (decodeString)
|
|
|
import Zipper
|
|
|
@@ -26,6 +26,8 @@ type Model
|
|
|
|
|
|
type alias ReadyModel =
|
|
|
{ draft : Draft
|
|
|
+ , highlighted : Maybe Draft.PickCard
|
|
|
+ , flipHighlighted : Bool
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -38,7 +40,13 @@ init : { setData : String, draftData : String } -> ( Model, Cmd Msg )
|
|
|
init flags =
|
|
|
case decodeString Draft.decode flags.draftData of
|
|
|
Ok draftData ->
|
|
|
- ( Ready { draft = draftData }, Cmd.none )
|
|
|
+ ( Ready
|
|
|
+ { draft = draftData
|
|
|
+ , highlighted = Nothing
|
|
|
+ , flipHighlighted = False
|
|
|
+ }
|
|
|
+ , Cmd.none
|
|
|
+ )
|
|
|
|
|
|
Err _ ->
|
|
|
( Error { error = "Error decoding draft data" }, Cmd.none )
|
|
|
@@ -47,6 +55,8 @@ init flags =
|
|
|
type Msg
|
|
|
= Increment
|
|
|
| Decrement
|
|
|
+ | Highlight Draft.PickCard
|
|
|
+ | FlipHighlightedCard
|
|
|
|
|
|
|
|
|
update : Msg -> Model -> ( Model, Cmd Msg )
|
|
|
@@ -60,6 +70,18 @@ update msg model =
|
|
|
Decrement ->
|
|
|
( Ready { mdl | draft = Zipper.moveLeft mdl.draft }, Cmd.none )
|
|
|
|
|
|
+ Highlight card ->
|
|
|
+ ( Ready
|
|
|
+ { mdl
|
|
|
+ | highlighted = Just card
|
|
|
+ , flipHighlighted = False
|
|
|
+ }
|
|
|
+ , Cmd.none
|
|
|
+ )
|
|
|
+
|
|
|
+ FlipHighlightedCard ->
|
|
|
+ ( Ready { mdl | flipHighlighted = not mdl.flipHighlighted }, Cmd.none )
|
|
|
+
|
|
|
Error mdl ->
|
|
|
( Error mdl, Cmd.none )
|
|
|
|
|
|
@@ -80,21 +102,27 @@ view model =
|
|
|
|
|
|
viewReady : ReadyModel -> Html Msg
|
|
|
viewReady model =
|
|
|
- div []
|
|
|
- [ div []
|
|
|
- [ button
|
|
|
- [ onClick Decrement
|
|
|
- , disabled (not (Zipper.hasLeft model.draft))
|
|
|
- ]
|
|
|
- [ text "Previous" ]
|
|
|
- , span [] [ text ("Pick " ++ String.fromInt (Zipper.position model.draft)) ]
|
|
|
- , button
|
|
|
- [ onClick Increment
|
|
|
- , disabled (not (Zipper.hasRight model.draft))
|
|
|
- ]
|
|
|
- [ text "Next" ]
|
|
|
- ]
|
|
|
+ div [ class "grid grid-cols-12 gap-6 h-full bg-slate-100" ]
|
|
|
+ [ viewSidebar model
|
|
|
, viewDraft model.draft
|
|
|
+ , viewHighlightedCard model
|
|
|
+ ]
|
|
|
+
|
|
|
+
|
|
|
+viewSidebar : ReadyModel -> Html Msg
|
|
|
+viewSidebar model =
|
|
|
+ div [ class "col-span-2 p-6 bg-slate-600" ]
|
|
|
+ [ button
|
|
|
+ [ onClick Decrement
|
|
|
+ , disabled (not (Zipper.hasLeft model.draft))
|
|
|
+ ]
|
|
|
+ [ text "Previous" ]
|
|
|
+ , span [] [ text ("Pick " ++ String.fromInt (Zipper.position model.draft)) ]
|
|
|
+ , button
|
|
|
+ [ onClick Increment
|
|
|
+ , disabled (not (Zipper.hasRight model.draft))
|
|
|
+ ]
|
|
|
+ [ text "Next" ]
|
|
|
]
|
|
|
|
|
|
|
|
|
@@ -117,15 +145,41 @@ viewDraft draft =
|
|
|
-- Making this a keyed node forces Elm to recreate each card when the card name changes,
|
|
|
-- so the old image doesn't hang around during loading of the new card image
|
|
|
Keyed.node "div"
|
|
|
- [ class "grid grid-cols-8 w-100 gap-6" ]
|
|
|
+ [ class "col-span-8 grid grid-cols-8 auto-rows-min gap-6 p-6" ]
|
|
|
picks
|
|
|
|
|
|
|
|
|
+viewHighlightedCard : ReadyModel -> Html Msg
|
|
|
+viewHighlightedCard model =
|
|
|
+ div [ class "col-span-2 shadow-xl bg-slate-600 p-6" ]
|
|
|
+ [ case model.highlighted of
|
|
|
+ Just { name, frontImage, backImage } ->
|
|
|
+ let
|
|
|
+ url =
|
|
|
+ case ( model.flipHighlighted, backImage ) of
|
|
|
+ ( True, Just backUrl ) ->
|
|
|
+ backUrl
|
|
|
+
|
|
|
+ _ ->
|
|
|
+ frontImage
|
|
|
+ in
|
|
|
+ div
|
|
|
+ [ onClick FlipHighlightedCard ]
|
|
|
+ [ img [ src url, alt name ] [] ]
|
|
|
+
|
|
|
+ Nothing ->
|
|
|
+ div [] []
|
|
|
+ ]
|
|
|
+
|
|
|
+
|
|
|
viewKeyedCard : Bool -> Draft.PickCard -> ( String, Html Msg )
|
|
|
viewKeyedCard wasChosen { name, frontImage, backImage } =
|
|
|
( name
|
|
|
, div
|
|
|
- [ classList [ ( "border-4 border-green-500", wasChosen ) ]
|
|
|
+ [ classList
|
|
|
+ [ ( "border-4 border-green-500", wasChosen )
|
|
|
+ ]
|
|
|
+ , Events.onMouseEnter (Highlight { name = name, frontImage = frontImage, backImage = backImage })
|
|
|
]
|
|
|
[ img [ src frontImage, alt name ] [] ]
|
|
|
)
|