Refactor page layout
This commit is contained in:
parent
df9d5e888f
commit
b9511ff229
4 changed files with 249 additions and 175 deletions
|
@ -350,111 +350,6 @@ searchBar model =
|
|||
viewCardBrowser : Model -> E.Element Msg
|
||||
viewCardBrowser model =
|
||||
let
|
||||
viewCard : Card.Copy -> E.Element Msg
|
||||
viewCard copy =
|
||||
let
|
||||
maxDimensions =
|
||||
{ width = 480, height = 680 }
|
||||
in
|
||||
E.el
|
||||
[ Border.rounded 10
|
||||
, E.clip
|
||||
, E.width (E.fill |> E.maximum maxDimensions.width)
|
||||
]
|
||||
<|
|
||||
E.image
|
||||
[ E.width E.fill
|
||||
, E.behindContent <|
|
||||
E.html <|
|
||||
Spinner.view UI.manaSpinner model.spinner
|
||||
]
|
||||
{ src =
|
||||
Url.Builder.crossOrigin "https://api.scryfall.com"
|
||||
[ "cards", copy.card.scryfallId ]
|
||||
[ Url.Builder.string "format" "image"
|
||||
, Url.Builder.string "version" "border_crop"
|
||||
]
|
||||
, description = copy.card.name
|
||||
}
|
||||
|
||||
prices card =
|
||||
Maybe.Extra.values
|
||||
[ Maybe.map (\usd -> { currency = "usd", amount = usd }) <|
|
||||
Maybe.Extra.or card.prices.usd card.prices.usd_foil
|
||||
, Maybe.map (\eur -> { currency = "eur", amount = eur }) <|
|
||||
Maybe.Extra.or card.prices.eur card.prices.eur_foil
|
||||
, Maybe.map (\tix -> { currency = "tix", amount = tix }) card.prices.tix
|
||||
]
|
||||
|
||||
cardDetails copy =
|
||||
let
|
||||
cardImage =
|
||||
if UI.isMobile model.device then
|
||||
E.none
|
||||
|
||||
else
|
||||
E.row [ E.width E.fill ]
|
||||
[ E.el [ E.width <| E.fillPortion 1 ] E.none
|
||||
, E.el [ E.width <| E.fillPortion 5 ] <|
|
||||
viewCard copy
|
||||
, E.el [ E.width <| E.fillPortion 1 ] E.none
|
||||
]
|
||||
in
|
||||
E.column
|
||||
[ E.spacing 20
|
||||
, E.padding 10
|
||||
, E.width E.fill
|
||||
]
|
||||
[ cardImage
|
||||
, E.paragraph [ Font.heavy, Font.size 24, Font.center, Font.color UI.colors.title ]
|
||||
[ E.text copy.card.name ]
|
||||
, E.row [ E.spacing 5, E.centerX ] <|
|
||||
List.map UI.priceBadge (prices copy.card)
|
||||
, E.wrappedRow [ E.spacing 10 ] [ Symbol.text model.symbols 24 copy.card.manaCost, UI.text copy.card.typeLine ]
|
||||
, E.paragraph [] <|
|
||||
List.map (Symbol.text model.symbols 16) (String.lines copy.card.oracleText)
|
||||
]
|
||||
|
||||
details =
|
||||
if UI.isMobile model.device then
|
||||
E.el
|
||||
[ E.spacing 10
|
||||
, E.padding 10
|
||||
, E.height E.fill
|
||||
, E.width E.fill
|
||||
, Background.color UI.colors.sidebar
|
||||
, E.scrollbarY
|
||||
]
|
||||
(model.activeCard
|
||||
|> Maybe.map cardDetails
|
||||
|> Maybe.withDefault E.none
|
||||
)
|
||||
|
||||
else
|
||||
E.el
|
||||
[ E.alignTop
|
||||
, E.width <| E.fillPortion 1
|
||||
, E.height E.fill
|
||||
, E.scrollbarY
|
||||
, Background.color UI.colors.sidebar
|
||||
]
|
||||
(model.activeCard
|
||||
|> Maybe.map cardDetails
|
||||
|> Maybe.withDefault
|
||||
E.none
|
||||
)
|
||||
|
||||
closedetails =
|
||||
Input.button
|
||||
[ E.height (E.px 30)
|
||||
, E.width E.fill
|
||||
, Background.color UI.colors.secondary
|
||||
, Border.rounded 5
|
||||
, Font.color UI.colors.text
|
||||
, Font.center
|
||||
]
|
||||
{ label = E.text "Close", onPress = Just ClearCardDetails }
|
||||
|
||||
navButton text maybeUrl =
|
||||
case maybeUrl of
|
||||
Just url ->
|
||||
|
@ -535,29 +430,7 @@ viewCardBrowser model =
|
|||
Spinner.view UI.manaSpinner model.spinner
|
||||
|
||||
Ready cardPage ->
|
||||
if UI.isMobile model.device then
|
||||
E.column
|
||||
[ E.width E.fill
|
||||
, E.height E.fill
|
||||
, Font.color UI.colors.text
|
||||
, E.scrollbarY
|
||||
]
|
||||
<|
|
||||
case model.activeCard of
|
||||
Just _ ->
|
||||
[ details, closedetails ]
|
||||
|
||||
Nothing ->
|
||||
[ cards cardPage ]
|
||||
|
||||
else
|
||||
E.row
|
||||
[ E.width E.fill
|
||||
, E.height E.fill
|
||||
, Font.color UI.colors.text
|
||||
, E.scrollbarY
|
||||
]
|
||||
[ details, cards cardPage ]
|
||||
cards cardPage
|
||||
|
||||
|
||||
onEnter : msg -> E.Attribute msg
|
||||
|
@ -577,31 +450,144 @@ onEnter msg =
|
|||
)
|
||||
|
||||
|
||||
viewCardDetails model =
|
||||
let
|
||||
viewCard : Card.Copy -> E.Element Msg
|
||||
viewCard copy =
|
||||
let
|
||||
maxDimensions =
|
||||
{ width = 480, height = 680 }
|
||||
in
|
||||
E.el
|
||||
[ Border.rounded 10
|
||||
, E.clip
|
||||
, E.width (E.fill |> E.maximum maxDimensions.width)
|
||||
]
|
||||
<|
|
||||
E.image
|
||||
[ E.width E.fill
|
||||
, E.behindContent <|
|
||||
E.html <|
|
||||
Spinner.view UI.manaSpinner model.spinner
|
||||
]
|
||||
{ src =
|
||||
Url.Builder.crossOrigin "https://api.scryfall.com"
|
||||
[ "cards", copy.card.scryfallId ]
|
||||
[ Url.Builder.string "format" "image"
|
||||
, Url.Builder.string "version" "border_crop"
|
||||
]
|
||||
, description = copy.card.name
|
||||
}
|
||||
|
||||
prices card =
|
||||
Maybe.Extra.values
|
||||
[ Maybe.map (\usd -> { currency = "usd", amount = usd }) <|
|
||||
Maybe.Extra.or card.prices.usd card.prices.usd_foil
|
||||
, Maybe.map (\eur -> { currency = "eur", amount = eur }) <|
|
||||
Maybe.Extra.or card.prices.eur card.prices.eur_foil
|
||||
, Maybe.map (\tix -> { currency = "tix", amount = tix }) card.prices.tix
|
||||
]
|
||||
|
||||
cardDetails copy =
|
||||
let
|
||||
cardImage =
|
||||
if UI.isMobile model.device then
|
||||
E.none
|
||||
|
||||
else
|
||||
E.row [ E.width E.fill ]
|
||||
[ E.el [ E.width <| E.fillPortion 1 ] E.none
|
||||
, E.el [ E.width <| E.fillPortion 5 ] <|
|
||||
viewCard copy
|
||||
, E.el [ E.width <| E.fillPortion 1 ] E.none
|
||||
]
|
||||
in
|
||||
E.column
|
||||
[ E.spacing 20
|
||||
, E.padding 10
|
||||
, E.width E.fill
|
||||
, E.height E.fill
|
||||
, Font.color UI.colors.text
|
||||
]
|
||||
[ cardImage
|
||||
, E.paragraph [ Font.heavy, Font.size 24, Font.center, Font.color UI.colors.title ]
|
||||
[ E.text copy.card.name ]
|
||||
, E.row [ E.spacing 5, E.centerX ] <|
|
||||
List.map UI.priceBadge (prices copy.card)
|
||||
, E.wrappedRow [ E.spacing 10 ] [ Symbol.text model.symbols 24 copy.card.manaCost, UI.text copy.card.typeLine ]
|
||||
, E.paragraph [] <|
|
||||
List.map (Symbol.text model.symbols 16) (String.lines copy.card.oracleText)
|
||||
]
|
||||
|
||||
closedetails =
|
||||
Input.button
|
||||
[ E.height (E.px 30)
|
||||
, E.width E.fill
|
||||
, Background.color UI.colors.secondary
|
||||
, Border.rounded 5
|
||||
, Font.color UI.colors.text
|
||||
, Font.center
|
||||
]
|
||||
{ label = E.text "Close", onPress = Just ClearCardDetails }
|
||||
in
|
||||
if UI.isMobile model.device then
|
||||
E.column
|
||||
[ E.width E.fill
|
||||
, E.height E.fill
|
||||
]
|
||||
[ model.activeCard
|
||||
|> Maybe.map cardDetails
|
||||
|> Maybe.withDefault E.none
|
||||
, closedetails
|
||||
]
|
||||
|
||||
else
|
||||
E.el
|
||||
[ E.alignTop
|
||||
, E.width <| E.fillPortion 1
|
||||
, E.height E.fill
|
||||
, E.scrollbarY
|
||||
, Background.color UI.colors.sidebar
|
||||
]
|
||||
(model.activeCard
|
||||
|> Maybe.map cardDetails
|
||||
|> Maybe.withDefault
|
||||
E.none
|
||||
)
|
||||
|
||||
|
||||
view : Model -> E.Element Msg
|
||||
view model =
|
||||
E.column
|
||||
[ E.width E.fill
|
||||
, E.height E.fill
|
||||
]
|
||||
[ searchBar model
|
||||
, viewCardBrowser model
|
||||
, UI.footer <|
|
||||
let
|
||||
footer =
|
||||
case model.collectionStatistics of
|
||||
Just statistics ->
|
||||
E.el [ E.centerY, Font.size 16, Font.italic ] <|
|
||||
E.text <|
|
||||
String.concat
|
||||
[ String.fromInt statistics.cards
|
||||
, " cards in collection spanning "
|
||||
, String.fromInt statistics.sets
|
||||
, " sets (Estimated value: $"
|
||||
, statistics.value
|
||||
, ")"
|
||||
]
|
||||
Just <|
|
||||
E.el [ E.centerY, Font.size 16, Font.italic ] <|
|
||||
E.text <|
|
||||
String.concat
|
||||
[ String.fromInt statistics.cards
|
||||
, " cards in collection spanning "
|
||||
, String.fromInt statistics.sets
|
||||
, " sets (Estimated value: $"
|
||||
, statistics.value
|
||||
, ")"
|
||||
]
|
||||
|
||||
Nothing ->
|
||||
E.none
|
||||
]
|
||||
Nothing
|
||||
in
|
||||
UI.layout model.device
|
||||
{ toolbar = Just <| searchBar model
|
||||
, sidebar =
|
||||
if UI.isMobile model.device then
|
||||
Maybe.map (\_ -> viewCardDetails model) model.activeCard
|
||||
|
||||
else
|
||||
Just <| viewCardDetails model
|
||||
, content = viewCardBrowser model
|
||||
, footer = footer
|
||||
}
|
||||
|
||||
|
||||
subscriptions : Model -> Sub Msg
|
||||
|
|
|
@ -170,38 +170,43 @@ viewDeck symbols deck =
|
|||
|
||||
view : Model -> E.Element Msg
|
||||
view model =
|
||||
E.column
|
||||
[ E.width E.fill
|
||||
, E.height E.fill
|
||||
, E.clipX
|
||||
]
|
||||
[ case model.deck of
|
||||
Ready deck ->
|
||||
viewDeck model.symbols deck
|
||||
|
||||
Failed ->
|
||||
E.none
|
||||
|
||||
NotFound ->
|
||||
UI.pageNotFound
|
||||
|
||||
Loading ->
|
||||
E.el [ E.height E.fill, E.centerX ] <|
|
||||
E.html <|
|
||||
Spinner.view UI.manaSpinner
|
||||
model.spinner
|
||||
, UI.footer <|
|
||||
let
|
||||
footer =
|
||||
case model.deck of
|
||||
Ready deck ->
|
||||
UI.text <|
|
||||
String.join " "
|
||||
[ String.fromInt (List.sum <| List.map .quantity deck.cards)
|
||||
, "cards"
|
||||
]
|
||||
Just <|
|
||||
UI.text <|
|
||||
String.join " "
|
||||
[ String.fromInt (List.sum <| List.map .quantity deck.cards)
|
||||
, "cards"
|
||||
]
|
||||
|
||||
_ ->
|
||||
Nothing
|
||||
|
||||
content =
|
||||
case model.deck of
|
||||
Ready deck ->
|
||||
viewDeck model.symbols deck
|
||||
|
||||
Failed ->
|
||||
E.none
|
||||
]
|
||||
|
||||
NotFound ->
|
||||
UI.pageNotFound
|
||||
|
||||
Loading ->
|
||||
E.el [ E.height E.fill, E.centerX ] <|
|
||||
E.html <|
|
||||
Spinner.view UI.manaSpinner
|
||||
model.spinner
|
||||
in
|
||||
UI.layout model.device
|
||||
{ toolbar = Nothing
|
||||
, sidebar = Nothing
|
||||
, content = content
|
||||
, footer = footer
|
||||
}
|
||||
|
||||
|
||||
subscriptions : Model -> Sub Msg
|
||||
|
|
|
@ -103,7 +103,13 @@ view model =
|
|||
]
|
||||
[ UI.title deck.name ]
|
||||
in
|
||||
E.column [ E.width E.fill, E.centerX ] <| List.map deckRow deckPage.values
|
||||
UI.layout model.device
|
||||
{ toolbar = Nothing
|
||||
, sidebar = Nothing
|
||||
, content =
|
||||
E.column [ E.width E.fill, E.centerX ] <| List.map deckRow deckPage.values
|
||||
, footer = Nothing
|
||||
}
|
||||
|
||||
|
||||
subscriptions : Model -> Sub Msg
|
||||
|
|
|
@ -5,6 +5,7 @@ module UI exposing
|
|||
, footer
|
||||
, getViewport
|
||||
, isMobile
|
||||
, layout
|
||||
, manaSpinner
|
||||
, pageNotFound
|
||||
, priceBadge
|
||||
|
@ -325,3 +326,79 @@ footer element =
|
|||
, E.alignBottom
|
||||
]
|
||||
element
|
||||
|
||||
|
||||
type alias Page msg =
|
||||
{ toolbar : Maybe (E.Element msg)
|
||||
, sidebar : Maybe (E.Element msg)
|
||||
, content : E.Element msg
|
||||
, footer : Maybe (E.Element msg)
|
||||
}
|
||||
|
||||
|
||||
layout : E.Device -> Page msg -> E.Element msg
|
||||
layout device page =
|
||||
let
|
||||
toolbar : E.Element msg -> E.Element msg
|
||||
toolbar element =
|
||||
E.el
|
||||
[ E.padding 10
|
||||
, E.spacing 10
|
||||
, E.width E.fill
|
||||
, Background.color colors.navBar
|
||||
]
|
||||
element
|
||||
|
||||
sidebar : E.Element msg -> E.Element msg
|
||||
sidebar element =
|
||||
if isMobile device then
|
||||
E.el
|
||||
[ E.height E.fill
|
||||
, E.width E.fill
|
||||
, E.scrollbarY
|
||||
, Background.color colors.sidebar
|
||||
]
|
||||
element
|
||||
|
||||
else
|
||||
E.el
|
||||
[ E.alignTop
|
||||
, E.width <| E.fillPortion 1
|
||||
, E.height E.fill
|
||||
, E.scrollbarY
|
||||
, Background.color colors.sidebar
|
||||
]
|
||||
element
|
||||
|
||||
content : E.Element msg -> E.Element msg
|
||||
content element =
|
||||
E.el
|
||||
[ E.width <| E.fillPortion 3
|
||||
, E.height E.fill
|
||||
]
|
||||
element
|
||||
|
||||
maybe : Maybe (E.Element msg) -> E.Element msg
|
||||
maybe element =
|
||||
Maybe.withDefault E.none element
|
||||
in
|
||||
E.column
|
||||
[ E.width E.fill
|
||||
, E.height E.fill
|
||||
]
|
||||
[ maybe <| Maybe.map toolbar page.toolbar
|
||||
, if isMobile device then
|
||||
Maybe.withDefault page.content page.sidebar
|
||||
|
||||
else
|
||||
E.row
|
||||
[ E.width E.fill
|
||||
, E.height E.fill
|
||||
, Font.color colors.text
|
||||
, E.scrollbarY
|
||||
]
|
||||
[ maybe <| Maybe.map sidebar page.sidebar
|
||||
, content page.content
|
||||
]
|
||||
, footer <| maybe page.footer
|
||||
]
|
||||
|
|
Loading…
Reference in a new issue