Connect notification panel to notification toasts

This commit is contained in:
Max Brunsfeld 2023-10-13 11:21:45 -07:00
parent 034e9935d4
commit 8db86dcebf
15 changed files with 272 additions and 178 deletions

1
Cargo.lock generated
View file

@ -1566,6 +1566,7 @@ dependencies = [
"project", "project",
"recent_projects", "recent_projects",
"rich_text", "rich_text",
"rpc",
"schemars", "schemars",
"serde", "serde",
"serde_derive", "serde_derive",

View file

@ -26,11 +26,19 @@ impl Database {
&self, &self,
recipient_id: UserId, recipient_id: UserId,
limit: usize, limit: usize,
) -> Result<proto::AddNotifications> { before_id: Option<NotificationId>,
) -> Result<Vec<proto::Notification>> {
self.transaction(|tx| async move { self.transaction(|tx| async move {
let mut result = proto::AddNotifications::default(); let mut result = Vec::new();
let mut condition =
Condition::all().add(notification::Column::RecipientId.eq(recipient_id));
if let Some(before_id) = before_id {
condition = condition.add(notification::Column::Id.lt(before_id));
}
let mut rows = notification::Entity::find() let mut rows = notification::Entity::find()
.filter(notification::Column::RecipientId.eq(recipient_id)) .filter(condition)
.order_by_desc(notification::Column::Id) .order_by_desc(notification::Column::Id)
.limit(limit as u64) .limit(limit as u64)
.stream(&*tx) .stream(&*tx)
@ -40,7 +48,7 @@ impl Database {
let Some(kind) = self.notification_kinds_by_id.get(&row.kind) else { let Some(kind) = self.notification_kinds_by_id.get(&row.kind) else {
continue; continue;
}; };
result.notifications.push(proto::Notification { result.push(proto::Notification {
id: row.id.to_proto(), id: row.id.to_proto(),
kind: kind.to_string(), kind: kind.to_string(),
timestamp: row.created_at.assume_utc().unix_timestamp() as u64, timestamp: row.created_at.assume_utc().unix_timestamp() as u64,
@ -49,7 +57,7 @@ impl Database {
actor_id: row.actor_id.map(|id| id.to_proto()), actor_id: row.actor_id.map(|id| id.to_proto()),
}); });
} }
result.notifications.reverse(); result.reverse();
Ok(result) Ok(result)
}) })
.await .await

View file

@ -70,7 +70,7 @@ pub const CLEANUP_TIMEOUT: Duration = Duration::from_secs(10);
const MESSAGE_COUNT_PER_PAGE: usize = 100; const MESSAGE_COUNT_PER_PAGE: usize = 100;
const MAX_MESSAGE_LEN: usize = 1024; const MAX_MESSAGE_LEN: usize = 1024;
const INITIAL_NOTIFICATION_COUNT: usize = 30; const NOTIFICATION_COUNT_PER_PAGE: usize = 50;
lazy_static! { lazy_static! {
static ref METRIC_CONNECTIONS: IntGauge = static ref METRIC_CONNECTIONS: IntGauge =
@ -269,6 +269,7 @@ impl Server {
.add_request_handler(send_channel_message) .add_request_handler(send_channel_message)
.add_request_handler(remove_channel_message) .add_request_handler(remove_channel_message)
.add_request_handler(get_channel_messages) .add_request_handler(get_channel_messages)
.add_request_handler(get_notifications)
.add_request_handler(link_channel) .add_request_handler(link_channel)
.add_request_handler(unlink_channel) .add_request_handler(unlink_channel)
.add_request_handler(move_channel) .add_request_handler(move_channel)
@ -579,17 +580,15 @@ impl Server {
this.app_state.db.set_user_connected_once(user_id, true).await?; this.app_state.db.set_user_connected_once(user_id, true).await?;
} }
let (contacts, channels_for_user, channel_invites, notifications) = future::try_join4( let (contacts, channels_for_user, channel_invites) = future::try_join3(
this.app_state.db.get_contacts(user_id), this.app_state.db.get_contacts(user_id),
this.app_state.db.get_channels_for_user(user_id), this.app_state.db.get_channels_for_user(user_id),
this.app_state.db.get_channel_invites_for_user(user_id), this.app_state.db.get_channel_invites_for_user(user_id),
this.app_state.db.get_notifications(user_id, INITIAL_NOTIFICATION_COUNT)
).await?; ).await?;
{ {
let mut pool = this.connection_pool.lock(); let mut pool = this.connection_pool.lock();
pool.add_connection(connection_id, user_id, user.admin); pool.add_connection(connection_id, user_id, user.admin);
this.peer.send(connection_id, notifications)?;
this.peer.send(connection_id, build_initial_contacts_update(contacts, &pool))?; this.peer.send(connection_id, build_initial_contacts_update(contacts, &pool))?;
this.peer.send(connection_id, build_initial_channels_update( this.peer.send(connection_id, build_initial_channels_update(
channels_for_user, channels_for_user,
@ -2099,8 +2098,8 @@ async fn request_contact(
session.peer.send(connection_id, update.clone())?; session.peer.send(connection_id, update.clone())?;
session.peer.send( session.peer.send(
connection_id, connection_id,
proto::AddNotifications { proto::NewNotification {
notifications: vec![notification.clone()], notification: Some(notification.clone()),
}, },
)?; )?;
} }
@ -2158,8 +2157,8 @@ async fn respond_to_contact_request(
session.peer.send(connection_id, update.clone())?; session.peer.send(connection_id, update.clone())?;
session.peer.send( session.peer.send(
connection_id, connection_id,
proto::AddNotifications { proto::NewNotification {
notifications: vec![notification.clone()], notification: Some(notification.clone()),
}, },
)?; )?;
} }
@ -3008,6 +3007,26 @@ async fn get_channel_messages(
Ok(()) Ok(())
} }
async fn get_notifications(
request: proto::GetNotifications,
response: Response<proto::GetNotifications>,
session: Session,
) -> Result<()> {
let notifications = session
.db()
.await
.get_notifications(
session.user_id,
NOTIFICATION_COUNT_PER_PAGE,
request
.before_id
.map(|id| db::NotificationId::from_proto(id)),
)
.await?;
response.send(proto::GetNotificationsResponse { notifications })?;
Ok(())
}
async fn update_diff_base(request: proto::UpdateDiffBase, session: Session) -> Result<()> { async fn update_diff_base(request: proto::UpdateDiffBase, session: Session) -> Result<()> {
let project_id = ProjectId::from_proto(request.project_id); let project_id = ProjectId::from_proto(request.project_id);
let project_connection_ids = session let project_connection_ids = session

View file

@ -1,6 +1,6 @@
use crate::{rpc::RECONNECT_TIMEOUT, tests::TestServer}; use crate::{rpc::RECONNECT_TIMEOUT, tests::TestServer};
use call::ActiveCall; use call::ActiveCall;
use collab_ui::project_shared_notification::ProjectSharedNotification; use collab_ui::notifications::project_shared_notification::ProjectSharedNotification;
use editor::{Editor, ExcerptRange, MultiBuffer}; use editor::{Editor, ExcerptRange, MultiBuffer};
use gpui::{executor::Deterministic, geometry::vector::vec2f, TestAppContext, ViewHandle}; use gpui::{executor::Deterministic, geometry::vector::vec2f, TestAppContext, ViewHandle};
use live_kit_client::MacOSDisplay; use live_kit_client::MacOSDisplay;

View file

@ -42,6 +42,7 @@ rich_text = { path = "../rich_text" }
picker = { path = "../picker" } picker = { path = "../picker" }
project = { path = "../project" } project = { path = "../project" }
recent_projects = { path = "../recent_projects" } recent_projects = { path = "../recent_projects" }
rpc = { path = "../rpc" }
settings = { path = "../settings" } settings = { path = "../settings" }
feature_flags = {path = "../feature_flags"} feature_flags = {path = "../feature_flags"}
theme = { path = "../theme" } theme = { path = "../theme" }
@ -68,6 +69,7 @@ editor = { path = "../editor", features = ["test-support"] }
gpui = { path = "../gpui", features = ["test-support"] } gpui = { path = "../gpui", features = ["test-support"] }
notifications = { path = "../notifications", features = ["test-support"] } notifications = { path = "../notifications", features = ["test-support"] }
project = { path = "../project", features = ["test-support"] } project = { path = "../project", features = ["test-support"] }
rpc = { path = "../rpc", features = ["test-support"] }
settings = { path = "../settings", features = ["test-support"] } settings = { path = "../settings", features = ["test-support"] }
util = { path = "../util", features = ["test-support"] } util = { path = "../util", features = ["test-support"] }
workspace = { path = "../workspace", features = ["test-support"] } workspace = { path = "../workspace", features = ["test-support"] }

View file

@ -1,10 +1,10 @@
use crate::{ use crate::{
contact_notification::ContactNotification, face_pile::FacePile, toggle_deafen, toggle_mute, face_pile::FacePile, toggle_deafen, toggle_mute, toggle_screen_sharing, LeaveCall,
toggle_screen_sharing, LeaveCall, ToggleDeafen, ToggleMute, ToggleScreenSharing, ToggleDeafen, ToggleMute, ToggleScreenSharing,
}; };
use auto_update::AutoUpdateStatus; use auto_update::AutoUpdateStatus;
use call::{ActiveCall, ParticipantLocation, Room}; use call::{ActiveCall, ParticipantLocation, Room};
use client::{proto::PeerId, Client, ContactEventKind, SignIn, SignOut, User, UserStore}; use client::{proto::PeerId, Client, SignIn, SignOut, User, UserStore};
use clock::ReplicaId; use clock::ReplicaId;
use context_menu::{ContextMenu, ContextMenuItem}; use context_menu::{ContextMenu, ContextMenuItem};
use gpui::{ use gpui::{
@ -151,28 +151,6 @@ impl CollabTitlebarItem {
this.window_activation_changed(active, cx) this.window_activation_changed(active, cx)
})); }));
subscriptions.push(cx.observe(&user_store, |_, _, cx| cx.notify())); subscriptions.push(cx.observe(&user_store, |_, _, cx| cx.notify()));
subscriptions.push(
cx.subscribe(&user_store, move |this, user_store, event, cx| {
if let Some(workspace) = this.workspace.upgrade(cx) {
workspace.update(cx, |workspace, cx| {
if let client::Event::Contact { user, kind } = event {
if let ContactEventKind::Requested | ContactEventKind::Accepted = kind {
workspace.show_notification(user.id as usize, cx, |cx| {
cx.add_view(|cx| {
ContactNotification::new(
user.clone(),
*kind,
user_store,
cx,
)
})
})
}
}
});
}
}),
);
Self { Self {
workspace: workspace.weak_handle(), workspace: workspace.weak_handle(),

View file

@ -2,13 +2,10 @@ pub mod channel_view;
pub mod chat_panel; pub mod chat_panel;
pub mod collab_panel; pub mod collab_panel;
mod collab_titlebar_item; mod collab_titlebar_item;
mod contact_notification;
mod face_pile; mod face_pile;
mod incoming_call_notification;
pub mod notification_panel; pub mod notification_panel;
mod notifications; pub mod notifications;
mod panel_settings; mod panel_settings;
pub mod project_shared_notification;
mod sharing_status_indicator; mod sharing_status_indicator;
use call::{report_call_event_for_room, ActiveCall, Room}; use call::{report_call_event_for_room, ActiveCall, Room};
@ -48,8 +45,7 @@ pub fn init(app_state: &Arc<AppState>, cx: &mut AppContext) {
collab_titlebar_item::init(cx); collab_titlebar_item::init(cx);
collab_panel::init(cx); collab_panel::init(cx);
chat_panel::init(cx); chat_panel::init(cx);
incoming_call_notification::init(&app_state, cx); notifications::init(&app_state, cx);
project_shared_notification::init(&app_state, cx);
sharing_status_indicator::init(cx); sharing_status_indicator::init(cx);
cx.add_global_action(toggle_screen_sharing); cx.add_global_action(toggle_screen_sharing);

View file

@ -1,5 +1,7 @@
use crate::{ use crate::{
format_timestamp, is_channels_feature_enabled, render_avatar, NotificationPanelSettings, format_timestamp, is_channels_feature_enabled,
notifications::contact_notification::ContactNotification, render_avatar,
NotificationPanelSettings,
}; };
use anyhow::Result; use anyhow::Result;
use channel::ChannelStore; use channel::ChannelStore;
@ -39,6 +41,7 @@ pub struct NotificationPanel {
notification_list: ListState<Self>, notification_list: ListState<Self>,
pending_serialization: Task<Option<()>>, pending_serialization: Task<Option<()>>,
subscriptions: Vec<gpui::Subscription>, subscriptions: Vec<gpui::Subscription>,
workspace: WeakViewHandle<Workspace>,
local_timezone: UtcOffset, local_timezone: UtcOffset,
has_focus: bool, has_focus: bool,
} }
@ -64,6 +67,7 @@ impl NotificationPanel {
let fs = workspace.app_state().fs.clone(); let fs = workspace.app_state().fs.clone();
let client = workspace.app_state().client.clone(); let client = workspace.app_state().client.clone();
let user_store = workspace.app_state().user_store.clone(); let user_store = workspace.app_state().user_store.clone();
let workspace_handle = workspace.weak_handle();
let notification_list = let notification_list =
ListState::<Self>::new(0, Orientation::Top, 1000., move |this, ix, cx| { ListState::<Self>::new(0, Orientation::Top, 1000., move |this, ix, cx| {
@ -96,6 +100,7 @@ impl NotificationPanel {
notification_store: NotificationStore::global(cx), notification_store: NotificationStore::global(cx),
notification_list, notification_list,
pending_serialization: Task::ready(None), pending_serialization: Task::ready(None),
workspace: workspace_handle,
has_focus: false, has_focus: false,
subscriptions: Vec::new(), subscriptions: Vec::new(),
active: false, active: false,
@ -177,7 +182,7 @@ impl NotificationPanel {
let notification_store = self.notification_store.read(cx); let notification_store = self.notification_store.read(cx);
let user_store = self.user_store.read(cx); let user_store = self.user_store.read(cx);
let channel_store = self.channel_store.read(cx); let channel_store = self.channel_store.read(cx);
let entry = notification_store.notification_at(ix).unwrap(); let entry = notification_store.notification_at(ix)?;
let now = OffsetDateTime::now_utc(); let now = OffsetDateTime::now_utc();
let timestamp = entry.timestamp; let timestamp = entry.timestamp;
@ -293,7 +298,7 @@ impl NotificationPanel {
&mut self, &mut self,
_: ModelHandle<NotificationStore>, _: ModelHandle<NotificationStore>,
event: &NotificationEvent, event: &NotificationEvent,
_: &mut ViewContext<Self>, cx: &mut ViewContext<Self>,
) { ) {
match event { match event {
NotificationEvent::NotificationsUpdated { NotificationEvent::NotificationsUpdated {
@ -301,7 +306,33 @@ impl NotificationPanel {
new_count, new_count,
} => { } => {
self.notification_list.splice(old_range.clone(), *new_count); self.notification_list.splice(old_range.clone(), *new_count);
cx.notify();
} }
NotificationEvent::NewNotification { entry } => match entry.notification {
Notification::ContactRequest { actor_id }
| Notification::ContactRequestAccepted { actor_id } => {
let user_store = self.user_store.clone();
let Some(user) = user_store.read(cx).get_cached_user(actor_id) else {
return;
};
self.workspace
.update(cx, |workspace, cx| {
workspace.show_notification(actor_id as usize, cx, |cx| {
cx.add_view(|cx| {
ContactNotification::new(
user.clone(),
entry.notification.clone(),
user_store,
cx,
)
})
})
})
.ok();
}
Notification::ChannelInvitation { .. } => {}
Notification::ChannelMessageMention { .. } => {}
},
} }
} }
} }

View file

@ -2,13 +2,23 @@ use client::User;
use gpui::{ use gpui::{
elements::*, elements::*,
platform::{CursorStyle, MouseButton}, platform::{CursorStyle, MouseButton},
AnyElement, Element, ViewContext, AnyElement, AppContext, Element, ViewContext,
}; };
use std::sync::Arc; use std::sync::Arc;
use workspace::AppState;
pub mod contact_notification;
pub mod incoming_call_notification;
pub mod project_shared_notification;
enum Dismiss {} enum Dismiss {}
enum Button {} enum Button {}
pub fn init(app_state: &Arc<AppState>, cx: &mut AppContext) {
incoming_call_notification::init(app_state, cx);
project_shared_notification::init(app_state, cx);
}
pub fn render_user_notification<F, V: 'static>( pub fn render_user_notification<F, V: 'static>(
user: Arc<User>, user: Arc<User>,
title: &'static str, title: &'static str,

View file

@ -1,14 +1,13 @@
use std::sync::Arc;
use crate::notifications::render_user_notification; use crate::notifications::render_user_notification;
use client::{ContactEventKind, User, UserStore}; use client::{ContactEventKind, User, UserStore};
use gpui::{elements::*, Entity, ModelHandle, View, ViewContext}; use gpui::{elements::*, Entity, ModelHandle, View, ViewContext};
use std::sync::Arc;
use workspace::notifications::Notification; use workspace::notifications::Notification;
pub struct ContactNotification { pub struct ContactNotification {
user_store: ModelHandle<UserStore>, user_store: ModelHandle<UserStore>,
user: Arc<User>, user: Arc<User>,
kind: client::ContactEventKind, notification: rpc::Notification,
} }
#[derive(Clone, PartialEq)] #[derive(Clone, PartialEq)]
@ -34,8 +33,8 @@ impl View for ContactNotification {
} }
fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> { fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
match self.kind { match self.notification {
ContactEventKind::Requested => render_user_notification( rpc::Notification::ContactRequest { .. } => render_user_notification(
self.user.clone(), self.user.clone(),
"wants to add you as a contact", "wants to add you as a contact",
Some("They won't be alerted if you decline."), Some("They won't be alerted if you decline."),
@ -56,7 +55,7 @@ impl View for ContactNotification {
], ],
cx, cx,
), ),
ContactEventKind::Accepted => render_user_notification( rpc::Notification::ContactRequestAccepted { .. } => render_user_notification(
self.user.clone(), self.user.clone(),
"accepted your contact request", "accepted your contact request",
None, None,
@ -78,7 +77,7 @@ impl Notification for ContactNotification {
impl ContactNotification { impl ContactNotification {
pub fn new( pub fn new(
user: Arc<User>, user: Arc<User>,
kind: client::ContactEventKind, notification: rpc::Notification,
user_store: ModelHandle<UserStore>, user_store: ModelHandle<UserStore>,
cx: &mut ViewContext<Self>, cx: &mut ViewContext<Self>,
) -> Self { ) -> Self {
@ -97,7 +96,7 @@ impl ContactNotification {
Self { Self {
user, user,
kind, notification,
user_store, user_store,
} }
} }

View file

@ -2,7 +2,7 @@ use anyhow::Result;
use channel::{ChannelMessage, ChannelMessageId, ChannelStore}; use channel::{ChannelMessage, ChannelMessageId, ChannelStore};
use client::{Client, UserStore}; use client::{Client, UserStore};
use collections::HashMap; use collections::HashMap;
use gpui::{AppContext, AsyncAppContext, Entity, ModelContext, ModelHandle}; use gpui::{AppContext, AsyncAppContext, Entity, ModelContext, ModelHandle, Task};
use rpc::{proto, AnyNotification, Notification, TypedEnvelope}; use rpc::{proto, AnyNotification, Notification, TypedEnvelope};
use std::{ops::Range, sync::Arc}; use std::{ops::Range, sync::Arc};
use sum_tree::{Bias, SumTree}; use sum_tree::{Bias, SumTree};
@ -14,7 +14,7 @@ pub fn init(client: Arc<Client>, user_store: ModelHandle<UserStore>, cx: &mut Ap
} }
pub struct NotificationStore { pub struct NotificationStore {
_client: Arc<Client>, client: Arc<Client>,
user_store: ModelHandle<UserStore>, user_store: ModelHandle<UserStore>,
channel_messages: HashMap<u64, ChannelMessage>, channel_messages: HashMap<u64, ChannelMessage>,
channel_store: ModelHandle<ChannelStore>, channel_store: ModelHandle<ChannelStore>,
@ -27,6 +27,9 @@ pub enum NotificationEvent {
old_range: Range<usize>, old_range: Range<usize>,
new_count: usize, new_count: usize,
}, },
NewNotification {
entry: NotificationEntry,
},
} }
#[derive(Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
@ -63,16 +66,19 @@ impl NotificationStore {
user_store: ModelHandle<UserStore>, user_store: ModelHandle<UserStore>,
cx: &mut ModelContext<Self>, cx: &mut ModelContext<Self>,
) -> Self { ) -> Self {
Self { let this = Self {
channel_store: ChannelStore::global(cx), channel_store: ChannelStore::global(cx),
notifications: Default::default(), notifications: Default::default(),
channel_messages: Default::default(), channel_messages: Default::default(),
_subscriptions: vec![ _subscriptions: vec![
client.add_message_handler(cx.handle(), Self::handle_add_notifications) client.add_message_handler(cx.handle(), Self::handle_new_notification)
], ],
user_store, user_store,
_client: client, client,
} };
this.load_more_notifications(cx).detach();
this
} }
pub fn notification_count(&self) -> usize { pub fn notification_count(&self) -> usize {
@ -93,18 +99,42 @@ impl NotificationStore {
cursor.item() cursor.item()
} }
async fn handle_add_notifications( pub fn load_more_notifications(&self, cx: &mut ModelContext<Self>) -> Task<Result<()>> {
let request = self
.client
.request(proto::GetNotifications { before_id: None });
cx.spawn(|this, cx| async move {
let response = request.await?;
Self::add_notifications(this, false, response.notifications, cx).await?;
Ok(())
})
}
async fn handle_new_notification(
this: ModelHandle<Self>, this: ModelHandle<Self>,
envelope: TypedEnvelope<proto::AddNotifications>, envelope: TypedEnvelope<proto::NewNotification>,
_: Arc<Client>, _: Arc<Client>,
cx: AsyncAppContext,
) -> Result<()> {
Self::add_notifications(
this,
true,
envelope.payload.notification.into_iter().collect(),
cx,
)
.await
}
async fn add_notifications(
this: ModelHandle<Self>,
is_new: bool,
notifications: Vec<proto::Notification>,
mut cx: AsyncAppContext, mut cx: AsyncAppContext,
) -> Result<()> { ) -> Result<()> {
let mut user_ids = Vec::new(); let mut user_ids = Vec::new();
let mut message_ids = Vec::new(); let mut message_ids = Vec::new();
let notifications = envelope let notifications = notifications
.payload
.notifications
.into_iter() .into_iter()
.filter_map(|message| { .filter_map(|message| {
Some(NotificationEntry { Some(NotificationEntry {
@ -195,6 +225,12 @@ impl NotificationStore {
cursor.next(&()); cursor.next(&());
} }
if is_new {
cx.emit(NotificationEvent::NewNotification {
entry: notification.clone(),
});
}
new_notifications.push(notification, &()); new_notifications.push(notification, &());
} }

View file

@ -155,25 +155,28 @@ message Envelope {
UpdateChannelBufferCollaborators update_channel_buffer_collaborators = 128; UpdateChannelBufferCollaborators update_channel_buffer_collaborators = 128;
RejoinChannelBuffers rejoin_channel_buffers = 129; RejoinChannelBuffers rejoin_channel_buffers = 129;
RejoinChannelBuffersResponse rejoin_channel_buffers_response = 130; RejoinChannelBuffersResponse rejoin_channel_buffers_response = 130;
AckBufferOperation ack_buffer_operation = 143; AckBufferOperation ack_buffer_operation = 131;
JoinChannelChat join_channel_chat = 131; JoinChannelChat join_channel_chat = 132;
JoinChannelChatResponse join_channel_chat_response = 132; JoinChannelChatResponse join_channel_chat_response = 133;
LeaveChannelChat leave_channel_chat = 133; LeaveChannelChat leave_channel_chat = 134;
SendChannelMessage send_channel_message = 134; SendChannelMessage send_channel_message = 135;
SendChannelMessageResponse send_channel_message_response = 135; SendChannelMessageResponse send_channel_message_response = 136;
ChannelMessageSent channel_message_sent = 136; ChannelMessageSent channel_message_sent = 137;
GetChannelMessages get_channel_messages = 137; GetChannelMessages get_channel_messages = 138;
GetChannelMessagesResponse get_channel_messages_response = 138; GetChannelMessagesResponse get_channel_messages_response = 139;
RemoveChannelMessage remove_channel_message = 139; RemoveChannelMessage remove_channel_message = 140;
AckChannelMessage ack_channel_message = 144; AckChannelMessage ack_channel_message = 141;
GetChannelMessagesById get_channel_messages_by_id = 142;
LinkChannel link_channel = 140; LinkChannel link_channel = 143;
UnlinkChannel unlink_channel = 141; UnlinkChannel unlink_channel = 144;
MoveChannel move_channel = 142; MoveChannel move_channel = 145;
NewNotification new_notification = 146;
GetNotifications get_notifications = 147;
GetNotificationsResponse get_notifications_response = 148; // Current max
AddNotifications add_notifications = 145;
GetChannelMessagesById get_channel_messages_by_id = 146; // Current max
} }
} }
@ -1563,7 +1566,15 @@ message UpdateDiffBase {
optional string diff_base = 3; optional string diff_base = 3;
} }
message AddNotifications { message GetNotifications {
optional uint64 before_id = 1;
}
message NewNotification {
Notification notification = 1;
}
message GetNotificationsResponse {
repeated Notification notifications = 1; repeated Notification notifications = 1;
} }

View file

@ -133,7 +133,8 @@ impl fmt::Display for PeerId {
messages!( messages!(
(Ack, Foreground), (Ack, Foreground),
(AddNotifications, Foreground), (AckBufferOperation, Background),
(AckChannelMessage, Background),
(AddProjectCollaborator, Foreground), (AddProjectCollaborator, Foreground),
(ApplyCodeAction, Background), (ApplyCodeAction, Background),
(ApplyCodeActionResponse, Background), (ApplyCodeActionResponse, Background),
@ -144,58 +145,74 @@ messages!(
(Call, Foreground), (Call, Foreground),
(CallCanceled, Foreground), (CallCanceled, Foreground),
(CancelCall, Foreground), (CancelCall, Foreground),
(ChannelMessageSent, Foreground),
(CopyProjectEntry, Foreground), (CopyProjectEntry, Foreground),
(CreateBufferForPeer, Foreground), (CreateBufferForPeer, Foreground),
(CreateChannel, Foreground), (CreateChannel, Foreground),
(CreateChannelResponse, Foreground), (CreateChannelResponse, Foreground),
(ChannelMessageSent, Foreground),
(CreateProjectEntry, Foreground), (CreateProjectEntry, Foreground),
(CreateRoom, Foreground), (CreateRoom, Foreground),
(CreateRoomResponse, Foreground), (CreateRoomResponse, Foreground),
(DeclineCall, Foreground), (DeclineCall, Foreground),
(DeleteChannel, Foreground),
(DeleteProjectEntry, Foreground), (DeleteProjectEntry, Foreground),
(Error, Foreground), (Error, Foreground),
(ExpandProjectEntry, Foreground), (ExpandProjectEntry, Foreground),
(ExpandProjectEntryResponse, Foreground),
(Follow, Foreground), (Follow, Foreground),
(FollowResponse, Foreground), (FollowResponse, Foreground),
(FormatBuffers, Foreground), (FormatBuffers, Foreground),
(FormatBuffersResponse, Foreground), (FormatBuffersResponse, Foreground),
(FuzzySearchUsers, Foreground), (FuzzySearchUsers, Foreground),
(GetChannelMembers, Foreground),
(GetChannelMembersResponse, Foreground),
(GetChannelMessages, Background),
(GetChannelMessagesById, Background),
(GetChannelMessagesResponse, Background),
(GetCodeActions, Background), (GetCodeActions, Background),
(GetCodeActionsResponse, Background), (GetCodeActionsResponse, Background),
(GetHover, Background),
(GetHoverResponse, Background),
(GetChannelMessages, Background),
(GetChannelMessagesResponse, Background),
(GetChannelMessagesById, Background),
(SendChannelMessage, Background),
(SendChannelMessageResponse, Background),
(GetCompletions, Background), (GetCompletions, Background),
(GetCompletionsResponse, Background), (GetCompletionsResponse, Background),
(GetDefinition, Background), (GetDefinition, Background),
(GetDefinitionResponse, Background), (GetDefinitionResponse, Background),
(GetTypeDefinition, Background),
(GetTypeDefinitionResponse, Background),
(GetDocumentHighlights, Background), (GetDocumentHighlights, Background),
(GetDocumentHighlightsResponse, Background), (GetDocumentHighlightsResponse, Background),
(GetReferences, Background), (GetHover, Background),
(GetReferencesResponse, Background), (GetHoverResponse, Background),
(GetNotifications, Foreground),
(GetNotificationsResponse, Foreground),
(GetPrivateUserInfo, Foreground),
(GetPrivateUserInfoResponse, Foreground),
(GetProjectSymbols, Background), (GetProjectSymbols, Background),
(GetProjectSymbolsResponse, Background), (GetProjectSymbolsResponse, Background),
(GetReferences, Background),
(GetReferencesResponse, Background),
(GetTypeDefinition, Background),
(GetTypeDefinitionResponse, Background),
(GetUsers, Foreground), (GetUsers, Foreground),
(Hello, Foreground), (Hello, Foreground),
(IncomingCall, Foreground), (IncomingCall, Foreground),
(InlayHints, Background),
(InlayHintsResponse, Background),
(InviteChannelMember, Foreground), (InviteChannelMember, Foreground),
(UsersResponse, Foreground), (JoinChannel, Foreground),
(JoinChannelBuffer, Foreground),
(JoinChannelBufferResponse, Foreground),
(JoinChannelChat, Foreground),
(JoinChannelChatResponse, Foreground),
(JoinProject, Foreground), (JoinProject, Foreground),
(JoinProjectResponse, Foreground), (JoinProjectResponse, Foreground),
(JoinRoom, Foreground), (JoinRoom, Foreground),
(JoinRoomResponse, Foreground), (JoinRoomResponse, Foreground),
(JoinChannelChat, Foreground), (LeaveChannelBuffer, Background),
(JoinChannelChatResponse, Foreground),
(LeaveChannelChat, Foreground), (LeaveChannelChat, Foreground),
(LeaveProject, Foreground), (LeaveProject, Foreground),
(LeaveRoom, Foreground), (LeaveRoom, Foreground),
(LinkChannel, Foreground),
(MoveChannel, Foreground),
(NewNotification, Foreground),
(OnTypeFormatting, Background),
(OnTypeFormattingResponse, Background),
(OpenBufferById, Background), (OpenBufferById, Background),
(OpenBufferByPath, Background), (OpenBufferByPath, Background),
(OpenBufferForSymbol, Background), (OpenBufferForSymbol, Background),
@ -203,58 +220,54 @@ messages!(
(OpenBufferResponse, Background), (OpenBufferResponse, Background),
(PerformRename, Background), (PerformRename, Background),
(PerformRenameResponse, Background), (PerformRenameResponse, Background),
(OnTypeFormatting, Background),
(OnTypeFormattingResponse, Background),
(InlayHints, Background),
(InlayHintsResponse, Background),
(ResolveInlayHint, Background),
(ResolveInlayHintResponse, Background),
(RefreshInlayHints, Foreground),
(Ping, Foreground), (Ping, Foreground),
(PrepareRename, Background), (PrepareRename, Background),
(PrepareRenameResponse, Background), (PrepareRenameResponse, Background),
(ExpandProjectEntryResponse, Foreground),
(ProjectEntryResponse, Foreground), (ProjectEntryResponse, Foreground),
(RefreshInlayHints, Foreground),
(RejoinChannelBuffers, Foreground),
(RejoinChannelBuffersResponse, Foreground),
(RejoinRoom, Foreground), (RejoinRoom, Foreground),
(RejoinRoomResponse, Foreground), (RejoinRoomResponse, Foreground),
(RemoveContact, Foreground),
(RemoveChannelMember, Foreground),
(RemoveChannelMessage, Foreground),
(ReloadBuffers, Foreground), (ReloadBuffers, Foreground),
(ReloadBuffersResponse, Foreground), (ReloadBuffersResponse, Foreground),
(RemoveChannelMember, Foreground),
(RemoveChannelMessage, Foreground),
(RemoveContact, Foreground),
(RemoveProjectCollaborator, Foreground), (RemoveProjectCollaborator, Foreground),
(RenameProjectEntry, Foreground),
(RequestContact, Foreground),
(RespondToContactRequest, Foreground),
(RespondToChannelInvite, Foreground),
(JoinChannel, Foreground),
(RoomUpdated, Foreground),
(SaveBuffer, Foreground),
(RenameChannel, Foreground), (RenameChannel, Foreground),
(RenameChannelResponse, Foreground), (RenameChannelResponse, Foreground),
(SetChannelMemberAdmin, Foreground), (RenameProjectEntry, Foreground),
(RequestContact, Foreground),
(ResolveInlayHint, Background),
(ResolveInlayHintResponse, Background),
(RespondToChannelInvite, Foreground),
(RespondToContactRequest, Foreground),
(RoomUpdated, Foreground),
(SaveBuffer, Foreground),
(SearchProject, Background), (SearchProject, Background),
(SearchProjectResponse, Background), (SearchProjectResponse, Background),
(SendChannelMessage, Background),
(SendChannelMessageResponse, Background),
(SetChannelMemberAdmin, Foreground),
(ShareProject, Foreground), (ShareProject, Foreground),
(ShareProjectResponse, Foreground), (ShareProjectResponse, Foreground),
(ShowContacts, Foreground), (ShowContacts, Foreground),
(StartLanguageServer, Foreground), (StartLanguageServer, Foreground),
(SynchronizeBuffers, Foreground), (SynchronizeBuffers, Foreground),
(SynchronizeBuffersResponse, Foreground), (SynchronizeBuffersResponse, Foreground),
(RejoinChannelBuffers, Foreground),
(RejoinChannelBuffersResponse, Foreground),
(Test, Foreground), (Test, Foreground),
(Unfollow, Foreground), (Unfollow, Foreground),
(UnlinkChannel, Foreground),
(UnshareProject, Foreground), (UnshareProject, Foreground),
(UpdateBuffer, Foreground), (UpdateBuffer, Foreground),
(UpdateBufferFile, Foreground), (UpdateBufferFile, Foreground),
(UpdateContacts, Foreground), (UpdateChannelBuffer, Foreground),
(DeleteChannel, Foreground), (UpdateChannelBufferCollaborators, Foreground),
(MoveChannel, Foreground),
(LinkChannel, Foreground),
(UnlinkChannel, Foreground),
(UpdateChannels, Foreground), (UpdateChannels, Foreground),
(UpdateContacts, Foreground),
(UpdateDiagnosticSummary, Foreground), (UpdateDiagnosticSummary, Foreground),
(UpdateDiffBase, Foreground),
(UpdateFollowers, Foreground), (UpdateFollowers, Foreground),
(UpdateInviteInfo, Foreground), (UpdateInviteInfo, Foreground),
(UpdateLanguageServer, Foreground), (UpdateLanguageServer, Foreground),
@ -263,18 +276,7 @@ messages!(
(UpdateProjectCollaborator, Foreground), (UpdateProjectCollaborator, Foreground),
(UpdateWorktree, Foreground), (UpdateWorktree, Foreground),
(UpdateWorktreeSettings, Foreground), (UpdateWorktreeSettings, Foreground),
(UpdateDiffBase, Foreground), (UsersResponse, Foreground),
(GetPrivateUserInfo, Foreground),
(GetPrivateUserInfoResponse, Foreground),
(GetChannelMembers, Foreground),
(GetChannelMembersResponse, Foreground),
(JoinChannelBuffer, Foreground),
(JoinChannelBufferResponse, Foreground),
(LeaveChannelBuffer, Background),
(UpdateChannelBuffer, Foreground),
(UpdateChannelBufferCollaborators, Foreground),
(AckBufferOperation, Background),
(AckChannelMessage, Background),
); );
request_messages!( request_messages!(
@ -286,73 +288,74 @@ request_messages!(
(Call, Ack), (Call, Ack),
(CancelCall, Ack), (CancelCall, Ack),
(CopyProjectEntry, ProjectEntryResponse), (CopyProjectEntry, ProjectEntryResponse),
(CreateChannel, CreateChannelResponse),
(CreateProjectEntry, ProjectEntryResponse), (CreateProjectEntry, ProjectEntryResponse),
(CreateRoom, CreateRoomResponse), (CreateRoom, CreateRoomResponse),
(CreateChannel, CreateChannelResponse),
(DeclineCall, Ack), (DeclineCall, Ack),
(DeleteChannel, Ack),
(DeleteProjectEntry, ProjectEntryResponse), (DeleteProjectEntry, ProjectEntryResponse),
(ExpandProjectEntry, ExpandProjectEntryResponse), (ExpandProjectEntry, ExpandProjectEntryResponse),
(Follow, FollowResponse), (Follow, FollowResponse),
(FormatBuffers, FormatBuffersResponse), (FormatBuffers, FormatBuffersResponse),
(FuzzySearchUsers, UsersResponse),
(GetChannelMembers, GetChannelMembersResponse),
(GetChannelMessages, GetChannelMessagesResponse),
(GetChannelMessagesById, GetChannelMessagesResponse),
(GetCodeActions, GetCodeActionsResponse), (GetCodeActions, GetCodeActionsResponse),
(GetHover, GetHoverResponse),
(GetCompletions, GetCompletionsResponse), (GetCompletions, GetCompletionsResponse),
(GetDefinition, GetDefinitionResponse), (GetDefinition, GetDefinitionResponse),
(GetTypeDefinition, GetTypeDefinitionResponse),
(GetDocumentHighlights, GetDocumentHighlightsResponse), (GetDocumentHighlights, GetDocumentHighlightsResponse),
(GetReferences, GetReferencesResponse), (GetHover, GetHoverResponse),
(GetNotifications, GetNotificationsResponse),
(GetPrivateUserInfo, GetPrivateUserInfoResponse), (GetPrivateUserInfo, GetPrivateUserInfoResponse),
(GetProjectSymbols, GetProjectSymbolsResponse), (GetProjectSymbols, GetProjectSymbolsResponse),
(FuzzySearchUsers, UsersResponse), (GetReferences, GetReferencesResponse),
(GetTypeDefinition, GetTypeDefinitionResponse),
(GetUsers, UsersResponse), (GetUsers, UsersResponse),
(IncomingCall, Ack),
(InlayHints, InlayHintsResponse),
(InviteChannelMember, Ack), (InviteChannelMember, Ack),
(JoinChannel, JoinRoomResponse),
(JoinChannelBuffer, JoinChannelBufferResponse),
(JoinChannelChat, JoinChannelChatResponse),
(JoinProject, JoinProjectResponse), (JoinProject, JoinProjectResponse),
(JoinRoom, JoinRoomResponse), (JoinRoom, JoinRoomResponse),
(JoinChannelChat, JoinChannelChatResponse), (LeaveChannelBuffer, Ack),
(LeaveRoom, Ack), (LeaveRoom, Ack),
(RejoinRoom, RejoinRoomResponse), (LinkChannel, Ack),
(IncomingCall, Ack), (MoveChannel, Ack),
(OnTypeFormatting, OnTypeFormattingResponse),
(OpenBufferById, OpenBufferResponse), (OpenBufferById, OpenBufferResponse),
(OpenBufferByPath, OpenBufferResponse), (OpenBufferByPath, OpenBufferResponse),
(OpenBufferForSymbol, OpenBufferForSymbolResponse), (OpenBufferForSymbol, OpenBufferForSymbolResponse),
(Ping, Ack),
(PerformRename, PerformRenameResponse), (PerformRename, PerformRenameResponse),
(Ping, Ack),
(PrepareRename, PrepareRenameResponse), (PrepareRename, PrepareRenameResponse),
(OnTypeFormatting, OnTypeFormattingResponse),
(InlayHints, InlayHintsResponse),
(ResolveInlayHint, ResolveInlayHintResponse),
(RefreshInlayHints, Ack), (RefreshInlayHints, Ack),
(RejoinChannelBuffers, RejoinChannelBuffersResponse),
(RejoinRoom, RejoinRoomResponse),
(ReloadBuffers, ReloadBuffersResponse), (ReloadBuffers, ReloadBuffersResponse),
(RequestContact, Ack),
(RemoveChannelMember, Ack), (RemoveChannelMember, Ack),
(RemoveContact, Ack),
(RespondToContactRequest, Ack),
(RespondToChannelInvite, Ack),
(SetChannelMemberAdmin, Ack),
(SendChannelMessage, SendChannelMessageResponse),
(GetChannelMessages, GetChannelMessagesResponse),
(GetChannelMessagesById, GetChannelMessagesResponse),
(GetChannelMembers, GetChannelMembersResponse),
(JoinChannel, JoinRoomResponse),
(RemoveChannelMessage, Ack), (RemoveChannelMessage, Ack),
(DeleteChannel, Ack), (RemoveContact, Ack),
(RenameProjectEntry, ProjectEntryResponse),
(RenameChannel, RenameChannelResponse), (RenameChannel, RenameChannelResponse),
(LinkChannel, Ack), (RenameProjectEntry, ProjectEntryResponse),
(UnlinkChannel, Ack), (RequestContact, Ack),
(MoveChannel, Ack), (ResolveInlayHint, ResolveInlayHintResponse),
(RespondToChannelInvite, Ack),
(RespondToContactRequest, Ack),
(SaveBuffer, BufferSaved), (SaveBuffer, BufferSaved),
(SearchProject, SearchProjectResponse), (SearchProject, SearchProjectResponse),
(SendChannelMessage, SendChannelMessageResponse),
(SetChannelMemberAdmin, Ack),
(ShareProject, ShareProjectResponse), (ShareProject, ShareProjectResponse),
(SynchronizeBuffers, SynchronizeBuffersResponse), (SynchronizeBuffers, SynchronizeBuffersResponse),
(RejoinChannelBuffers, RejoinChannelBuffersResponse),
(Test, Test), (Test, Test),
(UnlinkChannel, Ack),
(UpdateBuffer, Ack), (UpdateBuffer, Ack),
(UpdateParticipantLocation, Ack), (UpdateParticipantLocation, Ack),
(UpdateProject, Ack), (UpdateProject, Ack),
(UpdateWorktree, Ack), (UpdateWorktree, Ack),
(JoinChannelBuffer, JoinChannelBufferResponse),
(LeaveChannelBuffer, Ack)
); );
entity_messages!( entity_messages!(
@ -371,25 +374,25 @@ entity_messages!(
GetCodeActions, GetCodeActions,
GetCompletions, GetCompletions,
GetDefinition, GetDefinition,
GetTypeDefinition,
GetDocumentHighlights, GetDocumentHighlights,
GetHover, GetHover,
GetReferences,
GetProjectSymbols, GetProjectSymbols,
GetReferences,
GetTypeDefinition,
InlayHints,
JoinProject, JoinProject,
LeaveProject, LeaveProject,
OnTypeFormatting,
OpenBufferById, OpenBufferById,
OpenBufferByPath, OpenBufferByPath,
OpenBufferForSymbol, OpenBufferForSymbol,
PerformRename, PerformRename,
OnTypeFormatting,
InlayHints,
ResolveInlayHint,
RefreshInlayHints,
PrepareRename, PrepareRename,
RefreshInlayHints,
ReloadBuffers, ReloadBuffers,
RemoveProjectCollaborator, RemoveProjectCollaborator,
RenameProjectEntry, RenameProjectEntry,
ResolveInlayHint,
SaveBuffer, SaveBuffer,
SearchProject, SearchProject,
StartLanguageServer, StartLanguageServer,
@ -398,19 +401,19 @@ entity_messages!(
UpdateBuffer, UpdateBuffer,
UpdateBufferFile, UpdateBufferFile,
UpdateDiagnosticSummary, UpdateDiagnosticSummary,
UpdateDiffBase,
UpdateLanguageServer, UpdateLanguageServer,
UpdateProject, UpdateProject,
UpdateProjectCollaborator, UpdateProjectCollaborator,
UpdateWorktree, UpdateWorktree,
UpdateWorktreeSettings, UpdateWorktreeSettings,
UpdateDiffBase
); );
entity_messages!( entity_messages!(
channel_id, channel_id,
ChannelMessageSent, ChannelMessageSent,
UpdateChannelBuffer,
RemoveChannelMessage, RemoveChannelMessage,
UpdateChannelBuffer,
UpdateChannelBufferCollaborators, UpdateChannelBufferCollaborators,
); );