Ver Fonte

Step through draft

Cadel Watson há 1 ano atrás
pai
commit
b94841ce87
8 ficheiros alterados com 454 adições e 137 exclusões
  1. 112 112
      data/otj.json
  2. 6 3
      elm.json
  3. 8 2
      js/app.js
  4. 79 0
      package-lock.json
  5. 3 0
      package.json
  6. 63 0
      src/Draft.elm
  7. 106 20
      src/Main.elm
  8. 77 0
      src/Zipper.elm

Diff do ficheiro suprimidas por serem muito extensas
+ 112 - 112
data/otj.json


+ 6 - 3
elm.json

@@ -1,15 +1,18 @@
 {
     "type": "application",
-    "source-directories": ["src"],
+    "source-directories": [
+        "src"
+    ],
     "elm-version": "0.19.1",
     "dependencies": {
         "direct": {
+            "NoRedInk/elm-json-decode-pipeline": "1.0.1",
             "elm/browser": "1.0.2",
             "elm/core": "1.0.5",
-            "elm/html": "1.0.0"
+            "elm/html": "1.0.0",
+            "elm/json": "1.1.3"
         },
         "indirect": {
-            "elm/json": "1.1.3",
             "elm/time": "1.0.0",
             "elm/url": "1.0.0",
             "elm/virtual-dom": "1.0.2"

+ 8 - 2
js/app.js

@@ -1,3 +1,9 @@
-import { Elm } from '../src/Main.elm';
+import setData from "../data/otj.json";
+import draftData from "../data/example_draft.json";
 
-Elm.Main.init({ node: document.getElementById('myapp') });
+import {Elm} from '../src/Main.elm';
+
+Elm.Main.init({
+    node: document.getElementById('myapp'),
+    flags: {setData: JSON.stringify(setData), draftData: JSON.stringify(draftData)}
+});

+ 79 - 0
package-lock.json

@@ -7,6 +7,9 @@
     "": {
       "name": "my-program",
       "version": "1.0.0",
+      "dependencies": {
+        "elm-format": "^0.8.7"
+      },
       "devDependencies": {
         "@parcel/transformer-elm": "^2.0.0-rc.0",
         "autoprefixer": "^10.3.5",
@@ -16,6 +19,66 @@
         "tailwindcss": "^2.2.15"
       }
     },
+    "node_modules/@avh4/elm-format-darwin-arm64": {
+      "version": "0.8.7-2",
+      "resolved": "https://registry.npmjs.org/@avh4/elm-format-darwin-arm64/-/elm-format-darwin-arm64-0.8.7-2.tgz",
+      "integrity": "sha512-F5JD44mJ3KX960J5GkXMfh1/dtkXuPcQpX2EToHQKjLTZUfnhZ++ytQQt0gAvrJ0bzoOvhNzjNjUHDA1ruTVbg==",
+      "cpu": [
+        "arm64"
+      ],
+      "optional": true,
+      "os": [
+        "darwin"
+      ]
+    },
+    "node_modules/@avh4/elm-format-darwin-x64": {
+      "version": "0.8.7-2",
+      "resolved": "https://registry.npmjs.org/@avh4/elm-format-darwin-x64/-/elm-format-darwin-x64-0.8.7-2.tgz",
+      "integrity": "sha512-4pfF1cl0KyTion+7Mg4XKM3yi4Yc7vP76Kt/DotLVGJOSag4ISGic1og2mt8RZZ7XArybBmHNyYkiUbe/cEiCw==",
+      "cpu": [
+        "x64"
+      ],
+      "optional": true,
+      "os": [
+        "darwin"
+      ]
+    },
+    "node_modules/@avh4/elm-format-linux-arm64": {
+      "version": "0.8.7-2",
+      "resolved": "https://registry.npmjs.org/@avh4/elm-format-linux-arm64/-/elm-format-linux-arm64-0.8.7-2.tgz",
+      "integrity": "sha512-WkVmuce2zU6s9dupHhqPc886Vaqpea8dZlxv2fpZ4wSzPUbiiKHoHZzoVndMIMTUL0TZukP3Ps0n/lWO5R5+FA==",
+      "cpu": [
+        "arm64"
+      ],
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@avh4/elm-format-linux-x64": {
+      "version": "0.8.7-2",
+      "resolved": "https://registry.npmjs.org/@avh4/elm-format-linux-x64/-/elm-format-linux-x64-0.8.7-2.tgz",
+      "integrity": "sha512-kmncfJrTBjVT94JtQvMf4M5Pn2Yl0sZt3wo7AzgFiDnB/CiZ+KjJyXuWM64NeGiv4MQqzPq65tsFXUH1CIJeiQ==",
+      "cpu": [
+        "x64"
+      ],
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@avh4/elm-format-win32-x64": {
+      "version": "0.8.7-2",
+      "resolved": "https://registry.npmjs.org/@avh4/elm-format-win32-x64/-/elm-format-win32-x64-0.8.7-2.tgz",
+      "integrity": "sha512-sBdMBGq/8mD8Y5C+fIr5vlb3N50yB7S1MfgeAq2QEbvkr/sKrCZI540i43lZDH9gWsfA1w2W8wCe0penFYzsGw==",
+      "cpu": [
+        "x64"
+      ],
+      "optional": true,
+      "os": [
+        "win32"
+      ]
+    },
     "node_modules/@babel/code-frame": {
       "version": "7.24.2",
       "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz",
@@ -2958,6 +3021,22 @@
         "@elm_binaries/win32_x64": "0.19.1-0"
       }
     },
+    "node_modules/elm-format": {
+      "version": "0.8.7",
+      "resolved": "https://registry.npmjs.org/elm-format/-/elm-format-0.8.7.tgz",
+      "integrity": "sha512-sVzFXfWnb+6rzXK+q3e3Ccgr6/uS5mFbFk1VSmigC+x2XZ28QycAa7lS8owl009ALPhRQk+pZ95Eq5ANjpEZsQ==",
+      "hasInstallScript": true,
+      "bin": {
+        "elm-format": "bin/elm-format"
+      },
+      "optionalDependencies": {
+        "@avh4/elm-format-darwin-arm64": "0.8.7-2",
+        "@avh4/elm-format-darwin-x64": "0.8.7-2",
+        "@avh4/elm-format-linux-arm64": "0.8.7-2",
+        "@avh4/elm-format-linux-x64": "0.8.7-2",
+        "@avh4/elm-format-win32-x64": "0.8.7-2"
+      }
+    },
     "node_modules/elm-hot": {
       "version": "1.1.6",
       "resolved": "https://registry.npmjs.org/elm-hot/-/elm-hot-1.1.6.tgz",

+ 3 - 0
package.json

@@ -12,5 +12,8 @@
     "parcel": "latest",
     "postcss": "^8.3.7",
     "tailwindcss": "^2.2.15"
+  },
+  "dependencies": {
+    "elm-format": "^0.8.7"
   }
 }

+ 63 - 0
src/Draft.elm

@@ -0,0 +1,63 @@
+module Draft exposing (Draft, Pick, PickCard, decode)
+
+import Json.Decode as Decode exposing (Decoder)
+import Json.Decode.Pipeline as Decode
+import Zipper
+
+
+type alias Draft =
+    Zipper.Zipper Pick
+
+
+type alias Pick =
+    { chosen : PickCard
+    , available : List PickCard
+    }
+
+
+type alias PickCard =
+    { name : String
+    , frontImage : String
+    , backImage : Maybe String
+    }
+
+
+decode : Decoder Draft
+decode =
+    Decode.field "picks" (Decode.list decodePick)
+        |> Decode.map Zipper.fromList
+        |> Decode.andThen
+            (\z ->
+                case z of
+                    Just x ->
+                        Decode.succeed x
+
+                    Nothing ->
+                        Decode.fail "No picks in draft data"
+            )
+
+
+decodePick : Decoder Pick
+decodePick =
+    Decode.succeed Pick
+        |> Decode.required "pick" decodeCard
+        |> Decode.required "available" (Decode.list decodeCard)
+
+
+decodeCard : Decoder PickCard
+decodeCard =
+    Decode.succeed PickCard
+        |> Decode.required "name" Decode.string
+        |> Decode.required "image_url" Decode.string
+        |> Decode.required
+            "url_back"
+            (Decode.string
+                |> Decode.map
+                    (\s ->
+                        if s == "" then
+                            Nothing
+
+                        else
+                            Just s
+                    )
+            )

+ 106 - 20
src/Main.elm

@@ -1,22 +1,47 @@
 module Main exposing (..)
 
-import Browser
-import Html exposing (Html, button, div, text)
-import Html.Attributes exposing (class)
+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.Keyed as Keyed
+import Json.Decode exposing (decodeString)
+import Zipper
 
 
 main =
-    Browser.sandbox { init = init, update = update, view = view }
+    Browser.document
+        { init = init
+        , update = update
+        , view = view
+        , subscriptions = \_ -> Sub.none
+        }
 
 
-type alias Model =
-    Int
+type Model
+    = Ready ReadyModel
+    | Error ErrorModel
 
 
-init : Model
-init =
-    0
+type alias ReadyModel =
+    { draft : Draft
+    }
+
+
+type alias ErrorModel =
+    { error : String
+    }
+
+
+init : { setData : String, draftData : String } -> ( Model, Cmd Msg )
+init flags =
+    case decodeString Draft.decode flags.draftData of
+        Ok draftData ->
+            ( Ready { draft = draftData }, Cmd.none )
+
+        Err _ ->
+            ( Error { error = "Error decoding draft data" }, Cmd.none )
 
 
 type Msg
@@ -24,20 +49,81 @@ type Msg
     | Decrement
 
 
-update : Msg -> Model -> Model
+update : Msg -> Model -> ( Model, Cmd Msg )
 update msg model =
-    case msg of
-        Increment ->
-            model + 1
+    case model of
+        Ready mdl ->
+            case msg of
+                Increment ->
+                    ( Ready { mdl | draft = Zipper.moveRight mdl.draft }, Cmd.none )
 
-        Decrement ->
-            model - 1
+                Decrement ->
+                    ( Ready { mdl | draft = Zipper.moveLeft mdl.draft }, Cmd.none )
 
+        Error mdl ->
+            ( Error mdl, Cmd.none )
 
-view : Model -> Html Msg
+
+view : Model -> Document Msg
 view model =
-    div [ class "m-10 text-4xl" ]
-        [ button [ onClick Decrement ] [ text "-" ]
-        , div [ class "text-green-400" ] [ text (String.fromInt model) ]
-        , button [ onClick Increment ] [ text "+" ]
+    { title = "Drafter"
+    , body =
+        [ case model of
+            Ready mdl ->
+                viewReady mdl
+
+            Error mdl ->
+                viewError mdl
+        ]
+    }
+
+
+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" ]
+            ]
+        , viewDraft model.draft
+        ]
+
+
+viewError : ErrorModel -> Html Msg
+viewError model =
+    div [ class "error" ]
+        [ text model.error ]
+
+
+viewDraft : Draft -> Html Msg
+viewDraft draft =
+    let
+        chosen =
+            (Zipper.focus draft).chosen
+
+        picks =
+            List.map (\c -> viewKeyedCard (chosen.name == c.name) c)
+                (Zipper.focus draft).available
+    in
+    Keyed.node "div"
+        [ class "grid grid-cols-8 w-100 gap-6" ]
+        picks
+
+
+viewKeyedCard : Bool -> Draft.PickCard -> ( String, Html Msg )
+viewKeyedCard wasChosen { name, frontImage, backImage } =
+    ( name
+    , div
+        [ classList [ ( "border-4 border-green-500", wasChosen ) ]
         ]
+        [ img [ src frontImage, alt name ] [] ]
+    )

