Detailed changes
@@ -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))
@@ -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();
+ }
})?;
}
}
@@ -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();
})
@@ -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)
}