From b0fff226ea9cab0a393bb30be0ae34cfeef5b490 Mon Sep 17 00:00:00 2001 From: Correl Date: Fri, 16 Jul 2021 23:18:06 -0400 Subject: [PATCH] Add a card detail view --- tutor/server.py | 1 + www/public/index.html | 3 ++ www/src/App.elm | 122 +++++++++++++++++++++++++++++++----------- www/src/Card.elm | 5 ++ 4 files changed, 99 insertions(+), 32 deletions(-) diff --git a/tutor/server.py b/tutor/server.py index e339bdb..bb5c45e 100644 --- a/tutor/server.py +++ b/tutor/server.py @@ -90,6 +90,7 @@ class SearchHandler(tornado.web.RequestHandler): "color_identity": tutor.models.Color.to_string( card.color_identity ), + "oracle_text": card.oracle_text, } for card in cards[:limit] ] diff --git a/www/public/index.html b/www/public/index.html index 645d6cd..1a6517a 100644 --- a/www/public/index.html +++ b/www/public/index.html @@ -2,6 +2,9 @@ Bulk Tagging Dashboard + + + diff --git a/www/src/App.elm b/www/src/App.elm index 15ba5b8..995e1ab 100644 --- a/www/src/App.elm +++ b/www/src/App.elm @@ -10,6 +10,7 @@ import Dict import Element as E import Element.Background as Background import Element.Border as Border +import Element.Events as Events import Element.Font as Font import Element.Input as Input import Html.Events @@ -24,7 +25,7 @@ import Url.Parser exposing ((), ()) import Url.Parser.Query -type alias Window = +type alias Dimensions = { width : Int , height : Int } @@ -38,22 +39,25 @@ type alias Criteria = type alias Model = { navigationKey : Browser.Navigation.Key - , viewport : Window + , viewport : Dimensions , spinner : Spinner.Model , criteria : Criteria , cardPage : CardPage + , activeCard : Maybe Card.Card } type Msg = UrlChanged Url.Url - | ViewportChanged Window + | ViewportChanged Dimensions | LinkClicked Browser.UrlRequest | SpinnerMsg Spinner.Msg | UpdateCriteria CriteriaMsg | Search | GetPage Url.Url | FoundCards (Result Http.Error (Paginated.Page Card.Card)) + | ShowCardDetails Card.Card + | ClearCardDetails type CriteriaMsg @@ -181,6 +185,7 @@ init _ url key = , spinner = Spinner.init , criteria = criteria , cardPage = Loading Paginated.empty + , activeCard = Nothing } , Cmd.batch [ search criteria @@ -262,6 +267,12 @@ update msg model = FoundCards (Err _) -> ( model, Cmd.none ) + ShowCardDetails card -> + ( { model | activeCard = Just card }, Cmd.none ) + + ClearCardDetails -> + ( { model | activeCard = Nothing }, Cmd.none ) + colors = let @@ -288,36 +299,51 @@ viewCardBrowser : Model -> E.Element Msg viewCardBrowser model = let cardWidth = - -- 50% of the Scryfall border_crop image width - 240 + -- 30% of the Scryfall border_crop image width (480) + 144 cardHeight = - -- 50% of the Scryfall border_crop image height - 340 + -- 30% of the Scryfall border_crop image height (680) + 204 cardSpacing = - 10 + 5 - navigationButtonWidth = - 100 + availableWidth = + (model.viewport.width // 5) * 4 cardColumns = - -- Either 3, 6, or 9, based on viewport width + -- Either 6 or 9, based on viewport width let availableColumns = - (model.viewport.width - (2 * navigationButtonWidth)) + availableWidth // (cardWidth + cardSpacing) in - (max 3 >> min 9) (availableColumns // 3 * 3) + (max 6 >> min 9) (availableColumns // 3 * 3) cardRows = 18 // cardColumns - viewCard cardModel = - E.el [ Border.rounded 10, E.clip, E.width <| E.px cardWidth, E.height <| E.px cardHeight ] <| + minInfoWidth = + 1230 // 5 + + minBrowserWidth = + minInfoWidth * 4 + + viewCard : Dimensions -> Card.Card -> E.Element Msg + viewCard dimensions cardModel = + E.el + [ Border.rounded 10 + , E.clip + , E.width <| E.px dimensions.width + , E.height <| E.px dimensions.height + , Events.onMouseEnter <| ShowCardDetails cardModel + , Events.onMouseLeave <| ClearCardDetails + ] + <| E.image - [ E.width <| E.px cardWidth - , E.height <| E.px cardHeight + [ E.width <| E.px dimensions.width + , E.height <| E.px dimensions.height , E.behindContent <| E.html <| Spinner.view manaSpinner model.spinner @@ -336,15 +362,27 @@ viewCardBrowser model = Just url -> Input.button [ E.height E.fill - , E.width (E.px navigationButtonWidth) + , E.width E.fill , Background.color colors.primary + , Border.rounded 5 , Font.color colors.text , Font.center ] { label = E.text text, onPress = Just (GetPage url) } Nothing -> - E.el [ E.width (E.px navigationButtonWidth) ] E.none + E.el [ E.width E.fill ] E.none + + cardDetails card = + E.column + [ E.spacing 20 + , E.padding 10 + ] + <| + E.el [ E.centerX ] (viewCard { width = 192, height = 272 } card) + :: E.paragraph [ Font.heavy, Font.size 24, Font.center ] [ E.text card.name ] + :: List.map (\text -> E.paragraph [ Font.size 16 ] [ E.text text ]) + (String.lines card.oracleText) in case model.cardPage of Failed -> @@ -371,19 +409,39 @@ viewCardBrowser model = Ready cardPage -> E.row - [ E.width E.fill - , E.height (E.px (cardRows * (cardHeight + cardSpacing))) - , E.centerX - ] - <| - [ navButton "←" cardPage.prev - , E.wrappedRow - [ E.width (E.px (cardColumns * (cardWidth + cardSpacing))) - , E.centerX - , E.spacing cardSpacing + [ E.centerX + , E.height (E.px (3 * (cardHeight + cardSpacing))) + , Font.family + [ Font.typeface + "Libre Baskerville" + , Font.serif + ] + ] + [ E.column + [ E.height E.fill + , E.width <| E.px minInfoWidth + , Font.color colors.text + ] + [ Maybe.map cardDetails model.activeCard |> Maybe.withDefault E.none ] + , E.column + [ E.width (E.fill |> E.minimum minBrowserWidth) + , E.height E.fill + , E.spacing 10 + ] + <| + [ E.wrappedRow + [ E.width (E.px (cardColumns * (cardWidth + cardSpacing))) + , E.spacing cardSpacing + , E.paddingEach { left = cardSpacing // 2, top = 0, bottom = 0, right = 0 } + , E.centerX + , E.centerY + ] + (List.map (viewCard { width = cardWidth, height = cardHeight }) cardPage.values) + , E.row [ E.width E.fill, E.spacing 20 ] + [ navButton "←" cardPage.prev + , navButton "→" cardPage.next + ] ] - (List.map viewCard cardPage.values) - , navButton "→" cardPage.next ] @@ -409,7 +467,7 @@ view model = { title = "Tutor" , body = [ E.layout [ Background.color colors.background ] <| - E.column [ E.width E.fill, E.spacing 20 ] + E.column [ E.width (E.fill |> E.minimum 1280), E.spacing 20 ] [ E.row [ E.padding 10 , E.spacing 10 diff --git a/www/src/Card.elm b/www/src/Card.elm index 1f6c08f..268c866 100644 --- a/www/src/Card.elm +++ b/www/src/Card.elm @@ -9,6 +9,7 @@ type alias Card = , name : String , setCode : String , rarity : String + , oracleText : String } @@ -19,3 +20,7 @@ decode = |> JDP.required "name" Json.Decode.string |> JDP.required "set_code" Json.Decode.string |> JDP.required "rarity" Json.Decode.string + |> JDP.required "oracle_text" + (Json.Decode.nullable Json.Decode.string + |> Json.Decode.map (Maybe.withDefault "") + )