+ 77 - 0
src/Zipper.elm

@@ -0,0 +1,77 @@
+module Zipper exposing (..)
+
+import List exposing ((::))
+
+
+type Zipper a
+    = Zipper (List a) a (List a)
+
+
+fromList : List a -> Maybe (Zipper a)
+fromList list =
+    case list of
+        x :: xs ->
+            Just <| Zipper [] x xs
+
+        _ ->
+            Nothing
+
+
+toList : Zipper a -> List a
+toList (Zipper l f r) =
+    List.reverse l ++ f :: r
+
+
+moveLeft : Zipper a -> Zipper a
+moveLeft z =
+    case z of
+        Zipper (l :: ls) f rs ->
+            Zipper ls l (f :: rs)
+
+        _ ->
+            z
+
+
+moveRight : Zipper a -> Zipper a
+moveRight z =
+    case z of
+        Zipper ls f (r :: rs) ->
+            Zipper (f :: ls) r rs
+
+        _ ->
+            z
+
+
+length : Zipper a -> Int
+length (Zipper ls _ rs) =
+    List.length ls + 1 + List.length rs
+
+
+position : Zipper a -> Int
+position (Zipper ls _ _) =
+    List.length ls
+
+
+left : Zipper a -> List a
+left (Zipper ls _ _) =
+    ls
+
+
+right : Zipper a -> List a
+right (Zipper _ _ rs) =
+    rs
+
+
+hasLeft : Zipper a -> Bool
+hasLeft (Zipper ls _ _) =
+    not <| List.isEmpty ls
+
+
+hasRight : Zipper a -> Bool
+hasRight (Zipper _ _ rs) =
+    not <| List.isEmpty rs
+
+
+focus : Zipper a -> a
+focus (Zipper _ f _) =
+    f

Alguns ficheiros não foram mostrados porque muitos ficheiros mudaram neste diff