diff options
author | 2025-06-11 22:17:11 +0100 | |
---|---|---|
committer | 2025-06-11 22:17:11 +0100 | |
commit | adeac2e7cd93ea449de0ce30247adbd13cd7120d (patch) | |
tree | 4b12fa401cdfd84780f39e46c9517e705641009c | |
parent | 2cac8c729c8ee175f01f677f285382349a7f9f62 (diff) | |
download | macaw-web-adeac2e7cd93ea449de0ce30247adbd13cd7120d.tar.gz macaw-web-adeac2e7cd93ea449de0ce30247adbd13cd7120d.tar.bz2 macaw-web-adeac2e7cd93ea449de0ce30247adbd13cd7120d.zip |
feat: date dividers
-rw-r--r-- | assets/style.scss | 18 | ||||
-rw-r--r-- | src/components/message.rs | 122 | ||||
-rw-r--r-- | src/components/message_history_buffer.rs | 29 |
3 files changed, 110 insertions, 59 deletions
diff --git a/assets/style.scss b/assets/style.scss index 1aa37d9..f6e1d55 100644 --- a/assets/style.scss +++ b/assets/style.scss @@ -419,6 +419,24 @@ background: #00000060; overflow-y: scroll; } + +.messages-buffer .new-day { + display: flex; + align-items: center; + margin: 0.5em 0 0 0; + /* margin: 1em -1em; */ + + + &:before, + &:after { + content: ""; + flex: 1; + height: 2px; + margin: 0 1em; + background: black; + } +} + .chat-message { display: flex; padding: 4px 0; diff --git a/src/components/message.rs b/src/components/message.rs index 9eb0b09..1ddb603 100644 --- a/src/components/message.rs +++ b/src/components/message.rs @@ -4,69 +4,91 @@ use reactive_stores::{ArcStore, Store}; use crate::{ message::MacawMessage, - user::{NO_AVATAR, get_avatar, get_name}, + user::{get_avatar, get_name, NO_AVATAR}, }; use super::icon::Delivery; #[component] -pub fn Message(message: MacawMessage, major: bool, r#final: bool) -> impl IntoView { +pub fn Message(message: MacawMessage, major: bool, r#final: bool, new_day: bool) -> impl IntoView { let name = move || get_name(message.user.get().into(), false); // TODO: chrono-humanize? // TODO: if final, show delivery not only on hover. // {move || message_message.delivery().read().map(|delivery| delivery.to_string()).unwrap_or_default()} - if major { - view! { - <div class:final=r#final class="chat-message major"> - <div class="left"> - <Transition fallback=|| view! { <img class="avatar" src=NO_AVATAR /> }> - <img class="avatar" src=move || message.user.avatar().get() /> - </Transition> - </div> - <div class="middle"> - <div class="message-info"> - <div class="message-user-name">{name}</div> - <div class="message-timestamp"> + view! { + {move || { + if major { + view! { + <div class:final=r#final class="chat-message major"> + <div class="left"> + <Transition fallback=|| view! { <img class="avatar" src=NO_AVATAR /> }> + <img class="avatar" src=move || message.user.avatar().get() /> + </Transition> + </div> + <div class="middle"> + <div class="message-info"> + <div class="message-user-name">{name}</div> + <div class="message-timestamp"> + {move || { + message.get().timestamp().read().format("%H:%M").to_string() + }} + </div> + </div> + <div class="message-text"> + {move || message.get().body().read().body.clone()} + </div> + </div> + <div class="right message-delivery"> + {move || { + message + .get() + .delivery() + .get() + .map(|delivery| { + view! { <Delivery class:light=true delivery /> } + }) + }} + </div> + </div> + } + .into_any() + } else { + view! { + <div class:final=r#final class="chat-message minor"> + <div class="left message-timestamp"> {move || message.get().timestamp().read().format("%H:%M").to_string()} </div> + <div class="middle message-text"> + {move || message.get().body().read().body.clone()} + </div> + <div class="right message-delivery"> + {move || { + message + .get() + .delivery() + .get() + .map(|delivery| view! { <Delivery delivery /> }) + }} + </div> </div> - <div class="message-text"> - {move || message.get().body().read().body.clone()} + } + .into_any() + } + }} + {move || { + if new_day { + view! { + <div class="new-day"> + {move || { + message.get().timestamp().read().format("%Y-%m-%d").to_string() + }} </div> - </div> - <div class="right message-delivery"> - {move || { - message - .get() - .delivery() - .get() - .map(|delivery| view! { <Delivery class:light=true delivery /> }) - }} - </div> - </div> - } - .into_any() - } else { - view! { - <div class:final=r#final class="chat-message minor"> - <div class="left message-timestamp"> - {move || message.get().timestamp().read().format("%H:%M").to_string()} - </div> - <div class="middle message-text"> - {move || message.get().body().read().body.clone()} - </div> - <div class="right message-delivery"> - {move || { - message - .get() - .delivery() - .get() - .map(|delivery| view! { <Delivery delivery /> }) - }} - </div> - </div> - } - .into_any() + } + .into_any() + } else { + view! {}.into_any() + } + }} } } diff --git a/src/components/message_history_buffer.rs b/src/components/message_history_buffer.rs index cf4c328..9dc0473 100644 --- a/src/components/message_history_buffer.rs +++ b/src/components/message_history_buffer.rs @@ -111,23 +111,25 @@ pub fn MessageHistoryBuffer(chat: MacawChat) -> impl IntoView { .into_iter() .map(|(id, message)| { let message_timestamp = message.message.get().timestamp().read().naive_local(); - // TODO: mark new day - // if message_timestamp.date() > last_timestamp.date() { - // messages_view = messages_view.push(date(message_timestamp.date())); - // } - let major = if last_user.as_ref() != Some(&message.message.get().read().from) + let mut major = if last_user.as_ref() != Some(&message.message.get().read().from) || message_timestamp - last_timestamp > TimeDelta::minutes(3) { true } else { false }; + let new_day = if message_timestamp.date() > last_timestamp.date() { + major = true; + true + } else { + false + }; last_user = Some(message.get().from().get()); last_timestamp = message_timestamp; - (id, (message, major, false)) + (id, (message, major, false, new_day)) }) .collect::<Vec<_>>(); - if let Some((_id, (_, _, last))) = messages.last_mut() { + if let Some((_id, (_, _, last, _))) = messages.last_mut() { *last = true } messages.into_iter().rev() @@ -135,8 +137,17 @@ pub fn MessageHistoryBuffer(chat: MacawChat) -> impl IntoView { view! { <div class="messages-buffer"> - <For each=each key=|message| (message.0, message.1.1, message.1.2) let(message)> - <Message message=message.1.0.into() major=message.1.1 r#final=message.1.2 /> + <For + each=each + key=|message| (message.0, message.1.1, message.1.2, message.1.3) + let(message) + > + <Message + message=message.1.0.into() + major=message.1.1 + r#final=message.1.2 + new_day=message.1.3 + /> </For> </div> } |