Skip to content

Commit e8b3cea

Browse files
feat: update GPUI and refactor to make it happen
1 parent 113d9c6 commit e8b3cea

File tree

16 files changed

+975
-676
lines changed

16 files changed

+975
-676
lines changed

Cargo.lock

Lines changed: 801 additions & 530 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/chat/src/message.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::fmt::Debug;
22

33
use chrono::{DateTime, Utc};
4-
use gpui::{IntoElement, Render, View, WindowContext};
4+
use gpui::{IntoElement, Render, Entity, App};
55

66
use crate::async_list::AsyncListItem;
77
use crate::reaction::ReactionList;
@@ -12,12 +12,12 @@ pub trait Message: Clone + AsyncListItem + Send {
1212
type Content: Render;
1313

1414
fn get_author(&self) -> Self::Author;
15-
fn get_content(&self, cx: &mut WindowContext) -> View<Self::Content>;
15+
fn get_content(&self, cx: &mut App) -> Entity<Self::Content>;
1616
fn get_identifier(&self) -> Option<<Self as Message>::Identifier>;
1717
fn get_nonce(&self) -> impl PartialEq;
1818
fn should_group(&self, previous: &Self) -> bool;
1919
fn get_timestamp(&self) -> Option<DateTime<Utc>>;
20-
fn get_reactions(&mut self) -> &mut impl ReactionList;
20+
fn get_reactions(&mut self) -> Option<&mut impl ReactionList>;
2121
}
2222

2323
#[derive(Debug, Clone, Copy)]

