Fix scrolling to messages on clicking of notifications

This commit is contained in:
Max Brunsfeld 2023-10-19 14:04:34 -07:00
parent 851d7d0bc4
commit 44cb55fbe9
4 changed files with 60 additions and 24 deletions

View file

@ -257,11 +257,16 @@ impl ChannelChat {
let mut cursor = chat.messages.cursor::<(ChannelMessageId, Count)>();
let message_id = ChannelMessageId::Saved(message_id);
cursor.seek(&message_id, Bias::Left, &());
return ControlFlow::Break(if cursor.start().0 == message_id {
Some(cursor.start().1 .0)
} else {
None
});
return ControlFlow::Break(
if cursor
.item()
.map_or(false, |message| message.id == message_id)
{
Some(cursor.start().1 .0)
} else {
None
},
);
}
}
ControlFlow::Continue(chat.load_more_messages(cx))

View file

@ -257,6 +257,7 @@ impl ChatPanel {
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) {
self.markdown_data.clear();
let id = {
let chat = chat.read(cx);
let channel = chat.channel().clone();
@ -635,31 +636,38 @@ impl ChatPanel {
scroll_to_message_id: Option<u64>,
cx: &mut ViewContext<ChatPanel>,
) -> Task<Result<()>> {
if let Some((chat, _)) = &self.active_chat {
if chat.read(cx).channel().id == selected_channel_id {
return Task::ready(Ok(()));
}
}
let open_chat = self
.active_chat
.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 {
let chat = open_chat.await?;
this.update(&mut cx, |this, cx| {
this.markdown_data = Default::default();
this.set_active_chat(chat.clone(), cx);
})?;
if let Some(message_id) = scroll_to_message_id {
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.message_list.scroll_to(ListOffset {
item_ix,
offset_in_item: 0.,
});
this.update(&mut cx, |this, cx| {
if this.active_chat.as_ref().map_or(false, |(c, _)| *c == chat) {
this.message_list.scroll_to(ListOffset {
item_ix,
offset_in_item: 0.,
});
cx.notify();
}
})?;
}
}

View file

@ -119,6 +119,7 @@ impl NotificationPanel {
let mut old_dock_position = this.position(cx);
this.subscriptions.extend([
cx.observe(&this.notification_store, |_, _, cx| cx.notify()),
cx.subscribe(&this.notification_store, Self::on_notification_event),
cx.observe_global::<SettingsStore, _>(move |this: &mut Self, cx| {
let new_dock_position = this.position(cx);
@ -469,12 +470,12 @@ impl NotificationPanel {
return;
};
let id = entry.id;
let notification_id = entry.id;
self.current_notification_toast = Some((
id,
notification_id,
cx.spawn(|this, mut cx| async move {
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();
}),
));
@ -484,6 +485,7 @@ impl NotificationPanel {
workspace.show_notification(0, cx, |cx| {
let workspace = cx.weak_handle();
cx.add_view(|_| NotificationToast {
notification_id,
actor,
text,
workspace,
@ -645,6 +647,7 @@ fn render_icon_button<V: View>(style: &IconButton, svg_path: &'static str) -> im
}
pub struct NotificationToast {
notification_id: u64,
actor: Option<Arc<User>>,
text: String,
workspace: WeakViewHandle<Workspace>,
@ -657,10 +660,18 @@ pub enum ToastEvent {
impl NotificationToast {
fn focus_notification_panel(&self, cx: &mut AppContext) {
let workspace = self.workspace.clone();
let notification_id = self.notification_id;
cx.defer(move |cx| {
workspace
.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();
})

View file

@ -131,6 +131,17 @@ impl NotificationStore {
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<()>> {
let request = self
.client
@ -145,6 +156,7 @@ impl NotificationStore {
fn handle_connect(&mut self, cx: &mut ModelContext<Self>) -> Task<Result<()>> {
self.notifications = Default::default();
self.channel_messages = Default::default();
cx.notify();
self.load_more_notifications(cx)
}