collab_ui: Wire up project picker

Co-authored-by: Conrad <conrad@zed.dev>
This commit is contained in:
Piotr Osiewicz 2023-12-13 17:56:49 +01:00 committed by Max Brunsfeld
parent 48faa171b5
commit a91a42763f
3 changed files with 93 additions and 58 deletions

View file

@ -2,11 +2,13 @@ use crate::face_pile::FacePile;
use call::{ActiveCall, ParticipantLocation, Room};
use client::{proto::PeerId, Client, ParticipantIndex, User, UserStore};
use gpui::{
actions, canvas, div, point, px, rems, AppContext, Div, Element, Hsla, InteractiveElement,
IntoElement, Model, ParentElement, Path, Render, Stateful, StatefulInteractiveElement, Styled,
Subscription, ViewContext, VisualContext, WeakView, WindowBounds,
actions, canvas, div, overlay, point, px, rems, AppContext, DismissEvent, Div, Element,
FocusableView, Hsla, InteractiveElement, IntoElement, Model, Overlay, ParentElement, Path,
Render, Stateful, StatefulInteractiveElement, Styled, Subscription, ViewContext, VisualContext,
WeakView, WindowBounds,
};
use project::{Project, RepositoryEntry};
use recent_projects::RecentProjects;
use std::sync::Arc;
use theme::{ActiveTheme, PlayerColors};
use ui::{
@ -14,7 +16,7 @@ use ui::{
IconButton, IconElement, KeyBinding, Tooltip,
};
use util::ResultExt;
use workspace::{notifications::NotifyResultExt, Workspace};
use workspace::{notifications::NotifyResultExt, Workspace, WORKSPACE_DB};
const MAX_PROJECT_NAME_LENGTH: usize = 40;
const MAX_BRANCH_NAME_LENGTH: usize = 40;
@ -49,7 +51,7 @@ pub struct CollabTitlebarItem {
client: Arc<Client>,
workspace: WeakView<Workspace>,
//branch_popover: Option<ViewHandle<BranchList>>,
//project_popover: Option<ViewHandle<recent_projects::RecentProjects>>,
project_popover: Option<recent_projects::RecentProjects>,
//user_menu: ViewHandle<ContextMenu>,
_subscriptions: Vec<Subscription>,
}
@ -328,7 +330,7 @@ impl CollabTitlebarItem {
// menu
// }),
// branch_popover: None,
// project_popover: None,
project_popover: None,
_subscriptions: subscriptions,
}
}
@ -366,11 +368,27 @@ impl CollabTitlebarItem {
let name = util::truncate_and_trailoff(name, MAX_PROJECT_NAME_LENGTH);
div().border().border_color(gpui::red()).child(
Button::new("project_name_trigger", name)
.style(ButtonStyle::Subtle)
.tooltip(move |cx| Tooltip::text("Recent Projects", cx)),
)
div()
.border()
.border_color(gpui::red())
.child(
Button::new("project_name_trigger", name)
.style(ButtonStyle::Subtle)
.tooltip(move |cx| Tooltip::text("Recent Projects", cx))
.on_click(cx.listener(|this, _, cx| {
this.toggle_project_menu(&ToggleProjectMenu, cx);
})),
)
.children(self.project_popover.as_ref().map(|popover| {
overlay().child(
div()
.min_w_56()
.on_mouse_down_out(cx.listener_for(&popover.picker, |picker, _, cx| {
picker.cancel(&Default::default(), cx)
}))
.child(popover.picker.clone()),
)
}))
}
pub fn render_project_branch(&self, cx: &mut ViewContext<Self>) -> Option<impl Element> {
@ -611,43 +629,40 @@ impl CollabTitlebarItem {
// cx.notify();
// }
// pub fn toggle_project_menu(&mut self, _: &ToggleProjectMenu, cx: &mut ViewContext<Self>) {
// let workspace = self.workspace.clone();
// if self.project_popover.take().is_none() {
// cx.spawn(|this, mut cx| async move {
// let workspaces = WORKSPACE_DB
// .recent_workspaces_on_disk()
// .await
// .unwrap_or_default()
// .into_iter()
// .map(|(_, location)| location)
// .collect();
pub fn toggle_project_menu(&mut self, _: &ToggleProjectMenu, cx: &mut ViewContext<Self>) {
let workspace = self.workspace.clone();
if self.project_popover.take().is_none() {
cx.spawn(|this, mut cx| async move {
let workspaces = WORKSPACE_DB
.recent_workspaces_on_disk()
.await
.unwrap_or_default()
.into_iter()
.map(|(_, location)| location)
.collect();
// let workspace = workspace.clone();
// this.update(&mut cx, move |this, cx| {
// let view = cx.add_view(|cx| build_recent_projects(workspace, workspaces, cx));
let workspace = workspace.clone();
this.update(&mut cx, move |this, cx| {
let view = RecentProjects::open_popover(workspace, workspaces, cx);
// cx.subscribe(&view, |this, _, event, cx| {
// match event {
// PickerEvent::Dismiss => {
// this.project_popover = None;
// }
// }
// cx.notify();
// })
// .detach();
// cx.focus(&view);
// this.branch_popover.take();
// this.project_popover = Some(view);
// cx.notify();
// })
// .log_err();
// })
// .detach();
// }
// cx.notify();
// }
cx.subscribe(&view.picker, |this, _, _: &DismissEvent, cx| {
this.project_popover = None;
cx.notify();
})
.detach();
let focus_handle = view.focus_handle(cx);
cx.focus(&focus_handle);
// todo!()
//this.branch_popover.take();
this.project_popover = Some(view);
cx.notify();
})
.log_err();
})
.detach();
}
cx.notify();
}
// fn render_user_menu_button(
// &self,

View file

@ -1,8 +1,8 @@
use editor::Editor;
use gpui::{
div, prelude::*, rems, uniform_list, AnyElement, AppContext, Div, FocusHandle, FocusableView,
MouseButton, MouseDownEvent, Render, Task, UniformListScrollHandle, View, ViewContext,
WindowContext,
div, prelude::*, rems, uniform_list, AnyElement, AppContext, DismissEvent, Div, EventEmitter,
FocusHandle, FocusableView, MouseButton, MouseDownEvent, Render, Task, UniformListScrollHandle,
View, ViewContext, WindowContext,
};
use std::{cmp, sync::Arc};
use ui::{prelude::*, v_stack, Color, Divider, Label};
@ -113,8 +113,9 @@ impl<D: PickerDelegate> Picker<D> {
cx.notify();
}
fn cancel(&mut self, _: &menu::Cancel, cx: &mut ViewContext<Self>) {
pub fn cancel(&mut self, _: &menu::Cancel, cx: &mut ViewContext<Self>) {
self.delegate.dismissed(cx);
cx.emit(DismissEvent);
}
fn confirm(&mut self, _: &menu::Confirm, cx: &mut ViewContext<Self>) {
@ -146,9 +147,15 @@ impl<D: PickerDelegate> Picker<D> {
event: &editor::EditorEvent,
cx: &mut ViewContext<Self>,
) {
if let editor::EditorEvent::BufferEdited = event {
let query = self.editor.read(cx).text(cx);
self.update_matches(query, cx);
match event {
editor::EditorEvent::BufferEdited => {
let query = self.editor.read(cx).text(cx);
self.update_matches(query, cx);
}
editor::EditorEvent::Blurred => {
self.cancel(&menu::Cancel, cx);
}
_ => {}
}
}
@ -189,6 +196,8 @@ impl<D: PickerDelegate> Picker<D> {
}
}
impl<D: PickerDelegate> EventEmitter<DismissEvent> for Picker<D> {}
impl<D: PickerDelegate> Render for Picker<D> {
type Element = Div;

View file

@ -23,14 +23,15 @@ pub fn init(cx: &mut AppContext) {
cx.observe_new_views(RecentProjects::register).detach();
}
#[derive(Clone)]
pub struct RecentProjects {
picker: View<Picker<RecentProjectsDelegate>>,
pub picker: View<Picker<RecentProjectsDelegate>>,
}
impl ModalView for RecentProjects {}
impl RecentProjects {
fn new(delegate: RecentProjectsDelegate, cx: &mut ViewContext<Self>) -> Self {
fn new(delegate: RecentProjectsDelegate, cx: &mut WindowContext<'_>) -> Self {
Self {
picker: cx.build_view(|cx| Picker::new(delegate, cx)),
}
@ -86,6 +87,16 @@ impl RecentProjects {
Ok(())
}))
}
pub fn open_popover(
workspace: WeakView<Workspace>,
workspaces: Vec<WorkspaceLocation>,
cx: &mut WindowContext<'_>,
) -> Self {
Self::new(
RecentProjectsDelegate::new(workspace, workspaces, false),
cx,
)
}
}
impl EventEmitter<DismissEvent> for RecentProjects {}
@ -127,7 +138,7 @@ impl RecentProjectsDelegate {
}
}
}
impl EventEmitter<DismissEvent> for RecentProjectsDelegate {}
impl PickerDelegate for RecentProjectsDelegate {
type ListItem = ListItem;
@ -202,11 +213,11 @@ impl PickerDelegate for RecentProjectsDelegate {
.open_workspace_for_paths(workspace_location.paths().as_ref().clone(), cx)
})
.detach_and_log_err(cx);
self.dismissed(cx);
cx.emit(DismissEvent);
}
}
fn dismissed(&mut self, _cx: &mut ViewContext<Picker<Self>>) {}
fn dismissed(&mut self, _: &mut ViewContext<Picker<Self>>) {}
fn render_match(
&self,