mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-16 15:11:25 +00:00
collab_ui: Wire up project picker
Co-authored-by: Conrad <conrad@zed.dev>
This commit is contained in:
parent
48faa171b5
commit
a91a42763f
3 changed files with 93 additions and 58 deletions
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue