Compare commits

...

2 Commits

Author SHA1 Message Date
c81a8c1cd3 chore: Release
All checks were successful
Continuous integration / Check (push) Successful in 35s
Continuous integration / Test Suite (push) Successful in 40s
Continuous integration / Trunk (push) Successful in 37s
Continuous integration / Rustfmt (push) Successful in 39s
Continuous integration / build (push) Successful in 47s
Continuous integration / Disallow unused dependencies (push) Successful in 2m5s
2025-05-18 09:54:26 -07:00
7c3cfec3d1 web: improve keep unread logic in catchup, remove execess logging 2025-05-18 09:54:03 -07:00
6 changed files with 69 additions and 44 deletions

52
Cargo.lock generated
View File

@ -2989,6 +2989,20 @@ dependencies = [
[[package]] [[package]]
name = "letterbox-notmuch" name = "letterbox-notmuch"
version = "0.17.23" version = "0.17.23"
source = "sparse+https://git.z.xinu.tv/api/packages/wathiede/cargo/"
checksum = "8a84fbab124e9a800230b10f73ee96a22f2f723fb859368a67f5420d1a96efd6"
dependencies = [
"log",
"mailparse",
"serde",
"serde_json",
"thiserror 2.0.12",
"tracing",
]
[[package]]
name = "letterbox-notmuch"
version = "0.17.24"
dependencies = [ dependencies = [
"itertools", "itertools",
"log", "log",
@ -3001,28 +3015,14 @@ dependencies = [
"tracing", "tracing",
] ]
[[package]]
name = "letterbox-notmuch"
version = "0.17.23"
source = "sparse+https://git.z.xinu.tv/api/packages/wathiede/cargo/"
checksum = "8a84fbab124e9a800230b10f73ee96a22f2f723fb859368a67f5420d1a96efd6"
dependencies = [
"log",
"mailparse",
"serde",
"serde_json",
"thiserror 2.0.12",
"tracing",
]
[[package]] [[package]]
name = "letterbox-procmail2notmuch" name = "letterbox-procmail2notmuch"
version = "0.17.23" version = "0.17.24"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"clap", "clap",
"letterbox-notmuch 0.17.23 (sparse+https://git.z.xinu.tv/api/packages/wathiede/cargo/)", "letterbox-notmuch 0.17.23",
"letterbox-shared 0.17.23 (sparse+https://git.z.xinu.tv/api/packages/wathiede/cargo/)", "letterbox-shared 0.17.23",
"serde", "serde",
"sqlx", "sqlx",
"tokio 1.45.0", "tokio 1.45.0",
@ -3030,7 +3030,7 @@ dependencies = [
[[package]] [[package]]
name = "letterbox-server" name = "letterbox-server"
version = "0.17.23" version = "0.17.24"
dependencies = [ dependencies = [
"ammonia", "ammonia",
"anyhow", "anyhow",
@ -3048,8 +3048,8 @@ dependencies = [
"futures 0.3.31", "futures 0.3.31",
"headers", "headers",
"html-escape", "html-escape",
"letterbox-notmuch 0.17.23", "letterbox-notmuch 0.17.24",
"letterbox-shared 0.17.23", "letterbox-shared 0.17.24",
"linkify", "linkify",
"lol_html", "lol_html",
"mailparse", "mailparse",
@ -3074,6 +3074,8 @@ dependencies = [
[[package]] [[package]]
name = "letterbox-shared" name = "letterbox-shared"
version = "0.17.23" version = "0.17.23"
source = "sparse+https://git.z.xinu.tv/api/packages/wathiede/cargo/"
checksum = "73bd659acd51c1646a0988b57f899f1bb2af54c694bdcc7cdfa63e80b87f7d5f"
dependencies = [ dependencies = [
"build-info", "build-info",
"letterbox-notmuch 0.17.23", "letterbox-notmuch 0.17.23",
@ -3086,12 +3088,10 @@ dependencies = [
[[package]] [[package]]
name = "letterbox-shared" name = "letterbox-shared"
version = "0.17.23" version = "0.17.24"
source = "sparse+https://git.z.xinu.tv/api/packages/wathiede/cargo/"
checksum = "73bd659acd51c1646a0988b57f899f1bb2af54c694bdcc7cdfa63e80b87f7d5f"
dependencies = [ dependencies = [
"build-info", "build-info",
"letterbox-notmuch 0.17.23 (sparse+https://git.z.xinu.tv/api/packages/wathiede/cargo/)", "letterbox-notmuch 0.17.24",
"regex", "regex",
"serde", "serde",
"sqlx", "sqlx",
@ -3101,7 +3101,7 @@ dependencies = [
[[package]] [[package]]
name = "letterbox-web" name = "letterbox-web"
version = "0.17.23" version = "0.17.24"
dependencies = [ dependencies = [
"build-info", "build-info",
"build-info-build", "build-info-build",
@ -3113,7 +3113,7 @@ dependencies = [
"graphql_client", "graphql_client",
"human_format", "human_format",
"itertools", "itertools",
"letterbox-shared 0.17.23 (sparse+https://git.z.xinu.tv/api/packages/wathiede/cargo/)", "letterbox-shared 0.17.23",
"log", "log",
"seed", "seed",
"seed_hooks", "seed_hooks",

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.17.23" version = "0.17.24"
repository = "https://git.z.xinu.tv/wathiede/letterbox" repository = "https://git.z.xinu.tv/wathiede/letterbox"
[profile.dev] [profile.dev]

View File

@ -27,8 +27,8 @@ css-inline = "0.14.4"
futures = "0.3.31" futures = "0.3.31"
headers = "0.4.0" headers = "0.4.0"
html-escape = "0.2.13" html-escape = "0.2.13"
letterbox-notmuch = { path = "../notmuch", version = "0.17.23", registry = "xinu" } letterbox-notmuch = { path = "../notmuch", version = "0.17.24", registry = "xinu" }
letterbox-shared = { path = "../shared", version = "0.17.23", registry = "xinu" } letterbox-shared = { path = "../shared", version = "0.17.24", registry = "xinu" }
linkify = "0.10.0" linkify = "0.10.0"
lol_html = "2.3.0" lol_html = "2.3.0"
mailparse = "0.16.1" mailparse = "0.16.1"

View File

@ -12,7 +12,7 @@ version.workspace = true
[dependencies] [dependencies]
build-info = "0.0.40" build-info = "0.0.40"
letterbox-notmuch = { path = "../notmuch", version = "0.17.23", registry = "xinu" } letterbox-notmuch = { path = "../notmuch", version = "0.17.24", registry = "xinu" }
regex = "1.11.1" regex = "1.11.1"
serde = { version = "1.0.219", features = ["derive"] } serde = { version = "1.0.219", features = ["derive"] }
sqlx = "0.8.5" sqlx = "0.8.5"

View File

@ -72,10 +72,6 @@ fn on_url_changed(old: &Url, mut new: Url) -> Msg {
if did_change { if did_change {
messages.push(Msg::ScrollToTop) messages.push(Msg::ScrollToTop)
} }
info!(
"url changed\nold '{old}'\nnew '{new}', history {}",
history().length().unwrap_or(0)
);
let hpp = new.remaining_hash_path_parts(); let hpp = new.remaining_hash_path_parts();
let msg = match hpp.as_slice() { let msg = match hpp.as_slice() {
["t", tid] => Msg::ShowThreadRequest { ["t", tid] => Msg::ShowThreadRequest {
@ -553,7 +549,6 @@ pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
}); });
} }
Msg::ScrollToTop => { Msg::ScrollToTop => {
info!("scrolling to the top");
web_sys::window().unwrap().scroll_to_with_x_and_y(0., 0.); web_sys::window().unwrap().scroll_to_with_x_and_y(0., 0.);
} }
Msg::WindowScrolled => { Msg::WindowScrolled => {
@ -619,6 +614,36 @@ pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
orders.send_msg(Msg::CatchupRequest { query }); orders.send_msg(Msg::CatchupRequest { query });
} }
Msg::CatchupKeepUnread => { Msg::CatchupKeepUnread => {
if let Some(thread_id) = current_thread_id(&model.context) {
if let Context::ThreadResult {
thread:
ShowThreadQueryThread::EmailThread(ShowThreadQueryThreadOnEmailThread {
messages,
..
}),
..
} = &model.context
{
//orders.send_msg(Msg::SetUnread(thread_id, false));
let unread_messages: Vec<_> = messages
.iter()
.filter(|msg| msg.tags.iter().any(|t| t == "unread"))
.map(|msg| &msg.id)
.collect();
if unread_messages.is_empty() {
// All messages are read, so mark them all unread
orders.send_msg(Msg::SetUnread(thread_id, true));
} else {
// Do nothing if there are some messages unread
}
} else {
// News post, not email, just mark unread
orders.send_msg(Msg::SetUnread(thread_id, true));
};
} else {
// This shouldn't happen
warn!("no current thread_id");
}
orders.send_msg(Msg::CatchupNext); orders.send_msg(Msg::CatchupNext);
} }
Msg::CatchupMarkAsRead => { Msg::CatchupMarkAsRead => {

View File

@ -1,7 +1,7 @@
use std::{collections::VecDeque, rc::Rc}; use std::{collections::VecDeque, rc::Rc};
use letterbox_shared::WebsocketMessage; use letterbox_shared::WebsocketMessage;
use log::{error, info}; use log::{debug, error};
use seed::prelude::*; use seed::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
@ -122,13 +122,13 @@ pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
match msg { match msg {
Msg::WebSocketOpened => { Msg::WebSocketOpened => {
model.web_socket_reconnector = None; model.web_socket_reconnector = None;
info!("WebSocket connection is open now"); debug!("WebSocket connection is open now");
} }
Msg::TextMessageReceived(msg) => { Msg::TextMessageReceived(msg) => {
model.updates.push_back(msg); model.updates.push_back(msg);
} }
Msg::WebSocketClosed(close_event) => { Msg::WebSocketClosed(close_event) => {
info!( debug!(
r#"================== r#"==================
WebSocket connection was closed: WebSocket connection was closed:
Clean: {0} Clean: {0}
@ -148,7 +148,7 @@ Reason: {2}
} }
} }
Msg::WebSocketFailed => { Msg::WebSocketFailed => {
info!("WebSocket failed"); debug!("WebSocket failed");
if model.web_socket_reconnector.is_none() { if model.web_socket_reconnector.is_none() {
model.web_socket_reconnector = Some( model.web_socket_reconnector = Some(
orders.stream_with_handle(streams::backoff(None, Msg::ReconnectWebSocket)), orders.stream_with_handle(streams::backoff(None, Msg::ReconnectWebSocket)),
@ -156,7 +156,7 @@ Reason: {2}
} }
} }
Msg::ReconnectWebSocket(retries) => { Msg::ReconnectWebSocket(retries) => {
info!("Reconnect attempt: {}", retries); debug!("Reconnect attempt: {}", retries);
model.web_socket = create_websocket(&model.ws_url, orders).unwrap(); model.web_socket = create_websocket(&model.ws_url, orders).unwrap();
} }
Msg::SendMessage(msg) => { Msg::SendMessage(msg) => {
@ -177,16 +177,16 @@ fn create_websocket(url: &str, orders: &impl Orders<Msg>) -> Result<EventClient,
let send = msg_sender.clone(); let send = msg_sender.clone();
client.set_on_connection(Some(Box::new(move |client: &EventClient| { client.set_on_connection(Some(Box::new(move |client: &EventClient| {
info!("{:#?}", client.status); debug!("{:#?}", client.status);
let msg = match *client.status.borrow() { let msg = match *client.status.borrow() {
ConnectionStatus::Connecting => { ConnectionStatus::Connecting => {
info!("Connecting..."); debug!("Connecting...");
None None
} }
ConnectionStatus::Connected => Some(Msg::WebSocketOpened), ConnectionStatus::Connected => Some(Msg::WebSocketOpened),
ConnectionStatus::Error => Some(Msg::WebSocketFailed), ConnectionStatus::Error => Some(Msg::WebSocketFailed),
ConnectionStatus::Disconnected => { ConnectionStatus::Disconnected => {
info!("Disconnected"); debug!("Disconnected");
None None
} }
}; };
@ -195,7 +195,7 @@ fn create_websocket(url: &str, orders: &impl Orders<Msg>) -> Result<EventClient,
let send = msg_sender.clone(); let send = msg_sender.clone();
client.set_on_close(Some(Box::new(move |ev| { client.set_on_close(Some(Box::new(move |ev| {
info!("WS: Connection closed"); debug!("WS: Connection closed");
send(Some(Msg::WebSocketClosed(ev))); send(Some(Msg::WebSocketClosed(ev)));
}))); })));