Add a card detail view

This commit is contained in:
Correl Roush 2021-07-16 23:18:06 -04:00
parent b12d0c62ca
commit b0fff226ea
4 changed files with 99 additions and 32 deletions

View file

@ -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]
]

View file

@ -2,6 +2,9 @@
<head>
<title>Bulk Tagging Dashboard</title>
<script type="text/javascript" src="elm.js"></script>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Libre+Baskerville&display=swap" rel="stylesheet">
</head>
<meta charset="utf-8"/>
<body>

View file

@ -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

View file

@ -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 "")
)