web: rework header in thread view, tweak some styles, remove some logging

This commit is contained in:
Bill Thiede 2024-02-22 18:54:34 -08:00
parent c2a5fe19e3
commit 3f268415e9
3 changed files with 79 additions and 94 deletions

View File

@ -38,11 +38,11 @@
.body { .body {
background: white; background: white;
color: black; color: black;
margin-left: -0.5em;
margin-right: -0.5em;
margin-top: 0.5em; margin-top: 0.5em;
padding: 1em;
width: 0; width: 0;
min-width: 100%; min-width: 100%;
overflow-wrap: break-word;
} }
.error { .error {
@ -146,11 +146,19 @@
color: #555; color: #555;
} }
.mobile .search-results, .mobile .search-results {
.mobile .thread {
padding: 1em; padding: 1em;
} }
.mobile .thread h3 {
padding: 1em 1em 0;
overflow-wrap: break-word;
}
.mobile .thread .tags {
padding: 0 1em;
}
.search-results .row { .search-results .row {
display: flex; display: flex;
flex-direction: row; flex-direction: row;

View File

@ -180,7 +180,6 @@ pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
first, first,
last, last,
} => { } => {
info!("making FrontPageRequest: {query} after:{after:?} before:{before:?} first:{first:?} last:{last:?}");
model.query = query.clone(); model.query = query.clone();
orders.skip().perform_cmd(async move { orders.skip().perform_cmd(async move {
Msg::FrontPageResult( Msg::FrontPageResult(
@ -336,7 +335,6 @@ pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
} = &mut model.context } = &mut model.context
{ {
selected_threads.insert(tid); selected_threads.insert(tid);
info!("selected threads {selected_threads:?}");
} }
} }
Msg::SelectionRemoveThread(tid) => { Msg::SelectionRemoveThread(tid) => {
@ -345,19 +343,16 @@ pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
} = &mut model.context } = &mut model.context
{ {
selected_threads.remove(&tid); selected_threads.remove(&tid);
info!("selected threads {selected_threads:?}");
} }
} }
Msg::MessageCollapse(id) => { Msg::MessageCollapse(id) => {
if let Context::ThreadResult { open_messages, .. } = &mut model.context { if let Context::ThreadResult { open_messages, .. } = &mut model.context {
open_messages.remove(&id); open_messages.remove(&id);
info!("open_messages threads {open_messages:?}");
} }
} }
Msg::MessageExpand(id) => { Msg::MessageExpand(id) => {
if let Context::ThreadResult { open_messages, .. } = &mut model.context { if let Context::ThreadResult { open_messages, .. } = &mut model.context {
open_messages.insert(id); open_messages.insert(id);
info!("open_messages threads {open_messages:?}");
} }
} }
} }

View File

