diff --git a/web/src/crate_web/pages/crate.gleam b/web/src/crate_web/pages/crate.gleam index c24cffe..b17389f 100644 --- a/web/src/crate_web/pages/crate.gleam +++ b/web/src/crate_web/pages/crate.gleam @@ -218,47 +218,20 @@ fn grid(items: List(Entry), view: String) -> Element(Msg) { html.div([attr.class("grid")], list.map(items, card(_, view))) } -/// `cov.cover_card` always renders a status badge; inlined here (rather than -/// reused) so the badge can be dropped where it would just repeat the filter -/// chip already selected above the grid. fn card(entry: Entry, view: String) -> Element(Msg) { let snap = model.entry_snapshot(entry) - let seed = snap.title <> snap.artist_display - html.a( - [ - attr.class("cover-card"), - attr.href(route.to_path(Record(entry.entry_id))), - ], - [ - html.div( - [ - attr.class( - "cover-tile cover-tile--card cover-tile--" <> cov.cover_color(seed), - ), - ], - [cov.tile_art(snap.thumb_url, snap.title), card_badge(entry, view)], - ), - html.div([attr.class("cover-card__info")], [ - html.span([attr.class("cover-card__title")], [text(snap.title)]), - html.span([attr.class("cover-card__artist")], [ - text(snap.artist_display), - ]), - html.span([attr.class("cover-card__fmt")], [text(cov.format_line(snap))]), - ]), - ], + cov.cover_card( + route.to_path(Record(entry.entry_id)), + snap.title <> snap.artist_display, + entry.status, + snap.title, + snap.artist_display, + cov.format_line(snap), + snap.thumb_url, + !badge_redundant(entry.status, view), ) } -fn card_badge(entry: Entry, view: String) -> Element(Msg) { - case badge_redundant(entry.status, view) { - True -> element.none() - False -> - html.span([attr.class("cover-tile__badge")], [ - ctl.status_badge(entry.status), - ]) - } -} - /// The status badge just repeats the filter chip already selected above the /// grid (OWNED/WANTED); HISTORY isn't itself a status, so it always shows. fn badge_redundant(status: String, view: String) -> Bool { @@ -275,30 +248,15 @@ fn rows(items: List(Entry), view: String) -> Element(Msg) { fn row(entry: Entry, view: String) -> Element(Msg) { let snap = model.entry_snapshot(entry) - html.a([attr.class("row"), attr.href(route.to_path(Record(entry.entry_id)))], [ - html.div( - [ - attr.class( - "cover-tile cover-tile--row cover-tile--" - <> cov.cover_color(snap.title <> snap.artist_display), - ), - ], - [cov.tile_art(snap.thumb_url, snap.title)], - ), - html.div([attr.class("row__info")], [ - html.span([attr.class("row__title")], [text(snap.title)]), - html.span([attr.class("row__meta")], [text(cov.row_meta(snap))]), - ]), - row_badge(entry, view), - ]) -} - -fn row_badge(entry: Entry, view: String) -> Element(Msg) { - case badge_redundant(entry.status, view) { - True -> element.none() - False -> - html.span([attr.class("row__status")], [ctl.status_badge(entry.status)]) - } + cov.cover_row( + route.to_path(Record(entry.entry_id)), + snap.title <> snap.artist_display, + entry.status, + snap.title, + cov.row_meta(snap), + snap.thumb_url, + !badge_redundant(entry.status, view), + ) } fn loading_state( diff --git a/web/src/crate_web/pages/feed.gleam b/web/src/crate_web/pages/feed.gleam index e62f156..6c0f4ae 100644 --- a/web/src/crate_web/pages/feed.gleam +++ b/web/src/crate_web/pages/feed.gleam @@ -136,6 +136,7 @@ fn single_row( snap.title, cov.row_meta(snap), snap.thumb_url, + True, ), ]) } @@ -276,6 +277,7 @@ fn converge_row( snap.title, cov.row_meta(snap), snap.thumb_url, + True, ), ]) } diff --git a/web/src/crate_web/pages/public_crate.gleam b/web/src/crate_web/pages/public_crate.gleam index aa281d2..fb39257 100644 --- a/web/src/crate_web/pages/public_crate.gleam +++ b/web/src/crate_web/pages/public_crate.gleam @@ -174,6 +174,7 @@ fn card(handle: String, entry: Entry) -> Element(Msg) { snap.artist_display, cov.format_line(snap), snap.thumb_url, + True, ) } diff --git a/web/src/crate_web/ui/covers.gleam b/web/src/crate_web/ui/covers.gleam index 0d54ec9..14b90cc 100644 --- a/web/src/crate_web/ui/covers.gleam +++ b/web/src/crate_web/ui/covers.gleam @@ -55,6 +55,9 @@ pub fn cover_initial(title: String) -> String { } /// Grid card: colour tile with a status badge, plus the title/artist/format. +/// `show_badge` is `False` where the badge would just repeat a filter +/// already selected above the grid (e.g. an OWNED badge under the OWNED +/// filter). pub fn cover_card( href: String, seed: String, @@ -63,12 +66,13 @@ pub fn cover_card( artist: String, fmt: String, thumb: Option(String), + show_badge: Bool, ) -> Element(msg) { let color = cover_color(seed) html.a([attr.class("cover-card"), attr.href(href)], [ html.div([attr.class("cover-tile cover-tile--card cover-tile--" <> color)], [ tile_art(thumb, title), - html.span([attr.class("cover-tile__badge")], [ctl.status_badge(status)]), + badge(show_badge, "cover-tile__badge", status), ]), html.div([attr.class("cover-card__info")], [ html.span([attr.class("cover-card__title")], [text(title)]), @@ -80,6 +84,8 @@ pub fn cover_card( /// List row: a 48px cover thumb beside the title/meta, with the status /// sticker right-aligned; the list display's sibling to `cover_card`. +/// `show_badge` is `False` where the badge would just repeat a filter +/// already selected above the list. pub fn cover_row( href: String, seed: String, @@ -87,6 +93,7 @@ pub fn cover_row( title: String, meta: String, thumb: Option(String), + show_badge: Bool, ) -> Element(msg) { let color = cover_color(seed) html.a([attr.class("row"), attr.href(href)], [ @@ -97,10 +104,17 @@ pub fn cover_row( html.span([attr.class("row__title")], [text(title)]), html.span([attr.class("row__meta")], [text(meta)]), ]), - html.span([attr.class("row__status")], [ctl.status_badge(status)]), + badge(show_badge, "row__status", status), ]) } +fn badge(show: Bool, class: String, status: String) -> Element(msg) { + case show { + True -> html.span([attr.class(class)], [ctl.status_badge(status)]) + False -> element.none() + } +} + /// Full-bleed detail cover band with status sticker and a format sticker. pub fn detail_cover( seed: String,