Implement catchup mode

Show original/delivered To if no xinu.tv addresses in To/CC fields
This commit is contained in:
2025-02-24 14:37:34 -08:00
parent 76be5b7cac
commit 2e526dace1
7 changed files with 473 additions and 104 deletions

View File

@@ -53,6 +53,7 @@ pub fn init(url: Url, orders: &mut impl Orders<Msg>) -> Model {
client: version,
server: None,
},
catchup: None,
}
}
@@ -182,9 +183,9 @@ pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
}
Msg::GoToSearchResults => {
let url = urls::search(&model.query, 0);
info!("GoToSearchRestuls Start");
info!("GoToSearchResults Start");
orders.request_url(url);
info!("GoToSearchRestuls End");
info!("GoToSearchResults End");
}
Msg::UpdateQuery(query) => model.query = query,
@@ -390,6 +391,38 @@ pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
Msg::ShowThreadResult(bad) => {
error!("show_thread_query error: {bad:#?}");
}
Msg::CatchupRequest { query } => {
orders.perform_cmd(async move {
Msg::CatchupResult(
send_graphql::<_, graphql::catchup_query::ResponseData>(
graphql::CatchupQuery::build_query(graphql::catchup_query::Variables {
query,
}),
)
.await,
)
});
}
Msg::CatchupResult(Ok(graphql_client::Response {
data: Some(data), ..
})) => {
let items = data.catchup;
if items.is_empty() {
orders.send_msg(Msg::GoToSearchResults);
model.catchup = None;
} else {
orders.request_url(urls::thread(&items[0]));
model.catchup = Some(Catchup {
items: items
.into_iter()
.map(|id| CatchupItem { id, seen: false })
.collect(),
});
}
}
Msg::CatchupResult(bad) => {
error!("catchup_query error: {bad:#?}");
}
Msg::SelectionSetNone => {
if let Context::SearchResult {
selected_threads, ..
@@ -504,7 +537,6 @@ pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
});
}
Msg::WindowScrolled => {
info!("WindowScrolled");
if let Some(el) = model.content_el.get() {
let ih = window()
.inner_height()
@@ -513,7 +545,6 @@ pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
.value_of();
let r = el.get_bounding_client_rect();
info!("r {r:?} ih {ih}");
if r.height() < ih {
// The whole content fits in the window, no scrollbar
orders.send_msg(Msg::SetProgress(0.));
@@ -554,8 +585,67 @@ pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
}
model.versions.server = Some(version);
}
Msg::StartCatchup => {
let query = if model.query.contains("is:unread") {
model.query.to_string()
} else {
format!("{} is:unread", model.query)
};
info!("starting catchup mode w/ {}", query);
orders.send_msg(Msg::CatchupRequest { query });
}
Msg::CatchupKeepUnread => {
if let Some(thread_id) = current_thread_id(&model.context) {
orders.send_msg(Msg::SetUnread(thread_id, true));
};
orders.send_msg(Msg::CatchupNext);
}
Msg::CatchupMarkAsRead => {
if let Some(thread_id) = current_thread_id(&model.context) {
orders.send_msg(Msg::SetUnread(thread_id, false));
};
orders.send_msg(Msg::CatchupNext);
}
Msg::CatchupNext => {
let Some(catchup) = &mut model.catchup else {
orders.send_msg(Msg::GoToSearchResults);
return;
};
let Some(idx) = catchup.items.iter().position(|i| !i.seen) else {
orders.send_msg(Msg::GoToSearchResults);
return;
};
catchup.items[idx].seen = true;
if idx < catchup.items.len() - 1 {
orders.request_url(urls::thread(&catchup.items[idx + 1].id));
return;
} else {
orders.send_msg(Msg::GoToSearchResults);
return;
};
}
}
}
fn current_thread_id(context: &Context) -> Option<String> {
match context {
Context::ThreadResult {
thread:
ShowThreadQueryThread::EmailThread(ShowThreadQueryThreadOnEmailThread {
thread_id, ..
}),
..
} => Some(thread_id.clone()),
Context::ThreadResult {
thread:
ShowThreadQueryThread::NewsPost(ShowThreadQueryThreadOnNewsPost { thread_id, .. }),
..
} => Some(thread_id.clone()),
_ => None,
}
}
// `Model` describes our app state.
pub struct Model {
pub query: String,
@@ -565,6 +655,7 @@ pub struct Model {
pub read_completion_ratio: f64,
pub content_el: ElRef<HtmlElement>,
pub versions: Version,
pub catchup: Option<Catchup>,
}
#[derive(Debug)]
@@ -601,6 +692,15 @@ pub enum Context {
},
}
pub struct Catchup {
pub items: Vec<CatchupItem>,
}
pub struct CatchupItem {
pub id: String,
pub seen: bool,
}
pub struct Tag {
pub name: String,
pub bg_color: String,
@@ -651,10 +751,14 @@ pub enum Msg {
ShowThreadResult(
Result<graphql_client::Response<graphql::show_thread_query::ResponseData>, gloo_net::Error>,
),
CatchupRequest {
query: String,
},
CatchupResult(
Result<graphql_client::Response<graphql::catchup_query::ResponseData>, gloo_net::Error>,
),
#[allow(dead_code)]
SelectionSetNone,
#[allow(dead_code)]
SelectionSetAll,
SelectionAddTag(String),
#[allow(dead_code)]
@@ -673,4 +777,9 @@ pub enum Msg {
WindowScrolled,
SetProgress(f64),
UpdateServerVersion(String),
StartCatchup,
CatchupKeepUnread,
CatchupMarkAsRead,
CatchupNext,
}