diff options
author | 2025-04-11 15:10:25 +0100 | |
---|---|---|
committer | 2025-04-11 15:10:25 +0100 | |
commit | 80524e515406007915cb9978f403407a98c44e1e (patch) | |
tree | 895e7b8be01f6f13270c9f0604083df4be38b958 /src | |
parent | 4deb7470413a9d53323f6bedf26882ad2b0844a6 (diff) | |
download | macaw-80524e515406007915cb9978f403407a98c44e1e.tar.gz macaw-80524e515406007915cb9978f403407a98c44e1e.tar.bz2 macaw-80524e515406007915cb9978f403407a98c44e1e.zip |
feat: icons
Diffstat (limited to '')
-rw-r--r-- | src/icons.rs | 127 | ||||
-rw-r--r-- | src/main.rs | 87 | ||||
-rw-r--r-- | src/message_view.rs | 4 |
3 files changed, 178 insertions, 40 deletions
diff --git a/src/icons.rs b/src/icons.rs new file mode 100644 index 0000000..934a0c8 --- /dev/null +++ b/src/icons.rs @@ -0,0 +1,127 @@ +use iced::widget::svg; +use iced::widget::{svg::Handle, Svg}; +use iced::Element; + +pub enum Icon { + AddContact24, + Attachment24, + Away16, + Away16Color, + Bubble16, + Bubble16Color, + Bubble24, + Contact24, + Delivered16, + Dnd16, + Dnd16Color, + Error16Color, + Forward24, + Heart24, + NewBubble24, + Reply24, + Sending16, + Sent16, +} + +impl From<Icon> for Svg<'_> { + fn from(value: Icon) -> Self { + match value { + Icon::AddContact24 => svg(Handle::from_memory(include_bytes!( + "../assets/icons/addcontact24.svg" + ))) + .width(24) + .height(24), + Icon::Attachment24 => svg(Handle::from_memory(include_bytes!( + "../assets/icons/attachment24.svg" + ))) + .width(24) + .height(24), + Icon::Away16 => svg(Handle::from_memory(include_bytes!( + "../assets/icons/away16.svg" + ))) + .width(16) + .height(16), + Icon::Away16Color => svg(Handle::from_memory(include_bytes!( + "../assets/icons/away16color.svg" + ))) + .width(16) + .height(16), + Icon::Bubble16 => svg(Handle::from_memory(include_bytes!( + "../assets/icons/bubble16.svg" + ))) + .width(16) + .height(16), + Icon::Bubble16Color => svg(Handle::from_memory(include_bytes!( + "../assets/icons/bubble16color.svg" + ))) + .width(16) + .height(16), + Icon::Bubble24 => svg(Handle::from_memory(include_bytes!( + "../assets/icons/bubble24.svg" + ))) + .width(24) + .height(24), + Icon::Contact24 => svg(Handle::from_memory(include_bytes!( + "../assets/icons/contact24.svg" + ))) + .width(24) + .height(24), + Icon::Delivered16 => svg(Handle::from_memory(include_bytes!( + "../assets/icons/delivered16.svg" + ))) + .width(16) + .height(16), + Icon::Dnd16 => svg(Handle::from_memory(include_bytes!( + "../assets/icons/dnd16.svg" + ))) + .width(16) + .height(16), + Icon::Dnd16Color => svg(Handle::from_memory(include_bytes!( + "../assets/icons/dnd16color.svg" + ))) + .width(16) + .height(16), + Icon::Error16Color => svg(Handle::from_memory(include_bytes!( + "../assets/icons/error16color.svg" + ))) + .width(16) + .height(16), + Icon::Forward24 => svg(Handle::from_memory(include_bytes!( + "../assets/icons/forward24.svg" + ))) + .width(24) + .height(24), + Icon::Heart24 => svg(Handle::from_memory(include_bytes!( + "../assets/icons/heart24.svg" + ))) + .width(24) + .height(24), + Icon::NewBubble24 => svg(Handle::from_memory(include_bytes!( + "../assets/icons/newbubble24.svg" + ))) + .width(24) + .height(24), + Icon::Reply24 => svg(Handle::from_memory(include_bytes!( + "../assets/icons/reply24.svg" + ))) + .width(24) + .height(24), + Icon::Sending16 => svg(Handle::from_memory(include_bytes!( + "../assets/icons/sending16.svg" + ))) + .width(16) + .height(16), + Icon::Sent16 => svg(Handle::from_memory(include_bytes!( + "../assets/icons/sent16.svg" + ))) + .width(16) + .height(16), + } + } +} + +impl<Message> From<Icon> for Element<'_, Message> { + fn from(value: Icon) -> Self { + Into::<Svg>::into(value).into() + } +} diff --git a/src/main.rs b/src/main.rs index 0b8b3b8..106df79 100644 --- a/src/main.rs +++ b/src/main.rs @@ -23,10 +23,11 @@ use iced::widget::button::Status; use iced::widget::text::{Fragment, IntoFragment, Wrapping}; use iced::widget::{ button, center, checkbox, column, container, horizontal_space, image, mouse_area, opaque, row, - scrollable, stack, text, text_input, toggler, Column, Text, Toggler, + scrollable, stack, text, text_input, toggler, Column, Svg, Text, Toggler, }; use iced::Length::{self, Fill, Shrink}; use iced::{color, stream, Color, Element, Subscription, Task, Theme}; +use icons::Icon; use indexmap::{indexmap, IndexMap}; use jid::JID; use keyring::Entry; @@ -37,9 +38,10 @@ use thiserror::Error; use tokio::sync::mpsc::Sender; use tokio::sync::{mpsc, oneshot}; use tokio_stream::wrappers::ReceiverStream; -use tracing::{error, info}; +use tracing::{debug, error, info}; use uuid::Uuid; +mod icons; mod login_modal; mod message_view; @@ -488,6 +490,7 @@ async fn main() -> iced::Result { Task::stream(stream), ]) } else { + debug!("no auto connect"); Task::batch([ Task::perform( async move { luz_handle1.get_roster_with_users().await }, @@ -524,7 +527,7 @@ async fn main() -> iced::Result { }; iced::application("Macaw", Macaw::update, Macaw::view) .subscription(subscription) - .theme(Macaw::theme) + // .theme(Macaw::theme) .run_with(|| { ( Macaw::new( @@ -698,7 +701,8 @@ impl Macaw { } UpdateMessage::Presence { from, presence } => { // TODO: presence handling - self.presences.insert(from, presence); + info!("got presence from {:?} {:?}", from, presence); + self.presences.insert(from.as_bare(), presence); Task::none() } UpdateMessage::Message { to, message, from } => { @@ -886,7 +890,7 @@ impl Macaw { client.connection_state = ConnectionState::Connecting; let client = client.client.clone(); Task::future(async move { - client.connect().await; + client.connect().await.unwrap(); }) .discard() } @@ -896,7 +900,7 @@ impl Macaw { Account::LoggedIn(client) => { let client = client.client.clone(); Task::future(async move { - client.disconnect(Offline::default()).await; + client.disconnect(Offline::default()).await.unwrap(); }) .discard() } @@ -1105,8 +1109,13 @@ impl Macaw { open = true; } } - let chat_list_item = - chat_list_item(&self.roster, client.files_root(), chat, open); + let chat_list_item = chat_list_item( + &self.presences, + &self.roster, + client.files_root(), + chat, + open, + ); chats_list = chats_list.push(chat_list_item); } } @@ -1288,6 +1297,7 @@ where } fn chat_list_item<'a>( + presences: &HashMap<JID, Presence>, roster: &HashMap<JID, MacawContact>, file_root: &'a Path, chat_list_item: &'a ChatListItem, @@ -1339,36 +1349,37 @@ fn chat_list_item<'a>( latest_message_text = None; } - let avatar_image = if let Some(avatar) = avatar { + let mut avatar_stack = stack([]); + if let Some(avatar) = avatar { let mut path = file_root.join(avatar); path.set_extension("jpg"); info!("got avatar: {:?}", path); - Some(image(path).width(48).height(48)) - } else { - None - }; - let content: Element<Message> = if let Some(avatar_image) = avatar_image { - if let Some((message, time)) = latest_message_text { - row![ - avatar_image, - column![ - text(name), - row![ - container(text(message).wrapping(Wrapping::None)) - .clip(true) - .width(Fill), - text(time) - ] - .spacing(8) - .width(Fill) - ] - ] - .into() - } else { - row![avatar_image, text(name)].into() + avatar_stack = avatar_stack.push(image(path).width(48).height(48)); + } + let mut status_icon: Option<Icon> = None; + if let Some(presence) = presences.get(&chat_list_item.user.jid) { + debug!("found a presence"); + match &presence.presence { + PresenceType::Online(online) => match online.show { + Some(s) => match s { + filamento::presence::Show::Away => status_icon = Some(Icon::Away16Color), + filamento::presence::Show::Chat => status_icon = Some(Icon::Bubble16Color), + filamento::presence::Show::DoNotDisturb => status_icon = Some(Icon::Dnd16Color), + filamento::presence::Show::ExtendedAway => { + status_icon = Some(Icon::Away16Color) + } + }, + None => status_icon = Some(Icon::Bubble16Color), + }, + PresenceType::Offline(offline) => {} } - } else { - if let Some((message, time)) = latest_message_text { + } + if let Some(status_icon) = status_icon { + avatar_stack = avatar_stack.push(Into::<Svg>::into(status_icon)); + } + let content: Element<Message> = if let Some((message, time)) = latest_message_text { + row![ + avatar_stack, column![ text(name), row![ @@ -1380,10 +1391,10 @@ fn chat_list_item<'a>( .spacing(8) .width(Fill) ] - .into() - } else { - text(name).into() - } + ] + .into() + } else { + row![avatar_stack, text(name)].into() }; let mut button = button(content).on_press(Message::ToggleChat(chat_list_item.correspondent().clone())); diff --git a/src/message_view.rs b/src/message_view.rs index e936b69..fdb1a59 100644 --- a/src/message_view.rs +++ b/src/message_view.rs @@ -10,7 +10,7 @@ use indexmap::IndexMap; use serde::{Deserialize, Serialize}; use uuid::Uuid; -use crate::{MacawChat, MacawMessage}; +use crate::{icons::Icon, MacawChat, MacawMessage}; pub struct MessageView { // references chats, users @@ -152,7 +152,7 @@ impl MessageView { .wrapping(text::Wrapping::WordOrGlyph); let message_send_input = row![ text_editor, - button("send").on_press(Message::SendMessage(self.new_message.text())) + button(Icon::NewBubble24).on_press(Message::SendMessage(self.new_message.text())) ] .padding(8); column![ |