Compare commits

..

No commits in common. "8977f8bab5b312ee349d2eb44cffdc350d5997fc" and "00e8b0342edce054b89ee2165d5355d275fda1ae" have entirely different histories.

7 changed files with 58 additions and 97 deletions

38
Cargo.lock generated
View File

@ -1552,7 +1552,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d"
dependencies = [ dependencies = [
"libc", "libc",
"windows-sys 0.59.0", "windows-sys 0.52.0",
] ]
[[package]] [[package]]
@ -2886,7 +2886,7 @@ checksum = "e19b23d53f35ce9f56aebc7d1bb4e6ac1e9c0db7ac85c8d1760c04379edced37"
dependencies = [ dependencies = [
"hermit-abi 0.4.0", "hermit-abi 0.4.0",
"libc", "libc",
"windows-sys 0.59.0", "windows-sys 0.52.0",
] ]
[[package]] [[package]]
@ -2965,7 +2965,7 @@ dependencies = [
[[package]] [[package]]
name = "letterbox-notmuch" name = "letterbox-notmuch"
version = "0.9.3" version = "0.9.2"
dependencies = [ dependencies = [
"itertools 0.14.0", "itertools 0.14.0",
"log", "log",
@ -2980,14 +2980,14 @@ dependencies = [
[[package]] [[package]]
name = "letterbox-procmail2notmuch" name = "letterbox-procmail2notmuch"
version = "0.9.3" version = "0.9.2"
dependencies = [ dependencies = [
"anyhow", "anyhow",
] ]
[[package]] [[package]]
name = "letterbox-server" name = "letterbox-server"
version = "0.9.3" version = "0.9.2"
dependencies = [ dependencies = [
"ammonia", "ammonia",
"anyhow", "anyhow",
@ -3030,7 +3030,7 @@ dependencies = [
[[package]] [[package]]
name = "letterbox-shared" name = "letterbox-shared"
version = "0.9.3" version = "0.9.2"
dependencies = [ dependencies = [
"build-info", "build-info",
"letterbox-notmuch", "letterbox-notmuch",
@ -3039,7 +3039,7 @@ dependencies = [
[[package]] [[package]]
name = "letterbox-web" name = "letterbox-web"
version = "0.9.3" version = "0.9.2"
dependencies = [ dependencies = [
"build-info", "build-info",
"build-info-build", "build-info-build",
@ -3057,7 +3057,6 @@ dependencies = [
"seed_hooks", "seed_hooks",
"serde", "serde",
"serde_json", "serde_json",
"strum_macros 0.27.1",
"thiserror 2.0.11", "thiserror 2.0.11",
"uuid", "uuid",
"wasm-bindgen", "wasm-bindgen",
@ -4447,7 +4446,7 @@ dependencies = [
"once_cell", "once_cell",
"socket2", "socket2",
"tracing", "tracing",
"windows-sys 0.59.0", "windows-sys 0.52.0",
] ]
[[package]] [[package]]
@ -5130,7 +5129,7 @@ dependencies = [
"errno", "errno",
"libc", "libc",
"linux-raw-sys", "linux-raw-sys",
"windows-sys 0.59.0", "windows-sys 0.52.0",
] ]
[[package]] [[package]]
@ -5963,7 +5962,7 @@ version = "0.26.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06"
dependencies = [ dependencies = [
"strum_macros 0.26.4", "strum_macros",
] ]
[[package]] [[package]]
@ -5979,19 +5978,6 @@ dependencies = [
"syn 2.0.98", "syn 2.0.98",
] ]
[[package]]
name = "strum_macros"
version = "0.27.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c77a8c5abcaf0f9ce05d62342b7d298c346515365c36b673df4ebe3ced01fde8"
dependencies = [
"heck 0.5.0",
"proc-macro2",
"quote",
"rustversion",
"syn 2.0.98",
]
[[package]] [[package]]
name = "subtle" name = "subtle"
version = "1.0.0" version = "1.0.0"
@ -6219,7 +6205,7 @@ dependencies = [
"getrandom 0.3.1", "getrandom 0.3.1",
"once_cell", "once_cell",
"rustix", "rustix",
"windows-sys 0.59.0", "windows-sys 0.52.0",
] ]
[[package]] [[package]]
@ -7295,7 +7281,7 @@ version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
dependencies = [ dependencies = [
"windows-sys 0.59.0", "windows-sys 0.48.0",
] ]
[[package]] [[package]]

View File

@ -8,7 +8,7 @@ authors = ["Bill Thiede <git@xinu.tv>"]
edition = "2021" edition = "2021"
license = "UNLICENSED" license = "UNLICENSED"
publish = ["xinu"] publish = ["xinu"]
version = "0.9.3" version = "0.9.2"
repository = "https://git.z.xinu.tv/wathiede/letterbox" repository = "https://git.z.xinu.tv/wathiede/letterbox"
[profile.dev] [profile.dev]

View File

@ -48,8 +48,8 @@ urlencoding = "2.1.3"
#xtracing = { path = "../../xtracing" } #xtracing = { path = "../../xtracing" }
#xtracing = { git = "http://git-private.h.xinu.tv/wathiede/xtracing.git" } #xtracing = { git = "http://git-private.h.xinu.tv/wathiede/xtracing.git" }
xtracing = { version = "0.3.0", registry = "xinu" } xtracing = { version = "0.3.0", registry = "xinu" }
letterbox-notmuch = { version = "0.9.3", path = "../notmuch", registry = "xinu" } letterbox-notmuch = { version = "0.9.2", path = "../notmuch", registry = "xinu" }
letterbox-shared = { version = "0.9.3", path = "../shared", registry = "xinu" } letterbox-shared = { version = "0.9.2", path = "../shared", registry = "xinu" }
[build-dependencies] [build-dependencies]
build-info-build = "0.0.39" build-info-build = "0.0.39"

View File

@ -12,5 +12,5 @@ version.workspace = true
[dependencies] [dependencies]
build-info = "0.0.39" build-info = "0.0.39"
letterbox-notmuch = { version = "0.9.3", path = "../notmuch", registry = "xinu" } letterbox-notmuch = { version = "0.9.2", path = "../notmuch", registry = "xinu" }
serde = { version = "1.0.147", features = ["derive"] } serde = { version = "1.0.147", features = ["derive"] }

View File

@ -33,10 +33,9 @@ wasm-bindgen = "=0.2.100"
uuid = { version = "1.13.1", features = [ uuid = { version = "1.13.1", features = [
"js", "js",
] } # direct dep to set js feature, prevents Rng issues ] } # direct dep to set js feature, prevents Rng issues
letterbox-shared = { version = "0.9.3", path = "../shared", registry = "xinu" } letterbox-shared = { version = "0.9.2", path = "../shared", registry = "xinu" }
letterbox-notmuch = { version = "0.9.3", path = "../notmuch", registry = "xinu" } letterbox-notmuch = { version = "0.9.2", path = "../notmuch", registry = "xinu" }
seed_hooks = { version = "0.4.0", registry = "xinu" } seed_hooks = { version = "0.4.0", registry = "xinu" }
strum_macros = "0.27.1"
[package.metadata.wasm-pack.profile.release] [package.metadata.wasm-pack.profile.release]
wasm-opt = ['-Os'] wasm-opt = ['-Os']

View File

@ -116,7 +116,6 @@ fn on_url_changed(uc: subs::UrlChanged) -> Msg {
// `update` describes how to handle each `Msg`. // `update` describes how to handle each `Msg`.
pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) { pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
debug!("update({})", msg);
match msg { match msg {
Msg::Noop => {} Msg::Noop => {}
Msg::RefreshStart => { Msg::RefreshStart => {
@ -192,7 +191,10 @@ pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
}; };
} }
Msg::GoToSearchResults => { Msg::GoToSearchResults => {
orders.send_msg(Msg::SearchQuery(model.query.clone())); let url = urls::search(&model.query, 0);
info!("GoToSearchResults Start");
orders.request_url(url);
info!("GoToSearchResults End");
} }
Msg::UpdateQuery(query) => model.query = query, Msg::UpdateQuery(query) => model.query = query,
@ -603,7 +605,6 @@ pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
format!("{} is:unread", model.query) format!("{} is:unread", model.query)
}; };
info!("starting catchup mode w/ {}", query); info!("starting catchup mode w/ {}", query);
orders.send_msg(Msg::ScrollToTop);
orders.send_msg(Msg::CatchupRequest { query }); orders.send_msg(Msg::CatchupRequest { query });
} }
Msg::CatchupKeepUnread => { Msg::CatchupKeepUnread => {
@ -625,24 +626,19 @@ pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
return; return;
}; };
let Some(idx) = catchup.items.iter().position(|i| !i.seen) else { let Some(idx) = catchup.items.iter().position(|i| !i.seen) else {
// All items have been seen
orders.send_msg(Msg::CatchupExit);
orders.send_msg(Msg::GoToSearchResults); orders.send_msg(Msg::GoToSearchResults);
return; return;
}; };
catchup.items[idx].seen = true; catchup.items[idx].seen = true;
if idx < catchup.items.len() - 1 { if idx < catchup.items.len() - 1 {
// Reached last item
orders.request_url(urls::thread(&catchup.items[idx + 1].id)); orders.request_url(urls::thread(&catchup.items[idx + 1].id));
return; return;
} else { } else {
orders.send_msg(Msg::CatchupExit);
orders.send_msg(Msg::GoToSearchResults); orders.send_msg(Msg::GoToSearchResults);
return; return;
}; };
} }
Msg::CatchupExit => { Msg::CatchupExit => {
orders.send_msg(Msg::ScrollToTop);
model.catchup = None; model.catchup = None;
} }
} }
@ -734,7 +730,6 @@ pub enum RefreshingState {
Error(String), Error(String),
} }
// `Msg` describes the different events you can modify state with. // `Msg` describes the different events you can modify state with.
#[derive(strum_macros::Display)]
pub enum Msg { pub enum Msg {
Noop, Noop,
// Tell the client to refresh its state // Tell the client to refresh its state

View File

@ -21,8 +21,6 @@ use crate::{
const MAX_RAW_MESSAGE_SIZE: usize = 100_000; const MAX_RAW_MESSAGE_SIZE: usize = 100_000;
mod tw_classes { mod tw_classes {
use seed::{prelude::*, *};
pub const TAG: &[&str] = &[ pub const TAG: &[&str] = &[
"rounded-md", "rounded-md",
"px-2", "px-2",
@ -39,14 +37,8 @@ mod tw_classes {
"text-xs", "text-xs",
"[text-shadow:_0_1px_0_rgb(0_0_0_/_40%)]", "[text-shadow:_0_1px_0_rgb(0_0_0_/_40%)]",
]; ];
pub const BUTTON: &[&str] = &[
// TODO: should this be a builder pattern? "bg-neutral-900",
pub fn button() -> seed::Attrs {
button_with_color("bg-neutral-900", "hover:bg-neutral-700")
}
pub fn button_with_color<T: ToClasses>(bg: T, hover: T) -> seed::Attrs {
C![
"rounded-md", "rounded-md",
"p-2", "p-2",
"border", "border",
@ -56,13 +48,11 @@ mod tw_classes {
"transition-all", "transition-all",
"shadow-md", "shadow-md",
"hover:shadow-lg", "hover:shadow-lg",
"hover:bg-neutral-700",
"disabled:pointer-events-none", "disabled:pointer-events-none",
"disabled:opacity-50", "disabled:opacity-50",
"disabled:shadow-none", "disabled:shadow-none",
bg, ];
hover,
]
}
pub const CHECKBOX: &[&str] = &[ pub const CHECKBOX: &[&str] = &[
"w-8", "w-8",
@ -226,13 +216,13 @@ fn catchup_view(
"bg-black", "bg-black",
], ],
button![ button![
tw_classes::button(), C![&tw_classes::BUTTON],
span![i![C!["far", "fa-envelope"]]], span![i![C!["far", "fa-envelope"]]],
span![C!["pl-2"], "Keep unread"], span![C!["pl-2"], "Keep unread"],
ev(Ev::Click, move |_| Msg::CatchupKeepUnread) ev(Ev::Click, move |_| Msg::CatchupKeepUnread)
], ],
button![ button![
tw_classes::button_with_color("bg-green-800", "hover:bg-neutral-700"), C![&tw_classes::BUTTON, "bg-green-500"],
span![i![C!["far", "fa-envelope-open"]]], span![i![C!["far", "fa-envelope-open"]]],
span![C!["pl-2"], "Mark as read"], span![C!["pl-2"], "Mark as read"],
ev(Ev::Click, move |_| Msg::CatchupMarkAsRead) ev(Ev::Click, move |_| Msg::CatchupMarkAsRead)
@ -457,7 +447,7 @@ fn search_toolbar(
div![ div![
C!["gap-2", "flex", IF!(show_bulk_edit => "hidden")], C!["gap-2", "flex", IF!(show_bulk_edit => "hidden")],
div![button![ div![button![
tw_classes::button(), C![&tw_classes::BUTTON],
attrs! {At::Title => "Mark as read"}, attrs! {At::Title => "Mark as read"},
span![i![C!["far", "fa-eye"]]], span![i![C!["far", "fa-eye"]]],
span![C!["pl-2", "hidden", "md:inline"], "Catch-up"], span![C!["pl-2", "hidden", "md:inline"], "Catch-up"],
@ -486,16 +476,14 @@ fn search_toolbar(
], ],
div![ div![
button![ button![
tw_classes::button(), C![&tw_classes::BUTTON, "rounded-r-none"],
C!["rounded-r-none"],
attrs! {At::Title => "Mark as read"}, attrs! {At::Title => "Mark as read"},
span![i![C!["far", "fa-envelope-open"]]], span![i![C!["far", "fa-envelope-open"]]],
span![C!["pl-2", "hidden", "md:inline"], "Read"], span![C!["pl-2", "hidden", "md:inline"], "Read"],
ev(Ev::Click, |_| Msg::SelectionMarkAsRead) ev(Ev::Click, |_| Msg::SelectionMarkAsRead)
], ],
button![ button![
tw_classes::button(), C![&tw_classes::BUTTON, "rounded-l-none"],
C!["rounded-l-none"],
attrs! {At::Title => "Mark as unread"}, attrs! {At::Title => "Mark as unread"},
span![i![C!["far", "fa-envelope"]]], span![i![C!["far", "fa-envelope"]]],
span![C!["pl-2", "hidden", "md:inline"], "Unread"], span![C!["pl-2", "hidden", "md:inline"], "Unread"],
@ -503,8 +491,7 @@ fn search_toolbar(
] ]
], ],
div![button![ div![button![
tw_classes::button(), C![&tw_classes::BUTTON, "text-red-500"],
C!["text-red-500"],
attrs! {At::Title => "Mark as spam"}, attrs! {At::Title => "Mark as spam"},
span![i![C!["far", "fa-hand"]]], span![i![C!["far", "fa-hand"]]],
span![C!["pl-2", "hidden", "md:inline"], "Spam"], span![C!["pl-2", "hidden", "md:inline"], "Spam"],
@ -518,13 +505,13 @@ fn search_toolbar(
C!["flex", "gap-2", "items-center"], C!["flex", "gap-2", "items-center"],
p![format!("{count} results")], p![format!("{count} results")],
button![ button![
tw_classes::button(), C![&tw_classes::BUTTON],
IF!(!pager.has_previous_page => attrs!{ At::Disabled=>true }), IF!(!pager.has_previous_page => attrs!{ At::Disabled=>true }),
"<", "<",
IF!(pager.has_previous_page => ev(Ev::Click, |_| Msg::PreviousPage)), IF!(pager.has_previous_page => ev(Ev::Click, |_| Msg::PreviousPage)),
], ],
button![ button![
tw_classes::button(), C![&tw_classes::BUTTON],
IF!(!pager.has_next_page => attrs!{ At::Disabled=>true }), IF!(!pager.has_next_page => attrs!{ At::Disabled=>true }),
">", ">",
IF!(pager.has_next_page => ev(Ev::Click, |_| Msg::NextPage)) IF!(pager.has_next_page => ev(Ev::Click, |_| Msg::NextPage))
@ -1089,8 +1076,7 @@ fn thread(
C!["pt-4", "gap-2", "flex", "justify-around"], C!["pt-4", "gap-2", "flex", "justify-around"],
div![ div![
button![ button![
tw_classes::button(), C![&tw_classes::BUTTON, "rounded-r-none"],
C!["rounded-r-none"],
attrs! {At::Title => "Mark as read"}, attrs! {At::Title => "Mark as read"},
span![i![C!["far", "fa-envelope-open"]]], span![i![C!["far", "fa-envelope-open"]]],
span![C!["pl-2"], "Read"], span![C!["pl-2"], "Read"],
@ -1100,8 +1086,7 @@ fn thread(
])), ])),
], ],
button![ button![
tw_classes::button(), C![&tw_classes::BUTTON, "rounded-l-none"],
C!["rounded-l-none"],
attrs! {At::Title => "Mark as unread"}, attrs! {At::Title => "Mark as unread"},
span![i![C!["far", "fa-envelope"]]], span![i![C!["far", "fa-envelope"]]],
span![C!["pl-2"], "Unread"], span![C!["pl-2"], "Unread"],
@ -1112,8 +1097,7 @@ fn thread(
], ],
], ],
div![button![ div![button![
tw_classes::button(), C![&tw_classes::BUTTON, "text-red-500"],
C!["text-red-500"],
attrs! {At::Title => "Spam"}, attrs! {At::Title => "Spam"},
span![i![C!["far", "fa-hand"]]], span![i![C!["far", "fa-hand"]]],
span![C!["pl-2"], "Spam"], span![C!["pl-2"], "Spam"],
@ -1179,7 +1163,7 @@ fn view_header(
C!["flex", "px-4", "pt-4", "overflow-hidden"], C!["flex", "px-4", "pt-4", "overflow-hidden"],
a![ a![
C![IF![is_error => "bg-red-500"], "rounded-r-none"], C![IF![is_error => "bg-red-500"], "rounded-r-none"],
tw_classes::button(), C![&tw_classes::BUTTON],
span![i![C![ span![i![C![
"fa-solid", "fa-solid",
"fa-arrow-rotate-right", "fa-arrow-rotate-right",
@ -1188,7 +1172,7 @@ fn view_header(
ev(Ev::Click, |_| Msg::RefreshStart), ev(Ev::Click, |_| Msg::RefreshStart),
], ],
a![ a![
tw_classes::button(), C![&tw_classes::BUTTON],
C!["px-4", "rounded-none"], C!["px-4", "rounded-none"],
attrs! { attrs! {
At::Href => urls::search(unread_query(), 0) At::Href => urls::search(unread_query(), 0)
@ -1196,7 +1180,7 @@ fn view_header(
"Unread", "Unread",
], ],
a![ a![
tw_classes::button(), C![&tw_classes::BUTTON],
C!["px-4", "rounded-none"], C!["px-4", "rounded-none"],
attrs! { attrs! {
At::Href => urls::search("", 0) At::Href => urls::search("", 0)
@ -1383,8 +1367,7 @@ fn news_post(post: &ShowThreadQueryThreadOnNewsPost, content_el: &ElRef<HtmlElem
C!["pt-4", "gap-2", "flex", "justify-around"], C!["pt-4", "gap-2", "flex", "justify-around"],
div![ div![
button![ button![
tw_classes::button(), C![&tw_classes::BUTTON, "rounded-r-none"],
C!["rounded-r-none"],
attrs! {At::Title => "Mark as read"}, attrs! {At::Title => "Mark as read"},
span![i![C!["far", "fa-envelope-open"]]], span![i![C!["far", "fa-envelope-open"]]],
span![C!["pl-2"], "Read"], span![C!["pl-2"], "Read"],
@ -1394,8 +1377,7 @@ fn news_post(post: &ShowThreadQueryThreadOnNewsPost, content_el: &ElRef<HtmlElem
])), ])),
], ],
button![ button![
tw_classes::button(), C![&tw_classes::BUTTON, "rounded-l-none"],
C!["rounded-l-none"],
attrs! {At::Title => "Mark as unread"}, attrs! {At::Title => "Mark as unread"},
span![i![C!["far", "fa-envelope"]]], span![i![C!["far", "fa-envelope"]]],
span![C!["pl-2"], "Unread"], span![C!["pl-2"], "Unread"],
@ -1470,7 +1452,7 @@ fn render_news_post_header(post: &ShowThreadQueryThreadOnNewsPost) -> Node<Msg>
div![ div![
C!["flex", "gap-2", "pt-2", "text-sm"], C!["flex", "gap-2", "pt-2", "text-sm"],
a![ a![
tw_classes::button(), C![&tw_classes::BUTTON],
attrs! { attrs! {
At::Href => post.url, At::Href => post.url,
At::Target => "_blank", At::Target => "_blank",
@ -1479,7 +1461,7 @@ fn render_news_post_header(post: &ShowThreadQueryThreadOnNewsPost) -> Node<Msg>
i![C!["fas", "fa-up-right-from-square"]], i![C!["fas", "fa-up-right-from-square"]],
], ],
a![ a![
tw_classes::button(), C![&tw_classes::BUTTON],
attrs! { attrs! {
At::Href => add_archive_url, At::Href => add_archive_url,
At::Target => "_blank", At::Target => "_blank",
@ -1488,7 +1470,7 @@ fn render_news_post_header(post: &ShowThreadQueryThreadOnNewsPost) -> Node<Msg>
i![C!["fas", "fa-plus"]], i![C!["fas", "fa-plus"]],
], ],
a![ a![
tw_classes::button(), C![&tw_classes::BUTTON],
attrs! { attrs! {
At::Href => view_archive_url, At::Href => view_archive_url,
At::Target => "_blank", At::Target => "_blank",
@ -1555,8 +1537,7 @@ pub fn view_versions(versions: &Version) -> Node<Msg> {
fn click_to_top() -> Node<Msg> { fn click_to_top() -> Node<Msg> {
button![ button![
tw_classes::button_with_color("bg-red-500", "hover:bg-neutral-700"), C![&tw_classes::BUTTON, "bg-red-500", "lg:m-0", "m-4"],
C!["lg:m-0", "m-4"],
span!["Top"], span!["Top"],
span![i![C!["fas", "fa-arrow-turn-up"]]], span![i![C!["fas", "fa-arrow-turn-up"]]],
ev(Ev::Click, |_| Msg::ScrollToTop) ev(Ev::Click, |_| Msg::ScrollToTop)