web: have colored initials for From

Add scaffolding for profile pics
This commit is contained in:
Bill Thiede 2024-02-22 20:37:21 -08:00
parent 3f268415e9
commit 42484043a1
2 changed files with 73 additions and 16 deletions

View File

@ -11,8 +11,12 @@
<link rel="icon" href="https://static.xinu.tv/favicon/letterbox.svg" /> <link rel="icon" href="https://static.xinu.tv/favicon/letterbox.svg" />
<!-- Pretty checkboxes from https://justboil.github.io/bulma-checkbox/ --> <!-- Pretty checkboxes from https://justboil.github.io/bulma-checkbox/ -->
<link data-trunk rel="css" href="static/main.css" /> <link data-trunk rel="css" href="static/main.css" />
<!-- tall thin font for user icon -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@700&display=swap" rel="stylesheet">
<style> <style>
.message { <style>.message {
display: inline-block; display: inline-block;
padding: 0.5em; padding: 0.5em;
width: 100%; width: 100%;
@ -151,8 +155,8 @@
} }
.mobile .thread h3 { .mobile .thread h3 {
padding: 1em 1em 0;
overflow-wrap: break-word; overflow-wrap: break-word;
padding: 1em 1em 0;
} }
.mobile .thread .tags { .mobile .thread .tags {

View File

@ -26,11 +26,15 @@ fn set_title(title: &str) {
seed::document().set_title(&format!("lb: {}", title)); seed::document().set_title(&format!("lb: {}", title));
} }
fn compute_color(data: &str) -> String {
let mut hasher = DefaultHasher::new();
data.hash(&mut hasher);
format!("#{:06x}", hasher.finish() % (1 << 24))
}
fn tags_chiclet(tags: &[String], is_mobile: bool) -> impl Iterator<Item = Node<Msg>> + '_ { fn tags_chiclet(tags: &[String], is_mobile: bool) -> impl Iterator<Item = Node<Msg>> + '_ {
tags.iter().map(move |tag| { tags.iter().map(move |tag| {
let mut hasher = DefaultHasher::new(); let hex = compute_color(tag);
tag.hash(&mut hasher);
let hex = format!("#{:06x}", hasher.finish() % (1 << 24));
let style = style! {St::BackgroundColor=>hex}; let style = style! {St::BackgroundColor=>hex};
let classes = C!["tag", IF!(is_mobile => "is-small")]; let classes = C!["tag", IF!(is_mobile => "is-small")];
let tag = tag.clone(); let tag = tag.clone();
@ -355,26 +359,75 @@ 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);
let avatar: Option<String> = None;
//let avatar: Option<String> = Some(String::from("https://bulma.io/images/placeholders/64x64.png"));
let from: String = match &msg.from {
Some(ShowThreadQueryThreadMessagesFrom {
name: Some(name), ..
}) => name.to_string(),
Some(ShowThreadQueryThreadMessagesFrom {
addr: Some(addr), ..
}) => addr.to_string(),
_ => String::from("UNKNOWN"),
};
let initials: String = from
.to_lowercase()
.split(" ")
.map(|word| word.chars().next().unwrap())
// Limit to 2 characters because more characters don't fit in the box
.take(2)
.collect();
let img = if let Some(src) = avatar {
img![attrs! {At::Src=>src}]
} else {
let w = 64;
let h = 64;
let from_color = compute_color(&from);
svg![
attrs! {At::ViewBox=>format!("0 0 {w} {h}") },
style! {
St::Display => "block",
St::FontFamily => "Poppins",
St::FontSize => pt(32),
},
g![
rect![attrs! {
At::Fill=>from_color,
At::Stroke=>"black",
At::StrokeWidth=>"1",
// Round corners
//At::Rx => px(10),
At::X => 0,
At::Y => 0,
At::Width => h,
At::Height => h,
}],
text![
attrs! {
At::Fill => "white",
At::X => percent(50),
At::Y => percent(50),
At::DominantBaseline => "middle",
At::TextAnchor => "middle"
},
initials
]
]
]
};
div![ div![
C!["message"], C!["message"],
article![ article![
C!["media"], C!["media"],
figure![ figure![C!["media-left"], p![C!["image", "is-64x64"], img],],
C!["media-left"],
p![
C!["image", "is-64x64"],
img![attrs! {At::Src=>"https://bulma.io/images/placeholders/128x128.png"}],
],
],
div![ div![
C!["media-content"], C!["media-content"],
div![ div![
C!["content"], C!["content"],
p![ p![
msg.from.as_ref().map(|from| strong![from strong![from],
.name()
.as_ref()
.unwrap_or(&from.addr().unwrap_or("(UNKNOWN)"))]),
br![], br![],
IF!(!msg.to.is_empty() => IF!(!msg.to.is_empty() =>
nodes![ nodes![