Toolkit: Add thumbnail view, remove 'dark' from Link
This commit is contained in:
parent
5693e21ebb
commit
be3708a09e
|
@ -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;
|
||||||
|
|
|
@ -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};
|
||||||
|
|
|
@ -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
40
toolkit/src/thumbnail.rs
Normal 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
|
||||||
|
}
|
||||||
|
}
|
|
@ -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()
|
||||||
|
|
|
@ -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>
|
||||||
|
|
15
toolkit/templates/thumbnail.rs.html
Normal file
15
toolkit/templates/thumbnail.rs.html
Normal 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>
|
||||||
|
}
|
23
toolkit/templates/thumbnail_inner.rs.html
Normal file
23
toolkit/templates/thumbnail_inner.rs.html
Normal 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>
|
5
toolkit/templates/thumbnails.rs.html
Normal file
5
toolkit/templates/thumbnails.rs.html
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
@(body: Content)
|
||||||
|
|
||||||
|
<div class="toolkit-thumbnails">
|
||||||
|
@:body()
|
||||||
|
</div>
|
|
@ -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 {
|
||||||
|
|
|
@ -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">
|
||||||
|
|
Loading…
Reference in a new issue