summaryrefslogtreecommitdiffstats
path: root/src/lib.rs
diff options
context:
space:
mode:
authorLibravatar cel 🌸 <cel@bunny.garden>2025-05-07 00:26:44 +0100
committerLibravatar cel 🌸 <cel@bunny.garden>2025-05-07 00:26:44 +0100
commitd83baa78b0b029a5c25b781ee3f77ae3cbecf60d (patch)
treedfb12503c069dfd7a8d969119957fdb619a418c4 /src/lib.rs
parent7859947fcc643a96d20b7c56df912d8e3230429d (diff)
downloadmacaw-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.rs109
1 files changed, 103 insertions, 6 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 7ff95d7..d45bfc3 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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()
}