mirror of
https://github.com/youwen5/iamb.git
synced 2025-06-20 21:59:52 -07:00
Support sending and displaying message reactions (#2)
This commit is contained in:
parent
3629f15e0d
commit
c9c547acc1
10 changed files with 368 additions and 63 deletions
|
@ -9,8 +9,9 @@ use tokio;
|
|||
use matrix_sdk::{
|
||||
attachment::AttachmentConfig,
|
||||
media::{MediaFormat, MediaRequest},
|
||||
room::Room as MatrixRoom,
|
||||
room::{Joined, Room as MatrixRoom},
|
||||
ruma::{
|
||||
events::reaction::{ReactionEventContent, Relation as Reaction},
|
||||
events::room::message::{
|
||||
MessageType,
|
||||
OriginalRoomMessageEvent,
|
||||
|
@ -19,6 +20,7 @@ use matrix_sdk::{
|
|||
RoomMessageEventContent,
|
||||
TextMessageEventContent,
|
||||
},
|
||||
EventId,
|
||||
OwnedRoomId,
|
||||
RoomId,
|
||||
},
|
||||
|
@ -73,6 +75,7 @@ use crate::base::{
|
|||
};
|
||||
|
||||
use crate::message::{Message, MessageEvent, MessageKey, MessageTimeStamp};
|
||||
use crate::worker::Requester;
|
||||
|
||||
use super::scrollback::{Scrollback, ScrollbackState};
|
||||
|
||||
|
@ -115,6 +118,10 @@ impl ChatState {
|
|||
}
|
||||
}
|
||||
|
||||
fn get_joined(&self, worker: &Requester) -> Result<Joined, IambError> {
|
||||
worker.client.get_joined_room(self.id()).ok_or(IambError::NotJoined)
|
||||
}
|
||||
|
||||
fn get_reply_to<'a>(&self, info: &'a RoomInfo) -> Option<&'a OriginalRoomMessageEvent> {
|
||||
let key = self.reply_to.as_ref()?;
|
||||
let msg = info.messages.get(key)?;
|
||||
|
@ -149,7 +156,10 @@ impl ChatState {
|
|||
let settings = &store.application.settings;
|
||||
let info = store.application.rooms.entry(self.room_id.clone()).or_default();
|
||||
|
||||
let msg = self.scrollback.get_mut(info).ok_or(IambError::NoSelectedMessage)?;
|
||||
let msg = self
|
||||
.scrollback
|
||||
.get_mut(&mut info.messages)
|
||||
.ok_or(IambError::NoSelectedMessage)?;
|
||||
|
||||
match act {
|
||||
MessageAction::Cancel => {
|
||||
|
@ -282,19 +292,32 @@ impl ChatState {
|
|||
|
||||
Ok(None)
|
||||
},
|
||||
MessageAction::Redact(reason) => {
|
||||
let room = store
|
||||
.application
|
||||
.worker
|
||||
.client
|
||||
.get_joined_room(self.id())
|
||||
.ok_or(IambError::NotJoined)?;
|
||||
|
||||
MessageAction::React(emoji) => {
|
||||
let room = self.get_joined(&store.application.worker)?;
|
||||
let event_id = match &msg.event {
|
||||
MessageEvent::Original(ev) => ev.event_id.clone(),
|
||||
MessageEvent::Local(event_id, _) => event_id.clone(),
|
||||
MessageEvent::Redacted(_) => {
|
||||
let msg = "";
|
||||
let msg = "Cannot react to a redacted message";
|
||||
let err = UIError::Failure(msg.into());
|
||||
|
||||
return Err(err);
|
||||
},
|
||||
};
|
||||
|
||||
let reaction = Reaction::new(event_id, emoji);
|
||||
let msg = ReactionEventContent::new(reaction);
|
||||
let _ = room.send(msg, None).await.map_err(IambError::from)?;
|
||||
|
||||
Ok(None)
|
||||
},
|
||||
MessageAction::Redact(reason) => {
|
||||
let room = self.get_joined(&store.application.worker)?;
|
||||
let event_id = match &msg.event {
|
||||
MessageEvent::Original(ev) => ev.event_id.clone(),
|
||||
MessageEvent::Local(event_id, _) => event_id.clone(),
|
||||
MessageEvent::Redacted(_) => {
|
||||
let msg = "Cannot redact already redacted message";
|
||||
let err = UIError::Failure(msg.into());
|
||||
|
||||
return Err(err);
|
||||
|
@ -311,6 +334,46 @@ impl ChatState {
|
|||
self.reply_to = self.scrollback.get_key(info);
|
||||
self.focus = RoomFocus::MessageBar;
|
||||
|
||||
Ok(None)
|
||||
},
|
||||
MessageAction::Unreact(emoji) => {
|
||||
let room = self.get_joined(&store.application.worker)?;
|
||||
let event_id: &EventId = match &msg.event {
|
||||
MessageEvent::Original(ev) => ev.event_id.as_ref(),
|
||||
MessageEvent::Local(event_id, _) => event_id.as_ref(),
|
||||
MessageEvent::Redacted(_) => {
|
||||
let msg = "Cannot unreact to a redacted message";
|
||||
let err = UIError::Failure(msg.into());
|
||||
|
||||
return Err(err);
|
||||
},
|
||||
};
|
||||
|
||||
let reactions = match info.reactions.get(event_id) {
|
||||
Some(r) => r,
|
||||
None => return Ok(None),
|
||||
};
|
||||
|
||||
let reactions = reactions.iter().filter_map(|(event_id, (reaction, user_id))| {
|
||||
if user_id != &settings.profile.user_id {
|
||||
return None;
|
||||
}
|
||||
|
||||
if let Some(emoji) = &emoji {
|
||||
if emoji == reaction {
|
||||
return Some(event_id);
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
} else {
|
||||
return Some(event_id);
|
||||
}
|
||||
});
|
||||
|
||||
for reaction in reactions {
|
||||
let _ = room.redact(reaction, None, None).await.map_err(IambError::from)?;
|
||||
}
|
||||
|
||||
Ok(None)
|
||||
},
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ use modalkit::editing::{
|
|||
use crate::{
|
||||
base::{IambBufferId, IambInfo, ProgramContext, ProgramStore, RoomFocus, RoomInfo},
|
||||
config::ApplicationSettings,
|
||||
message::{Message, MessageCursor, MessageKey},
|
||||
message::{Message, MessageCursor, MessageKey, Messages},
|
||||
};
|
||||
|
||||
fn nth_key_before(pos: MessageKey, n: usize, info: &RoomInfo) -> MessageKey {
|
||||
|
@ -164,11 +164,11 @@ impl ScrollbackState {
|
|||
.or_else(|| info.messages.last_key_value().map(|kv| kv.0.clone()))
|
||||
}
|
||||
|
||||
pub fn get_mut<'a>(&mut self, info: &'a mut RoomInfo) -> Option<&'a mut Message> {
|
||||
pub fn get_mut<'a>(&mut self, messages: &'a mut Messages) -> Option<&'a mut Message> {
|
||||
if let Some(k) = &self.cursor.timestamp {
|
||||
info.messages.get_mut(k)
|
||||
messages.get_mut(k)
|
||||
} else {
|
||||
info.messages.last_entry().map(|o| o.into_mut())
|
||||
messages.last_entry().map(|o| o.into_mut())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue