Toolkit: Add thumbnail view, remove 'dark' from Link

This commit is contained in:
asonix 2021-01-23 22:01:48 -06:00
parent 5693e21ebb
commit be3708a09e
11 changed files with 237 additions and 82 deletions

View file

@ -20,6 +20,7 @@ $dark-body: #333;
$dark-text: #f5f5f5; $dark-text: #f5f5f5;
$dark-text-hover: #e5e5e5; $dark-text-hover: #e5e5e5;
$dark-border: #555; $dark-border: #555;
$dark-border-hover: #4a4a4a;
$dark-primary: #ec3d77; $dark-primary: #ec3d77;
$dark-primary-hover: #d72d66; $dark-primary-hover: #d72d66;
@ -46,6 +47,63 @@ img {
object-fit: contain; object-fit: contain;
} }
.toolkit-thumbnails {
display: flex;
flex-wrap: wrap;
justify-content: space-around;
padding: 4px;
img {
max-height: 150px;
}
.toolkit-thumbnail {
flex: 1 1 auto;
padding: 4px;
}
.toolkit-thumbnail--content {
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
padding: 16px 8px;
border-radius: 3px;
border-width: 1px;
border-style: solid;
}
.toolkit-thumbnail--image {
position: relative;
}
color: $dark;
background-color: $light-background;
.toolkit-thumbnail--content {
background-color: $white;
border-color: $border-light;
}
a.toolkit-thumbnail:hover .toolkit-thumbnail--content {
background-color: $lighter-background;
border-color: $secondary-border-hover;
}
}
.toolkit-dark .toolkit-thumbnails {
color: $dark-text;
background-color: $dark-body;
.toolkit-thumbnail--content {
background-color: $dark-heading;
border-color: $dark-border;
}
a.toolkit-thumbnail:hover .toolkit-thumbnail--content {
background-color: $dark-heading-hover;
border-color: $dark-border-hover;
}
}
.toolkit-select { .toolkit-select {
.toolkit-select--title { .toolkit-select--title {
display: block; display: block;
@ -244,30 +302,32 @@ img {
} }
} }
&.toolkit-dark { &:hover,
color: $dark-primary; &:focus,
&.toolkit-plain { &:active {
color: $dark-text; color: $primary-hover;
}
}
.toolkit-dark .toolkit-link {
color: $dark-primary;
&.toolkit-plain {
color: $dark-text;
&:hover, &:hover,
&:focus, &:focus,
&:active { &:active {
color: $dark-text-hover; color: $dark-text-hover;
}
} }
} }
&:hover, &:hover,
&:focus, &:focus,
&:active { &:active {
color: $primary-hover; color: $dark-primary-hover;
&.toolkit-dark {
color: $dark-primary-hover;
}
} }
} }
.toolkit-input { .toolkit-input {
width: 300px; width: 300px;
padding: 8px 0; padding: 8px 0;
@ -338,9 +398,53 @@ img {
} }
} }
.toolkit-indicator {
position: absolute;
top: 4px;
right: 4px;
height: 36px;
width: 36px;
border-width: 1px;
border-style: solid;
border-radius: 18px;
display: flex;
justify-content: space-around;
align-items: center;
font-weight: 600;
&__red {
border-color: $white;
color: $white;
background-color: $primary;
}
&__gray {
border-color: $white;
color: $white;
background-color: $dark-heading;
}
&__white {
border-color: $dark;
color: $dark;
background-color: $white;
}
}
.toolkit-tiles { .toolkit-tiles {
display: grid; display: grid;
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
color: $light-background;
a.tile-link {
color: $dark-text;
&:hover,
&:focus,
&:active {
color: $dark-text;
}
}
&__scroll { &__scroll {
grid-auto-flow: column; grid-auto-flow: column;
@ -361,40 +465,7 @@ img {
position: relative; position: relative;
} }
.toolkit-tile--banner { &__small .toolkit-tile--indicator {
position: absolute;
top: 4px;
right: 4px;
height: 36px;
width: 36px;
border-width: 1px;
border-style: solid;
border-radius: 18px;
display: flex;
justify-content: space-around;
align-items: center;
font-weight: 600;
&__red {
border-color: $white;
color: $white;
background-color: $primary;
}
&__gray {
border-color: $white;
color: $white;
background-color: $dark-heading;
}
&__white {
border-color: $dark;
color: $dark;
background-color: $white;
}
}
&__small .toolkit-tile--banner {
height: 26px; height: 26px;
width: 26px; width: 26px;
border-radius: 13px; border-radius: 13px;

View file

@ -11,6 +11,7 @@ mod link;
mod profile; mod profile;
mod select; mod select;
mod text_input; mod text_input;
mod thumbnail;
mod tile; mod tile;
pub use self::{ pub use self::{
@ -25,7 +26,8 @@ pub use self::{
profile::Profile, profile::Profile,
select::Select, select::Select,
text_input::TextInput, text_input::TextInput,
tile::{BannerColor, Tile, Tiles}, thumbnail::Thumbnail,
tile::{IndicatorColor, Tile, Tiles},
}; };
use chrono::{DateTime, Utc}; use chrono::{DateTime, Utc};

View file

@ -5,8 +5,8 @@ pub struct Link {
pub(crate) href: String, pub(crate) href: String,
pub(crate) kind: LinkKind, pub(crate) kind: LinkKind,
pub(crate) title: Option<String>, pub(crate) title: Option<String>,
classes: Vec<String>,
plain: bool, plain: bool,
dark: bool,
} }
impl Link { impl Link {
@ -22,8 +22,8 @@ impl Link {
href: href.to_owned(), href: href.to_owned(),
kind: LinkKind::NewTab, kind: LinkKind::NewTab,
title: None, title: None,
dark: false,
plain: false, plain: false,
classes: vec![],
} }
} }
@ -32,24 +32,23 @@ impl Link {
self self
} }
pub fn dark(mut self, dark: bool) -> Self {
self.dark = dark;
self
}
pub fn plain(mut self, plain: bool) -> Self { pub fn plain(mut self, plain: bool) -> Self {
self.plain = plain; self.plain = plain;
self self
} }
pub(crate) fn class_string(&self) -> String { pub fn class(mut self, class: &str) -> Self {
let mut classes = vec!["toolkit-link"]; self.classes.push(class.to_owned());
self
}
pub(crate) fn class_string(&self) -> String {
let mut classes = self.classes.clone();
classes.push("toolkit-link".to_owned());
if self.dark {
classes.push("toolkit-dark");
}
if self.plain { if self.plain {
classes.push("toolkit-plain"); classes.push("toolkit-plain".to_owned());
} }
classes.join(" ") classes.join(" ")

40
toolkit/src/thumbnail.rs Normal file
View file

@ -0,0 +1,40 @@
use crate::image::Image;
use crate::tile::{Indicator, IndicatorColor};
use std::rc::Rc;
pub struct Thumbnail {
image: Rc<dyn Image>,
pub(crate) title: String,
pub(crate) author: String,
pub(crate) indicator: Option<Indicator>,
pub(crate) href: Option<String>,
}
impl Thumbnail {
pub fn new(image: impl Image + 'static, title: &str, author: &str) -> Self {
Thumbnail {
image: Rc::new(image),
title: title.to_owned(),
author: author.to_owned(),
indicator: None,
href: None,
}
}
pub fn indicator(mut self, text: &str, color: IndicatorColor) -> Self {
self.indicator = Some(Indicator {
text: text.to_owned(),
color,
});
self
}
pub fn link(mut self, href: &str) -> Self {
self.href = Some(href.to_owned());
self
}
pub(crate) fn image(&self) -> &dyn Image {
&*self.image
}
}

View file

@ -44,26 +44,26 @@ pub enum TileFlag {
} }
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub enum BannerColor { pub enum IndicatorColor {
Red, Red,
White, White,
Gray, Gray,
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub(crate) struct Banner { pub(crate) struct Indicator {
pub(crate) text: String, pub(crate) text: String,
color: BannerColor, pub(crate) color: IndicatorColor,
} }
impl Banner { impl Indicator {
pub(crate) fn class_string(&self) -> String { pub(crate) fn class_string(&self) -> String {
let mut classes = vec!["toolkit-tile--banner".to_owned()]; let mut classes = vec!["toolkit-indicator".to_owned()];
match self.color { match self.color {
BannerColor::Red => classes.push("toolkit-tile--banner__red".to_owned()), IndicatorColor::Red => classes.push("toolkit-indicator__red".to_owned()),
BannerColor::White => classes.push("toolkit-tile--banner__white".to_owned()), IndicatorColor::White => classes.push("toolkit-indicator__white".to_owned()),
BannerColor::Gray => classes.push("toolkit-tile--banner__gray".to_owned()), IndicatorColor::Gray => classes.push("toolkit-indicator__gray".to_owned()),
} }
classes.join(" ") classes.join(" ")
@ -75,7 +75,7 @@ pub struct Tile {
pub(crate) title: Option<String>, pub(crate) title: Option<String>,
pub(crate) description: Option<String>, pub(crate) description: Option<String>,
pub(crate) link: Option<String>, pub(crate) link: Option<String>,
pub(crate) banner: Option<Banner>, pub(crate) indicator: Option<Indicator>,
pub(crate) flag: TileFlag, pub(crate) flag: TileFlag,
image: Rc<dyn Image>, image: Rc<dyn Image>,
} }
@ -86,14 +86,14 @@ impl Tile {
title: None, title: None,
description: None, description: None,
link: None, link: None,
banner: None, indicator: None,
flag: TileFlag::Normal, flag: TileFlag::Normal,
image: Rc::new(image), image: Rc::new(image),
} }
} }
pub fn banner(mut self, text: &str, color: BannerColor) -> Self { pub fn indicator(mut self, text: &str, color: IndicatorColor) -> Self {
self.banner = Some(Banner { self.indicator = Some(Indicator {
text: text.to_owned(), text: text.to_owned(),
color, color,
}); });
@ -144,7 +144,7 @@ impl std::fmt::Debug for Tile {
.field("title", &self.title) .field("title", &self.title)
.field("description", &self.description) .field("description", &self.description)
.field("link", &self.link) .field("link", &self.link)
.field("banner", &self.banner) .field("indicator", &self.indicator)
.field("flag", &self.flag) .field("flag", &self.flag)
.field("image", &"Box<dyn Image>") .field("image", &"Box<dyn Image>")
.finish() .finish()

View file

@ -1,15 +1,15 @@
@use chrono::{DateTime, Utc}; @use chrono::{DateTime, Utc};
@use crate::{Link, templates::link}; @use crate::{Link, templates::link};
@(time: DateTime<Utc>, dark: bool) @(time: DateTime<Utc>)
<span class="toolkit-time__long"> <span class="toolkit-time__long">
@:link(&Link::current_tab("#").title(&crate::time(time)).plain(true).dark(dark), { @:link(&Link::current_tab("#").title(&crate::time(time)).plain(true), {
@crate::time_ago_long(time) @crate::time_ago_long(time)
}) })
</span> </span>
<span class="toolkit-time__short"> <span class="toolkit-time__short">
@:link(&Link::current_tab("#").title(&crate::time(time)).plain(true).dark(dark), { @:link(&Link::current_tab("#").title(&crate::time(time)).plain(true), {
@crate::time_ago_short(time) @crate::time_ago_short(time)
}) })
</span> </span>

View file

@ -0,0 +1,15 @@
@use crate::{templates::link, Link};
@use crate::templates::thumbnail_inner;
@use crate::thumbnail::Thumbnail;
@(thumb: &Thumbnail)
@if let Some(href) = &thumb.href {
@:link(&Link::current_tab(href).plain(true).class("toolkit-thumbnail"), {
@:thumbnail_inner(thumb)
})
} else {
<div class="toolkit-thumbnail">
@:thumbnail_inner(thumb)
</div>
}

View file

@ -0,0 +1,23 @@
@use crate::templates::image;
@use crate::thumbnail::Thumbnail;
@(thumb: &Thumbnail)
<div class="toolkit-thumbnail--content">
<div class="toolkit-thumbnail--image">
@if let Some(indicator) = &thumb.indicator {
<div class="@indicator.class_string()">
@indicator.text
</div>
}
@:image(thumb.image())
</div>
<div class="toolkit-thumbnail--meta">
<div class="toolkit-thumbnail--title">
@thumb.title
</div>
<div class="toolkit-thumbnail--author">
@thumb.author
</div>
</div>
</div>

View file

@ -0,0 +1,5 @@
@(body: Content)
<div class="toolkit-thumbnails">
@:body()
</div>

View file

@ -5,7 +5,7 @@
@(tile: &Tile) @(tile: &Tile)
@if let Some(href) = &tile.link { @if let Some(href) = &tile.link {
@:link(&Link::current_tab(href).plain(true).dark(true), { @:link(&Link::current_tab(href).plain(true).class("tile-link"), {
@:tile_inner(tile) @:tile_inner(tile)
}) })
} else { } else {

View file

@ -4,9 +4,9 @@
@(tile: &Tile) @(tile: &Tile)
<div class="@tile.class_string()"> <div class="@tile.class_string()">
@if let Some(banner) = &tile.banner { @if let Some(indicator) = &tile.indicator {
<div class="@banner.class_string()"> <div class="@indicator.class_string()">
@banner.text @indicator.text
</div> </div>
} }
<div class="toolkit-tile--overlay"> <div class="toolkit-tile--overlay">