add send reaction
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
use std::cmp::Ordering;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use instant::Duration;
|
||||
|
||||
use anyhow::{Error, anyhow};
|
||||
use common::EventExt;
|
||||
use device::DeviceRegistry;
|
||||
use gpui::{App, AppContext, Context, EventEmitter, SharedString, Task};
|
||||
use instant::Duration;
|
||||
use itertools::Itertools;
|
||||
use nostr_sdk::prelude::*;
|
||||
use person::{Person, PersonRegistry};
|
||||
@@ -419,12 +419,23 @@ impl Room {
|
||||
}
|
||||
|
||||
// Construct a rumor event for direct message
|
||||
pub fn rumor<S, I>(&self, content: S, replies: I, cx: &App) -> Option<UnsignedEvent>
|
||||
pub fn rumor<S, I>(
|
||||
&self,
|
||||
content: S,
|
||||
replies: I,
|
||||
reaction: bool,
|
||||
cx: &App,
|
||||
) -> Option<UnsignedEvent>
|
||||
where
|
||||
S: Into<String>,
|
||||
I: IntoIterator<Item = EventId>,
|
||||
{
|
||||
let kind = Kind::PrivateDirectMessage;
|
||||
let kind = if reaction {
|
||||
Kind::Reaction
|
||||
} else {
|
||||
Kind::PrivateDirectMessage
|
||||
};
|
||||
|
||||
let content: String = content.into();
|
||||
let replies: Vec<EventId> = replies.into_iter().collect();
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@ use ui::{
|
||||
|
||||
use crate::text::RenderedText;
|
||||
|
||||
const REACTION_EMOJIS: &[&str] = &["👍", "👎", "😄", "🎉", "😕", "❤️", "🚀", "👀"];
|
||||
const COMPACT_REACTION_EMOJIS: &[&str] = &["👍", "❤️", "👀"];
|
||||
|
||||
mod actions;
|
||||
mod text;
|
||||
|
||||
@@ -331,24 +334,49 @@ impl ChatPanel {
|
||||
// Get the message which includes all attachments
|
||||
let content = self.get_input_value(cx);
|
||||
|
||||
// Get the replies to this message
|
||||
let replies: Vec<EventId> = self.replies_to.read(cx).iter().copied().collect();
|
||||
|
||||
// Return if message is empty
|
||||
if content.trim().is_empty() {
|
||||
window.push_notification("Cannot send an empty message", cx);
|
||||
return;
|
||||
}
|
||||
|
||||
self.send_message(&content, window, cx);
|
||||
self.send_message(&content, replies, false, window, cx);
|
||||
}
|
||||
|
||||
fn send_reaction(
|
||||
&mut self,
|
||||
emoji: &str,
|
||||
target: &EventId,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
// Return if emoji is empty
|
||||
if emoji.trim().is_empty() {
|
||||
window.push_notification("Cannot send an empty reaction", cx);
|
||||
return;
|
||||
}
|
||||
|
||||
self.send_message(emoji, vec![*target], true, window, cx);
|
||||
}
|
||||
|
||||
/// Send a message to all members of the chat
|
||||
fn send_message(&mut self, value: &str, window: &mut Window, cx: &mut Context<Self>) {
|
||||
fn send_message(
|
||||
&mut self,
|
||||
value: &str,
|
||||
replies: Vec<EventId>,
|
||||
reaction: bool,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
if value.trim().is_empty() {
|
||||
window.push_notification("Cannot send an empty message", cx);
|
||||
return;
|
||||
}
|
||||
|
||||
let room = self.room.clone();
|
||||
let replies: Vec<EventId> = self.replies_to.read(cx).iter().copied().collect();
|
||||
let content = value.to_string();
|
||||
let sent_ids = self.sent_ids.clone();
|
||||
|
||||
@@ -357,7 +385,7 @@ impl ChatPanel {
|
||||
return;
|
||||
};
|
||||
let (rumor, send_task) = match room_entity.read_with(cx, |room, cx| {
|
||||
let rumor = room.rumor(content.clone(), replies, cx)?;
|
||||
let rumor = room.rumor(content.clone(), replies, reaction, cx)?;
|
||||
let send_task = room.send(rumor.clone(), cx)?;
|
||||
Some((rumor, send_task))
|
||||
}) {
|
||||
@@ -575,7 +603,10 @@ impl ChatPanel {
|
||||
fn on_command(&mut self, command: &Command, window: &mut Window, cx: &mut Context<Self>) {
|
||||
match command {
|
||||
Command::Insert(content) => {
|
||||
self.send_message(content, window, cx);
|
||||
self.input.update(cx, |this, cx| {
|
||||
let new_value = format!("{} {}", this.value(), content);
|
||||
this.set_value(new_value, window, cx);
|
||||
});
|
||||
}
|
||||
Command::ChangeSubject(subject) => {
|
||||
if self
|
||||
@@ -990,13 +1021,9 @@ impl ChatPanel {
|
||||
.w_full()
|
||||
.px_2()
|
||||
.border_l_2()
|
||||
.border_color(cx.theme().element_selected)
|
||||
.border_color(cx.theme().element_active)
|
||||
.text_sm()
|
||||
.child(
|
||||
div()
|
||||
.text_color(cx.theme().text_accent)
|
||||
.child(author.name()),
|
||||
)
|
||||
.child(div().child(author.name()))
|
||||
.child(
|
||||
div()
|
||||
.w_full()
|
||||
@@ -1192,6 +1219,29 @@ impl ChatPanel {
|
||||
.border_1()
|
||||
.border_color(cx.theme().border)
|
||||
.bg(cx.theme().background)
|
||||
.children({
|
||||
let mut items = vec![];
|
||||
|
||||
for emoji in COMPACT_REACTION_EMOJIS {
|
||||
items.push(
|
||||
Button::new(*emoji)
|
||||
.label(*emoji)
|
||||
.tooltip(*emoji)
|
||||
.small()
|
||||
.ghost()
|
||||
.on_click({
|
||||
let emoji = *emoji;
|
||||
let id = *id;
|
||||
cx.listener(move |this, _event, window, cx| {
|
||||
this.send_reaction(emoji, &id, window, cx);
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
items
|
||||
})
|
||||
.child(div().flex_shrink_0().h_4().w_px().bg(cx.theme().border))
|
||||
.child(
|
||||
Button::new("reply")
|
||||
.icon(IconName::Reply)
|
||||
@@ -1305,7 +1355,7 @@ impl ChatPanel {
|
||||
.gap_1()
|
||||
.text_xs()
|
||||
.text_color(cx.theme().text_muted)
|
||||
.child(SharedString::from("Replying to:"))
|
||||
.child("Replying to:")
|
||||
.child(
|
||||
div()
|
||||
.text_color(cx.theme().text_accent)
|
||||
@@ -1402,15 +1452,10 @@ impl ChatPanel {
|
||||
.ghost()
|
||||
.large()
|
||||
.dropdown_menu_with_anchor(gpui::Anchor::BottomLeft, move |this, _window, _cx| {
|
||||
this.horizontal()
|
||||
.menu("👍", Box::new(Command::Insert("👍")))
|
||||
.menu("👎", Box::new(Command::Insert("👎")))
|
||||
.menu("😄", Box::new(Command::Insert("😄")))
|
||||
.menu("🎉", Box::new(Command::Insert("🎉")))
|
||||
.menu("😕", Box::new(Command::Insert("😕")))
|
||||
.menu("❤️", Box::new(Command::Insert("❤️")))
|
||||
.menu("🚀", Box::new(Command::Insert("🚀")))
|
||||
.menu("👀", Box::new(Command::Insert("👀")))
|
||||
let menu = this.horizontal();
|
||||
REACTION_EMOJIS.iter().fold(menu, |this, emoji| {
|
||||
this.menu(*emoji, Box::new(Command::Insert(emoji)))
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user