Support sending custom emoji in messages and reactions
This commit is contained in:
@@ -6,7 +6,7 @@ use settings::SignerKind;
|
||||
#[derive(Action, Clone, PartialEq, Eq, Deserialize)]
|
||||
#[action(namespace = chat, no_json)]
|
||||
pub enum Command {
|
||||
Insert(&'static str),
|
||||
Insert(String),
|
||||
ChangeSubject(String),
|
||||
ChangeSigner(SignerKind),
|
||||
ToggleBackup,
|
||||
|
||||
@@ -5,7 +5,7 @@ use std::sync::{Arc, LazyLock, RwLock};
|
||||
pub use actions::*;
|
||||
use anyhow::Error;
|
||||
use chat::{ChatRegistry, Message, Room, RoomEvent, SendReport};
|
||||
use common::TimestampExt;
|
||||
use common::{TimestampExt, emojis_from_tags};
|
||||
use gpui::prelude::FluentBuilder;
|
||||
use gpui::{
|
||||
AnyElement, App, AppContext, ClipboardItem, Context, Entity, EventEmitter, FocusHandle,
|
||||
@@ -53,6 +53,10 @@ const PRIVATE_NOTICE: &str =
|
||||
static EMOJI_RE: LazyLock<Regex> =
|
||||
LazyLock::new(|| Regex::new(r"^[\p{Emoji}\u{200D}\u{FE0F}\u{20E3}]+$").unwrap());
|
||||
|
||||
/// Regex matching a single custom emoji reference, like `:soapbox:`
|
||||
static CUSTOM_EMOJI_RE: LazyLock<Regex> =
|
||||
LazyLock::new(|| Regex::new(r"^:[A-Za-z0-9_-]+:$").unwrap());
|
||||
|
||||
mod actions;
|
||||
mod file;
|
||||
pub mod text;
|
||||
@@ -331,7 +335,7 @@ impl ChatPanel {
|
||||
// If replying to exactly one message with only a valid emoji,
|
||||
// send as a reaction instead of a text message
|
||||
if replies.len() == 1
|
||||
&& EMOJI_RE.is_match(&content)
|
||||
&& (EMOJI_RE.is_match(&content) || CUSTOM_EMOJI_RE.is_match(&content))
|
||||
&& self.attachments.read(cx).is_empty()
|
||||
&& files.is_empty()
|
||||
{
|
||||
@@ -536,7 +540,7 @@ impl ChatPanel {
|
||||
return;
|
||||
}
|
||||
|
||||
let emojis = Message::emojis_from_tags(&event.tags);
|
||||
let emojis = emojis_from_tags(&event.tags);
|
||||
let image = Message::reaction_image(&event.content, &emojis)
|
||||
.map(|url| SharedUri::from(url.to_string()));
|
||||
|
||||
@@ -1753,15 +1757,23 @@ impl ChatPanel {
|
||||
})
|
||||
}
|
||||
|
||||
fn render_emoji_menu(&self, _window: &Window, _cx: &Context<Self>) -> impl IntoElement {
|
||||
fn render_emoji_menu(&self, _window: &Window, cx: &Context<Self>) -> impl IntoElement {
|
||||
let emojis = PersonRegistry::current_emojis(cx);
|
||||
|
||||
Button::new("emoji")
|
||||
.icon(IconName::Emoji)
|
||||
.ghost()
|
||||
.large()
|
||||
.dropdown_menu_with_anchor(gpui::Anchor::BottomLeft, move |this, _window, _cx| {
|
||||
let menu = this.horizontal();
|
||||
REACTION_EMOJIS.iter().fold(menu, |this, emoji| {
|
||||
this.menu(*emoji, Box::new(Command::Insert(emoji)))
|
||||
let menu = REACTION_EMOJIS
|
||||
.iter()
|
||||
.fold(this.horizontal(), |this, emoji| {
|
||||
this.menu(*emoji, Box::new(Command::Insert(emoji.to_string())))
|
||||
});
|
||||
|
||||
emojis.iter().fold(menu, |this, (shortcode, _)| {
|
||||
let label = format!(":{shortcode}:");
|
||||
this.menu(label.clone(), Box::new(Command::Insert(label)))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user