From 859f2d2862a4f0c49c5d8e22136fb9c136e73c4b Mon Sep 17 00:00:00 2001 From: Conrad Irwin Date: Sat, 2 Dec 2023 00:57:41 -0700 Subject: [PATCH] Get ChannelModal opening --- crates/collab_ui2/src/collab_panel.rs | 72 +- .../src/collab_panel/channel_modal.rs | 738 +++++++++--------- crates/copilot_button2/src/copilot_button.rs | 4 +- crates/picker2/src/picker2.rs | 9 + 4 files changed, 410 insertions(+), 413 deletions(-) diff --git a/crates/collab_ui2/src/collab_panel.rs b/crates/collab_ui2/src/collab_panel.rs index b90df68c2a8ac08ed3e7a2fdf0ff31fe0f920998..9b2af2cfb1b77be0e200607c760e9cd11d6f7634 100644 --- a/crates/collab_ui2/src/collab_panel.rs +++ b/crates/collab_ui2/src/collab_panel.rs @@ -1,5 +1,5 @@ #![allow(unused)] -// mod channel_modal; +mod channel_modal; mod contact_finder; // use crate::{ @@ -192,6 +192,8 @@ use workspace::{ use crate::{face_pile::FacePile, CollaborationPanelSettings}; +use self::channel_modal::ChannelModal; + pub fn init(cx: &mut AppContext) { cx.observe_new_views(|workspace: &mut Workspace, _| { workspace.register_action(|workspace, _: &ToggleFocus, cx| { @@ -2058,13 +2060,11 @@ impl CollabPanel { } fn invite_members(&mut self, channel_id: ChannelId, cx: &mut ViewContext) { - todo!(); - // self.show_channel_modal(channel_id, channel_modal::Mode::InviteMembers, cx); + self.show_channel_modal(channel_id, channel_modal::Mode::InviteMembers, cx); } fn manage_members(&mut self, channel_id: ChannelId, cx: &mut ViewContext) { - todo!(); - // self.show_channel_modal(channel_id, channel_modal::Mode::ManageMembers, cx); + self.show_channel_modal(channel_id, channel_modal::Mode::ManageMembers, cx); } fn remove_selected_channel(&mut self, _: &Remove, cx: &mut ViewContext) { @@ -2156,38 +2156,36 @@ impl CollabPanel { }) } - // fn show_channel_modal( - // &mut self, - // channel_id: ChannelId, - // mode: channel_modal::Mode, - // cx: &mut ViewContext, - // ) { - // let workspace = self.workspace.clone(); - // let user_store = self.user_store.clone(); - // let channel_store = self.channel_store.clone(); - // let members = self.channel_store.update(cx, |channel_store, cx| { - // channel_store.get_channel_member_details(channel_id, cx) - // }); - - // cx.spawn(|_, mut cx| async move { - // let members = members.await?; - // workspace.update(&mut cx, |workspace, cx| { - // workspace.toggle_modal(cx, |_, cx| { - // cx.add_view(|cx| { - // ChannelModal::new( - // user_store.clone(), - // channel_store.clone(), - // channel_id, - // mode, - // members, - // cx, - // ) - // }) - // }); - // }) - // }) - // .detach(); - // } + fn show_channel_modal( + &mut self, + channel_id: ChannelId, + mode: channel_modal::Mode, + cx: &mut ViewContext, + ) { + let workspace = self.workspace.clone(); + let user_store = self.user_store.clone(); + let channel_store = self.channel_store.clone(); + let members = self.channel_store.update(cx, |channel_store, cx| { + channel_store.get_channel_member_details(channel_id, cx) + }); + + cx.spawn(|_, mut cx| async move { + let members = members.await?; + workspace.update(&mut cx, |workspace, cx| { + workspace.toggle_modal(cx, |cx| { + ChannelModal::new( + user_store.clone(), + channel_store.clone(), + channel_id, + mode, + members, + cx, + ) + }); + }) + }) + .detach(); + } // fn remove_selected_channel(&mut self, action: &RemoveChannel, cx: &mut ViewContext) { // self.remove_channel(action.channel_id, cx) diff --git a/crates/collab_ui2/src/collab_panel/channel_modal.rs b/crates/collab_ui2/src/collab_panel/channel_modal.rs index 0ccf0894b25fc1fc04ed884769c87b78bfaa72fc..fc1a4c5fb7f8f9e3b7c2a63a885207306a7c1ed3 100644 --- a/crates/collab_ui2/src/collab_panel/channel_modal.rs +++ b/crates/collab_ui2/src/collab_panel/channel_modal.rs @@ -3,58 +3,54 @@ use client::{ proto::{self, ChannelRole, ChannelVisibility}, User, UserId, UserStore, }; -use context_menu::{ContextMenu, ContextMenuItem}; use fuzzy::{match_strings, StringMatchCandidate}; use gpui::{ - actions, - elements::*, - platform::{CursorStyle, MouseButton}, - AppContext, ClipboardItem, Entity, ModelHandle, MouseState, Task, View, ViewContext, - ViewHandle, + actions, div, AppContext, ClipboardItem, DismissEvent, Div, Entity, EventEmitter, + FocusableView, Model, ParentElement, Render, Styled, Task, View, ViewContext, VisualContext, + WeakView, }; -use picker::{Picker, PickerDelegate, PickerEvent}; +use picker::{Picker, PickerDelegate}; use std::sync::Arc; +use ui::v_stack; use util::TryFutureExt; -use workspace::Modal; actions!( - channel_modal, - [ - SelectNextControl, - ToggleMode, - ToggleMemberAdmin, - RemoveMember - ] + SelectNextControl, + ToggleMode, + ToggleMemberAdmin, + RemoveMember ); -pub fn init(cx: &mut AppContext) { - Picker::::init(cx); - cx.add_action(ChannelModal::toggle_mode); - cx.add_action(ChannelModal::toggle_member_admin); - cx.add_action(ChannelModal::remove_member); - cx.add_action(ChannelModal::dismiss); -} +// pub fn init(cx: &mut AppContext) { +// Picker::::init(cx); +// cx.add_action(ChannelModal::toggle_mode); +// cx.add_action(ChannelModal::toggle_member_admin); +// cx.add_action(ChannelModal::remove_member); +// cx.add_action(ChannelModal::dismiss); +// } pub struct ChannelModal { - picker: ViewHandle>, - channel_store: ModelHandle, + picker: View>, + channel_store: Model, channel_id: ChannelId, has_focus: bool, } impl ChannelModal { pub fn new( - user_store: ModelHandle, - channel_store: ModelHandle, + user_store: Model, + channel_store: Model, channel_id: ChannelId, mode: Mode, members: Vec, cx: &mut ViewContext, ) -> Self { cx.observe(&channel_store, |_, _, cx| cx.notify()).detach(); - let picker = cx.add_view(|cx| { + let channel_modal = cx.view().downgrade(); + let picker = cx.build_view(|cx| { Picker::new( ChannelModalDelegate { + channel_modal, matching_users: Vec::new(), matching_member_indices: Vec::new(), selected_index: 0, @@ -64,20 +60,17 @@ impl ChannelModal { match_candidates: Vec::new(), members, mode, - context_menu: cx.add_view(|cx| { - let mut menu = ContextMenu::new(cx.view_id(), cx); - menu.set_position_mode(OverlayPositionMode::Local); - menu - }), + // context_menu: cx.add_view(|cx| { + // let mut menu = ContextMenu::new(cx.view_id(), cx); + // menu.set_position_mode(OverlayPositionMode::Local); + // menu + // }), }, cx, ) - .with_theme(|theme| theme.collab_panel.tabbed_modal.picker.clone()) }); - cx.subscribe(&picker, |_, _, e, cx| cx.emit(*e)).detach(); - - let has_focus = picker.read(cx).has_focus(); + let has_focus = picker.focus_handle(cx).contains_focused(cx); Self { picker, @@ -88,7 +81,7 @@ impl ChannelModal { } fn toggle_mode(&mut self, _: &ToggleMode, cx: &mut ViewContext) { - let mode = match self.picker.read(cx).delegate().mode { + let mode = match self.picker.read(cx).delegate.mode { Mode::ManageMembers => Mode::InviteMembers, Mode::InviteMembers => Mode::ManageMembers, }; @@ -103,20 +96,20 @@ impl ChannelModal { let mut members = channel_store .update(&mut cx, |channel_store, cx| { channel_store.get_channel_member_details(channel_id, cx) - }) + })? .await?; members.sort_by(|a, b| a.sort_key().cmp(&b.sort_key())); this.update(&mut cx, |this, cx| { this.picker - .update(cx, |picker, _| picker.delegate_mut().members = members); + .update(cx, |picker, _| picker.delegate.members = members); })?; } this.update(&mut cx, |this, cx| { this.picker.update(cx, |picker, cx| { - let delegate = picker.delegate_mut(); + let delegate = &mut picker.delegate; delegate.mode = mode; delegate.selected_index = 0; picker.set_query("", cx); @@ -131,203 +124,194 @@ impl ChannelModal { fn toggle_member_admin(&mut self, _: &ToggleMemberAdmin, cx: &mut ViewContext) { self.picker.update(cx, |picker, cx| { - picker.delegate_mut().toggle_selected_member_admin(cx); + picker.delegate.toggle_selected_member_admin(cx); }) } fn remove_member(&mut self, _: &RemoveMember, cx: &mut ViewContext) { self.picker.update(cx, |picker, cx| { - picker.delegate_mut().remove_selected_member(cx); + picker.delegate.remove_selected_member(cx); }); } fn dismiss(&mut self, _: &menu::Cancel, cx: &mut ViewContext) { - cx.emit(PickerEvent::Dismiss); + cx.emit(DismissEvent); } } -impl Entity for ChannelModal { - type Event = PickerEvent; -} - -impl View for ChannelModal { - fn ui_name() -> &'static str { - "ChannelModal" - } - - fn render(&mut self, cx: &mut ViewContext) -> AnyElement { - let theme = &theme::current(cx).collab_panel.tabbed_modal; - - let mode = self.picker.read(cx).delegate().mode; - let Some(channel) = self.channel_store.read(cx).channel_for_id(self.channel_id) else { - return Empty::new().into_any(); - }; - - enum InviteMembers {} - enum ManageMembers {} - - fn render_mode_button( - mode: Mode, - text: &'static str, - current_mode: Mode, - theme: &theme::TabbedModal, - cx: &mut ViewContext, - ) -> AnyElement { - let active = mode == current_mode; - MouseEventHandler::new::(0, cx, move |state, _| { - let contained_text = theme.tab_button.style_for(active, state); - Label::new(text, contained_text.text.clone()) - .contained() - .with_style(contained_text.container.clone()) - }) - .on_click(MouseButton::Left, move |_, this, cx| { - if !active { - this.set_mode(mode, cx); - } - }) - .with_cursor_style(CursorStyle::PointingHand) - .into_any() - } - - fn render_visibility( - channel_id: ChannelId, - visibility: ChannelVisibility, - theme: &theme::TabbedModal, - cx: &mut ViewContext, - ) -> AnyElement { - enum TogglePublic {} - - if visibility == ChannelVisibility::Members { - return Flex::row() - .with_child( - MouseEventHandler::new::(0, cx, move |state, _| { - let style = theme.visibility_toggle.style_for(state); - Label::new(format!("{}", "Public access: OFF"), style.text.clone()) - .contained() - .with_style(style.container.clone()) - }) - .on_click(MouseButton::Left, move |_, this, cx| { - this.channel_store - .update(cx, |channel_store, cx| { - channel_store.set_channel_visibility( - channel_id, - ChannelVisibility::Public, - cx, - ) - }) - .detach_and_log_err(cx); - }) - .with_cursor_style(CursorStyle::PointingHand), - ) - .into_any(); - } - - Flex::row() - .with_child( - MouseEventHandler::new::(0, cx, move |state, _| { - let style = theme.visibility_toggle.style_for(state); - Label::new(format!("{}", "Public access: ON"), style.text.clone()) - .contained() - .with_style(style.container.clone()) - }) - .on_click(MouseButton::Left, move |_, this, cx| { - this.channel_store - .update(cx, |channel_store, cx| { - channel_store.set_channel_visibility( - channel_id, - ChannelVisibility::Members, - cx, - ) - }) - .detach_and_log_err(cx); - }) - .with_cursor_style(CursorStyle::PointingHand), - ) - .with_spacing(14.0) - .with_child( - MouseEventHandler::new::(1, cx, move |state, _| { - let style = theme.channel_link.style_for(state); - Label::new(format!("{}", "copy link"), style.text.clone()) - .contained() - .with_style(style.container.clone()) - }) - .on_click(MouseButton::Left, move |_, this, cx| { - if let Some(channel) = - this.channel_store.read(cx).channel_for_id(channel_id) - { - let item = ClipboardItem::new(channel.link()); - cx.write_to_clipboard(item); - } - }) - .with_cursor_style(CursorStyle::PointingHand), - ) - .into_any() - } - - Flex::column() - .with_child( - Flex::column() - .with_child( - Label::new(format!("#{}", channel.name), theme.title.text.clone()) - .contained() - .with_style(theme.title.container.clone()), - ) - .with_child(render_visibility(channel.id, channel.visibility, theme, cx)) - .with_child(Flex::row().with_children([ - render_mode_button::( - Mode::InviteMembers, - "Invite members", - mode, - theme, - cx, - ), - render_mode_button::( - Mode::ManageMembers, - "Manage members", - mode, - theme, - cx, - ), - ])) - .expanded() - .contained() - .with_style(theme.header), - ) - .with_child( - ChildView::new(&self.picker, cx) - .contained() - .with_style(theme.body), - ) - .constrained() - .with_max_height(theme.max_height) - .with_max_width(theme.max_width) - .contained() - .with_style(theme.modal) - .into_any() - } - - fn focus_in(&mut self, _: gpui::AnyViewHandle, cx: &mut ViewContext) { - self.has_focus = true; - if cx.is_self_focused() { - cx.focus(&self.picker) - } - } +impl EventEmitter for ChannelModal {} - fn focus_out(&mut self, _: gpui::AnyViewHandle, _: &mut ViewContext) { - self.has_focus = false; +impl FocusableView for ChannelModal { + fn focus_handle(&self, cx: &AppContext) -> gpui::FocusHandle { + self.picker.focus_handle(cx) } } -impl Modal for ChannelModal { - fn has_focus(&self) -> bool { - self.has_focus +impl Render for ChannelModal { + type Element = Div; + + fn render(&mut self, cx: &mut ViewContext) -> Self::Element { + v_stack().min_w_96().child(self.picker.clone()) + // let theme = &theme::current(cx).collab_panel.tabbed_modal; + + // let mode = self.picker.read(cx).delegate().mode; + // let Some(channel) = self.channel_store.read(cx).channel_for_id(self.channel_id) else { + // return Empty::new().into_any(); + // }; + + // enum InviteMembers {} + // enum ManageMembers {} + + // fn render_mode_button( + // mode: Mode, + // text: &'static str, + // current_mode: Mode, + // theme: &theme::TabbedModal, + // cx: &mut ViewContext, + // ) -> AnyElement { + // let active = mode == current_mode; + // MouseEventHandler::new::(0, cx, move |state, _| { + // let contained_text = theme.tab_button.style_for(active, state); + // Label::new(text, contained_text.text.clone()) + // .contained() + // .with_style(contained_text.container.clone()) + // }) + // .on_click(MouseButton::Left, move |_, this, cx| { + // if !active { + // this.set_mode(mode, cx); + // } + // }) + // .with_cursor_style(CursorStyle::PointingHand) + // .into_any() + // } + + // fn render_visibility( + // channel_id: ChannelId, + // visibility: ChannelVisibility, + // theme: &theme::TabbedModal, + // cx: &mut ViewContext, + // ) -> AnyElement { + // enum TogglePublic {} + + // if visibility == ChannelVisibility::Members { + // return Flex::row() + // .with_child( + // MouseEventHandler::new::(0, cx, move |state, _| { + // let style = theme.visibility_toggle.style_for(state); + // Label::new(format!("{}", "Public access: OFF"), style.text.clone()) + // .contained() + // .with_style(style.container.clone()) + // }) + // .on_click(MouseButton::Left, move |_, this, cx| { + // this.channel_store + // .update(cx, |channel_store, cx| { + // channel_store.set_channel_visibility( + // channel_id, + // ChannelVisibility::Public, + // cx, + // ) + // }) + // .detach_and_log_err(cx); + // }) + // .with_cursor_style(CursorStyle::PointingHand), + // ) + // .into_any(); + // } + + // Flex::row() + // .with_child( + // MouseEventHandler::new::(0, cx, move |state, _| { + // let style = theme.visibility_toggle.style_for(state); + // Label::new(format!("{}", "Public access: ON"), style.text.clone()) + // .contained() + // .with_style(style.container.clone()) + // }) + // .on_click(MouseButton::Left, move |_, this, cx| { + // this.channel_store + // .update(cx, |channel_store, cx| { + // channel_store.set_channel_visibility( + // channel_id, + // ChannelVisibility::Members, + // cx, + // ) + // }) + // .detach_and_log_err(cx); + // }) + // .with_cursor_style(CursorStyle::PointingHand), + // ) + // .with_spacing(14.0) + // .with_child( + // MouseEventHandler::new::(1, cx, move |state, _| { + // let style = theme.channel_link.style_for(state); + // Label::new(format!("{}", "copy link"), style.text.clone()) + // .contained() + // .with_style(style.container.clone()) + // }) + // .on_click(MouseButton::Left, move |_, this, cx| { + // if let Some(channel) = + // this.channel_store.read(cx).channel_for_id(channel_id) + // { + // let item = ClipboardItem::new(channel.link()); + // cx.write_to_clipboard(item); + // } + // }) + // .with_cursor_style(CursorStyle::PointingHand), + // ) + // .into_any() + // } + + // Flex::column() + // .with_child( + // Flex::column() + // .with_child( + // Label::new(format!("#{}", channel.name), theme.title.text.clone()) + // .contained() + // .with_style(theme.title.container.clone()), + // ) + // .with_child(render_visibility(channel.id, channel.visibility, theme, cx)) + // .with_child(Flex::row().with_children([ + // render_mode_button::( + // Mode::InviteMembers, + // "Invite members", + // mode, + // theme, + // cx, + // ), + // render_mode_button::( + // Mode::ManageMembers, + // "Manage members", + // mode, + // theme, + // cx, + // ), + // ])) + // .expanded() + // .contained() + // .with_style(theme.header), + // ) + // .with_child( + // ChildView::new(&self.picker, cx) + // .contained() + // .with_style(theme.body), + // ) + // .constrained() + // .with_max_height(theme.max_height) + // .with_max_width(theme.max_width) + // .contained() + // .with_style(theme.modal) + // .into_any() } - fn dismiss_on_event(event: &Self::Event) -> bool { - match event { - PickerEvent::Dismiss => true, - } - } + // fn focus_in(&mut self, _: gpui::AnyViewHandle, cx: &mut ViewContext) { + // self.has_focus = true; + // if cx.is_self_focused() { + // cx.focus(&self.picker) + // } + // } + + // fn focus_out(&mut self, _: gpui::AnyViewHandle, _: &mut ViewContext) { + // self.has_focus = false; + // } } #[derive(Copy, Clone, PartialEq)] @@ -337,19 +321,22 @@ pub enum Mode { } pub struct ChannelModalDelegate { + channel_modal: WeakView, matching_users: Vec>, matching_member_indices: Vec, - user_store: ModelHandle, - channel_store: ModelHandle, + user_store: Model, + channel_store: Model, channel_id: ChannelId, selected_index: usize, mode: Mode, match_candidates: Vec, members: Vec, - context_menu: ViewHandle, + // context_menu: ViewHandle, } impl PickerDelegate for ChannelModalDelegate { + type ListItem = Div; + fn placeholder_text(&self) -> Arc { "Search collaborator by username...".into() } @@ -382,19 +369,19 @@ impl PickerDelegate for ChannelModalDelegate { } })); - let matches = cx.background().block(match_strings( + let matches = cx.background_executor().block(match_strings( &self.match_candidates, &query, true, usize::MAX, &Default::default(), - cx.background().clone(), + cx.background_executor().clone(), )); cx.spawn(|picker, mut cx| async move { picker .update(&mut cx, |picker, cx| { - let delegate = picker.delegate_mut(); + let delegate = &mut picker.delegate; delegate.matching_member_indices.clear(); delegate .matching_member_indices @@ -412,8 +399,7 @@ impl PickerDelegate for ChannelModalDelegate { async { let users = search_users.await?; picker.update(&mut cx, |picker, cx| { - let delegate = picker.delegate_mut(); - delegate.matching_users = users; + picker.delegate.matching_users = users; cx.notify(); })?; anyhow::Ok(()) @@ -445,138 +431,142 @@ impl PickerDelegate for ChannelModalDelegate { } fn dismissed(&mut self, cx: &mut ViewContext>) { - cx.emit(PickerEvent::Dismiss); + self.channel_modal + .update(cx, |_, cx| { + cx.emit(DismissEvent); + }) + .ok(); } fn render_match( &self, ix: usize, - mouse_state: &mut MouseState, selected: bool, - cx: &gpui::AppContext, - ) -> AnyElement> { - let full_theme = &theme::current(cx); - let theme = &full_theme.collab_panel.channel_modal; - let tabbed_modal = &full_theme.collab_panel.tabbed_modal; - let (user, role) = self.user_at_index(ix).unwrap(); - let request_status = self.member_status(user.id, cx); - - let style = tabbed_modal - .picker - .item - .in_state(selected) - .style_for(mouse_state); - - let in_manage = matches!(self.mode, Mode::ManageMembers); - - let mut result = Flex::row() - .with_children(user.avatar.clone().map(|avatar| { - Image::from_data(avatar) - .with_style(theme.contact_avatar) - .aligned() - .left() - })) - .with_child( - Label::new(user.github_login.clone(), style.label.clone()) - .contained() - .with_style(theme.contact_username) - .aligned() - .left(), - ) - .with_children({ - (in_manage && request_status == Some(proto::channel_member::Kind::Invitee)).then( - || { - Label::new("Invited", theme.member_tag.text.clone()) - .contained() - .with_style(theme.member_tag.container) - .aligned() - .left() - }, - ) - }) - .with_children(if in_manage && role == Some(ChannelRole::Admin) { - Some( - Label::new("Admin", theme.member_tag.text.clone()) - .contained() - .with_style(theme.member_tag.container) - .aligned() - .left(), - ) - } else if in_manage && role == Some(ChannelRole::Guest) { - Some( - Label::new("Guest", theme.member_tag.text.clone()) - .contained() - .with_style(theme.member_tag.container) - .aligned() - .left(), - ) - } else { - None - }) - .with_children({ - let svg = match self.mode { - Mode::ManageMembers => Some( - Svg::new("icons/ellipsis.svg") - .with_color(theme.member_icon.color) - .constrained() - .with_width(theme.member_icon.icon_width) - .aligned() - .constrained() - .with_width(theme.member_icon.button_width) - .with_height(theme.member_icon.button_width) - .contained() - .with_style(theme.member_icon.container), - ), - Mode::InviteMembers => match request_status { - Some(proto::channel_member::Kind::Member) => Some( - Svg::new("icons/check.svg") - .with_color(theme.member_icon.color) - .constrained() - .with_width(theme.member_icon.icon_width) - .aligned() - .constrained() - .with_width(theme.member_icon.button_width) - .with_height(theme.member_icon.button_width) - .contained() - .with_style(theme.member_icon.container), - ), - Some(proto::channel_member::Kind::Invitee) => Some( - Svg::new("icons/check.svg") - .with_color(theme.invitee_icon.color) - .constrained() - .with_width(theme.invitee_icon.icon_width) - .aligned() - .constrained() - .with_width(theme.invitee_icon.button_width) - .with_height(theme.invitee_icon.button_width) - .contained() - .with_style(theme.invitee_icon.container), - ), - Some(proto::channel_member::Kind::AncestorMember) | None => None, - }, - }; - - svg.map(|svg| svg.aligned().flex_float().into_any()) - }) - .contained() - .with_style(style.container) - .constrained() - .with_height(tabbed_modal.row_height) - .into_any(); - - if selected { - result = Stack::new() - .with_child(result) - .with_child( - ChildView::new(&self.context_menu, cx) - .aligned() - .top() - .right(), - ) - .into_any(); - } - - result + cx: &mut ViewContext>, + ) -> Option { + None + // let full_theme = &theme::current(cx); + // let theme = &full_theme.collab_panel.channel_modal; + // let tabbed_modal = &full_theme.collab_panel.tabbed_modal; + // let (user, role) = self.user_at_index(ix).unwrap(); + // let request_status = self.member_status(user.id, cx); + + // let style = tabbed_modal + // .picker + // .item + // .in_state(selected) + // .style_for(mouse_state); + + // let in_manage = matches!(self.mode, Mode::ManageMembers); + + // let mut result = Flex::row() + // .with_children(user.avatar.clone().map(|avatar| { + // Image::from_data(avatar) + // .with_style(theme.contact_avatar) + // .aligned() + // .left() + // })) + // .with_child( + // Label::new(user.github_login.clone(), style.label.clone()) + // .contained() + // .with_style(theme.contact_username) + // .aligned() + // .left(), + // ) + // .with_children({ + // (in_manage && request_status == Some(proto::channel_member::Kind::Invitee)).then( + // || { + // Label::new("Invited", theme.member_tag.text.clone()) + // .contained() + // .with_style(theme.member_tag.container) + // .aligned() + // .left() + // }, + // ) + // }) + // .with_children(if in_manage && role == Some(ChannelRole::Admin) { + // Some( + // Label::new("Admin", theme.member_tag.text.clone()) + // .contained() + // .with_style(theme.member_tag.container) + // .aligned() + // .left(), + // ) + // } else if in_manage && role == Some(ChannelRole::Guest) { + // Some( + // Label::new("Guest", theme.member_tag.text.clone()) + // .contained() + // .with_style(theme.member_tag.container) + // .aligned() + // .left(), + // ) + // } else { + // None + // }) + // .with_children({ + // let svg = match self.mode { + // Mode::ManageMembers => Some( + // Svg::new("icons/ellipsis.svg") + // .with_color(theme.member_icon.color) + // .constrained() + // .with_width(theme.member_icon.icon_width) + // .aligned() + // .constrained() + // .with_width(theme.member_icon.button_width) + // .with_height(theme.member_icon.button_width) + // .contained() + // .with_style(theme.member_icon.container), + // ), + // Mode::InviteMembers => match request_status { + // Some(proto::channel_member::Kind::Member) => Some( + // Svg::new("icons/check.svg") + // .with_color(theme.member_icon.color) + // .constrained() + // .with_width(theme.member_icon.icon_width) + // .aligned() + // .constrained() + // .with_width(theme.member_icon.button_width) + // .with_height(theme.member_icon.button_width) + // .contained() + // .with_style(theme.member_icon.container), + // ), + // Some(proto::channel_member::Kind::Invitee) => Some( + // Svg::new("icons/check.svg") + // .with_color(theme.invitee_icon.color) + // .constrained() + // .with_width(theme.invitee_icon.icon_width) + // .aligned() + // .constrained() + // .with_width(theme.invitee_icon.button_width) + // .with_height(theme.invitee_icon.button_width) + // .contained() + // .with_style(theme.invitee_icon.container), + // ), + // Some(proto::channel_member::Kind::AncestorMember) | None => None, + // }, + // }; + + // svg.map(|svg| svg.aligned().flex_float().into_any()) + // }) + // .contained() + // .with_style(style.container) + // .constrained() + // .with_height(tabbed_modal.row_height) + // .into_any(); + + // if selected { + // result = Stack::new() + // .with_child(result) + // .with_child( + // ChildView::new(&self.context_menu, cx) + // .aligned() + // .top() + // .right(), + // ) + // .into_any(); + // } + + // result } } @@ -623,7 +613,7 @@ impl ChannelModalDelegate { cx.spawn(|picker, mut cx| async move { update.await?; picker.update(&mut cx, |picker, cx| { - let this = picker.delegate_mut(); + let this = &mut picker.delegate; if let Some(member) = this.members.iter_mut().find(|m| m.user.id == user.id) { member.role = new_role; } @@ -644,7 +634,7 @@ impl ChannelModalDelegate { cx.spawn(|picker, mut cx| async move { update.await?; picker.update(&mut cx, |picker, cx| { - let this = picker.delegate_mut(); + let this = &mut picker.delegate; if let Some(ix) = this.members.iter_mut().position(|m| m.user.id == user_id) { this.members.remove(ix); this.matching_member_indices.retain_mut(|member_ix| { @@ -683,7 +673,7 @@ impl ChannelModalDelegate { kind: proto::channel_member::Kind::Invitee, role: ChannelRole::Member, }; - let members = &mut this.delegate_mut().members; + let members = &mut this.delegate.members; match members.binary_search_by_key(&new_member.sort_key(), |k| k.sort_key()) { Ok(ix) | Err(ix) => members.insert(ix, new_member), } @@ -695,23 +685,23 @@ impl ChannelModalDelegate { } fn show_context_menu(&mut self, role: ChannelRole, cx: &mut ViewContext>) { - self.context_menu.update(cx, |context_menu, cx| { - context_menu.show( - Default::default(), - AnchorCorner::TopRight, - vec![ - ContextMenuItem::action("Remove", RemoveMember), - ContextMenuItem::action( - if role == ChannelRole::Admin { - "Make non-admin" - } else { - "Make admin" - }, - ToggleMemberAdmin, - ), - ], - cx, - ) - }) + // self.context_menu.update(cx, |context_menu, cx| { + // context_menu.show( + // Default::default(), + // AnchorCorner::TopRight, + // vec![ + // ContextMenuItem::action("Remove", RemoveMember), + // ContextMenuItem::action( + // if role == ChannelRole::Admin { + // "Make non-admin" + // } else { + // "Make admin" + // }, + // ToggleMemberAdmin, + // ), + // ], + // cx, + // ) + // }) } } diff --git a/crates/copilot_button2/src/copilot_button.rs b/crates/copilot_button2/src/copilot_button.rs index 0fac4924178372b97b537024f1987161b618c014..aab59a9cad500a97a93f6c12990ba43cdb25b528 100644 --- a/crates/copilot_button2/src/copilot_button.rs +++ b/crates/copilot_button2/src/copilot_button.rs @@ -68,7 +68,7 @@ impl Render for CopilotButton { if let Status::Error(e) = status { return div().child( - IconButton::new("github-copilot", icon) + IconButton::new("copilot-error", icon) .on_click(cx.listener(move |this, _, cx| { if let Some(workspace) = cx.window_handle().downcast::() { workspace.update(cx, |workspace, cx| { @@ -98,7 +98,7 @@ impl Render for CopilotButton { let this = cx.view().clone(); div().child( - popover_menu("github-copilot") + popover_menu("copilot") .menu(move |cx| match status { Status::Authorized => this.update(cx, |this, cx| this.build_copilot_menu(cx)), _ => this.update(cx, |this, cx| this.build_copilot_start_menu(cx)), diff --git a/crates/picker2/src/picker2.rs b/crates/picker2/src/picker2.rs index 44056dabd16528b7a1aa28ab2e966b05f2ce0b43..89513be8b38b49f973dd7430d16c532405711071 100644 --- a/crates/picker2/src/picker2.rs +++ b/crates/picker2/src/picker2.rs @@ -178,6 +178,15 @@ impl Picker { } cx.notify(); } + + pub fn query(&self, cx: &AppContext) -> String { + self.editor.read(cx).text(cx) + } + + pub fn set_query(&self, query: impl Into>, cx: &mut ViewContext) { + self.editor + .update(cx, |editor, cx| editor.set_text(query, cx)); + } } impl Render for Picker {