web: refactor mark read logic to be two phases

This commit is contained in:
Bill Thiede 2025-01-12 09:25:44 -08:00
parent 9ce0aacab0
commit 13a7de4956
2 changed files with 28 additions and 27 deletions

View File

@ -180,6 +180,12 @@ pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
Context::None => (), // do nothing (yet?) Context::None => (), // do nothing (yet?)
}; };
} }
Msg::GoToSearchResults => {
let url = urls::search(&model.query, 0);
info!("GoToSearchRestuls Start");
orders.request_url(url);
info!("GoToSearchRestuls End");
}
Msg::UpdateQuery(query) => model.query = query, Msg::UpdateQuery(query) => model.query = query,
Msg::SearchQuery(query) => { Msg::SearchQuery(query) => {
@ -187,7 +193,6 @@ pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
} }
Msg::SetUnread(query, unread) => { Msg::SetUnread(query, unread) => {
let search_url = urls::search(&model.query, 0).to_string();
orders.skip().perform_cmd(async move { orders.skip().perform_cmd(async move {
let res: Result< let res: Result<
graphql_client::Response<graphql::mark_read_mutation::ResponseData>, graphql_client::Response<graphql::mark_read_mutation::ResponseData>,
@ -202,15 +207,10 @@ pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
if let Err(e) = res { if let Err(e) = res {
error!("Failed to set read for {query} to {unread}: {e}"); error!("Failed to set read for {query} to {unread}: {e}");
} }
seed::window() Msg::Refresh
.location()
.set_href(&search_url)
.expect("failed to change location");
Msg::Noop
}); });
} }
Msg::AddTag(query, tag) => { Msg::AddTag(query, tag) => {
let search_url = urls::search(&model.query, 0).to_string();
orders.skip().perform_cmd(async move { orders.skip().perform_cmd(async move {
let res: Result< let res: Result<
graphql_client::Response<graphql::add_tag_mutation::ResponseData>, graphql_client::Response<graphql::add_tag_mutation::ResponseData>,
@ -225,15 +225,10 @@ pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
if let Err(e) = res { if let Err(e) = res {
error!("Failed to add tag {tag} to {query}: {e}"); error!("Failed to add tag {tag} to {query}: {e}");
} }
seed::window() Msg::GoToSearchResults
.location()
.set_href(&search_url)
.expect("failed to change location");
Msg::Noop
}); });
} }
Msg::RemoveTag(query, tag) => { Msg::RemoveTag(query, tag) => {
let search_url = urls::search(&model.query, 0).to_string();
orders.skip().perform_cmd(async move { orders.skip().perform_cmd(async move {
let res: Result< let res: Result<
graphql_client::Response<graphql::remove_tag_mutation::ResponseData>, graphql_client::Response<graphql::remove_tag_mutation::ResponseData>,
@ -249,11 +244,7 @@ pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
error!("Failed to remove tag {tag} to {query}: {e}"); error!("Failed to remove tag {tag} to {query}: {e}");
} }
// TODO: reconsider this behavior // TODO: reconsider this behavior
seed::window() Msg::GoToSearchResults
.location()
.set_href(&search_url)
.expect("failed to change location");
Msg::Noop
}); });
} }
@ -637,6 +628,7 @@ pub enum Msg {
RefreshDone(Option<gloo_net::Error>), RefreshDone(Option<gloo_net::Error>),
NextPage, NextPage,
PreviousPage, PreviousPage,
GoToSearchResults,
UpdateQuery(String), UpdateQuery(String),
SearchQuery(String), SearchQuery(String),

View File

@ -760,14 +760,20 @@ fn thread(
attrs! {At::Title => "Mark as read"}, attrs! {At::Title => "Mark as read"},
span![C!["icon", "is-small"], i![C!["far", "fa-envelope-open"]]], span![C!["icon", "is-small"], i![C!["far", "fa-envelope-open"]]],
IF!(show_icon_text=>span!["Read"]), IF!(show_icon_text=>span!["Read"]),
ev(Ev::Click, move |_| Msg::SetUnread(read_thread_id, false)), ev(Ev::Click, move |_| Msg::MultiMsg(vec![
Msg::SetUnread(read_thread_id, false),
Msg::GoToSearchResults
])),
], ],
button![ button![
C!["button", "mark-unread"], C!["button", "mark-unread"],
attrs! {At::Title => "Mark as unread"}, attrs! {At::Title => "Mark as unread"},
span![C!["icon", "is-small"], i![C!["far", "fa-envelope"]]], span![C!["icon", "is-small"], i![C!["far", "fa-envelope"]]],
IF!(show_icon_text=>span!["Unread"]), IF!(show_icon_text=>span!["Unread"]),
ev(Ev::Click, move |_| Msg::SetUnread(unread_thread_id, true)), ev(Ev::Click, move |_| Msg::MultiMsg(vec![
Msg::SetUnread(unread_thread_id, true),
Msg::GoToSearchResults
])),
], ],
], ],
], ],
@ -782,7 +788,8 @@ fn thread(
IF!(show_icon_text=>span!["Spam"]), IF!(show_icon_text=>span!["Spam"]),
ev(Ev::Click, move |_| Msg::MultiMsg(vec![ ev(Ev::Click, move |_| Msg::MultiMsg(vec![
Msg::AddTag(spam_add_thread_id, "Spam".to_string()), Msg::AddTag(spam_add_thread_id, "Spam".to_string()),
Msg::SetUnread(spam_unread_thread_id, false) Msg::SetUnread(spam_unread_thread_id, false),
Msg::GoToSearchResults
])), ])),
], ],
], ],
@ -1060,14 +1067,20 @@ fn news_post(
attrs! {At::Title => "Mark as read"}, attrs! {At::Title => "Mark as read"},
span![C!["icon", "is-small"], i![C!["far", "fa-envelope-open"]]], span![C!["icon", "is-small"], i![C!["far", "fa-envelope-open"]]],
IF!(show_icon_text=>span!["Read"]), IF!(show_icon_text=>span!["Read"]),
ev(Ev::Click, move |_| Msg::SetUnread(read_thread_id, false)), ev(Ev::Click, move |_| Msg::MultiMsg(vec![
Msg::SetUnread(read_thread_id, false),
Msg::GoToSearchResults
])),
], ],
button![ button![
C!["button", "mark-unread"], C!["button", "mark-unread"],
attrs! {At::Title => "Mark as unread"}, attrs! {At::Title => "Mark as unread"},
span![C!["icon", "is-small"], i![C!["far", "fa-envelope"]]], span![C!["icon", "is-small"], i![C!["far", "fa-envelope"]]],
IF!(show_icon_text=>span!["Unread"]), IF!(show_icon_text=>span!["Unread"]),
ev(Ev::Click, move |_| Msg::SetUnread(unread_thread_id, true)), ev(Ev::Click, move |_| Msg::MultiMsg(vec![
Msg::SetUnread(unread_thread_id, true),
Msg::GoToSearchResults
])),
], ],
], ],
], ],
@ -1096,12 +1109,8 @@ fn news_post(
fn render_news_post_header(post: &ShowThreadQueryThreadOnNewsPost) -> Node<Msg> { fn render_news_post_header(post: &ShowThreadQueryThreadOnNewsPost) -> Node<Msg> {
let from = &post.site; let from = &post.site;
// TODO: move avatar/favicon stuff to the server side and and come up with a solution for emails // TODO: move avatar/favicon stuff to the server side and and come up with a solution for emails
let avatar: Option<String> = None;
//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;
// TODO: use https://www.google.com/s2/favicons?domain={domain}
let avatar = render_avatar(avatar, &from, true);
let url = &post.url; let url = &post.url;
let idx = url let idx = url
.match_indices('/') .match_indices('/')