Compare commits

..

No commits in common. "88f8a9d53725460fe49cd81ce6053447b6e9f62e" and "031b8ce80e102cb6a466fe5634d7f55201c2894b" have entirely different histories.

8 changed files with 102 additions and 41 deletions

10
Cargo.lock generated
View File

@ -2469,7 +2469,7 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]] [[package]]
name = "letterbox" name = "letterbox"
version = "0.0.51" version = "0.0.50"
dependencies = [ dependencies = [
"build-info", "build-info",
"build-info-build", "build-info-build",
@ -2988,7 +2988,7 @@ dependencies = [
[[package]] [[package]]
name = "notmuch" name = "notmuch"
version = "0.0.51" version = "0.0.50"
dependencies = [ dependencies = [
"itertools 0.10.5", "itertools 0.10.5",
"log", "log",
@ -3625,7 +3625,7 @@ dependencies = [
[[package]] [[package]]
name = "procmail2notmuch" name = "procmail2notmuch"
version = "0.0.51" version = "0.0.50"
dependencies = [ dependencies = [
"anyhow", "anyhow",
] ]
@ -4547,7 +4547,7 @@ dependencies = [
[[package]] [[package]]
name = "server" name = "server"
version = "0.0.51" version = "0.0.50"
dependencies = [ dependencies = [
"ammonia", "ammonia",
"anyhow", "anyhow",
@ -4646,7 +4646,7 @@ dependencies = [
[[package]] [[package]]
name = "shared" name = "shared"
version = "0.0.51" version = "0.0.50"
dependencies = [ dependencies = [
"build-info", "build-info",
"notmuch", "notmuch",

View File

@ -1,6 +1,6 @@
[package] [package]
name = "notmuch" name = "notmuch"
version = "0.0.51" version = "0.0.50"
edition = "2021" edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

View File

@ -1,6 +1,6 @@
[package] [package]
name = "procmail2notmuch" name = "procmail2notmuch"
version = "0.0.51" version = "0.0.50"
edition = "2021" edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

View File

@ -1,6 +1,6 @@
[package] [package]
name = "server" name = "server"
version = "0.0.51" version = "0.0.50"
edition = "2021" edition = "2021"
default-run = "server" default-run = "server"

View File

@ -424,6 +424,7 @@ impl QueryRoot {
.field("body") .field("body")
.field("contentTree") .field("contentTree")
.exists(); .exists();
// TODO: look at thread_id and conditionally load newsreader
if newsreader::is_newsreader_thread(&thread_id) { if newsreader::is_newsreader_thread(&thread_id) {
Ok(newsreader::thread(config, pool, thread_id).await?) Ok(newsreader::thread(config, pool, thread_id).await?)
} else { } else {

View File

@ -1,6 +1,6 @@
[package] [package]
name = "shared" name = "shared"
version = "0.0.51" version = "0.0.50"
edition = "2021" edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

View File

@ -1,5 +1,5 @@
[package] [package]
version = "0.0.51" version = "0.0.50"
name = "letterbox" name = "letterbox"
repository = "https://github.com/seed-rs/seed-quickstart" repository = "https://github.com/seed-rs/seed-quickstart"
authors = ["Bill Thiede <git@xinu.tv>"] authors = ["Bill Thiede <git@xinu.tv>"]

View File

@ -375,7 +375,7 @@ fn has_unread(tags: &[String]) -> bool {
tags.contains(&String::from("unread")) tags.contains(&String::from("unread"))
} }
fn render_avatar(_avatar: Option<String>, from: &str, big: bool) -> Node<Msg> { fn render_avatar(avatar: Option<String>, from: &str, big: bool) -> Node<Msg> {
let initials: String = from let initials: String = from
.to_lowercase() .to_lowercase()
.trim() .trim()
@ -404,6 +404,60 @@ fn render_avatar(_avatar: Option<String>, from: &str, big: bool) -> Node<Msg> {
span![initials] span![initials]
] ]
} }
fn render_svg_avatar(avatar: Option<String>, from: &str) -> Node<Msg> {
let initials: String = from
.to_lowercase()
.trim()
.split(" ")
.map(|word| word.chars().next().unwrap())
.filter(|c| c.is_alphanumeric())
// Limit to 2 characters because more characters don't fit in the box
.take(2)
.collect();
if let Some(src) = avatar {
img![attrs! {At::Src=>src}]
} else {
let w = 64;
let h = 64;
let from_color = compute_color(from);
svg![
attrs! {
At::Width=>w,
At::Height=>h,
At::ViewBox=>format!("0 0 {w} {h}")
},
style! {
St::Display => "block",
St::FontFamily => "Poppins",
St::FontSize => pt(28),
},
g![
rect![attrs! {
At::Fill=>from_color,
At::Stroke=>"black",
At::StrokeWidth=>"1",
// Round corners
//At::Rx => px(10),
At::X => 0,
At::Y => 0,
At::Width => h,
At::Height => h,
}],
text![
attrs! {
At::Fill => "white",
At::X => percent(50),
At::Y => percent(50),
At::DominantBaseline => "middle",
At::TextAnchor => "middle"
},
initials
]
]
]
}
}
fn copy_text_widget(text: &str) -> Node<Msg> { fn copy_text_widget(text: &str) -> Node<Msg> {
let text = text.to_string(); let text = text.to_string();
@ -550,7 +604,7 @@ fn render_closed_header(msg: &ShowThreadQueryThreadOnEmailThreadMessages) -> Nod
C!["font-semibold"], C!["font-semibold"],
"CC: " "CC: "
], ],
msg.cc.iter().map(|cc| { msg.cc.iter().enumerate().map(|(i, cc)| {
let ShowThreadQueryThreadOnEmailThreadMessagesCc { name, addr } = cc; let ShowThreadQueryThreadOnEmailThreadMessagesCc { name, addr } = cc;
span![ span![
name.as_ref().unwrap_or_else(|| addr.as_ref().unwrap_or(&unknown)) name.as_ref().unwrap_or_else(|| addr.as_ref().unwrap_or(&unknown))
@ -977,6 +1031,7 @@ fn news_post(
show_icon_text: bool, show_icon_text: bool,
content_el: &ElRef<HtmlElement>, content_el: &ElRef<HtmlElement>,
) -> Node<Msg> { ) -> Node<Msg> {
// TODO(wathiede): show per-message subject if it changes significantly from top-level subject
let subject = &post.title; let subject = &post.title;
set_title(subject); set_title(subject);
let read_thread_id = post.thread_id.clone(); let read_thread_id = post.thread_id.clone();
@ -1034,16 +1089,17 @@ fn render_news_post_header(post: &ShowThreadQueryThreadOnNewsPost) -> Node<Msg>
//let avatar: Option<String> = Some(String::from("https://bulma.io/images/placeholders/64x64.png")); //let avatar: Option<String> = Some(String::from("https://bulma.io/images/placeholders/64x64.png"));
let id = post.thread_id.clone(); let id = post.thread_id.clone();
let is_unread = !post.is_read; let is_unread = !post.is_read;
let avatar = render_avatar(avatar, &from, true); let img = render_avatar(avatar, &from, true);
article![
C!["media"],
figure![C!["media-left"], p![C!["image", "is-64x64"], img]],
div![ div![
C!["flex", "p-4"], C!["media-content"],
div![avatar],
div![ div![
C!["px-4", "mr-auto"], C!["content"],
div![ p![
span![C!["font-semibold", "text-sm"], from,], strong![from],
div![ br![],
C!["text-xs"],
small![a![ small![a![
attrs! { attrs! {
At::Href => post.url, At::Href => post.url,
@ -1051,16 +1107,19 @@ fn render_news_post_header(post: &ShowThreadQueryThreadOnNewsPost) -> Node<Msg>
}, },
"Source ", "Source ",
i![C!["fas", "fa-up-right-from-square"]], i![C!["fas", "fa-up-right-from-square"]],
]] ]],
] table![tr![td![
] attrs! {At::ColSpan=>2},
span![C!["header"], human_age(post.timestamp)]
]]],
], ],
],
],
div![
C!["media-right"],
span![ span![
C!["text-right"], C!["read-status"],
div![C!["text-xs", "text-nowrap"], human_age(post.timestamp)],
i![C![ i![C![
"mx-4"
"read-status",
"far", "far",
if is_unread { if is_unread {
"fa-envelope" "fa-envelope"
@ -1074,6 +1133,7 @@ fn render_news_post_header(post: &ShowThreadQueryThreadOnNewsPost) -> Node<Msg>
Msg::SetUnread(id, !is_unread) Msg::SetUnread(id, !is_unread)
}) })
] ]
]
} }
fn reading_progress(ratio: f64) -> Node<Msg> { fn reading_progress(ratio: f64) -> Node<Msg> {
let percent = ratio * 100.; let percent = ratio * 100.;