@ -5,7 +5,7 @@ use std::{
use chrono::{DateTime, Datelike, Duration, Local, Utc}; use chrono::{DateTime, Datelike, Duration, Local, Utc};
use itertools::Itertools; use itertools::Itertools;
use log::error; use log::{error, info};
use seed::{prelude::*, *}; use seed::{prelude::*, *};
use seed_hooks::{state_access::CloneState, topo, use_state}; use seed_hooks::{state_access::CloneState, topo, use_state};
use wasm_timer::Instant; use wasm_timer::Instant;
@ -351,90 +351,75 @@ fn has_unread(tags: &[String]) -> bool {
tags.contains(&String::from("unread")) tags.contains(&String::from("unread"))
} }
fn read_message_render(msg: &ShowThreadQueryThreadMessages, open: bool) -> Node<Msg> { fn message_render(msg: &ShowThreadQueryThreadMessages, open: bool) -> Node<Msg> {
let id = msg.id.clone(); let id = msg.id.clone();
let expand_id = msg.id.clone(); let expand_id = msg.id.clone();
let is_unread = has_unread(&msg.tags); let is_unread = has_unread(&msg.tags);
div![ div![
C!["message"], C!["message"],
div![ article![
C!["headers"], C!["media"],
span![ figure![
C!["read-status"], C!["media-left"],
i![ p![
style! { C!["image", "is-64x64"],
St::Color => "gold" img![attrs! {At::Src=>"https://bulma.io/images/placeholders/128x128.png"}],
},
C![
"far",
if is_unread {
"fa-envelope"
} else {
"fa-envelope-open"
},
],
ev(Ev::Click, move |e| {
e.stop_propagation();
Msg::SetUnread(format!("id:{id}"), !is_unread)
}),
], ],
], ],
" ",
msg.from
.as_ref()
.map(|from| span![C!["header"], view_address(&from)]),
" ",
msg.timestamp.map(|ts| span![C!["header"], human_age(ts)]),
// TODO(wathiede): add first line of message body
],
ev(Ev::Click, move |e| {
e.stop_propagation();
if open {
Msg::MessageCollapse(expand_id)
} else {
Msg::MessageExpand(expand_id)
}
}),
]
}
fn unread_message_render(msg: &ShowThreadQueryThreadMessages, open: bool) -> Node<Msg> {
let id = msg.id.clone();
let expand_id = msg.id.clone();
let is_unread = has_unread(&msg.tags);
div![
C!["message"],
div![
C!["headers"],
span![
C!["read-status"],
i![
style! {
St::Color => "gold"
},
C![
"far",
if is_unread {
"fa-envelope"
} else {
"fa-envelope-open"
},
],
ev(Ev::Click, move |e| {
e.stop_propagation();
Msg::SetUnread(format!("id:{id}"), !is_unread)
}),
],
],
msg.from
.as_ref()
.map(|from| div![C!["header"], "From: ", view_address(&from)]),
msg.timestamp
.map(|ts| div![C!["header"], "Date: ", human_age(ts)]),
div![C!["header"], "Message-ID: ", &msg.id],
div![ div![
C!["header"], C!["media-content"],
IF!(!msg.to.is_empty() => span!["To: ", view_addresses(&msg.to)]), div![
IF!(!msg.cc.is_empty() => span!["CC: ", view_addresses(&msg.cc)]) C!["content"],
p![
msg.from.as_ref().map(|from| strong![from
.name()
.as_ref()
.unwrap_or(&from.addr().unwrap_or("(UNKNOWN)"))]),
br![],
IF!(!msg.to.is_empty() =>
nodes![
small![" to "],
msg.to.iter().enumerate().map(|(i, to)| small![
if i > 0 { ", " } else { "" },
to.name()
.as_ref()
.unwrap_or(&to.addr().unwrap_or("(UNKNOWN)"))
]).collect::<Vec<_>>()
]),
IF!(!msg.cc.is_empty() =>
nodes![
small![" cc "],
msg.cc.iter().enumerate().map(|(i, cc)| small![
if i > 0 { ", " } else { "" },
cc.name()
.as_ref()
.unwrap_or(&cc.addr().unwrap_or("(UNKNOWN)"))
]).collect::<Vec<_>>()
]),
br![],
msg.timestamp.map(|ts| span![C!["header"], human_age(ts)]),
],
],
],
div![
C!["media-right"],
span![
C!["read-status"],
i![
C![
"far",
if is_unread {
"fa-envelope"
} else {
"fa-envelope-open"
},
],
ev(Ev::Click, move |e| {
e.stop_propagation();
Msg::SetUnread(format!("id:{id}"), !is_unread)
}),
],
],
], ],
ev(Ev::Click, move |e| { ev(Ev::Click, move |e| {
e.stop_propagation(); e.stop_propagation();
@ -445,6 +430,7 @@ fn unread_message_render(msg: &ShowThreadQueryThreadMessages, open: bool) -> Nod
} }
}), }),
], ],
IF!(open =>
div![ div![
C!["body"], C!["body"],
match &msg.body { match &msg.body {
@ -480,7 +466,7 @@ fn unread_message_render(msg: &ShowThreadQueryThreadMessages, open: bool) -> Nod
view_content_tree(&content_tree), view_content_tree(&content_tree),
], ],
} }
], ])
] ]
} }
@ -500,18 +486,14 @@ fn thread(thread: &ShowThreadQueryThread, open_messages: &HashSet<String>) -> No
tags.sort(); tags.sort();
let messages = thread.messages.iter().map(|msg| { let messages = thread.messages.iter().map(|msg| {
let open = open_messages.contains(&msg.id); let open = open_messages.contains(&msg.id);
if open { message_render(&msg, open)
unread_message_render(&msg, open)
} else {
read_message_render(&msg, open)
}
}); });
let read_thread_id = thread.thread_id.clone(); let read_thread_id = thread.thread_id.clone();
let unread_thread_id = thread.thread_id.clone(); let unread_thread_id = thread.thread_id.clone();
div![ div![
C!["thread"], C!["thread"],
h3![C!["is-size-5"], &thread.subject,], h3![C!["is-size-5"], &thread.subject],
tags_chiclet(&tags, false), span![C!["tags"], tags_chiclet(&tags, false)],
span![ span![
C!["level-item", "buttons", "has-addons"], C!["level-item", "buttons", "has-addons"],
button![ button![