From a13d5d1254b7e835dd76d6cd9ade8aa6633f033e Mon Sep 17 00:00:00 2001 From: Waradu Date: Sat, 16 Nov 2024 12:29:50 +0100 Subject: [PATCH] feat: message images --- src/chat/src/message.rs | 1 + src/discord/src/channel/mod.rs | 6 +++++- src/discord/src/client.rs | 17 ++++++++++++++++- src/discord/src/message/content.rs | 16 +++++++++++++++- src/discord/src/message/mod.rs | 7 ++++++- src/ui/src/channel/message.rs | 2 +- 6 files changed, 44 insertions(+), 5 deletions(-) diff --git a/src/chat/src/message.rs b/src/chat/src/message.rs index 7cf0a9e..000721a 100644 --- a/src/chat/src/message.rs +++ b/src/chat/src/message.rs @@ -3,6 +3,7 @@ use gpui::Element; pub trait Message: Clone { fn get_author(&self) -> &impl MessageAuthor; fn get_content(&self) -> impl Element; + fn get_images(&self) -> impl Element; fn get_identifier(&self) -> String; fn get_nonce(&self) -> Option<&String>; } diff --git a/src/discord/src/channel/mod.rs b/src/discord/src/channel/mod.rs index 7a4359f..76337a0 100644 --- a/src/discord/src/channel/mod.rs +++ b/src/discord/src/channel/mod.rs @@ -7,7 +7,7 @@ use crate::{ client::DiscordClient, message::{ author::{DiscordMessageAuthor, DisplayName}, - content::DiscordMessageContent, + content::{DiscordImageContent, DiscordMessageContent}, DiscordMessage, }, snowflake::Snowflake, @@ -53,6 +53,10 @@ impl Channel for DiscordChannel { DiscordMessage { content: DiscordMessageContent { content, is_pending: true }, author: self.client.user().clone(), + images: DiscordImageContent { + images: vec![], + is_pending: true, + }, id: Snowflake { content: 0 }, nonce: Some(nonce), } diff --git a/src/discord/src/client.rs b/src/discord/src/client.rs index c232f75..7841ad1 100644 --- a/src/discord/src/client.rs +++ b/src/discord/src/client.rs @@ -16,7 +16,7 @@ use tokio::sync::{broadcast, Mutex, RwLock}; use crate::{ message::{ author::{DiscordMessageAuthor, DisplayName}, - content::DiscordMessageContent, + content::{DiscordImageContent, DiscordMessageContent}, DiscordMessage, }, snowflake::{self, Snowflake}, @@ -108,6 +108,21 @@ impl EventHandler for DiscordClient { display_name: DisplayName(msg.author.name.clone()), icon: msg.author.avatar_url().unwrap_or(msg.author.default_avatar_url()), }, + images: DiscordImageContent { + images: msg + .attachments + .clone() + .into_iter() + .filter(|attachment| { + if let Some(content_type) = &attachment.content_type { + content_type.starts_with("image/") + } else { + false + } + }) + .collect(), + is_pending: false, + }, content: DiscordMessageContent { content: msg.content.clone(), is_pending: false, diff --git a/src/discord/src/message/content.rs b/src/discord/src/message/content.rs index 2289177..4cc2a48 100644 --- a/src/discord/src/message/content.rs +++ b/src/discord/src/message/content.rs @@ -1,4 +1,5 @@ -use gpui::{div, IntoElement, ParentElement, Render, RenderOnce, Styled, WindowContext}; +use gpui::{div, img, px, IntoElement, ParentElement, Render, RenderOnce, Styled, WindowContext}; +use serenity::all::Attachment; #[derive(Clone, IntoElement)] pub struct DiscordMessageContent { @@ -6,8 +7,21 @@ pub struct DiscordMessageContent { pub is_pending: bool, } +#[derive(Clone, IntoElement)] +pub struct DiscordImageContent { + pub images: Vec, + pub is_pending: bool, +} + impl RenderOnce for DiscordMessageContent { fn render(self, _: &mut WindowContext) -> impl IntoElement { div().opacity(if self.is_pending { 0.25 } else { 1.0 }).child(self.content.clone()) } } +impl RenderOnce for DiscordImageContent { + fn render(self, _: &mut WindowContext) -> impl IntoElement { + div() + .opacity(if self.is_pending { 0.25 } else { 1.0 }) + .children(self.images.into_iter().map(|image| img(image.url).object_fit(gpui::ObjectFit::Contain).rounded_2xl().h(px(128.)).w(px(128.)))) + } +} diff --git a/src/discord/src/message/mod.rs b/src/discord/src/message/mod.rs index 650a1a4..1774a1a 100644 --- a/src/discord/src/message/mod.rs +++ b/src/discord/src/message/mod.rs @@ -1,5 +1,5 @@ use author::DiscordMessageAuthor; -use content::DiscordMessageContent; +use content::{DiscordImageContent, DiscordMessageContent}; use gpui::{Element, IntoElement}; use scope_chat::message::Message; @@ -11,6 +11,7 @@ pub mod content; #[derive(Clone)] pub struct DiscordMessage { pub content: DiscordMessageContent, + pub images: DiscordImageContent, pub author: DiscordMessageAuthor, pub id: Snowflake, pub nonce: Option, @@ -25,6 +26,10 @@ impl Message for DiscordMessage { self.content.clone().into_element() } + fn get_images(&self) -> impl Element { + self.images.clone().into_element() + } + fn get_identifier(&self) -> String { self.id.to_string() } diff --git a/src/ui/src/channel/message.rs b/src/ui/src/channel/message.rs index 5b6afda..a823a4c 100644 --- a/src/ui/src/channel/message.rs +++ b/src/ui/src/channel/message.rs @@ -9,5 +9,5 @@ pub fn message(message: impl Message) -> impl IntoElement { .gap_2() .p_2() .child(img(message.get_author().get_icon()).object_fit(gpui::ObjectFit::Fill).bg(rgb(0xFFFFFF)).rounded_full().w_12().h_12()) - .child(div().flex().flex_col().child(message.get_author().get_display_name()).child(message.get_content())) + .child(div().flex().flex_col().child(message.get_author().get_display_name()).child(message.get_content()).child(message.get_images())) }