mirror of
https://github.com/zed-industries/zed.git
synced 2024-12-24 17:28:40 +00:00
Fix scrolling to messages on clicking of notifications
This commit is contained in:
parent
851d7d0bc4
commit
44cb55fbe9
4 changed files with 60 additions and 24 deletions
|
@ -257,11 +257,16 @@ impl ChannelChat {
|
||||||
let mut cursor = chat.messages.cursor::<(ChannelMessageId, Count)>();
|
let mut cursor = chat.messages.cursor::<(ChannelMessageId, Count)>();
|
||||||
let message_id = ChannelMessageId::Saved(message_id);
|
let message_id = ChannelMessageId::Saved(message_id);
|
||||||
cursor.seek(&message_id, Bias::Left, &());
|
cursor.seek(&message_id, Bias::Left, &());
|
||||||
return ControlFlow::Break(if cursor.start().0 == message_id {
|
return ControlFlow::Break(
|
||||||
Some(cursor.start().1 .0)
|
if cursor
|
||||||
} else {
|
.item()
|
||||||
None
|
.map_or(false, |message| message.id == message_id)
|
||||||
});
|
{
|
||||||
|
Some(cursor.start().1 .0)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ControlFlow::Continue(chat.load_more_messages(cx))
|
ControlFlow::Continue(chat.load_more_messages(cx))
|
||||||
|
|
|
@ -257,6 +257,7 @@ impl ChatPanel {
|
||||||
|
|
||||||
fn set_active_chat(&mut self, chat: ModelHandle<ChannelChat>, cx: &mut ViewContext<Self>) {
|
fn set_active_chat(&mut self, chat: ModelHandle<ChannelChat>, cx: &mut ViewContext<Self>) {
|
||||||
if self.active_chat.as_ref().map(|e| &e.0) != Some(&chat) {
|
if self.active_chat.as_ref().map(|e| &e.0) != Some(&chat) {
|
||||||
|
self.markdown_data.clear();
|
||||||
let id = {
|
let id = {
|
||||||
let chat = chat.read(cx);
|
let chat = chat.read(cx);
|
||||||
let channel = chat.channel().clone();
|
let channel = chat.channel().clone();
|
||||||
|
@ -635,31 +636,38 @@ impl ChatPanel {
|
||||||
scroll_to_message_id: Option<u64>,
|
scroll_to_message_id: Option<u64>,
|
||||||
cx: &mut ViewContext<ChatPanel>,
|
cx: &mut ViewContext<ChatPanel>,
|
||||||
) -> Task<Result<()>> {
|
) -> Task<Result<()>> {
|
||||||
if let Some((chat, _)) = &self.active_chat {
|
let open_chat = self
|
||||||
if chat.read(cx).channel().id == selected_channel_id {
|
.active_chat
|
||||||
return Task::ready(Ok(()));
|
.as_ref()
|
||||||
}
|
.and_then(|(chat, _)| {
|
||||||
}
|
(chat.read(cx).channel().id == selected_channel_id)
|
||||||
|
.then(|| Task::ready(anyhow::Ok(chat.clone())))
|
||||||
|
})
|
||||||
|
.unwrap_or_else(|| {
|
||||||
|
self.channel_store.update(cx, |store, cx| {
|
||||||
|
store.open_channel_chat(selected_channel_id, cx)
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
let open_chat = self.channel_store.update(cx, |store, cx| {
|
|
||||||
store.open_channel_chat(selected_channel_id, cx)
|
|
||||||
});
|
|
||||||
cx.spawn(|this, mut cx| async move {
|
cx.spawn(|this, mut cx| async move {
|
||||||
let chat = open_chat.await?;
|
let chat = open_chat.await?;
|
||||||
this.update(&mut cx, |this, cx| {
|
this.update(&mut cx, |this, cx| {
|
||||||
this.markdown_data = Default::default();
|
|
||||||
this.set_active_chat(chat.clone(), cx);
|
this.set_active_chat(chat.clone(), cx);
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
if let Some(message_id) = scroll_to_message_id {
|
if let Some(message_id) = scroll_to_message_id {
|
||||||
if let Some(item_ix) =
|
if let Some(item_ix) =
|
||||||
ChannelChat::load_history_since_message(chat, message_id, cx.clone()).await
|
ChannelChat::load_history_since_message(chat.clone(), message_id, cx.clone())
|
||||||
|
.await
|
||||||
{
|
{
|
||||||
this.update(&mut cx, |this, _| {
|
this.update(&mut cx, |this, cx| {
|
||||||
this.message_list.scroll_to(ListOffset {
|
if this.active_chat.as_ref().map_or(false, |(c, _)| *c == chat) {
|
||||||
item_ix,
|
this.message_list.scroll_to(ListOffset {
|
||||||
offset_in_item: 0.,
|
item_ix,
|
||||||
});
|
offset_in_item: 0.,
|
||||||
|
});
|
||||||
|
cx.notify();
|
||||||
|
}
|
||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,6 +119,7 @@ impl NotificationPanel {
|
||||||
|
|
||||||
let mut old_dock_position = this.position(cx);
|
let mut old_dock_position = this.position(cx);
|
||||||
this.subscriptions.extend([
|
this.subscriptions.extend([
|
||||||
|
cx.observe(&this.notification_store, |_, _, cx| cx.notify()),
|
||||||
cx.subscribe(&this.notification_store, Self::on_notification_event),
|
cx.subscribe(&this.notification_store, Self::on_notification_event),
|
||||||
cx.observe_global::<SettingsStore, _>(move |this: &mut Self, cx| {
|
cx.observe_global::<SettingsStore, _>(move |this: &mut Self, cx| {
|
||||||
let new_dock_position = this.position(cx);
|
let new_dock_position = this.position(cx);
|
||||||
|
@ -469,12 +470,12 @@ impl NotificationPanel {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let id = entry.id;
|
let notification_id = entry.id;
|
||||||
self.current_notification_toast = Some((
|
self.current_notification_toast = Some((
|
||||||
id,
|
notification_id,
|
||||||
cx.spawn(|this, mut cx| async move {
|
cx.spawn(|this, mut cx| async move {
|
||||||
cx.background().timer(TOAST_DURATION).await;
|
cx.background().timer(TOAST_DURATION).await;
|
||||||
this.update(&mut cx, |this, cx| this.remove_toast(id, cx))
|
this.update(&mut cx, |this, cx| this.remove_toast(notification_id, cx))
|
||||||
.ok();
|
.ok();
|
||||||
}),
|
}),
|
||||||
));
|
));
|
||||||
|
@ -484,6 +485,7 @@ impl NotificationPanel {
|
||||||
workspace.show_notification(0, cx, |cx| {
|
workspace.show_notification(0, cx, |cx| {
|
||||||
let workspace = cx.weak_handle();
|
let workspace = cx.weak_handle();
|
||||||
cx.add_view(|_| NotificationToast {
|
cx.add_view(|_| NotificationToast {
|
||||||
|
notification_id,
|
||||||
actor,
|
actor,
|
||||||
text,
|
text,
|
||||||
workspace,
|
workspace,
|
||||||
|
@ -645,6 +647,7 @@ fn render_icon_button<V: View>(style: &IconButton, svg_path: &'static str) -> im
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct NotificationToast {
|
pub struct NotificationToast {
|
||||||
|
notification_id: u64,
|
||||||
actor: Option<Arc<User>>,
|
actor: Option<Arc<User>>,
|
||||||
text: String,
|
text: String,
|
||||||
workspace: WeakViewHandle<Workspace>,
|
workspace: WeakViewHandle<Workspace>,
|
||||||
|
@ -657,10 +660,18 @@ pub enum ToastEvent {
|
||||||
impl NotificationToast {
|
impl NotificationToast {
|
||||||
fn focus_notification_panel(&self, cx: &mut AppContext) {
|
fn focus_notification_panel(&self, cx: &mut AppContext) {
|
||||||
let workspace = self.workspace.clone();
|
let workspace = self.workspace.clone();
|
||||||
|
let notification_id = self.notification_id;
|
||||||
cx.defer(move |cx| {
|
cx.defer(move |cx| {
|
||||||
workspace
|
workspace
|
||||||
.update(cx, |workspace, cx| {
|
.update(cx, |workspace, cx| {
|
||||||
workspace.focus_panel::<NotificationPanel>(cx);
|
if let Some(panel) = workspace.focus_panel::<NotificationPanel>(cx) {
|
||||||
|
panel.update(cx, |panel, cx| {
|
||||||
|
let store = panel.notification_store.read(cx);
|
||||||
|
if let Some(entry) = store.notification_for_id(notification_id) {
|
||||||
|
panel.did_click_notification(&entry.clone().notification, cx);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.ok();
|
.ok();
|
||||||
})
|
})
|
||||||
|
|
|
@ -131,6 +131,17 @@ impl NotificationStore {
|
||||||
cursor.item()
|
cursor.item()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn notification_for_id(&self, id: u64) -> Option<&NotificationEntry> {
|
||||||
|
let mut cursor = self.notifications.cursor::<NotificationId>();
|
||||||
|
cursor.seek(&NotificationId(id), Bias::Left, &());
|
||||||
|
if let Some(item) = cursor.item() {
|
||||||
|
if item.id == id {
|
||||||
|
return Some(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
pub fn load_more_notifications(&self, cx: &mut ModelContext<Self>) -> Task<Result<()>> {
|
pub fn load_more_notifications(&self, cx: &mut ModelContext<Self>) -> Task<Result<()>> {
|
||||||
let request = self
|
let request = self
|
||||||
.client
|
.client
|
||||||
|
@ -145,6 +156,7 @@ impl NotificationStore {
|
||||||
fn handle_connect(&mut self, cx: &mut ModelContext<Self>) -> Task<Result<()>> {
|
fn handle_connect(&mut self, cx: &mut ModelContext<Self>) -> Task<Result<()>> {
|
||||||
self.notifications = Default::default();
|
self.notifications = Default::default();
|
||||||
self.channel_messages = Default::default();
|
self.channel_messages = Default::default();
|
||||||
|
cx.notify();
|
||||||
self.load_more_notifications(cx)
|
self.load_more_notifications(cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue