web: style checkboxes, tweak mobile search bar width

This commit is contained in:
Bill Thiede 2025-01-26 13:42:20 -08:00
parent 89897aa48f
commit 44b60d5070

View File

@ -20,7 +20,8 @@ use crate::{
// format!() calls all over with magic strings representing notmuch specific syntax. // format!() calls all over with magic strings representing notmuch specific syntax.
const MAX_RAW_MESSAGE_SIZE: usize = 100_000; const MAX_RAW_MESSAGE_SIZE: usize = 100_000;
const BUTTON_CLASSES: &[&str] = &[ mod styles {
pub const BUTTON: &[&str] = &[
"bg-slate-900", "bg-slate-900",
"rounded-md", "rounded-md",
"p-2", "p-2",
@ -35,7 +36,19 @@ const BUTTON_CLASSES: &[&str] = &[
"disabled:pointer-events-none", "disabled:pointer-events-none",
"disabled:opacity-50", "disabled:opacity-50",
"disabled:shadow-none", "disabled:shadow-none",
]; ];
pub const CHECKBOX: &[&str] = &[
"w-8",
"h-8",
"accent-green-600",
"appearance-none",
"checked:appearance-auto",
"rounded",
"border",
"border-gray-500",
];
}
pub fn view(model: &Model) -> Node<Msg> { pub fn view(model: &Model) -> Node<Msg> {
let content = match &model.context { let content = match &model.context {
@ -65,7 +78,7 @@ pub fn view(model: &Model) -> Node<Msg> {
], ],
reading_progress(model.read_completion_ratio), reading_progress(model.read_completion_ratio),
div![ div![
C!["flex-auto", "p-4"], C!["flex-auto"],
view_header(&model.query, &model.refreshing_state, true), view_header(&model.query, &model.refreshing_state, true),
content, content,
view_header(&model.query, &model.refreshing_state, false), view_header(&model.query, &model.refreshing_state, false),
@ -94,15 +107,27 @@ fn search_results(
if let Some(idx) = unread_idx { if let Some(idx) = unread_idx {
tags.remove(idx); tags.remove(idx);
}; };
let is_unread = unread_idx.is_some();
// TODO: add check-all button, and tristate indicator
div![ div![
C!["NOTPORTED", "row"], C![
label![ "flex",
C!["NOTPORTED", "b-checkbox", "checkbox", "is-large"], "flex-nowrap",
input![attrs! { "w-auto",
"flex-auto",
"py-4",
"border-b",
"border-gray-800"
],
div![
C!["flex", "items-center", "mr-4"],
input![
C![&styles::CHECKBOX],
attrs! {
At::Type=>"checkbox", At::Type=>"checkbox",
At::Checked=>selected_threads.contains(&tid).as_at_value(), At::Checked=>selected_threads.contains(&tid).as_at_value(),
}], }
span![C!["NOTPORTED", "check"]], ],
ev(Ev::Input, move |e| { ev(Ev::Input, move |e| {
if let Some(input) = e if let Some(input) = e
.target() .target()
@ -121,29 +146,24 @@ fn search_results(
}), }),
], ],
a![ a![
C!["NOTPORTED", "has-text-light", "summary"], C!["flex-grow"],
IF!(unread_idx.is_some() => C!["NOTPORTED","unread"]), IF!(is_unread => C!["font-bold"]),
attrs! { attrs! {
At::Href => urls::thread(&tid) At::Href => urls::thread(&tid)
}, },
div![C!["NOTPORTED", "subject"], &r.subject], div![&r.subject],
span![ span![C!["text-xs"], pretty_authors(&r.authors)],
C!["NOTPORTED", "from", "is-size-7"],
pretty_authors(&r.authors)
],
div![ div![
span![C!["NOTPORTED", "is-size-7"], tags_chiclet(&tags, true)], C!["flex", "flex-wrap", "justify-between"],
span![ span![tags_chiclet(&tags, true)],
C!["NOTPORTED", "is-size-7", "float-right", "date"], span![C!["text-sm"], datetime]
datetime
]
] ]
] ]
] ]
}); });
let show_bulk_edit = !selected_threads.is_empty(); let show_bulk_edit = !selected_threads.is_empty();
div![ div![
C!["flex", "flex-col"], C!["flex", "flex-col", "flex-auto", "p-4"],
search_toolbar(count, pager, show_bulk_edit), search_toolbar(count, pager, show_bulk_edit),
div![rows], div![rows],
search_toolbar(count, pager, show_bulk_edit), search_toolbar(count, pager, show_bulk_edit),
@ -158,11 +178,18 @@ fn tags_chiclet(tags: &[String], is_mobile: bool) -> impl Iterator<Item = Node<M
tags.iter().map(move |tag| { tags.iter().map(move |tag| {
let hex = compute_color(tag); let hex = compute_color(tag);
let style = style! {St::BackgroundColor=>hex}; let style = style! {St::BackgroundColor=>hex};
let classes = C!["NOTPORTED", "tag", IF!(is_mobile => "is-small")]; let classes = C![
"rounded-md",
"px-2",
"py-1",
"mr-1",
"text-xs",
"[text-shadow:_0_1px_0_rgb(0_0_0_/_40%)]",
];
let tag = tag.clone(); let tag = tag.clone();
a![match tag.as_str() { a![match tag.as_str() {
"attachment" => span![classes, style, "📎"], "attachment" => span![classes, style, "📎"],
"replied" => span![classes, style, i![C!["NOTPORTED", "fa-solid", "fa-reply"]]], "replied" => span![classes, style, i![C!["fa-solid", "fa-reply"]]],
_ => span![classes, style, &tag], _ => span![classes, style, &tag],
},] },]
}) })
@ -363,19 +390,11 @@ fn view_search_results(
] ]
] ]
}); });
return h1!["HELLO"];
div![ div![
C!["NOTPORTED", "search-results"], C!["flex"],
search_toolbar(count, pager, show_bulk_edit), search_toolbar(count, pager, show_bulk_edit),
table![ div![
C![
"table",
"index",
"is-fullwidth",
"is-hoverable",
"is-narrow",
"is-striped",
],
thead![tr![ thead![tr![
th![ th![
C!["NOTPORTED", "edit"], C!["NOTPORTED", "edit"],
@ -420,14 +439,14 @@ fn search_toolbar(
div![ div![
div![ div![
button![ button![
C![&BUTTON_CLASSES, "rounded-r-none"], C![&styles::BUTTON, "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![
C![&BUTTON_CLASSES, "rounded-l-none"], C![&styles::BUTTON, "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"],
@ -439,7 +458,7 @@ fn search_toolbar(
div![ div![
div![ div![
button![ button![
C![&BUTTON_CLASSES, "text-red-500"], C![&styles::BUTTON, "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"],
@ -457,13 +476,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![
C![&BUTTON_CLASSES], C![&styles::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![
C![&BUTTON_CLASSES], C![&styles::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))
@ -979,10 +998,10 @@ fn view_header(
}; };
let query = Url::decode_uri_component(query).unwrap_or("".to_string()); let query = Url::decode_uri_component(query).unwrap_or("".to_string());
nav![ nav![
C!["flex"], C!["flex", "p-4"],
a![ a![
C![IF![is_error => "bg-red-500"], "rounded-r-none"], C![IF![is_error => "bg-red-500"], "rounded-r-none"],
C![&BUTTON_CLASSES], C![&styles::BUTTON],
span![i![C![ span![i![C![
"fa-solid", "fa-solid",
"fa-arrow-rotate-right", "fa-arrow-rotate-right",
@ -991,7 +1010,7 @@ fn view_header(
ev(Ev::Click, |_| Msg::RefreshStart), ev(Ev::Click, |_| Msg::RefreshStart),
], ],
a![ a![
C![&BUTTON_CLASSES], C![&styles::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)
@ -999,7 +1018,7 @@ fn view_header(
"Unread", "Unread",
], ],
a![ a![
C![&BUTTON_CLASSES], C![&styles::BUTTON],
C!["px-4", "rounded-none"], C!["px-4", "rounded-none"],
attrs! { attrs! {
At::Href => urls::search("", 0) At::Href => urls::search("", 0)
@ -1007,7 +1026,7 @@ fn view_header(
"All", "All",
], ],
input![ input![
C!["grow", "px-4", "text-black"], C!["grow", "pl-4", "text-black", "rounded-r"],
attrs! { attrs! {
At::Placeholder => "Search"; At::Placeholder => "Search";
At::AutoFocus => auto_focus_search.as_at_value(); At::AutoFocus => auto_focus_search.as_at_value();