Channel chat: Add edit message (#9035)

**Summary**:
- Removed reply message from message_menu
- Made render_popover_buttons a bit more reusable
- Fixed issue that you can't close the reply/edit preview when you are
not focusing the message editor
- Notify only the new people that were mentioned inside the edited
message

**Follow up**
- Fix that we update the notification message for the people that we
mentioned already
- Fix that we remove the notification when a message gets deleted.
  - Fix last acknowledge message id is in correct now

**Todo**:
- [x] Add tests
- [x] Change new added bindings to the `Editor::Cancel` event.

Release Notes:

- Added editing of chat messages
([#6707](https://github.com/zed-industries/zed/issues/6707)).

<img width="239" alt="Screenshot 2024-03-09 at 11 55 23"
src="https://github.com/zed-industries/zed/assets/62463826/b0949f0d-0f8b-43e1-ac20-4c6d40ac41e1">
<img width="240" alt="Screenshot 2024-03-13 at 13 34 23"
src="https://github.com/zed-industries/zed/assets/62463826/d0636da2-c5aa-4fed-858e-4bebe5695ba7">

---------

Co-authored-by: Bennet Bo Fenner <53836821+bennetbo@users.noreply.github.com>
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
This commit is contained in:
Remco Smits 2024-03-20 02:49:04 +01:00 committed by GitHub
parent 5139aa3811
commit 3dadfe4787
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 743 additions and 149 deletions

View file

@ -6,7 +6,7 @@ use crate::{
self, BufferId, Channel, ChannelId, ChannelRole, ChannelsForUser, CreatedChannelMessage,
Database, InviteMemberResult, MembershipUpdated, MessageId, NotificationId, Project,
ProjectId, RemoveChannelMemberResult, ReplicaId, RespondToChannelInvite, RoomId, ServerId,
User, UserId,
UpdatedChannelMessage, User, UserId,
},
executor::Executor,
AppState, Error, RateLimit, RateLimiter, Result,
@ -283,6 +283,7 @@ impl Server {
.add_message_handler(leave_channel_chat)
.add_request_handler(send_channel_message)
.add_request_handler(remove_channel_message)
.add_request_handler(update_channel_message)
.add_request_handler(get_channel_messages)
.add_request_handler(get_channel_messages_by_id)
.add_request_handler(get_notifications)
@ -3191,6 +3192,7 @@ async fn send_channel_message(
},
)
.await?;
let message = proto::ChannelMessage {
sender_id: session.user_id.to_proto(),
id: message_id.to_proto(),
@ -3199,6 +3201,7 @@ async fn send_channel_message(
timestamp: timestamp.unix_timestamp() as u64,
nonce: Some(nonce),
reply_to_message_id: request.reply_to_message_id,
edited_at: None,
};
broadcast(
Some(session.connection_id),
@ -3261,6 +3264,71 @@ async fn remove_channel_message(
Ok(())
}
async fn update_channel_message(
request: proto::UpdateChannelMessage,
response: Response<proto::UpdateChannelMessage>,
session: Session,
) -> Result<()> {
let channel_id = ChannelId::from_proto(request.channel_id);
let message_id = MessageId::from_proto(request.message_id);
let updated_at = OffsetDateTime::now_utc();
let UpdatedChannelMessage {
message_id,
participant_connection_ids,
notifications,
reply_to_message_id,
timestamp,
} = session
.db()
.await
.update_channel_message(
channel_id,
message_id,
session.user_id,
request.body.as_str(),
&request.mentions,
updated_at,
)
.await?;
let nonce = request
.nonce
.clone()
.ok_or_else(|| anyhow!("nonce can't be blank"))?;
let message = proto::ChannelMessage {
sender_id: session.user_id.to_proto(),
id: message_id.to_proto(),
body: request.body.clone(),
mentions: request.mentions.clone(),
timestamp: timestamp.assume_utc().unix_timestamp() as u64,
nonce: Some(nonce),
reply_to_message_id: reply_to_message_id.map(|id| id.to_proto()),
edited_at: Some(updated_at.unix_timestamp() as u64),
};
response.send(proto::Ack {})?;
let pool = &*session.connection_pool().await;
broadcast(
Some(session.connection_id),
participant_connection_ids,
|connection| {
session.peer.send(
connection,
proto::ChannelMessageUpdate {
channel_id: channel_id.to_proto(),
message: Some(message.clone()),
},
)
},
);
send_notifications(pool, &session.peer, notifications);
Ok(())
}
/// Mark a channel message as read
async fn acknowledge_channel_message(
request: proto::AckChannelMessage,