Skip to content

Commit 63e5d86

Browse files
committed
mostly-broken pending messages
1 parent 0a37c32 commit 63e5d86

File tree

6 files changed

+77
-45
lines changed

6 files changed

+77
-45
lines changed

src/chat/src/channel.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ pub trait Channel: Clone {
77

88
fn get_receiver(&self) -> broadcast::Receiver<Self::Message>;
99

10-
fn send_message(&self, content: String, nonce: String) -> impl std::future::Future<Output = ()>;
10+
fn send_message(&self, content: String, nonce: String) -> Self::Message;
1111
}

src/discord/src/channel/mod.rs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::sync::Arc;
33
use scope_chat::channel::Channel;
44
use tokio::sync::{broadcast, RwLock};
55

6-
use crate::{client::DiscordClient, message::DiscordMessage, snowflake::Snowflake};
6+
use crate::{client::DiscordClient, message::{author::{DiscordMessageAuthor, DisplayName}, content::DiscordMessageContent, DiscordMessage}, snowflake::Snowflake};
77

88
pub struct DiscordChannel {
99
channel_id: Snowflake,
@@ -28,10 +28,22 @@ impl Channel for DiscordChannel {
2828
self.receiver.resubscribe()
2929
}
3030

31-
async fn send_message(&self, content: String, nonce: String) {
32-
println!("Sending: {:?}", content);
33-
34-
self.client.write().await.send_message(self.channel_id, content, nonce).await;
31+
fn send_message(&self, content: String, nonce: String) -> DiscordMessage {
32+
let client = self.client.clone();
33+
let channel_id = self.channel_id;
34+
let sent_content = content.clone();
35+
let sent_nonce = nonce.clone();
36+
37+
tokio::spawn(async move {
38+
client.write().await.send_message(channel_id, sent_content, sent_nonce).await;
39+
});
40+
41+
DiscordMessage {
42+
content: DiscordMessageContent { content, is_pending: true },
43+
author: DiscordMessageAuthor { display_name: DisplayName("Pending".to_owned()), icon: "".to_owned() },
44+
id: Snowflake { content: 0 },
45+
nonce: Some(nonce),
46+
}
3547
}
3648
}
3749

src/discord/src/client.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,8 @@ impl EventHandler for RemoteDiscordClient {
8080
icon: msg.author.avatar_url().unwrap_or(msg.author.default_avatar_url()),
8181
},
8282
content: DiscordMessageContent {
83-
content: msg.content.clone()
83+
content: msg.content.clone(),
84+
is_pending: false,
8485
},
8586
nonce: msg.nonce.clone().map(|n| match n {
8687
Nonce::Number(n) => n.to_string(),

src/discord/src/message/content.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
use gpui::{IntoElement, Render, RenderOnce, WindowContext};
1+
use gpui::{div, IntoElement, ParentElement, Render, RenderOnce, Styled, WindowContext};
22

33
#[derive(Clone, IntoElement)]
44
pub struct DiscordMessageContent {
55
pub content: String,
6+
pub is_pending: bool,
67
}
78

89
impl RenderOnce for DiscordMessageContent {
910
fn render(self, _: &mut WindowContext) -> impl IntoElement {
10-
self.content.clone()
11+
div().opacity(if self.is_pending { 0.5 } else { 1.0 }).child(self.content.clone())
1112
}
1213
}

src/ui/src/channel/message_list.rs

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,51 @@ use scope_backend_discord::{
99
};
1010
use scope_chat::message::Message;
1111

12-
pub struct MessageList<M: Message> {
13-
pub(super) messages: Vec<M>,
12+
#[derive(Clone)]
13+
pub struct MessageList<M: Message + 'static> {
14+
real_messages: Vec<M>,
15+
pending_messages: Vec<M>,
1416
}
1517

1618
impl<M: Message> MessageList<M> {
1719
pub fn new() -> MessageList<M> {
18-
Self { messages: Vec::default() }
20+
Self {
21+
real_messages: Vec::default(),
22+
pending_messages: Vec::default(),
23+
}
1924
}
2025

2126
pub fn add_external_message(&mut self, message: M) {
27+
self.real_messages.push(message);
28+
}
29+
30+
pub fn add_pending_message(&mut self, pending_message: M) {
31+
self.pending_messages.push(pending_message);
32+
}
33+
34+
pub fn length(&self) -> usize {
35+
self.real_messages.len() + self.pending_messages.len()
36+
}
37+
38+
pub fn get(&self, index: usize) -> Option<&M> {
39+
if index >= self.pending_messages.len() {
40+
self.real_messages.get(index - self.pending_messages.len())
41+
} else {
42+
self.pending_messages.get(index)
43+
}
44+
}
45+
46+
pub fn create_list_state(&self) -> ListState {
47+
let clone = self.clone();
2248

49+
ListState::new(
50+
clone.length(),
51+
ListAlignment::Bottom,
52+
Pixels(20.),
53+
move |idx, _cx| {
54+
let item = clone.get(idx).unwrap().clone();
55+
div().child(message(item)).into_any_element()
56+
},
57+
)
2358
}
2459
}

src/ui/src/channel/mod.rs

Lines changed: 16 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -31,32 +31,17 @@ impl<M: Message + 'static> ChannelView<M> {
3131
loop {
3232
let message = channel.get_receiver().recv().await.unwrap();
3333

34-
println!("Got Message!");
35-
36-
async_model
37-
.update(&mut async_ctx, |data, ctx| {
38-
data.messages.push(message);
39-
ctx.notify();
40-
})
41-
.unwrap();
42-
}
43-
})
44-
.detach();
45-
46-
ctx
47-
.observe(&state_model, |this: &mut ChannelView<M>, model, cx| {
48-
let items = model.read(cx).messages.clone();
49-
50-
this.list_state = ListState::new(items.len(), ListAlignment::Bottom, Pixels(20.), move |idx, _cx| {
51-
let item = items.get(idx).unwrap().clone();
52-
div().child(message(item)).into_any_element()
53-
});
54-
55-
cx.notify();
56-
})
57-
.detach();
34+
async_model.update(&mut async_ctx, |data, ctx| {
35+
data.add_external_message(message);
36+
ctx.notify();
37+
}).unwrap();
38+
}
39+
}).detach();
5840

59-
let items = state_model.read(ctx).messages.clone();
41+
ctx.observe(&state_model, |this: &mut ChannelView<M>, model, cx| {
42+
this.list_state = model.read(cx).create_list_state();
43+
cx.notify();
44+
}).detach();
6045

6146
let message_input = ctx.new_view(|cx| {
6247
let mut input = components::input::TextInput::new(cx);
@@ -76,21 +61,19 @@ impl<M: Message + 'static> ChannelView<M> {
7661
text_input.set_text("", cx);
7762
});
7863

79-
ctx.foreground_executor().spawn(async move {
80-
let nonce = random_string::generate(20, random_string::charsets::ALPHANUMERIC);
64+
let nonce = random_string::generate(20, random_string::charsets::ALPHANUMERIC);
65+
let pending = channel_sender.send_message(content, nonce);
8166

82-
channel_sender.send_message(content, nonce).await;
83-
}).detach();
67+
channel_view.list_model.update(ctx, move |v, _| {
68+
v.add_pending_message(pending);
69+
});
8470
}
8571
_ => {}
8672
}
8773
}).detach();
8874

8975
ChannelView::<M> {
90-
list_state: ListState::new(items.len(), ListAlignment::Bottom, Pixels(20.), move |idx, _cx| {
91-
let item = items.get(idx).unwrap().clone();
92-
div().child(message(item)).into_any_element()
93-
}),
76+
list_state: state_model.read(ctx).create_list_state(),
9477
list_model: state_model,
9578
message_input,
9679
}

0 commit comments

Comments
 (0)