Implement catchup mode
Show original/delivered To if no xinu.tv addresses in To/CC fields
This commit is contained in:
121
web/src/state.rs
121
web/src/state.rs
@@ -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,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user