Finish implementing drag and drop

Mikayla created

Change summary

crates/channel/src/channel_store/channel_index.rs | 14 ++---
crates/collab_ui/src/collab_panel.rs              | 44 ++++++----------
crates/drag_and_drop/src/drag_and_drop.rs         | 13 +++-
3 files changed, 32 insertions(+), 39 deletions(-)

Detailed changes

crates/channel/src/channel_store/channel_index.rs 🔗

@@ -6,16 +6,14 @@ use rpc::proto;
 
 use super::ChannelPath;
 
-pub type ChannelsById = HashMap<ChannelId, Arc<Channel>>;
-
 #[derive(Default, Debug)]
 pub struct ChannelIndex {
     paths: Vec<ChannelPath>,
-    channels_by_id: ChannelsById,
+    channels_by_id: HashMap<ChannelId, Arc<Channel>>,
 }
 
 impl ChannelIndex {
-    pub fn by_id(&self) -> &ChannelsById {
+    pub fn by_id(&self) -> &HashMap<ChannelId, Arc<Channel>> {
         &self.channels_by_id
     }
 
@@ -55,7 +53,7 @@ impl Deref for ChannelIndex {
 #[derive(Debug)]
 pub struct ChannelPathsInsertGuard<'a> {
     paths: &'a mut Vec<ChannelPath>,
-    channels_by_id: &'a mut ChannelsById,
+    channels_by_id: &'a mut HashMap<ChannelId, Arc<Channel>>,
 }
 
 impl<'a> ChannelPathsInsertGuard<'a> {
@@ -122,13 +120,13 @@ impl<'a> ChannelPathsInsertGuard<'a> {
                 let mut new_path = Vec::with_capacity(parent.len() + 1);
                 new_path.extend_from_slice(parent);
                 new_path.push(channel_id);
-                new_paths.push(ChannelPath(new_path.into()));
+                new_paths.push(ChannelPath::new(new_path.into()));
             } else {
                 for descendant in descendants.iter() {
                     let mut new_path = Vec::with_capacity(parent.len() + descendant.len());
                     new_path.extend_from_slice(parent);
                     new_path.extend_from_slice(descendant);
-                    new_paths.push(ChannelPath(new_path.into()));
+                    new_paths.push(ChannelPath::new(new_path.into()));
                 }
             }
         }
@@ -157,7 +155,7 @@ impl<'a> Drop for ChannelPathsInsertGuard<'a> {
 
 fn channel_path_sorting_key<'a>(
     path: &'a [ChannelId],
-    channels_by_id: &'a ChannelsById,
+    channels_by_id: &'a HashMap<ChannelId, Arc<Channel>>,
 ) -> impl 'a + Iterator<Item = Option<&'a str>> {
     path.iter()
         .map(|id| Some(channels_by_id.get(id)?.name.as_str()))

crates/collab_ui/src/collab_panel.rs 🔗

@@ -33,7 +33,7 @@ use gpui::{
         vector::{vec2f, Vector2F},
     },
     impl_actions,
-    platform::{CursorStyle, ModifiersChangedEvent, MouseButton, PromptLevel},
+    platform::{CursorStyle, MouseButton, PromptLevel},
     serde_json, AnyElement, AppContext, AsyncAppContext, Element, Entity, FontCache, ModelHandle,
     Subscription, Task, View, ViewContext, ViewHandle, WeakViewHandle,
 };
@@ -263,7 +263,7 @@ pub struct CollabPanel {
     subscriptions: Vec<Subscription>,
     collapsed_sections: Vec<Section>,
     collapsed_channels: Vec<ChannelPath>,
-    dragged_channel_target: Option<ChannelData>,
+    drag_target_channel: Option<ChannelData>,
     workspace: WeakViewHandle<Workspace>,
     context_menu_on_selected: bool,
 }
@@ -529,7 +529,7 @@ impl CollabPanel {
                 workspace: workspace.weak_handle(),
                 client: workspace.app_state().client.clone(),
                 context_menu_on_selected: true,
-                dragged_channel_target: None,
+                drag_target_channel: None,
                 list_state,
             };
 
@@ -1672,7 +1672,7 @@ impl CollabPanel {
             .currently_dragged::<DraggedChannel>(cx.window())
             .is_some()
             && self
-                .dragged_channel_target
+                .drag_target_channel
                 .as_ref()
                 .filter(|(_, dragged_path)| path.starts_with(dragged_path))
                 .is_some()
@@ -1771,7 +1771,7 @@ impl CollabPanel {
                 )
         })
         .on_click(MouseButton::Left, move |_, this, cx| {
-            if this.dragged_channel_target.take().is_none() {
+            if this.drag_target_channel.take().is_none() {
                 this.join_channel_chat(channel_id, cx);
             }
         })
@@ -1814,19 +1814,20 @@ impl CollabPanel {
             let channel = channel.clone();
             let path = path.clone();
             move |_, this, cx| {
-                if cx
-                    .global::<DragAndDrop<Workspace>>()
-                    .currently_dragged::<DraggedChannel>(cx.window())
-                    .is_some()
+                if let Some((_, _dragged_channel)) =
+                    cx.global::<DragAndDrop<Workspace>>()
+                        .currently_dragged::<DraggedChannel>(cx.window())
                 {
-                    if let Some(dragged_channel_target) = &this.dragged_channel_target {
-                        if dragged_channel_target.0 != channel || dragged_channel_target.1 != path {
-                            this.dragged_channel_target = Some((channel.clone(), path.clone()));
+                    match &this.drag_target_channel {
+                        Some(current_target)
+                            if current_target.0 == channel && current_target.1 == path =>
+                        {
+                            return
+                        }
+                        _ => {
+                            this.drag_target_channel = Some((channel.clone(), path.clone()));
                             cx.notify();
                         }
-                    } else {
-                        this.dragged_channel_target = Some((channel.clone(), path.clone()));
-                        cx.notify();
                     }
                 }
             }
@@ -2840,19 +2841,6 @@ impl View for CollabPanel {
         self.has_focus = false;
     }
 
-    fn modifiers_changed(&mut self, _: &ModifiersChangedEvent, cx: &mut ViewContext<Self>) -> bool {
-        if cx
-            .global::<DragAndDrop<Workspace>>()
-            .currently_dragged::<DraggedChannel>(cx.window())
-            .is_some()
-        {
-            cx.notify();
-            true
-        } else {
-            false
-        }
-    }
-
     fn render(&mut self, cx: &mut gpui::ViewContext<'_, '_, Self>) -> gpui::AnyElement<Self> {
         let theme = &theme::current(cx).collab_panel;
 

crates/drag_and_drop/src/drag_and_drop.rs 🔗

@@ -185,10 +185,11 @@ impl<V: 'static> DragAndDrop<V> {
                 Some(&State::Dragging {
                     region_offset,
                     region,
+                    modifiers,
                     ..
                 }) => {
                     this.currently_dragged = Some(State::Dragging {
-                        modifiers: event.modifiers,
+                        modifiers,
                         window,
                         region_offset,
                         region,
@@ -205,7 +206,7 @@ impl<V: 'static> DragAndDrop<V> {
     }
 
     pub fn update_modifiers(new_modifiers: Modifiers, cx: &mut ViewContext<V>) -> bool {
-        cx.update_global(|this: &mut Self, _| match &mut this.currently_dragged {
+        let result = cx.update_global(|this: &mut Self, _| match &mut this.currently_dragged {
             Some(state) => match state {
                 State::Dragging { modifiers, .. } => {
                     *modifiers = new_modifiers;
@@ -214,7 +215,13 @@ impl<V: 'static> DragAndDrop<V> {
                 _ => false,
             },
             None => false,
-        })
+        });
+
+        if result {
+            cx.notify();
+        }
+
+        result
     }
 
     pub fn render(cx: &mut ViewContext<V>) -> Option<AnyElement<V>> {