diff options
author | 2025-05-07 00:26:44 +0100 | |
---|---|---|
committer | 2025-05-07 00:26:44 +0100 | |
commit | d83baa78b0b029a5c25b781ee3f77ae3cbecf60d (patch) | |
tree | dfb12503c069dfd7a8d969119957fdb619a418c4 /src/lib.rs | |
parent | 7859947fcc643a96d20b7c56df912d8e3230429d (diff) | |
download | macaw-web-d83baa78b0b029a5c25b781ee3f77ae3cbecf60d.tar.gz macaw-web-d83baa78b0b029a5c25b781ee3f77ae3cbecf60d.tar.bz2 macaw-web-d83baa78b0b029a5c25b781ee3f77ae3cbecf60d.zip |
feat: message sent icons
Diffstat (limited to '')
-rw-r--r-- | src/lib.rs | 109 |
1 files changed, 103 insertions, 6 deletions
@@ -13,7 +13,7 @@ use std::{ use chrono::{NaiveDateTime, TimeDelta}; use filamento::{ - chat::{Body, Chat, ChatStoreFields, Message, MessageStoreFields}, db::Db, error::{CommandError, ConnectionError, DatabaseError}, files::FilesMem, roster::{Contact, ContactStoreFields}, user::{User, UserStoreFields}, UpdateMessage + chat::{Body, Chat, ChatStoreFields, Delivery, Message, MessageStoreFields}, db::Db, error::{CommandError, ConnectionError, DatabaseError}, files::FilesMem, roster::{Contact, ContactStoreFields}, user::{User, UserStoreFields}, UpdateMessage }; use futures::stream::StreamExt; use indexmap::IndexMap; @@ -605,13 +605,110 @@ pub fn MessageHistoryBuffer(chat: MacawChat) -> impl IntoView { view! { <div class="messages-buffer"> - <For each=each key=|message| message.0 let(message)> + <For each=each key=|message| (message.0, message.1.1, message.1.2) let(message)> <Message message=message.1.0 major=message.1.1 r#final=message.1.2 /> </For> </div> } } +#[derive(Copy, Clone)] +pub enum Icon { + AddContact24, + Attachment24, + Away16, + Away16Color, + Bubble16, + Bubble16Color, + Bubble24, + Contact24, + Delivered16, + Dnd16, + Dnd16Color, + Error16Color, + Forward24, + Heart24, + NewBubble24, + Reply24, + Sending16, + Sent16, +} + +pub const ICONS_SRC: &str = "/assets/icons/"; + +impl Icon { + pub fn src(&self) -> String { + match self { + Icon::AddContact24 => format!("{}addcontact24.svg", ICONS_SRC), + Icon::Attachment24 => format!("{}attachment24.svg", ICONS_SRC), + Icon::Away16 => format!("{}away16.svg", ICONS_SRC), + Icon::Away16Color => format!("{}away16color.svg", ICONS_SRC), + Icon::Bubble16 => format!("{}bubble16.svg", ICONS_SRC), + Icon::Bubble16Color => format!("{}bubble16color.svg", ICONS_SRC), + Icon::Bubble24 => format!("{}bubble24.svg", ICONS_SRC), + Icon::Contact24 => format!("{}contact24.svg", ICONS_SRC), + Icon::Delivered16 => format!("{}delivered16.svg", ICONS_SRC), + Icon::Dnd16 => format!("{}dnd16.svg", ICONS_SRC), + Icon::Dnd16Color => format!("{}dnd16color.svg", ICONS_SRC), + Icon::Error16Color => format!("{}error16color.svg", ICONS_SRC), + Icon::Forward24 => format!("{}forward24.svg", ICONS_SRC), + Icon::Heart24 => format!("{}heart24.svg", ICONS_SRC), + Icon::NewBubble24 => format!("{}newbubble24.svg", ICONS_SRC), + Icon::Reply24 => format!("{}reply24.svg", ICONS_SRC), + Icon::Sending16 => format!("{}sending16.svg", ICONS_SRC), + Icon::Sent16 => format!("{}sent16.svg", ICONS_SRC), + } + } + + pub fn size(&self) -> isize { + match self { + Icon::AddContact24 => 24, + Icon::Attachment24 => 24, + Icon::Away16 => 16, + Icon::Away16Color => 16, + Icon::Bubble16 => 16, + Icon::Bubble16Color => 16, + Icon::Bubble24 => 24, + Icon::Contact24 => 24, + Icon::Delivered16 => 16, + Icon::Dnd16 => 16, + Icon::Dnd16Color => 16, + Icon::Error16Color => 16, + Icon::Forward24 => 24, + Icon::Heart24 => 24, + Icon::NewBubble24 => 24, + Icon::Reply24 => 24, + Icon::Sending16 => 16, + Icon::Sent16 => 16, + } + } +} + +#[component] +pub fn IconComponent(icon: Icon) -> impl IntoView { + view! { + <img class:icon=true style=move || format!("height: {}px; width: {}px", icon.size(), icon.size()) src=move || icon.src() /> + } +} + +#[component] +pub fn Delivery(delivery: Delivery) -> impl IntoView { + match delivery { + // TODO: proper icon coloring/theming + Delivery::Sending => view! { <IconComponent class:visible=true class:light=true icon=Icon::Sending16 /> }.into_any(), + Delivery::Written => view! { <IconComponent class:light=true icon=Icon::Sent16 /> }.into_any(), + // TODO: message receipts + // Delivery::Written => view! {}.into_any(), + Delivery::Sent => view! { <IconComponent class:light=true icon=Icon::Sent16 /> }.into_any(), + Delivery::Delivered => view! { <IconComponent class:light=true icon=Icon::Delivered16 /> }.into_any(), + // TODO: check if there is also the icon class + Delivery::Read => view! { <IconComponent class:light=true class:read=true icon=Icon::Delivered16 /> }.into_any(), + Delivery::Failed => view! { <IconComponent class:visible=true class:light=true icon=Icon::Error16Color /> }.into_any(), + // TODO: queued icon + Delivery::Queued => view! { <IconComponent class:visible=true class:light=true icon=Icon::Sending16 /> }.into_any(), + } +} + #[component] pub fn Message(message: MacawMessage, major: bool, r#final: bool) -> impl IntoView { let message_message = *message.message; @@ -624,7 +721,7 @@ pub fn Message(message: MacawMessage, major: bool, r#final: bool) -> impl IntoVi // {move || message_message.delivery().read().map(|delivery| delivery.to_string()).unwrap_or_default()} if major { view! { - <div class="chat-message major"> + <div class:final=r#final class="chat-message major"> <div class="left"><img class="avatar" src=avatar /></div> <div class="middle"> <div class="message-info"> @@ -635,17 +732,17 @@ pub fn Message(message: MacawMessage, major: bool, r#final: bool) -> impl IntoVi {move || message_message.body().read().body.clone()} </div> </div> - <div class="right message-delivery"></div> + <div class="right message-delivery">{move || message_message.delivery().get().map(|delivery| view! { <Delivery class:light=true delivery /> } ) }</div> </div> }.into_any() } else { view! { - <div class="chat-message minor"> + <div class:final=r#final class="chat-message minor"> <div class="left message-timestamp"> {move || message_message.timestamp().read().format("%H:%M").to_string()} </div> <div class="middle message-text">{move || message_message.body().read().body.clone()}</div> - <div class="right message-delivery"></div> + <div class="right message-delivery">{move || message_message.delivery().get().map(|delivery| view! { <Delivery delivery /> } ) }</div> </div> }.into_any() } |