From 740f488460c5e00d332169ab63bef9c5e483f915 Mon Sep 17 00:00:00 2001 From: Correl Roush Date: Tue, 10 Jan 2023 23:12:33 -0500 Subject: [PATCH] Group cards by type in deck editor --- tutor/server.py | 1 + www/src/Card.elm | 4 ++ www/src/Pages/DeckEditor.elm | 86 +++++++++++++++++++++++++++++++----- 3 files changed, 79 insertions(+), 12 deletions(-) diff --git a/tutor/server.py b/tutor/server.py index 0b682ed..372eaa1 100644 --- a/tutor/server.py +++ b/tutor/server.py @@ -77,6 +77,7 @@ class JSONEncoder(json.JSONEncoder): "collector_number": card.collector_number, "rarity": str(card.rarity), "color_identity": tutor.models.Color.to_string(card.color_identity), + "type_line": card.type_line, "oracle_text": card.oracle_text, "prices": { "usd": price(card.price_usd), diff --git a/www/src/Card.elm b/www/src/Card.elm index 74afc9a..be4bac5 100644 --- a/www/src/Card.elm +++ b/www/src/Card.elm @@ -16,6 +16,7 @@ type alias Prices = type alias Oracle = { oracleId : String , name : String + , typeLine : String , oracleText : String } @@ -25,6 +26,7 @@ type alias Card = , name : String , setCode : String , rarity : String + , typeLine : String , oracleText : String , prices : Prices } @@ -42,6 +44,7 @@ decodeOracle = Json.Decode.succeed Oracle |> JDP.required "oracle_id" Json.Decode.string |> JDP.required "name" Json.Decode.string + |> JDP.required "type_line" Json.Decode.string |> JDP.required "oracle_text" (Json.Decode.nullable Json.Decode.string |> Json.Decode.map (Maybe.withDefault "") @@ -55,6 +58,7 @@ decode = |> JDP.required "name" Json.Decode.string |> JDP.required "set_code" Json.Decode.string |> JDP.required "rarity" Json.Decode.string + |> JDP.required "type_line" Json.Decode.string |> JDP.required "oracle_text" (Json.Decode.nullable Json.Decode.string |> Json.Decode.map (Maybe.withDefault "") diff --git a/www/src/Pages/DeckEditor.elm b/www/src/Pages/DeckEditor.elm index 0e19a3e..9199bd6 100644 --- a/www/src/Pages/DeckEditor.elm +++ b/www/src/Pages/DeckEditor.elm @@ -39,6 +39,52 @@ type Deck | Failed +type alias Grouped = + { creatures : List Deck.Card + , instants : List Deck.Card + , sorceries : List Deck.Card + , enchantments : List Deck.Card + , lands : List Deck.Card + } + + +type alias Group = + { label : String, cards : List Deck.Card } + + +groups : List Deck.Card -> List Group +groups cards = + let + last : List a -> Maybe a + last xs = + List.reverse xs |> List.head + + typeOf : Deck.Card -> String + typeOf card = + String.split "—" card.card.typeLine + |> List.head + |> Maybe.andThen (\types -> String.words types |> last) + |> Maybe.withDefault "" + + isA : String -> Deck.Card -> Bool + isA cardType card = + typeOf card == cardType + + isEmpty : Group -> Bool + isEmpty group = + List.isEmpty group.cards + in + List.filter (\l -> not <| isEmpty l) + [ Group "Creatures" <| List.filter (isA "Creature") cards + , Group "Planeswalkers" <| List.filter (isA "Planeswalker") cards + , Group "Instants" <| List.filter (isA "Instant") cards + , Group "Sorceries" <| List.filter (isA "Sorcery") cards + , Group "Enchantments" <| List.filter (isA "Enchantment") cards + , Group "Artifacts" <| List.filter (isA "Artifact") cards + , Group "Lands" <| List.filter (isA "Land") cards + ] + + init : Browser.Navigation.Key -> Url.Url -> E.Device -> Int -> ( Model, Cmd Msg ) init key url device deckId = ( { navigationKey = key @@ -73,19 +119,35 @@ update msg model = viewDeck : Deck.Deck -> E.Element Msg viewDeck deck = - E.column [ E.height E.fill, E.width E.fill, E.centerX, E.spacing 5 ] <| + let + viewGroup group = + E.column [ E.spacing 10 ] + [ E.paragraph [ Font.heavy ] [ UI.title group.label ] + , E.wrappedRow [ E.spacing 10 ] <| + List.map + (\dc -> + UI.cardRow + { foil = False + , subtitle = "x" ++ String.fromInt dc.quantity + } + [ E.width <| E.px 400, E.clipX, Background.color UI.colors.background ] + dc.card + ) + group.cards + ] + in + E.column [ E.height E.fill, E.centerX, E.spacing 5 ] <| [ E.paragraph [ Font.heavy, Font.size 24, Font.center ] [ UI.title deck.name ] - , E.wrappedRow [ E.width E.fill, E.height E.fill, E.scrollbarY ] <| - List.map - (\dc -> - UI.cardRow - { foil = False - , subtitle = "x" ++ String.fromInt dc.quantity - } - [ E.width <| E.px 400, E.clipX ] - dc.card - ) - deck.cards + , E.column + [ E.height E.fill + , E.spacing 10 + , Background.color UI.colors.sidebar + , E.scrollbarY + , E.clipX + ] + <| + List.map viewGroup <| + groups deck.cards ]