src/chat/src/reaction.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ pub enum MessageReactionType {
1212
#[derive(Clone, PartialEq)]
1313
pub enum ReactionEmoji {
1414
Simple(String),
15-
Custom { url: String, animated: bool, name: Option<String> },
15+
Custom { url: String, animated: bool, name: Option<String>, id: u64 },
1616
}
1717

1818
impl Debug for ReactionEmoji {
@@ -25,6 +25,7 @@ impl Debug for ReactionEmoji {
2525
}
2626

2727
pub trait MessageReaction: IntoElement {
28+
2829
fn get_count(&self, kind: Option<MessageReactionType>) -> u64;
2930
fn get_self_reaction(&self) -> Option<MessageReactionType>;
3031
fn get_emoji(&self) -> ReactionEmoji;

src/discord/src/channel/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@ impl Channel for DiscordChannel {
7575
content,
7676
sent_time: Utc::now(),
7777
list_item_id: Snowflake::random(),
78-
reactions: Default::default(),
7978
},
8079
content: OnceLock::new(),
8180
}

src/discord/src/client.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ use std::{
66
use crate::message::reaction::discord_reaction_to_emoji;
77
use atomic_refcell::AtomicRefCell;
88
use dashmap::DashMap;
9-
use scope_chat::reaction::{MessageReactionType, ReactionEvent, ReactionOperation};
10-
use serenity::all::Reaction;
9+
use scope_chat::reaction::{MessageReactionType, ReactionEmoji, ReactionEvent, ReactionOperation};
10+
use serenity::all::{EmojiId, Reaction, ReactionType};
1111
use serenity::{
1212
all::{
1313
Cache, CacheHttp, ChannelId, Context, CreateMessage, EventHandler, GatewayIntents, GetMessages, GuildId, Http, Member, Message, MessageId,
@@ -146,6 +146,19 @@ impl DiscordClient {
146146
}
147147
}
148148
}
149+
150+
pub async fn add_reaction(&self, channel_id: ChannelId, message_id: MessageId, emoji: ReactionEmoji) {
151+
let reaction_type = match emoji {
152+
ReactionEmoji::Simple(c) => ReactionType::Unicode(c),
153+
ReactionEmoji::Custom { name, animated, id, .. } => ReactionType::Custom {
154+
id: EmojiId::new(id),
155+
animated,
156+
name,
157+
},
158+
};
159+
160+
channel_id.create_reaction(self.discord().http.clone(), message_id, reaction_type).await.unwrap();
161+
}
149162
}
150163

151164
#[async_trait]

src/discord/src/message/author.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::sync::Arc;
22

3-
use gpui::{div, img, IntoElement, ParentElement, RenderOnce, SharedString, Styled, WindowContext};
3+
use gpui::{div, img, App, IntoElement, ParentElement, RenderOnce, SharedString, Styled, Window};
44
use scope_chat::message::{IconRenderConfig, MessageAuthor};
55
use url::Url;
66

@@ -72,7 +72,7 @@ impl MessageAuthor for DiscordMessageAuthor {
7272
pub struct DisplayName(pub SharedString);
7373

7474
impl RenderOnce for DisplayName {
75-
fn render(self, _: &mut WindowContext) -> impl IntoElement {
75+
fn render(self, _: &mut Window, _: &mut App) -> impl IntoElement {
7676
div().text_sm().child(self.0)
7777
}
7878
}
@@ -81,7 +81,7 @@ impl RenderOnce for DisplayName {
8181
pub struct DisplayIcon(pub String, pub IconRenderConfig);
8282

8383
impl RenderOnce for DisplayIcon {
84-
fn render(self, _: &mut WindowContext) -> impl IntoElement {
84+
fn render(self, _: &mut Window, _: &mut App) -> impl IntoElement {
8585
let mut url = Url::parse(&self.0).unwrap();
8686
let mut query_params = querystring::querify(url.query().unwrap_or(""));
8787

src/discord/src/message/content.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,38 @@
11
use crate::message::reaction_list::DiscordReactionList;
2-
use gpui::{div, IntoElement, ParentElement, Render, Styled, ViewContext};
2+
use gpui::prelude::FluentBuilder;
3+
use gpui::{div, Context, IntoElement, ParentElement, Render, Styled, Window};
34
use serenity::all::Message;
45

56
#[derive(Clone, Debug)]
67
pub struct DiscordMessageContent {
78
pub content: String,
89
pub is_pending: bool,
9-
pub reactions: DiscordReactionList,
10+
pub reactions: Option<DiscordReactionList>,
1011
}
1112

1213
impl DiscordMessageContent {
1314
pub fn pending(content: String) -> DiscordMessageContent {
1415
DiscordMessageContent {
1516
content,
1617
is_pending: true,
17-
reactions: Default::default(),
18+
reactions: None,
1819
}
1920
}
2021

2122
pub fn received(message: &Message, reactions: &DiscordReactionList) -> DiscordMessageContent {
2223
DiscordMessageContent {
2324
content: message.content.clone(),
2425
is_pending: false,
25-
reactions: reactions.clone(),
26+
reactions: Some(reactions.clone()),
2627
}
2728
}
2829
}
2930

3031
impl Render for DiscordMessageContent {
31-
fn render(&mut self, _: &mut ViewContext<DiscordMessageContent>) -> impl IntoElement {
32+
fn render(&mut self, _: &mut Window, _: &mut Context<DiscordMessageContent>) -> impl IntoElement {
3233
div()
33-
.opacity(if self.is_pending { 0.25 } else { 1.0 })
34-
.child(self.content.clone())
35-
.child(self.reactions.clone())
34+
.opacity(if self.is_pending { 0.25 } else { 1.0 })
35+
.child(self.content.clone())
36+
.when_some(self.reactions.clone(), |d, reactions| d.child(reactions))
3637
}
3738
}

src/discord/src/message/mod.rs

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::message::reaction_list::DiscordReactionList;
44
use author::DiscordMessageAuthor;
55
use chrono::{DateTime, Utc};
66
use content::DiscordMessageContent;
7-
use gpui::{View, VisualContext, WindowContext};
7+
use gpui::{App, AppContext, Entity};
88
use scope_chat::reaction::ReactionList;
99
use scope_chat::{async_list::AsyncListItem, message::Message};
1010
use serenity::all::{ModelError, Nonce};
@@ -23,7 +23,6 @@ pub enum DiscordMessageData {
2323
content: String,
2424
sent_time: DateTime<Utc>,
2525
list_item_id: Snowflake,
26-
reactions: DiscordReactionList
2726
},
2827
Received(Arc<serenity::model::channel::Message>, Option<Arc<serenity::model::guild::Member>>, DiscordReactionList),
2928
}
@@ -33,7 +32,7 @@ pub struct DiscordMessage {
3332
pub client: Arc<DiscordClient>,
3433
pub channel: Arc<serenity::model::channel::Channel>,
3534
pub data: DiscordMessageData,
36-
pub content: OnceLock<View<DiscordMessageContent>>,
35+
pub content: OnceLock<Entity<DiscordMessageContent>>,
3736
}
3837

3938
impl DiscordMessage {
@@ -46,7 +45,7 @@ impl DiscordMessage {
4645
}
4746
.unwrap();
4847

49-
let reactions = (&msg.reactions).into();
48+
let reactions = DiscordReactionList::new_serenity(msg.reactions.clone(), channel.id(), msg.id.clone(), client.clone());
5049

5150
Self {
5251
client,
@@ -62,7 +61,7 @@ impl DiscordMessage {
6261
channel: Arc<serenity::model::channel::Channel>,
6362
member: Option<Arc<serenity::model::guild::Member>>,
6463
) -> Self {
65-
let reactions = (&msg.reactions).into();
64+
let reactions = DiscordReactionList::new_serenity(msg.reactions.clone(), channel.id(), msg.id.clone(), client.clone());
6665
Self {
6766
client,
6867
channel,
@@ -130,7 +129,7 @@ impl Message for DiscordMessage {
130129
}
131130

132131
// TODO: want reviewer discussion. I'm really stretching the abilities of gpui here and im not sure if this is the right way to do this.
133-
fn get_content(&self, cx: &mut WindowContext) -> View<Self::Content> {
132+
fn get_content(&self, cx: &mut App) -> Entity<Self::Content> {
134133
self
135134
.content
136135
.get_or_init(|| {
@@ -139,7 +138,7 @@ impl Message for DiscordMessage {
139138
DiscordMessageData::Received(message, _, reactions) => DiscordMessageContent::received(message, reactions),
140139
};
141140

142-
cx.new_view(|_cx| content)
141+
cx.new(|_| content)
143142
})
144143
.clone()
145144
}
@@ -174,10 +173,10 @@ impl Message for DiscordMessage {
174173
}
175174
}
176175

177-
fn get_reactions(&mut self) -> &mut impl ReactionList {
176+
fn get_reactions(&mut self) -> Option<&mut impl ReactionList> {
178177
match &mut self.data {
179-
DiscordMessageData::Pending { reactions, .. } => reactions,
180-
DiscordMessageData::Received(_, _, reactions) => reactions,
178+
DiscordMessageData::Pending { .. } => None,
179+
DiscordMessageData::Received(_, _, reactions) => Some(reactions),
181180
}
182181
}
183182
}

src/discord/src/message/reaction.rs

Lines changed: 26 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
use components::theme::ActiveTheme;
2-
use gpui::{div, img, px, AnyElement, InteractiveElement, IntoElement, ParentElement, RenderOnce, Rgba, StatefulInteractiveElement, Styled, WindowContext};
32
use gpui::prelude::FluentBuilder;
3+
use gpui::{div, img, px, AnyElement, App, IntoElement, ParentElement, RenderOnce, Rgba, Styled};
44
use scope_chat::reaction::MessageReactionType::Normal;
55
use scope_chat::reaction::{MessageReaction, MessageReactionType, ReactionEmoji};
66
use serenity::all::ReactionType;
7+
use std::fmt::Debug;
78
use MessageReactionType::Burst;
89

910
#[derive(Clone, Debug)]
@@ -46,7 +47,7 @@ impl DiscordMessageReaction {
4647
}
4748
}
4849

49-
fn use_local(&mut self) {
50+
fn swap_to_local(&mut self) {
5051
let (count_normal, count_burst) = match &self.data {
5152
ReactionData::Message(reaction) => (reaction.count_details.normal, reaction.count_details.burst),
5253
ReactionData::Local {
@@ -64,6 +65,12 @@ impl DiscordMessageReaction {
6465
burst_colours,
6566
}
6667
}
68+
fn render_emoji(emoji: &ReactionEmoji) -> AnyElement {
69+
match emoji {
70+
ReactionEmoji::Simple(character) => div().text_size(px(12f32)).child(character.clone()).into_any_element(),
71+
ReactionEmoji::Custom { url, .. } => img(url.clone()).w(px(16f32)).h(px(16f32)).into_any_element(),
72+
}
73+
}
6774
}
6875

6976
impl MessageReaction for DiscordMessageReaction {
@@ -114,7 +121,7 @@ impl MessageReaction for DiscordMessageReaction {
114121
}
115122

116123
fn increment(&mut self, kind: MessageReactionType, user_is_self: bool, by: isize) {
117-
self.use_local();
124+
self.swap_to_local();
118125
match kind {
119126
Burst => {
120127
if let ReactionData::Local { count_burst, .. } = &mut self.data {
@@ -140,47 +147,34 @@ impl MessageReaction for DiscordMessageReaction {
140147
}
141148
}
142149

143-
impl DiscordMessageReaction {
144-
fn render_emoji(emoji: &ReactionEmoji) -> AnyElement {
145-
match emoji {
146-
ReactionEmoji::Simple(character) => div().text_size(px(12f32)).child(character.clone()).into_any_element(),
147-
ReactionEmoji::Custom { url, .. } => img(url.clone()).w(px(16f32)).h(px(16f32)).into_any_element(),
148-
}
149-
}
150-
}
151-
152150
impl RenderOnce for DiscordMessageReaction {
153-
fn render(self, cx: &mut WindowContext) -> impl IntoElement {
151+
fn render(self, _: &mut gpui::Window, cx: &mut App) -> impl IntoElement {
154152
let emoji = self.get_emoji();
155-
let async_emoji = emoji.clone();
156153
let theme = cx.theme();
157154
div()
158-
.px_1()
159-
.py_px()
160-
.border_1()
161-
.border_color(theme.border)
162-
.when(self.get_self_reaction().is_some(), |s| s.border_color(theme.accent))
163-
.bg(theme.panel)
164-
.rounded_md()
165-
.flex()
166-
.id("reaction")
167-
.on_click(move |_, _| {
168-
eprintln!("Reaction {:?} clicked", async_emoji);
169-
})
170-
.justify_center()
171-
.items_center()
172-
.gap_1()
173-
.child(Self::render_emoji(&emoji))
174-
.child(self.get_count(None).to_string())
155+
.px_1()
156+
.py_px()
157+
.border_1()
158+
.border_color(theme.border)
159+
.when(self.get_self_reaction().is_some(), |s| s.border_color(theme.accent))
160+
.bg(theme.panel)
161+
.rounded_md()
162+
.flex()
163+
.justify_center()
164+
.items_center()
165+
.gap_1()
166+
.child(Self::render_emoji(&emoji))
167+
.child(self.get_count(None).to_string())
175168
}
176169
}
177170

178-
pub fn discord_reaction_to_emoji(reaction: &serenity::all::ReactionType) -> ReactionEmoji {
171+
pub fn discord_reaction_to_emoji(reaction: &ReactionType) -> ReactionEmoji {
179172
match reaction {
180173
ReactionType::Custom { animated, id, name } => ReactionEmoji::Custom {
181174
url: format!("https://cdn.discordapp.com/emojis/{}.png", id),
182175
animated: *animated,
183176
name: name.clone(),
177+
id: id.get(),
184178
},
185179
ReactionType::Unicode(character) => ReactionEmoji::Simple(character.clone()),
186180
ty => {

0 commit comments

Comments
 (0)