mirror of
https://github.com/zed-industries/zed.git
synced 2024-12-27 11:01:40 +03:00
Remove ViewContext::dispatch_action
This commit is contained in:
parent
d815fc88ae
commit
c4472b0786
@ -51,9 +51,8 @@ impl Entity for AutoUpdater {
|
|||||||
|
|
||||||
pub fn init(http_client: Arc<dyn HttpClient>, server_url: String, cx: &mut AppContext) {
|
pub fn init(http_client: Arc<dyn HttpClient>, server_url: String, cx: &mut AppContext) {
|
||||||
if let Some(version) = (*ZED_APP_VERSION).or_else(|| cx.platform().app_version().ok()) {
|
if let Some(version) = (*ZED_APP_VERSION).or_else(|| cx.platform().app_version().ok()) {
|
||||||
let server_url = server_url;
|
|
||||||
let auto_updater = cx.add_model(|cx| {
|
let auto_updater = cx.add_model(|cx| {
|
||||||
let updater = AutoUpdater::new(version, http_client, server_url.clone());
|
let updater = AutoUpdater::new(version, http_client, server_url);
|
||||||
|
|
||||||
let mut update_subscription = cx
|
let mut update_subscription = cx
|
||||||
.global::<Settings>()
|
.global::<Settings>()
|
||||||
@ -74,25 +73,32 @@ pub fn init(http_client: Arc<dyn HttpClient>, server_url: String, cx: &mut AppCo
|
|||||||
updater
|
updater
|
||||||
});
|
});
|
||||||
cx.set_global(Some(auto_updater));
|
cx.set_global(Some(auto_updater));
|
||||||
cx.add_global_action(|_: &Check, cx| {
|
cx.add_global_action(check);
|
||||||
if let Some(updater) = AutoUpdater::get(cx) {
|
cx.add_global_action(view_release_notes);
|
||||||
updater.update(cx, |updater, cx| updater.poll(cx));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
cx.add_global_action(move |_: &ViewReleaseNotes, cx| {
|
|
||||||
let latest_release_url = if cx.has_global::<ReleaseChannel>()
|
|
||||||
&& *cx.global::<ReleaseChannel>() == ReleaseChannel::Preview
|
|
||||||
{
|
|
||||||
format!("{server_url}/releases/preview/latest")
|
|
||||||
} else {
|
|
||||||
format!("{server_url}/releases/latest")
|
|
||||||
};
|
|
||||||
cx.platform().open_url(&latest_release_url);
|
|
||||||
});
|
|
||||||
cx.add_action(UpdateNotification::dismiss);
|
cx.add_action(UpdateNotification::dismiss);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn check(_: &Check, cx: &mut AppContext) {
|
||||||
|
if let Some(updater) = AutoUpdater::get(cx) {
|
||||||
|
updater.update(cx, |updater, cx| updater.poll(cx));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn view_release_notes(_: &ViewReleaseNotes, cx: &mut AppContext) {
|
||||||
|
if let Some(auto_updater) = AutoUpdater::get(cx) {
|
||||||
|
let server_url = &auto_updater.read(cx).server_url;
|
||||||
|
let latest_release_url = if cx.has_global::<ReleaseChannel>()
|
||||||
|
&& *cx.global::<ReleaseChannel>() == ReleaseChannel::Preview
|
||||||
|
{
|
||||||
|
format!("{server_url}/releases/preview/latest")
|
||||||
|
} else {
|
||||||
|
format!("{server_url}/releases/latest")
|
||||||
|
};
|
||||||
|
cx.platform().open_url(&latest_release_url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn notify_of_any_new_update(
|
pub fn notify_of_any_new_update(
|
||||||
workspace: WeakViewHandle<Workspace>,
|
workspace: WeakViewHandle<Workspace>,
|
||||||
cx: &mut AppContext,
|
cx: &mut AppContext,
|
||||||
|
@ -63,8 +63,8 @@ impl View for UpdateNotification {
|
|||||||
.with_height(style.button_width)
|
.with_height(style.button_width)
|
||||||
})
|
})
|
||||||
.with_padding(Padding::uniform(5.))
|
.with_padding(Padding::uniform(5.))
|
||||||
.on_click(MouseButton::Left, move |_, _, cx| {
|
.on_click(MouseButton::Left, move |_, this, cx| {
|
||||||
cx.dispatch_action(Cancel)
|
this.dismiss(&Default::default(), cx)
|
||||||
})
|
})
|
||||||
.aligned()
|
.aligned()
|
||||||
.constrained()
|
.constrained()
|
||||||
@ -84,7 +84,7 @@ impl View for UpdateNotification {
|
|||||||
})
|
})
|
||||||
.with_cursor_style(CursorStyle::PointingHand)
|
.with_cursor_style(CursorStyle::PointingHand)
|
||||||
.on_click(MouseButton::Left, |_, _, cx| {
|
.on_click(MouseButton::Left, |_, _, cx| {
|
||||||
cx.dispatch_action(ViewReleaseNotes)
|
crate::view_release_notes(&Default::default(), cx)
|
||||||
})
|
})
|
||||||
.into_any_named("update notification")
|
.into_any_named("update notification")
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
use gpui::{
|
use gpui::{
|
||||||
elements::*, platform::MouseButton, AppContext, Entity, Subscription, View, ViewContext,
|
elements::*, platform::MouseButton, AppContext, Entity, Subscription, View, ViewContext,
|
||||||
ViewHandle,
|
ViewHandle, WeakViewHandle,
|
||||||
};
|
};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use search::ProjectSearchView;
|
use search::ProjectSearchView;
|
||||||
use settings::Settings;
|
use settings::Settings;
|
||||||
use workspace::{
|
use workspace::{
|
||||||
item::{ItemEvent, ItemHandle},
|
item::{ItemEvent, ItemHandle},
|
||||||
ToolbarItemLocation, ToolbarItemView,
|
ToolbarItemLocation, ToolbarItemView, Workspace,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub enum Event {
|
pub enum Event {
|
||||||
@ -19,15 +19,17 @@ pub struct Breadcrumbs {
|
|||||||
active_item: Option<Box<dyn ItemHandle>>,
|
active_item: Option<Box<dyn ItemHandle>>,
|
||||||
project_search: Option<ViewHandle<ProjectSearchView>>,
|
project_search: Option<ViewHandle<ProjectSearchView>>,
|
||||||
subscription: Option<Subscription>,
|
subscription: Option<Subscription>,
|
||||||
|
workspace: WeakViewHandle<Workspace>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Breadcrumbs {
|
impl Breadcrumbs {
|
||||||
pub fn new() -> Self {
|
pub fn new(workspace: &Workspace) -> Self {
|
||||||
Self {
|
Self {
|
||||||
pane_focused: false,
|
pane_focused: false,
|
||||||
active_item: Default::default(),
|
active_item: Default::default(),
|
||||||
subscription: Default::default(),
|
subscription: Default::default(),
|
||||||
project_search: Default::default(),
|
project_search: Default::default(),
|
||||||
|
workspace: workspace.weak_handle(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -85,8 +87,12 @@ impl View for Breadcrumbs {
|
|||||||
let style = style.style_for(state, false);
|
let style = style.style_for(state, false);
|
||||||
crumbs.with_style(style.container)
|
crumbs.with_style(style.container)
|
||||||
})
|
})
|
||||||
.on_click(MouseButton::Left, |_, _, cx| {
|
.on_click(MouseButton::Left, |_, this, cx| {
|
||||||
cx.dispatch_action(outline::Toggle);
|
if let Some(workspace) = this.workspace.upgrade(cx) {
|
||||||
|
workspace.update(cx, |workspace, cx| {
|
||||||
|
outline::toggle(workspace, &Default::default(), cx)
|
||||||
|
})
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.with_tooltip::<Breadcrumbs>(
|
.with_tooltip::<Breadcrumbs>(
|
||||||
0,
|
0,
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
collaborator_list_popover, collaborator_list_popover::CollaboratorListPopover,
|
|
||||||
contact_notification::ContactNotification, contacts_popover, face_pile::FacePile,
|
contact_notification::ContactNotification, contacts_popover, face_pile::FacePile,
|
||||||
ToggleScreenSharing,
|
toggle_screen_sharing, ToggleScreenSharing,
|
||||||
};
|
};
|
||||||
use call::{ActiveCall, ParticipantLocation, Room};
|
use call::{ActiveCall, ParticipantLocation, Room};
|
||||||
use client::{proto::PeerId, ContactEventKind, SignIn, SignOut, User, UserStore};
|
use client::{proto::PeerId, ContactEventKind, SignIn, SignOut, User, UserStore};
|
||||||
@ -27,7 +26,6 @@ use workspace::{FollowNextCollaborator, Workspace};
|
|||||||
actions!(
|
actions!(
|
||||||
collab,
|
collab,
|
||||||
[
|
[
|
||||||
ToggleCollaboratorList,
|
|
||||||
ToggleContactsMenu,
|
ToggleContactsMenu,
|
||||||
ToggleUserMenu,
|
ToggleUserMenu,
|
||||||
ShareProject,
|
ShareProject,
|
||||||
@ -36,7 +34,6 @@ actions!(
|
|||||||
);
|
);
|
||||||
|
|
||||||
pub fn init(cx: &mut AppContext) {
|
pub fn init(cx: &mut AppContext) {
|
||||||
cx.add_action(CollabTitlebarItem::toggle_collaborator_list_popover);
|
|
||||||
cx.add_action(CollabTitlebarItem::toggle_contacts_popover);
|
cx.add_action(CollabTitlebarItem::toggle_contacts_popover);
|
||||||
cx.add_action(CollabTitlebarItem::share_project);
|
cx.add_action(CollabTitlebarItem::share_project);
|
||||||
cx.add_action(CollabTitlebarItem::unshare_project);
|
cx.add_action(CollabTitlebarItem::unshare_project);
|
||||||
@ -48,7 +45,6 @@ pub struct CollabTitlebarItem {
|
|||||||
user_store: ModelHandle<UserStore>,
|
user_store: ModelHandle<UserStore>,
|
||||||
contacts_popover: Option<ViewHandle<ContactsPopover>>,
|
contacts_popover: Option<ViewHandle<ContactsPopover>>,
|
||||||
user_menu: ViewHandle<ContextMenu>,
|
user_menu: ViewHandle<ContextMenu>,
|
||||||
collaborator_list_popover: Option<ViewHandle<CollaboratorListPopover>>,
|
|
||||||
_subscriptions: Vec<Subscription>,
|
_subscriptions: Vec<Subscription>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,7 +168,6 @@ impl CollabTitlebarItem {
|
|||||||
menu.set_position_mode(OverlayPositionMode::Local);
|
menu.set_position_mode(OverlayPositionMode::Local);
|
||||||
menu
|
menu
|
||||||
}),
|
}),
|
||||||
collaborator_list_popover: None,
|
|
||||||
_subscriptions: subscriptions,
|
_subscriptions: subscriptions,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -217,36 +212,6 @@ impl CollabTitlebarItem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn toggle_collaborator_list_popover(
|
|
||||||
&mut self,
|
|
||||||
_: &ToggleCollaboratorList,
|
|
||||||
cx: &mut ViewContext<Self>,
|
|
||||||
) {
|
|
||||||
match self.collaborator_list_popover.take() {
|
|
||||||
Some(_) => {}
|
|
||||||
None => {
|
|
||||||
if let Some(workspace) = self.workspace.upgrade(cx) {
|
|
||||||
let user_store = workspace.read(cx).user_store().clone();
|
|
||||||
let view = cx.add_view(|cx| CollaboratorListPopover::new(user_store, cx));
|
|
||||||
|
|
||||||
cx.subscribe(&view, |this, _, event, cx| {
|
|
||||||
match event {
|
|
||||||
collaborator_list_popover::Event::Dismissed => {
|
|
||||||
this.collaborator_list_popover = None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cx.notify();
|
|
||||||
})
|
|
||||||
.detach();
|
|
||||||
|
|
||||||
self.collaborator_list_popover = Some(view);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cx.notify();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn toggle_contacts_popover(&mut self, _: &ToggleContactsMenu, cx: &mut ViewContext<Self>) {
|
pub fn toggle_contacts_popover(&mut self, _: &ToggleContactsMenu, cx: &mut ViewContext<Self>) {
|
||||||
if self.contacts_popover.take().is_none() {
|
if self.contacts_popover.take().is_none() {
|
||||||
if let Some(workspace) = self.workspace.upgrade(cx) {
|
if let Some(workspace) = self.workspace.upgrade(cx) {
|
||||||
@ -357,8 +322,8 @@ impl CollabTitlebarItem {
|
|||||||
.with_style(style.container)
|
.with_style(style.container)
|
||||||
})
|
})
|
||||||
.with_cursor_style(CursorStyle::PointingHand)
|
.with_cursor_style(CursorStyle::PointingHand)
|
||||||
.on_click(MouseButton::Left, move |_, _, cx| {
|
.on_click(MouseButton::Left, move |_, this, cx| {
|
||||||
cx.dispatch_action(ToggleContactsMenu);
|
this.toggle_contacts_popover(&Default::default(), cx)
|
||||||
})
|
})
|
||||||
.with_tooltip::<ToggleContactsMenu>(
|
.with_tooltip::<ToggleContactsMenu>(
|
||||||
0,
|
0,
|
||||||
@ -405,7 +370,7 @@ impl CollabTitlebarItem {
|
|||||||
})
|
})
|
||||||
.with_cursor_style(CursorStyle::PointingHand)
|
.with_cursor_style(CursorStyle::PointingHand)
|
||||||
.on_click(MouseButton::Left, move |_, _, cx| {
|
.on_click(MouseButton::Left, move |_, _, cx| {
|
||||||
cx.dispatch_action(ToggleScreenSharing);
|
toggle_screen_sharing(&Default::default(), cx)
|
||||||
})
|
})
|
||||||
.with_tooltip::<ToggleScreenSharing>(
|
.with_tooltip::<ToggleScreenSharing>(
|
||||||
0,
|
0,
|
||||||
@ -451,11 +416,11 @@ impl CollabTitlebarItem {
|
|||||||
.with_style(style.container)
|
.with_style(style.container)
|
||||||
})
|
})
|
||||||
.with_cursor_style(CursorStyle::PointingHand)
|
.with_cursor_style(CursorStyle::PointingHand)
|
||||||
.on_click(MouseButton::Left, move |_, _, cx| {
|
.on_click(MouseButton::Left, move |_, this, cx| {
|
||||||
if is_shared {
|
if is_shared {
|
||||||
cx.dispatch_action(UnshareProject);
|
this.unshare_project(&Default::default(), cx);
|
||||||
} else {
|
} else {
|
||||||
cx.dispatch_action(ShareProject);
|
this.share_project(&Default::default(), cx);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.with_tooltip::<ShareUnshare>(
|
.with_tooltip::<ShareUnshare>(
|
||||||
@ -496,8 +461,8 @@ impl CollabTitlebarItem {
|
|||||||
.with_style(style.container)
|
.with_style(style.container)
|
||||||
})
|
})
|
||||||
.with_cursor_style(CursorStyle::PointingHand)
|
.with_cursor_style(CursorStyle::PointingHand)
|
||||||
.on_click(MouseButton::Left, move |_, _, cx| {
|
.on_click(MouseButton::Left, move |_, this, cx| {
|
||||||
cx.dispatch_action(ToggleUserMenu);
|
this.toggle_user_menu(&Default::default(), cx)
|
||||||
})
|
})
|
||||||
.with_tooltip::<ToggleUserMenu>(
|
.with_tooltip::<ToggleUserMenu>(
|
||||||
0,
|
0,
|
||||||
@ -527,8 +492,13 @@ impl CollabTitlebarItem {
|
|||||||
.with_style(style.container)
|
.with_style(style.container)
|
||||||
})
|
})
|
||||||
.with_cursor_style(CursorStyle::PointingHand)
|
.with_cursor_style(CursorStyle::PointingHand)
|
||||||
.on_click(MouseButton::Left, move |_, _, cx| {
|
.on_click(MouseButton::Left, move |_, this, cx| {
|
||||||
cx.dispatch_action(SignIn);
|
if let Some(workspace) = this.workspace.upgrade(cx) {
|
||||||
|
let client = workspace.read(cx).app_state().client.clone();
|
||||||
|
cx.app_context()
|
||||||
|
.spawn(|cx| async move { client.authenticate_and_connect(true, &cx).await })
|
||||||
|
.detach_and_log_err(cx);
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.into_any()
|
.into_any()
|
||||||
}
|
}
|
||||||
@ -862,7 +832,7 @@ impl CollabTitlebarItem {
|
|||||||
})
|
})
|
||||||
.with_cursor_style(CursorStyle::PointingHand)
|
.with_cursor_style(CursorStyle::PointingHand)
|
||||||
.on_click(MouseButton::Left, |_, _, cx| {
|
.on_click(MouseButton::Left, |_, _, cx| {
|
||||||
cx.dispatch_action(auto_update::Check);
|
auto_update::check(&Default::default(), cx);
|
||||||
})
|
})
|
||||||
.into_any(),
|
.into_any(),
|
||||||
),
|
),
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
mod collab_titlebar_item;
|
mod collab_titlebar_item;
|
||||||
mod collaborator_list_popover;
|
|
||||||
mod contact_finder;
|
mod contact_finder;
|
||||||
mod contact_list;
|
mod contact_list;
|
||||||
mod contact_notification;
|
mod contact_notification;
|
||||||
|
@ -1,161 +0,0 @@
|
|||||||
use call::ActiveCall;
|
|
||||||
use client::UserStore;
|
|
||||||
use gpui::Action;
|
|
||||||
use gpui::{actions, elements::*, platform::MouseButton, Entity, ModelHandle, View, ViewContext};
|
|
||||||
use settings::Settings;
|
|
||||||
|
|
||||||
use crate::collab_titlebar_item::ToggleCollaboratorList;
|
|
||||||
|
|
||||||
pub(crate) enum Event {
|
|
||||||
Dismissed,
|
|
||||||
}
|
|
||||||
|
|
||||||
enum Collaborator {
|
|
||||||
SelfUser { username: String },
|
|
||||||
RemoteUser { username: String },
|
|
||||||
}
|
|
||||||
|
|
||||||
actions!(collaborator_list_popover, [NoOp]);
|
|
||||||
|
|
||||||
pub(crate) struct CollaboratorListPopover {
|
|
||||||
list_state: ListState<Self>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Entity for CollaboratorListPopover {
|
|
||||||
type Event = Event;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl View for CollaboratorListPopover {
|
|
||||||
fn ui_name() -> &'static str {
|
|
||||||
"CollaboratorListPopover"
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
|
|
||||||
let theme = cx.global::<Settings>().theme.clone();
|
|
||||||
|
|
||||||
MouseEventHandler::<Self, Self>::new(0, cx, |_, _| {
|
|
||||||
List::new(self.list_state.clone())
|
|
||||||
.contained()
|
|
||||||
.with_style(theme.contacts_popover.container) //TODO: Change the name of this theme key
|
|
||||||
.constrained()
|
|
||||||
.with_width(theme.contacts_popover.width)
|
|
||||||
.with_height(theme.contacts_popover.height)
|
|
||||||
})
|
|
||||||
.on_down_out(MouseButton::Left, move |_, _, cx| {
|
|
||||||
cx.dispatch_action(ToggleCollaboratorList);
|
|
||||||
})
|
|
||||||
.into_any()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn focus_out(&mut self, _: gpui::AnyViewHandle, cx: &mut ViewContext<Self>) {
|
|
||||||
cx.emit(Event::Dismissed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CollaboratorListPopover {
|
|
||||||
pub fn new(user_store: ModelHandle<UserStore>, cx: &mut ViewContext<Self>) -> Self {
|
|
||||||
let active_call = ActiveCall::global(cx);
|
|
||||||
|
|
||||||
let mut collaborators = user_store
|
|
||||||
.read(cx)
|
|
||||||
.current_user()
|
|
||||||
.map(|u| Collaborator::SelfUser {
|
|
||||||
username: u.github_login.clone(),
|
|
||||||
})
|
|
||||||
.into_iter()
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
//TODO: What should the canonical sort here look like, consult contacts list implementation
|
|
||||||
if let Some(room) = active_call.read(cx).room() {
|
|
||||||
for participant in room.read(cx).remote_participants() {
|
|
||||||
collaborators.push(Collaborator::RemoteUser {
|
|
||||||
username: participant.1.user.github_login.clone(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Self {
|
|
||||||
list_state: ListState::new(
|
|
||||||
collaborators.len(),
|
|
||||||
Orientation::Top,
|
|
||||||
0.,
|
|
||||||
move |_, index, cx| match &collaborators[index] {
|
|
||||||
Collaborator::SelfUser { username } => render_collaborator_list_entry(
|
|
||||||
index,
|
|
||||||
username,
|
|
||||||
None::<NoOp>,
|
|
||||||
None,
|
|
||||||
Svg::new("icons/chevron_right_12.svg"),
|
|
||||||
NoOp,
|
|
||||||
"Leave call".to_owned(),
|
|
||||||
cx,
|
|
||||||
),
|
|
||||||
|
|
||||||
Collaborator::RemoteUser { username } => render_collaborator_list_entry(
|
|
||||||
index,
|
|
||||||
username,
|
|
||||||
Some(NoOp),
|
|
||||||
Some(format!("Follow {username}")),
|
|
||||||
Svg::new("icons/x_mark_12.svg"),
|
|
||||||
NoOp,
|
|
||||||
format!("Remove {username} from call"),
|
|
||||||
cx,
|
|
||||||
),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render_collaborator_list_entry<UA: Action + Clone, IA: Action + Clone>(
|
|
||||||
index: usize,
|
|
||||||
username: &str,
|
|
||||||
username_action: Option<UA>,
|
|
||||||
username_tooltip: Option<String>,
|
|
||||||
icon: Svg,
|
|
||||||
icon_action: IA,
|
|
||||||
icon_tooltip: String,
|
|
||||||
cx: &mut ViewContext<CollaboratorListPopover>,
|
|
||||||
) -> AnyElement<CollaboratorListPopover> {
|
|
||||||
enum Username {}
|
|
||||||
enum UsernameTooltip {}
|
|
||||||
enum Icon {}
|
|
||||||
enum IconTooltip {}
|
|
||||||
|
|
||||||
let theme = &cx.global::<Settings>().theme;
|
|
||||||
let username_theme = theme.contact_list.contact_username.text.clone();
|
|
||||||
let tooltip_theme = theme.tooltip.clone();
|
|
||||||
|
|
||||||
let username =
|
|
||||||
MouseEventHandler::<Username, CollaboratorListPopover>::new(index, cx, |_, _| {
|
|
||||||
Label::new(username.to_owned(), username_theme.clone())
|
|
||||||
})
|
|
||||||
.on_click(MouseButton::Left, move |_, _, cx| {
|
|
||||||
if let Some(username_action) = username_action.clone() {
|
|
||||||
cx.dispatch_action(username_action);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Flex::row()
|
|
||||||
.with_child(if let Some(username_tooltip) = username_tooltip {
|
|
||||||
username
|
|
||||||
.with_tooltip::<UsernameTooltip>(
|
|
||||||
index,
|
|
||||||
username_tooltip,
|
|
||||||
None,
|
|
||||||
tooltip_theme.clone(),
|
|
||||||
cx,
|
|
||||||
)
|
|
||||||
.into_any()
|
|
||||||
} else {
|
|
||||||
username.into_any()
|
|
||||||
})
|
|
||||||
.with_child(
|
|
||||||
MouseEventHandler::<Icon, CollaboratorListPopover>::new(index, cx, |_, _| icon)
|
|
||||||
.on_click(MouseButton::Left, move |_, _, cx| {
|
|
||||||
cx.dispatch_action(icon_action.clone())
|
|
||||||
})
|
|
||||||
.with_tooltip::<IconTooltip>(index, icon_tooltip, None, tooltip_theme, cx),
|
|
||||||
)
|
|
||||||
.into_any()
|
|
||||||
}
|
|
@ -1,4 +1,3 @@
|
|||||||
use crate::contacts_popover;
|
|
||||||
use call::ActiveCall;
|
use call::ActiveCall;
|
||||||
use client::{proto::PeerId, Contact, User, UserStore};
|
use client::{proto::PeerId, Contact, User, UserStore};
|
||||||
use editor::{Cancel, Editor};
|
use editor::{Cancel, Editor};
|
||||||
@ -140,6 +139,7 @@ pub struct RespondToContactRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub enum Event {
|
pub enum Event {
|
||||||
|
ToggleContactFinder,
|
||||||
Dismissed,
|
Dismissed,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1116,11 +1116,14 @@ impl ContactList {
|
|||||||
)
|
)
|
||||||
.with_padding(Padding::uniform(2.))
|
.with_padding(Padding::uniform(2.))
|
||||||
.with_cursor_style(CursorStyle::PointingHand)
|
.with_cursor_style(CursorStyle::PointingHand)
|
||||||
.on_click(MouseButton::Left, move |_, _, cx| {
|
.on_click(MouseButton::Left, move |_, this, cx| {
|
||||||
cx.dispatch_action(RemoveContact {
|
this.remove_contact(
|
||||||
user_id,
|
&RemoveContact {
|
||||||
github_login: github_login.clone(),
|
user_id,
|
||||||
})
|
github_login: github_login.clone(),
|
||||||
|
},
|
||||||
|
cx,
|
||||||
|
);
|
||||||
})
|
})
|
||||||
.flex_float(),
|
.flex_float(),
|
||||||
)
|
)
|
||||||
@ -1203,11 +1206,14 @@ impl ContactList {
|
|||||||
render_icon_button(button_style, "icons/x_mark_8.svg").aligned()
|
render_icon_button(button_style, "icons/x_mark_8.svg").aligned()
|
||||||
})
|
})
|
||||||
.with_cursor_style(CursorStyle::PointingHand)
|
.with_cursor_style(CursorStyle::PointingHand)
|
||||||
.on_click(MouseButton::Left, move |_, _, cx| {
|
.on_click(MouseButton::Left, move |_, this, cx| {
|
||||||
cx.dispatch_action(RespondToContactRequest {
|
this.respond_to_contact_request(
|
||||||
user_id,
|
&RespondToContactRequest {
|
||||||
accept: false,
|
user_id,
|
||||||
})
|
accept: false,
|
||||||
|
},
|
||||||
|
cx,
|
||||||
|
);
|
||||||
})
|
})
|
||||||
.contained()
|
.contained()
|
||||||
.with_margin_right(button_spacing),
|
.with_margin_right(button_spacing),
|
||||||
@ -1225,11 +1231,14 @@ impl ContactList {
|
|||||||
.flex_float()
|
.flex_float()
|
||||||
})
|
})
|
||||||
.with_cursor_style(CursorStyle::PointingHand)
|
.with_cursor_style(CursorStyle::PointingHand)
|
||||||
.on_click(MouseButton::Left, move |_, _, cx| {
|
.on_click(MouseButton::Left, move |_, this, cx| {
|
||||||
cx.dispatch_action(RespondToContactRequest {
|
this.respond_to_contact_request(
|
||||||
user_id,
|
&RespondToContactRequest {
|
||||||
accept: true,
|
user_id,
|
||||||
})
|
accept: true,
|
||||||
|
},
|
||||||
|
cx,
|
||||||
|
);
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
@ -1246,11 +1255,14 @@ impl ContactList {
|
|||||||
})
|
})
|
||||||
.with_padding(Padding::uniform(2.))
|
.with_padding(Padding::uniform(2.))
|
||||||
.with_cursor_style(CursorStyle::PointingHand)
|
.with_cursor_style(CursorStyle::PointingHand)
|
||||||
.on_click(MouseButton::Left, move |_, _, cx| {
|
.on_click(MouseButton::Left, move |_, this, cx| {
|
||||||
cx.dispatch_action(RemoveContact {
|
this.remove_contact(
|
||||||
user_id,
|
&RemoveContact {
|
||||||
github_login: github_login.clone(),
|
user_id,
|
||||||
})
|
github_login: github_login.clone(),
|
||||||
|
},
|
||||||
|
cx,
|
||||||
|
);
|
||||||
})
|
})
|
||||||
.flex_float(),
|
.flex_float(),
|
||||||
);
|
);
|
||||||
@ -1318,7 +1330,7 @@ impl View for ContactList {
|
|||||||
})
|
})
|
||||||
.with_cursor_style(CursorStyle::PointingHand)
|
.with_cursor_style(CursorStyle::PointingHand)
|
||||||
.on_click(MouseButton::Left, |_, _, cx| {
|
.on_click(MouseButton::Left, |_, _, cx| {
|
||||||
cx.dispatch_action(contacts_popover::ToggleContactFinder)
|
cx.emit(Event::ToggleContactFinder)
|
||||||
})
|
})
|
||||||
.with_tooltip::<AddContact>(
|
.with_tooltip::<AddContact>(
|
||||||
0,
|
0,
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
contact_finder::{build_contact_finder, ContactFinder},
|
contact_finder::{build_contact_finder, ContactFinder},
|
||||||
contact_list::ContactList,
|
contact_list::ContactList,
|
||||||
ToggleContactsMenu,
|
|
||||||
};
|
};
|
||||||
use client::UserStore;
|
use client::UserStore;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
@ -72,8 +71,11 @@ impl ContactsPopover {
|
|||||||
let child = cx
|
let child = cx
|
||||||
.add_view(|cx| ContactList::new(&workspace, cx).with_editor_text(editor_text, cx));
|
.add_view(|cx| ContactList::new(&workspace, cx).with_editor_text(editor_text, cx));
|
||||||
cx.focus(&child);
|
cx.focus(&child);
|
||||||
self._subscription = Some(cx.subscribe(&child, |_, _, event, cx| match event {
|
self._subscription = Some(cx.subscribe(&child, |this, _, event, cx| match event {
|
||||||
crate::contact_list::Event::Dismissed => cx.emit(Event::Dismissed),
|
crate::contact_list::Event::Dismissed => cx.emit(Event::Dismissed),
|
||||||
|
crate::contact_list::Event::ToggleContactFinder => {
|
||||||
|
this.toggle_contact_finder(&Default::default(), cx)
|
||||||
|
}
|
||||||
}));
|
}));
|
||||||
self.child = Child::ContactList(child);
|
self.child = Child::ContactList(child);
|
||||||
cx.notify();
|
cx.notify();
|
||||||
@ -106,9 +108,7 @@ impl View for ContactsPopover {
|
|||||||
.with_width(theme.contacts_popover.width)
|
.with_width(theme.contacts_popover.width)
|
||||||
.with_height(theme.contacts_popover.height)
|
.with_height(theme.contacts_popover.height)
|
||||||
})
|
})
|
||||||
.on_down_out(MouseButton::Left, move |_, _, cx| {
|
.on_down_out(MouseButton::Left, move |_, _, cx| cx.emit(Event::Dismissed))
|
||||||
cx.dispatch_action(ToggleContactsMenu);
|
|
||||||
})
|
|
||||||
.into_any()
|
.into_any()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use crate::toggle_screen_sharing;
|
||||||
use call::ActiveCall;
|
use call::ActiveCall;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
color::Color,
|
color::Color,
|
||||||
@ -7,8 +8,6 @@ use gpui::{
|
|||||||
};
|
};
|
||||||
use settings::Settings;
|
use settings::Settings;
|
||||||
|
|
||||||
use crate::ToggleScreenSharing;
|
|
||||||
|
|
||||||
pub fn init(cx: &mut AppContext) {
|
pub fn init(cx: &mut AppContext) {
|
||||||
let active_call = ActiveCall::global(cx);
|
let active_call = ActiveCall::global(cx);
|
||||||
|
|
||||||
@ -54,7 +53,7 @@ impl View for SharingStatusIndicator {
|
|||||||
.aligned()
|
.aligned()
|
||||||
})
|
})
|
||||||
.on_click(MouseButton::Left, |_, _, cx| {
|
.on_click(MouseButton::Left, |_, _, cx| {
|
||||||
cx.dispatch_action(ToggleScreenSharing);
|
toggle_screen_sharing(&Default::default(), cx)
|
||||||
})
|
})
|
||||||
.into_any()
|
.into_any()
|
||||||
}
|
}
|
||||||
|
@ -485,7 +485,11 @@ impl ContextMenu {
|
|||||||
.contained()
|
.contained()
|
||||||
.with_style(style.container)
|
.with_style(style.container)
|
||||||
})
|
})
|
||||||
.on_down_out(MouseButton::Left, |_, _, cx| cx.dispatch_action(Cancel))
|
.on_down_out(MouseButton::Left, |_, this, cx| {
|
||||||
.on_down_out(MouseButton::Right, |_, _, cx| cx.dispatch_action(Cancel))
|
this.cancel(&Default::default(), cx);
|
||||||
|
})
|
||||||
|
.on_down_out(MouseButton::Right, |_, this, cx| {
|
||||||
|
this.cancel(&Default::default(), cx);
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -196,7 +196,7 @@ impl CopilotCodeVerification {
|
|||||||
.contained()
|
.contained()
|
||||||
.with_style(style.auth.prompting.hint.container.clone()),
|
.with_style(style.auth.prompting.hint.container.clone()),
|
||||||
)
|
)
|
||||||
.with_child(theme::ui::cta_button_with_click::<ConnectButton, _, _, _>(
|
.with_child(theme::ui::cta_button::<ConnectButton, _, _, _>(
|
||||||
if connect_clicked {
|
if connect_clicked {
|
||||||
"Waiting for connection..."
|
"Waiting for connection..."
|
||||||
} else {
|
} else {
|
||||||
@ -250,7 +250,7 @@ impl CopilotCodeVerification {
|
|||||||
.contained()
|
.contained()
|
||||||
.with_style(enabled_style.hint.container),
|
.with_style(enabled_style.hint.container),
|
||||||
)
|
)
|
||||||
.with_child(theme::ui::cta_button_with_click::<DoneButton, _, _, _>(
|
.with_child(theme::ui::cta_button::<DoneButton, _, _, _>(
|
||||||
"Done",
|
"Done",
|
||||||
style.auth.content_width,
|
style.auth.content_width,
|
||||||
&style.auth.cta_button,
|
&style.auth.cta_button,
|
||||||
@ -304,7 +304,7 @@ impl CopilotCodeVerification {
|
|||||||
.contained()
|
.contained()
|
||||||
.with_style(unauthorized_style.warning.container),
|
.with_style(unauthorized_style.warning.container),
|
||||||
)
|
)
|
||||||
.with_child(theme::ui::cta_button_with_click::<Self, _, _, _>(
|
.with_child(theme::ui::cta_button::<Self, _, _, _>(
|
||||||
"Subscribe on GitHub",
|
"Subscribe on GitHub",
|
||||||
style.auth.content_width,
|
style.auth.content_width,
|
||||||
&style.auth.cta_button,
|
&style.auth.cta_button,
|
||||||
|
@ -3,18 +3,19 @@ use editor::{Editor, GoToDiagnostic};
|
|||||||
use gpui::{
|
use gpui::{
|
||||||
elements::*,
|
elements::*,
|
||||||
platform::{CursorStyle, MouseButton},
|
platform::{CursorStyle, MouseButton},
|
||||||
serde_json, AppContext, Entity, ModelHandle, Subscription, View, ViewContext, ViewHandle,
|
serde_json, AppContext, Entity, Subscription, View, ViewContext, ViewHandle, WeakViewHandle,
|
||||||
WeakViewHandle,
|
|
||||||
};
|
};
|
||||||
use language::Diagnostic;
|
use language::Diagnostic;
|
||||||
use lsp::LanguageServerId;
|
use lsp::LanguageServerId;
|
||||||
use project::Project;
|
|
||||||
use settings::Settings;
|
use settings::Settings;
|
||||||
use workspace::{item::ItemHandle, StatusItemView};
|
use workspace::{item::ItemHandle, StatusItemView, Workspace};
|
||||||
|
|
||||||
|
use crate::ProjectDiagnosticsEditor;
|
||||||
|
|
||||||
pub struct DiagnosticIndicator {
|
pub struct DiagnosticIndicator {
|
||||||
summary: project::DiagnosticSummary,
|
summary: project::DiagnosticSummary,
|
||||||
active_editor: Option<WeakViewHandle<Editor>>,
|
active_editor: Option<WeakViewHandle<Editor>>,
|
||||||
|
workspace: WeakViewHandle<Workspace>,
|
||||||
current_diagnostic: Option<Diagnostic>,
|
current_diagnostic: Option<Diagnostic>,
|
||||||
in_progress_checks: HashSet<LanguageServerId>,
|
in_progress_checks: HashSet<LanguageServerId>,
|
||||||
_observe_active_editor: Option<Subscription>,
|
_observe_active_editor: Option<Subscription>,
|
||||||
@ -25,7 +26,8 @@ pub fn init(cx: &mut AppContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl DiagnosticIndicator {
|
impl DiagnosticIndicator {
|
||||||
pub fn new(project: &ModelHandle<Project>, cx: &mut ViewContext<Self>) -> Self {
|
pub fn new(workspace: &Workspace, cx: &mut ViewContext<Self>) -> Self {
|
||||||
|
let project = workspace.project();
|
||||||
cx.subscribe(project, |this, project, event, cx| match event {
|
cx.subscribe(project, |this, project, event, cx| match event {
|
||||||
project::Event::DiskBasedDiagnosticsStarted { language_server_id } => {
|
project::Event::DiskBasedDiagnosticsStarted { language_server_id } => {
|
||||||
this.in_progress_checks.insert(*language_server_id);
|
this.in_progress_checks.insert(*language_server_id);
|
||||||
@ -46,6 +48,7 @@ impl DiagnosticIndicator {
|
|||||||
.language_servers_running_disk_based_diagnostics()
|
.language_servers_running_disk_based_diagnostics()
|
||||||
.collect(),
|
.collect(),
|
||||||
active_editor: None,
|
active_editor: None,
|
||||||
|
workspace: workspace.weak_handle(),
|
||||||
current_diagnostic: None,
|
current_diagnostic: None,
|
||||||
_observe_active_editor: None,
|
_observe_active_editor: None,
|
||||||
}
|
}
|
||||||
@ -163,8 +166,12 @@ impl View for DiagnosticIndicator {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
.with_cursor_style(CursorStyle::PointingHand)
|
.with_cursor_style(CursorStyle::PointingHand)
|
||||||
.on_click(MouseButton::Left, |_, _, cx| {
|
.on_click(MouseButton::Left, |_, this, cx| {
|
||||||
cx.dispatch_action(crate::Deploy)
|
if let Some(workspace) = this.workspace.upgrade(cx) {
|
||||||
|
workspace.update(cx, |workspace, cx| {
|
||||||
|
ProjectDiagnosticsEditor::deploy(workspace, &Default::default(), cx)
|
||||||
|
})
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.with_tooltip::<Summary>(
|
.with_tooltip::<Summary>(
|
||||||
0,
|
0,
|
||||||
@ -200,8 +207,8 @@ impl View for DiagnosticIndicator {
|
|||||||
.with_margin_left(item_spacing)
|
.with_margin_left(item_spacing)
|
||||||
})
|
})
|
||||||
.with_cursor_style(CursorStyle::PointingHand)
|
.with_cursor_style(CursorStyle::PointingHand)
|
||||||
.on_click(MouseButton::Left, |_, _, cx| {
|
.on_click(MouseButton::Left, |_, this, cx| {
|
||||||
cx.dispatch_action(GoToDiagnostic)
|
this.go_to_next_diagnostic(&Default::default(), cx)
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -809,10 +809,13 @@ impl CompletionsMenu {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
.with_cursor_style(CursorStyle::PointingHand)
|
.with_cursor_style(CursorStyle::PointingHand)
|
||||||
.on_down(MouseButton::Left, move |_, _, cx| {
|
.on_down(MouseButton::Left, move |_, this, cx| {
|
||||||
cx.dispatch_action(ConfirmCompletion {
|
this.confirm_completion(
|
||||||
item_ix: Some(item_ix),
|
&ConfirmCompletion {
|
||||||
});
|
item_ix: Some(item_ix),
|
||||||
|
},
|
||||||
|
cx,
|
||||||
|
);
|
||||||
})
|
})
|
||||||
.into_any(),
|
.into_any(),
|
||||||
);
|
);
|
||||||
@ -970,9 +973,23 @@ impl CodeActionsMenu {
|
|||||||
.with_style(item_style)
|
.with_style(item_style)
|
||||||
})
|
})
|
||||||
.with_cursor_style(CursorStyle::PointingHand)
|
.with_cursor_style(CursorStyle::PointingHand)
|
||||||
.on_down(MouseButton::Left, move |_, _, cx| {
|
.on_down(MouseButton::Left, move |_, this, cx| {
|
||||||
cx.dispatch_action(ConfirmCodeAction {
|
let workspace = this
|
||||||
item_ix: Some(item_ix),
|
.workspace
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|(workspace, _)| workspace.upgrade(cx));
|
||||||
|
cx.window_context().defer(move |cx| {
|
||||||
|
if let Some(workspace) = workspace {
|
||||||
|
workspace.update(cx, |workspace, cx| {
|
||||||
|
if let Some(task) = Editor::confirm_code_action(
|
||||||
|
workspace,
|
||||||
|
&Default::default(),
|
||||||
|
cx,
|
||||||
|
) {
|
||||||
|
task.detach_and_log_err(cx);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.into_any(),
|
.into_any(),
|
||||||
@ -3138,10 +3155,13 @@ impl Editor {
|
|||||||
})
|
})
|
||||||
.with_cursor_style(CursorStyle::PointingHand)
|
.with_cursor_style(CursorStyle::PointingHand)
|
||||||
.with_padding(Padding::uniform(3.))
|
.with_padding(Padding::uniform(3.))
|
||||||
.on_down(MouseButton::Left, |_, _, cx| {
|
.on_down(MouseButton::Left, |_, this, cx| {
|
||||||
cx.dispatch_action(ToggleCodeActions {
|
this.toggle_code_actions(
|
||||||
deployed_from_indicator: true,
|
&ToggleCodeActions {
|
||||||
});
|
deployed_from_indicator: true,
|
||||||
|
},
|
||||||
|
cx,
|
||||||
|
);
|
||||||
})
|
})
|
||||||
.into_any(),
|
.into_any(),
|
||||||
)
|
)
|
||||||
|
@ -211,10 +211,13 @@ impl EditorElement {
|
|||||||
enum GutterHandlers {}
|
enum GutterHandlers {}
|
||||||
scene.push_mouse_region(
|
scene.push_mouse_region(
|
||||||
MouseRegion::new::<GutterHandlers>(cx.view_id(), cx.view_id() + 1, gutter_bounds)
|
MouseRegion::new::<GutterHandlers>(cx.view_id(), cx.view_id() + 1, gutter_bounds)
|
||||||
.on_hover(|hover, _: &mut Editor, cx| {
|
.on_hover(|hover, editor: &mut Editor, cx| {
|
||||||
cx.dispatch_action(GutterHover {
|
editor.gutter_hover(
|
||||||
hovered: hover.started,
|
&GutterHover {
|
||||||
})
|
hovered: hover.started,
|
||||||
|
},
|
||||||
|
cx,
|
||||||
|
);
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -754,8 +757,8 @@ impl EditorElement {
|
|||||||
|
|
||||||
scene.push_mouse_region(
|
scene.push_mouse_region(
|
||||||
MouseRegion::new::<FoldMarkers>(cx.view_id(), *id as usize, bound)
|
MouseRegion::new::<FoldMarkers>(cx.view_id(), *id as usize, bound)
|
||||||
.on_click(MouseButton::Left, move |_, _: &mut Editor, cx| {
|
.on_click(MouseButton::Left, move |_, editor: &mut Editor, cx| {
|
||||||
cx.dispatch_action(UnfoldAt { buffer_row })
|
editor.unfold_at(&UnfoldAt { buffer_row }, cx)
|
||||||
})
|
})
|
||||||
.with_notify_on_hover(true)
|
.with_notify_on_hover(true)
|
||||||
.with_notify_on_click(true),
|
.with_notify_on_click(true),
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
use crate::{
|
||||||
|
display_map::ToDisplayPoint, Anchor, AnchorRangeExt, DisplayPoint, Editor, EditorSnapshot,
|
||||||
|
EditorStyle, RangeToAnchorExt,
|
||||||
|
};
|
||||||
use futures::FutureExt;
|
use futures::FutureExt;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
actions,
|
actions,
|
||||||
@ -12,11 +16,6 @@ use settings::Settings;
|
|||||||
use std::{ops::Range, sync::Arc, time::Duration};
|
use std::{ops::Range, sync::Arc, time::Duration};
|
||||||
use util::TryFutureExt;
|
use util::TryFutureExt;
|
||||||
|
|
||||||
use crate::{
|
|
||||||
display_map::ToDisplayPoint, Anchor, AnchorRangeExt, DisplayPoint, Editor, EditorSnapshot,
|
|
||||||
EditorStyle, GoToDiagnostic, RangeToAnchorExt,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const HOVER_DELAY_MILLIS: u64 = 350;
|
pub const HOVER_DELAY_MILLIS: u64 = 350;
|
||||||
pub const HOVER_REQUEST_DELAY_MILLIS: u64 = 200;
|
pub const HOVER_REQUEST_DELAY_MILLIS: u64 = 200;
|
||||||
|
|
||||||
@ -668,8 +667,8 @@ impl DiagnosticPopover {
|
|||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
.on_move(|_, _, _| {}) // Consume move events so they don't reach regions underneath.
|
.on_move(|_, _, _| {}) // Consume move events so they don't reach regions underneath.
|
||||||
.on_click(MouseButton::Left, |_, _, cx| {
|
.on_click(MouseButton::Left, |_, this, cx| {
|
||||||
cx.dispatch_action(GoToDiagnostic)
|
this.go_to_diagnostic(&Default::default(), cx)
|
||||||
})
|
})
|
||||||
.with_cursor_style(CursorStyle::PointingHand)
|
.with_cursor_style(CursorStyle::PointingHand)
|
||||||
.with_tooltip::<PrimaryDiagnostic>(
|
.with_tooltip::<PrimaryDiagnostic>(
|
||||||
|
@ -1,15 +1,16 @@
|
|||||||
use gpui::{
|
use gpui::{
|
||||||
elements::*,
|
elements::*,
|
||||||
platform::{CursorStyle, MouseButton},
|
platform::{CursorStyle, MouseButton},
|
||||||
Entity, View, ViewContext,
|
Entity, View, ViewContext, WeakViewHandle,
|
||||||
};
|
};
|
||||||
use settings::Settings;
|
use settings::Settings;
|
||||||
use workspace::{item::ItemHandle, StatusItemView};
|
use workspace::{item::ItemHandle, StatusItemView, Workspace};
|
||||||
|
|
||||||
use crate::feedback_editor::{FeedbackEditor, GiveFeedback};
|
use crate::feedback_editor::{FeedbackEditor, GiveFeedback};
|
||||||
|
|
||||||
pub struct DeployFeedbackButton {
|
pub struct DeployFeedbackButton {
|
||||||
active: bool,
|
active: bool,
|
||||||
|
workspace: WeakViewHandle<Workspace>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Entity for DeployFeedbackButton {
|
impl Entity for DeployFeedbackButton {
|
||||||
@ -17,8 +18,11 @@ impl Entity for DeployFeedbackButton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl DeployFeedbackButton {
|
impl DeployFeedbackButton {
|
||||||
pub fn new() -> Self {
|
pub fn new(workspace: &Workspace) -> Self {
|
||||||
DeployFeedbackButton { active: false }
|
DeployFeedbackButton {
|
||||||
|
active: false,
|
||||||
|
workspace: workspace.weak_handle(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,9 +56,12 @@ impl View for DeployFeedbackButton {
|
|||||||
.with_style(style.container)
|
.with_style(style.container)
|
||||||
})
|
})
|
||||||
.with_cursor_style(CursorStyle::PointingHand)
|
.with_cursor_style(CursorStyle::PointingHand)
|
||||||
.on_click(MouseButton::Left, move |_, _, cx| {
|
.on_click(MouseButton::Left, move |_, this, cx| {
|
||||||
if !active {
|
if !active {
|
||||||
cx.dispatch_action(GiveFeedback)
|
if let Some(workspace) = this.workspace.upgrade(cx) {
|
||||||
|
workspace
|
||||||
|
.update(cx, |workspace, cx| FeedbackEditor::deploy(workspace, cx))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.with_tooltip::<Self>(
|
.with_tooltip::<Self>(
|
||||||
|
@ -3,20 +3,10 @@ pub mod feedback_editor;
|
|||||||
pub mod feedback_info_text;
|
pub mod feedback_info_text;
|
||||||
pub mod submit_feedback_button;
|
pub mod submit_feedback_button;
|
||||||
|
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
mod system_specs;
|
mod system_specs;
|
||||||
use gpui::{actions, impl_actions, platform::PromptLevel, AppContext, ClipboardItem, ViewContext};
|
use gpui::{actions, platform::PromptLevel, AppContext, ClipboardItem, ViewContext};
|
||||||
use serde::Deserialize;
|
|
||||||
use system_specs::SystemSpecs;
|
use system_specs::SystemSpecs;
|
||||||
use workspace::{AppState, Workspace};
|
use workspace::Workspace;
|
||||||
|
|
||||||
#[derive(Deserialize, Clone, PartialEq)]
|
|
||||||
pub struct OpenBrowser {
|
|
||||||
pub url: Arc<str>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl_actions!(zed, [OpenBrowser]);
|
|
||||||
|
|
||||||
actions!(
|
actions!(
|
||||||
zed,
|
zed,
|
||||||
@ -28,29 +18,20 @@ actions!(
|
|||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
pub fn init(app_state: Arc<AppState>, cx: &mut AppContext) {
|
pub fn init(cx: &mut AppContext) {
|
||||||
let system_specs = SystemSpecs::new(&cx);
|
feedback_editor::init(cx);
|
||||||
let system_specs_text = system_specs.to_string();
|
|
||||||
|
|
||||||
feedback_editor::init(system_specs, app_state, cx);
|
|
||||||
|
|
||||||
cx.add_global_action(move |action: &OpenBrowser, cx| cx.platform().open_url(&action.url));
|
|
||||||
|
|
||||||
let url = format!(
|
|
||||||
"https://github.com/zed-industries/community/issues/new?assignees=&labels=defect%2Ctriage&template=2_bug_report.yml&environment={}",
|
|
||||||
urlencoding::encode(&system_specs_text)
|
|
||||||
);
|
|
||||||
|
|
||||||
cx.add_action(
|
cx.add_action(
|
||||||
move |_: &mut Workspace,
|
move |_: &mut Workspace,
|
||||||
_: &CopySystemSpecsIntoClipboard,
|
_: &CopySystemSpecsIntoClipboard,
|
||||||
cx: &mut ViewContext<Workspace>| {
|
cx: &mut ViewContext<Workspace>| {
|
||||||
|
let specs = SystemSpecs::new(&cx).to_string();
|
||||||
cx.prompt(
|
cx.prompt(
|
||||||
PromptLevel::Info,
|
PromptLevel::Info,
|
||||||
&format!("Copied into clipboard:\n\n{system_specs_text}"),
|
&format!("Copied into clipboard:\n\n{specs}"),
|
||||||
&["OK"],
|
&["OK"],
|
||||||
);
|
);
|
||||||
let item = ClipboardItem::new(system_specs_text.clone());
|
let item = ClipboardItem::new(specs.clone());
|
||||||
cx.write_to_clipboard(item);
|
cx.write_to_clipboard(item);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -58,24 +39,24 @@ pub fn init(app_state: Arc<AppState>, cx: &mut AppContext) {
|
|||||||
cx.add_action(
|
cx.add_action(
|
||||||
|_: &mut Workspace, _: &RequestFeature, cx: &mut ViewContext<Workspace>| {
|
|_: &mut Workspace, _: &RequestFeature, cx: &mut ViewContext<Workspace>| {
|
||||||
let url = "https://github.com/zed-industries/community/issues/new?assignees=&labels=enhancement%2Ctriage&template=0_feature_request.yml";
|
let url = "https://github.com/zed-industries/community/issues/new?assignees=&labels=enhancement%2Ctriage&template=0_feature_request.yml";
|
||||||
cx.dispatch_action(OpenBrowser {
|
cx.platform().open_url(url);
|
||||||
url: url.into(),
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
cx.add_action(
|
cx.add_action(
|
||||||
move |_: &mut Workspace, _: &FileBugReport, cx: &mut ViewContext<Workspace>| {
|
move |_: &mut Workspace, _: &FileBugReport, cx: &mut ViewContext<Workspace>| {
|
||||||
cx.dispatch_action(OpenBrowser {
|
let url = format!(
|
||||||
url: url.clone().into(),
|
"https://github.com/zed-industries/community/issues/new?assignees=&labels=defect%2Ctriage&template=2_bug_report.yml&environment={}",
|
||||||
});
|
urlencoding::encode(&SystemSpecs::new(&cx).to_string())
|
||||||
|
);
|
||||||
|
cx.platform().open_url(&url);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
cx.add_action(
|
cx.add_global_action(open_zed_community_repo);
|
||||||
|_: &mut Workspace, _: &OpenZedCommunityRepo, cx: &mut ViewContext<Workspace>| {
|
}
|
||||||
let url = "https://github.com/zed-industries/community";
|
|
||||||
cx.dispatch_action(OpenBrowser { url: url.into() });
|
pub fn open_zed_community_repo(_: &OpenZedCommunityRepo, cx: &mut AppContext) {
|
||||||
},
|
let url = "https://github.com/zed-industries/community";
|
||||||
);
|
cx.platform().open_url(&url);
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,4 @@
|
|||||||
use std::{
|
use crate::system_specs::SystemSpecs;
|
||||||
any::TypeId,
|
|
||||||
borrow::Cow,
|
|
||||||
ops::{Range, RangeInclusive},
|
|
||||||
sync::Arc,
|
|
||||||
};
|
|
||||||
|
|
||||||
use anyhow::bail;
|
use anyhow::bail;
|
||||||
use client::{Client, ZED_SECRET_CLIENT_TOKEN, ZED_SERVER_URL};
|
use client::{Client, ZED_SECRET_CLIENT_TOKEN, ZED_SERVER_URL};
|
||||||
use editor::{Anchor, Editor};
|
use editor::{Anchor, Editor};
|
||||||
@ -19,40 +13,34 @@ use gpui::{
|
|||||||
use isahc::Request;
|
use isahc::Request;
|
||||||
use language::Buffer;
|
use language::Buffer;
|
||||||
use postage::prelude::Stream;
|
use postage::prelude::Stream;
|
||||||
|
|
||||||
use project::Project;
|
use project::Project;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
use std::{
|
||||||
|
any::TypeId,
|
||||||
|
borrow::Cow,
|
||||||
|
ops::{Range, RangeInclusive},
|
||||||
|
sync::Arc,
|
||||||
|
};
|
||||||
use util::ResultExt;
|
use util::ResultExt;
|
||||||
use workspace::{
|
use workspace::{
|
||||||
item::{Item, ItemHandle},
|
item::{Item, ItemEvent, ItemHandle},
|
||||||
searchable::{SearchableItem, SearchableItemHandle},
|
searchable::{SearchableItem, SearchableItemHandle},
|
||||||
AppState, Workspace,
|
smallvec::SmallVec,
|
||||||
|
Workspace,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{submit_feedback_button::SubmitFeedbackButton, system_specs::SystemSpecs};
|
|
||||||
|
|
||||||
const FEEDBACK_CHAR_LIMIT: RangeInclusive<usize> = 10..=5000;
|
const FEEDBACK_CHAR_LIMIT: RangeInclusive<usize> = 10..=5000;
|
||||||
const FEEDBACK_SUBMISSION_ERROR_TEXT: &str =
|
const FEEDBACK_SUBMISSION_ERROR_TEXT: &str =
|
||||||
"Feedback failed to submit, see error log for details.";
|
"Feedback failed to submit, see error log for details.";
|
||||||
|
|
||||||
actions!(feedback, [GiveFeedback, SubmitFeedback]);
|
actions!(feedback, [GiveFeedback, SubmitFeedback]);
|
||||||
|
|
||||||
pub fn init(system_specs: SystemSpecs, app_state: Arc<AppState>, cx: &mut AppContext) {
|
pub fn init(cx: &mut AppContext) {
|
||||||
cx.add_action({
|
cx.add_action({
|
||||||
move |workspace: &mut Workspace, _: &GiveFeedback, cx: &mut ViewContext<Workspace>| {
|
move |workspace: &mut Workspace, _: &GiveFeedback, cx: &mut ViewContext<Workspace>| {
|
||||||
FeedbackEditor::deploy(system_specs.clone(), workspace, app_state.clone(), cx);
|
FeedbackEditor::deploy(workspace, cx);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
cx.add_async_action(
|
|
||||||
|submit_feedback_button: &mut SubmitFeedbackButton, _: &SubmitFeedback, cx| {
|
|
||||||
if let Some(active_item) = submit_feedback_button.active_item.as_ref() {
|
|
||||||
Some(active_item.update(cx, |feedback_editor, cx| feedback_editor.handle_save(cx)))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
@ -94,7 +82,7 @@ impl FeedbackEditor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_save(&mut self, cx: &mut ViewContext<Self>) -> Task<anyhow::Result<()>> {
|
pub fn submit(&mut self, cx: &mut ViewContext<Self>) -> Task<anyhow::Result<()>> {
|
||||||
let feedback_text = self.editor.read(cx).text(cx);
|
let feedback_text = self.editor.read(cx).text(cx);
|
||||||
let feedback_char_count = feedback_text.chars().count();
|
let feedback_char_count = feedback_text.chars().count();
|
||||||
let feedback_text = feedback_text.trim().to_string();
|
let feedback_text = feedback_text.trim().to_string();
|
||||||
@ -133,10 +121,8 @@ impl FeedbackEditor {
|
|||||||
if answer == Some(0) {
|
if answer == Some(0) {
|
||||||
match FeedbackEditor::submit_feedback(&feedback_text, client, specs).await {
|
match FeedbackEditor::submit_feedback(&feedback_text, client, specs).await {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
this.update(&mut cx, |_, cx| {
|
this.update(&mut cx, |_, cx| cx.emit(editor::Event::Closed))
|
||||||
cx.dispatch_action(workspace::CloseActiveItem);
|
.log_err();
|
||||||
})
|
|
||||||
.log_err();
|
|
||||||
}
|
}
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
log::error!("{}", error);
|
log::error!("{}", error);
|
||||||
@ -198,22 +184,21 @@ impl FeedbackEditor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl FeedbackEditor {
|
impl FeedbackEditor {
|
||||||
pub fn deploy(
|
pub fn deploy(workspace: &mut Workspace, cx: &mut ViewContext<Workspace>) {
|
||||||
system_specs: SystemSpecs,
|
let markdown = workspace
|
||||||
_: &mut Workspace,
|
.app_state()
|
||||||
app_state: Arc<AppState>,
|
.languages
|
||||||
cx: &mut ViewContext<Workspace>,
|
.language_for_name("Markdown");
|
||||||
) {
|
|
||||||
let markdown = app_state.languages.language_for_name("Markdown");
|
|
||||||
cx.spawn(|workspace, mut cx| async move {
|
cx.spawn(|workspace, mut cx| async move {
|
||||||
let markdown = markdown.await.log_err();
|
let markdown = markdown.await.log_err();
|
||||||
workspace
|
workspace
|
||||||
.update(&mut cx, |workspace, cx| {
|
.update(&mut cx, |workspace, cx| {
|
||||||
workspace.with_local_workspace(&app_state, cx, |workspace, cx| {
|
workspace.with_local_workspace(cx, |workspace, cx| {
|
||||||
let project = workspace.project().clone();
|
let project = workspace.project().clone();
|
||||||
let buffer = project
|
let buffer = project
|
||||||
.update(cx, |project, cx| project.create_buffer("", markdown, cx))
|
.update(cx, |project, cx| project.create_buffer("", markdown, cx))
|
||||||
.expect("creating buffers on a local workspace always succeeds");
|
.expect("creating buffers on a local workspace always succeeds");
|
||||||
|
let system_specs = SystemSpecs::new(cx);
|
||||||
let feedback_editor = cx
|
let feedback_editor = cx
|
||||||
.add_view(|cx| FeedbackEditor::new(system_specs, project, buffer, cx));
|
.add_view(|cx| FeedbackEditor::new(system_specs, project, buffer, cx));
|
||||||
workspace.add_item(Box::new(feedback_editor), cx);
|
workspace.add_item(Box::new(feedback_editor), cx);
|
||||||
@ -291,7 +276,7 @@ impl Item for FeedbackEditor {
|
|||||||
_: ModelHandle<Project>,
|
_: ModelHandle<Project>,
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) -> Task<anyhow::Result<()>> {
|
) -> Task<anyhow::Result<()>> {
|
||||||
self.handle_save(cx)
|
self.submit(cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn save_as(
|
fn save_as(
|
||||||
@ -300,7 +285,7 @@ impl Item for FeedbackEditor {
|
|||||||
_: std::path::PathBuf,
|
_: std::path::PathBuf,
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) -> Task<anyhow::Result<()>> {
|
) -> Task<anyhow::Result<()>> {
|
||||||
self.handle_save(cx)
|
self.submit(cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reload(
|
fn reload(
|
||||||
@ -353,6 +338,10 @@ impl Item for FeedbackEditor {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn to_item_events(event: &Self::Event) -> SmallVec<[ItemEvent; 2]> {
|
||||||
|
Editor::to_item_events(event)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SearchableItem for FeedbackEditor {
|
impl SearchableItem for FeedbackEditor {
|
||||||
|
@ -6,7 +6,7 @@ use gpui::{
|
|||||||
use settings::Settings;
|
use settings::Settings;
|
||||||
use workspace::{item::ItemHandle, ToolbarItemLocation, ToolbarItemView};
|
use workspace::{item::ItemHandle, ToolbarItemLocation, ToolbarItemView};
|
||||||
|
|
||||||
use crate::{feedback_editor::FeedbackEditor, OpenZedCommunityRepo};
|
use crate::{feedback_editor::FeedbackEditor, open_zed_community_repo, OpenZedCommunityRepo};
|
||||||
|
|
||||||
pub struct FeedbackInfoText {
|
pub struct FeedbackInfoText {
|
||||||
active_item: Option<ViewHandle<FeedbackEditor>>,
|
active_item: Option<ViewHandle<FeedbackEditor>>,
|
||||||
@ -57,7 +57,7 @@ impl View for FeedbackInfoText {
|
|||||||
})
|
})
|
||||||
.with_cursor_style(CursorStyle::PointingHand)
|
.with_cursor_style(CursorStyle::PointingHand)
|
||||||
.on_click(MouseButton::Left, |_, _, cx| {
|
.on_click(MouseButton::Left, |_, _, cx| {
|
||||||
cx.dispatch_action(OpenZedCommunityRepo)
|
open_zed_community_repo(&Default::default(), cx)
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.with_child(
|
.with_child(
|
||||||
|
@ -1,12 +1,16 @@
|
|||||||
|
use crate::feedback_editor::{FeedbackEditor, SubmitFeedback};
|
||||||
|
use anyhow::Result;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
elements::{Label, MouseEventHandler},
|
elements::{Label, MouseEventHandler},
|
||||||
platform::{CursorStyle, MouseButton},
|
platform::{CursorStyle, MouseButton},
|
||||||
AnyElement, Element, Entity, View, ViewContext, ViewHandle,
|
AnyElement, AppContext, Element, Entity, Task, View, ViewContext, ViewHandle,
|
||||||
};
|
};
|
||||||
use settings::Settings;
|
use settings::Settings;
|
||||||
use workspace::{item::ItemHandle, ToolbarItemLocation, ToolbarItemView};
|
use workspace::{item::ItemHandle, ToolbarItemLocation, ToolbarItemView};
|
||||||
|
|
||||||
use crate::feedback_editor::{FeedbackEditor, SubmitFeedback};
|
pub fn init(cx: &mut AppContext) {
|
||||||
|
cx.add_async_action(SubmitFeedbackButton::submit);
|
||||||
|
}
|
||||||
|
|
||||||
pub struct SubmitFeedbackButton {
|
pub struct SubmitFeedbackButton {
|
||||||
pub(crate) active_item: Option<ViewHandle<FeedbackEditor>>,
|
pub(crate) active_item: Option<ViewHandle<FeedbackEditor>>,
|
||||||
@ -18,6 +22,18 @@ impl SubmitFeedbackButton {
|
|||||||
active_item: Default::default(),
|
active_item: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn submit(
|
||||||
|
&mut self,
|
||||||
|
_: &SubmitFeedback,
|
||||||
|
cx: &mut ViewContext<Self>,
|
||||||
|
) -> Option<Task<Result<()>>> {
|
||||||
|
if let Some(active_item) = self.active_item.as_ref() {
|
||||||
|
Some(active_item.update(cx, |feedback_editor, cx| feedback_editor.submit(cx)))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Entity for SubmitFeedbackButton {
|
impl Entity for SubmitFeedbackButton {
|
||||||
@ -39,8 +55,8 @@ impl View for SubmitFeedbackButton {
|
|||||||
.with_style(style.container)
|
.with_style(style.container)
|
||||||
})
|
})
|
||||||
.with_cursor_style(CursorStyle::PointingHand)
|
.with_cursor_style(CursorStyle::PointingHand)
|
||||||
.on_click(MouseButton::Left, |_, _, cx| {
|
.on_click(MouseButton::Left, |_, this, cx| {
|
||||||
cx.dispatch_action(SubmitFeedback)
|
this.submit(&Default::default(), cx);
|
||||||
})
|
})
|
||||||
.aligned()
|
.aligned()
|
||||||
.contained()
|
.contained()
|
||||||
|
@ -1745,10 +1745,6 @@ impl AppContext {
|
|||||||
self.pending_effects.push_back(Effect::RefreshWindows);
|
self.pending_effects.push_back(Effect::RefreshWindows);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dispatch_action_at(&mut self, window_id: usize, view_id: usize, action: impl Action) {
|
|
||||||
self.dispatch_any_action_at(window_id, view_id, Box::new(action));
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn dispatch_any_action_at(
|
pub fn dispatch_any_action_at(
|
||||||
&mut self,
|
&mut self,
|
||||||
window_id: usize,
|
window_id: usize,
|
||||||
@ -3189,13 +3185,6 @@ impl<'a, 'b, V: View> ViewContext<'a, 'b, V> {
|
|||||||
self.window_context.notify_view(window_id, view_id);
|
self.window_context.notify_view(window_id, view_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dispatch_action(&mut self, action: impl Action) {
|
|
||||||
let window_id = self.window_id;
|
|
||||||
let view_id = self.view_id;
|
|
||||||
self.window_context
|
|
||||||
.dispatch_action_at(window_id, view_id, action)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn defer(&mut self, callback: impl 'static + FnOnce(&mut V, &mut ViewContext<V>)) {
|
pub fn defer(&mut self, callback: impl 'static + FnOnce(&mut V, &mut ViewContext<V>)) {
|
||||||
let handle = self.handle();
|
let handle = self.handle();
|
||||||
self.window_context
|
self.window_context
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
actions, elements::*, impl_actions, platform::MouseButton, AppContext, Entity, EventContext,
|
actions, elements::*, impl_actions, platform::MouseButton, AppContext, Entity, View,
|
||||||
View, ViewContext, WeakViewHandle,
|
ViewContext, WeakViewHandle,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct Select {
|
pub struct Select {
|
||||||
@ -116,10 +116,9 @@ impl View for Select {
|
|||||||
.contained()
|
.contained()
|
||||||
.with_style(style.header)
|
.with_style(style.header)
|
||||||
})
|
})
|
||||||
.on_click(
|
.on_click(MouseButton::Left, move |_, this, cx| {
|
||||||
MouseButton::Left,
|
this.toggle(&Default::default(), cx);
|
||||||
move |_, _, cx: &mut EventContext<Self>| cx.dispatch_action(ToggleSelect),
|
}),
|
||||||
),
|
|
||||||
);
|
);
|
||||||
if self.is_open {
|
if self.is_open {
|
||||||
result.add_child(Overlay::new(
|
result.add_child(Overlay::new(
|
||||||
@ -143,12 +142,9 @@ impl View for Select {
|
|||||||
cx,
|
cx,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.on_click(
|
.on_click(MouseButton::Left, move |_, this, cx| {
|
||||||
MouseButton::Left,
|
this.select_item(&SelectItem(ix), cx);
|
||||||
move |_, _, cx: &mut EventContext<Self>| {
|
})
|
||||||
cx.dispatch_action(SelectItem(ix))
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.into_any()
|
.into_any()
|
||||||
}))
|
}))
|
||||||
},
|
},
|
||||||
|
@ -2,27 +2,23 @@ use editor::Editor;
|
|||||||
use gpui::{
|
use gpui::{
|
||||||
elements::*,
|
elements::*,
|
||||||
platform::{CursorStyle, MouseButton},
|
platform::{CursorStyle, MouseButton},
|
||||||
Entity, Subscription, View, ViewContext, ViewHandle,
|
Entity, Subscription, View, ViewContext, ViewHandle, WeakViewHandle,
|
||||||
};
|
};
|
||||||
use settings::Settings;
|
use settings::Settings;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use workspace::{item::ItemHandle, StatusItemView};
|
use workspace::{item::ItemHandle, StatusItemView, Workspace};
|
||||||
|
|
||||||
pub struct ActiveBufferLanguage {
|
pub struct ActiveBufferLanguage {
|
||||||
active_language: Option<Option<Arc<str>>>,
|
active_language: Option<Option<Arc<str>>>,
|
||||||
|
workspace: WeakViewHandle<Workspace>,
|
||||||
_observe_active_editor: Option<Subscription>,
|
_observe_active_editor: Option<Subscription>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for ActiveBufferLanguage {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::new()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ActiveBufferLanguage {
|
impl ActiveBufferLanguage {
|
||||||
pub fn new() -> Self {
|
pub fn new(workspace: &Workspace) -> Self {
|
||||||
Self {
|
Self {
|
||||||
active_language: None,
|
active_language: None,
|
||||||
|
workspace: workspace.weak_handle(),
|
||||||
_observe_active_editor: None,
|
_observe_active_editor: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -66,8 +62,12 @@ impl View for ActiveBufferLanguage {
|
|||||||
.with_style(style.container)
|
.with_style(style.container)
|
||||||
})
|
})
|
||||||
.with_cursor_style(CursorStyle::PointingHand)
|
.with_cursor_style(CursorStyle::PointingHand)
|
||||||
.on_click(MouseButton::Left, |_, _, cx| {
|
.on_click(MouseButton::Left, |_, this, cx| {
|
||||||
cx.dispatch_action(crate::Toggle)
|
if let Some(workspace) = this.workspace.upgrade(cx) {
|
||||||
|
workspace.update(cx, |workspace, cx| {
|
||||||
|
crate::toggle(workspace, &Default::default(), cx)
|
||||||
|
});
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.into_any()
|
.into_any()
|
||||||
} else {
|
} else {
|
||||||
|
@ -11,21 +11,18 @@ use project::Project;
|
|||||||
use settings::Settings;
|
use settings::Settings;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use util::ResultExt;
|
use util::ResultExt;
|
||||||
use workspace::{AppState, Workspace};
|
use workspace::Workspace;
|
||||||
|
|
||||||
actions!(language_selector, [Toggle]);
|
actions!(language_selector, [Toggle]);
|
||||||
|
|
||||||
pub fn init(app_state: Arc<AppState>, cx: &mut AppContext) {
|
pub fn init(cx: &mut AppContext) {
|
||||||
Picker::<LanguageSelectorDelegate>::init(cx);
|
Picker::<LanguageSelectorDelegate>::init(cx);
|
||||||
cx.add_action({
|
cx.add_action(toggle);
|
||||||
let language_registry = app_state.languages.clone();
|
|
||||||
move |workspace, _: &Toggle, cx| toggle(workspace, language_registry.clone(), cx)
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn toggle(
|
pub fn toggle(
|
||||||
workspace: &mut Workspace,
|
workspace: &mut Workspace,
|
||||||
registry: Arc<LanguageRegistry>,
|
_: &Toggle,
|
||||||
cx: &mut ViewContext<Workspace>,
|
cx: &mut ViewContext<Workspace>,
|
||||||
) -> Option<()> {
|
) -> Option<()> {
|
||||||
let (_, buffer, _) = workspace
|
let (_, buffer, _) = workspace
|
||||||
@ -34,6 +31,7 @@ fn toggle(
|
|||||||
.read(cx)
|
.read(cx)
|
||||||
.active_excerpt(cx)?;
|
.active_excerpt(cx)?;
|
||||||
workspace.toggle_modal(cx, |workspace, cx| {
|
workspace.toggle_modal(cx, |workspace, cx| {
|
||||||
|
let registry = workspace.app_state().languages.clone();
|
||||||
cx.add_view(|cx| {
|
cx.add_view(|cx| {
|
||||||
Picker::new(
|
Picker::new(
|
||||||
LanguageSelectorDelegate::new(buffer, workspace.project().clone(), registry),
|
LanguageSelectorDelegate::new(buffer, workspace.project().clone(), registry),
|
||||||
|
@ -24,7 +24,7 @@ pub fn init(cx: &mut AppContext) {
|
|||||||
OutlineView::init(cx);
|
OutlineView::init(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn toggle(workspace: &mut Workspace, _: &Toggle, cx: &mut ViewContext<Workspace>) {
|
pub fn toggle(workspace: &mut Workspace, _: &Toggle, cx: &mut ViewContext<Workspace>) {
|
||||||
if let Some(editor) = workspace
|
if let Some(editor) = workspace
|
||||||
.active_item(cx)
|
.active_item(cx)
|
||||||
.and_then(|item| item.downcast::<Editor>())
|
.and_then(|item| item.downcast::<Editor>())
|
||||||
|
@ -13,7 +13,7 @@ use gpui::{
|
|||||||
keymap_matcher::KeymapContext,
|
keymap_matcher::KeymapContext,
|
||||||
platform::{CursorStyle, MouseButton, PromptLevel},
|
platform::{CursorStyle, MouseButton, PromptLevel},
|
||||||
AnyElement, AppContext, ClipboardItem, Element, Entity, ModelHandle, Task, View, ViewContext,
|
AnyElement, AppContext, ClipboardItem, Element, Entity, ModelHandle, Task, View, ViewContext,
|
||||||
ViewHandle,
|
ViewHandle, WeakViewHandle,
|
||||||
};
|
};
|
||||||
use menu::{Confirm, SelectNext, SelectPrev};
|
use menu::{Confirm, SelectNext, SelectPrev};
|
||||||
use project::{Entry, EntryKind, Project, ProjectEntryId, ProjectPath, Worktree, WorktreeId};
|
use project::{Entry, EntryKind, Project, ProjectEntryId, ProjectPath, Worktree, WorktreeId};
|
||||||
@ -44,6 +44,7 @@ pub struct ProjectPanel {
|
|||||||
clipboard_entry: Option<ClipboardEntry>,
|
clipboard_entry: Option<ClipboardEntry>,
|
||||||
context_menu: ViewHandle<ContextMenu>,
|
context_menu: ViewHandle<ContextMenu>,
|
||||||
dragged_entry_destination: Option<Arc<Path>>,
|
dragged_entry_destination: Option<Arc<Path>>,
|
||||||
|
workspace: WeakViewHandle<Workspace>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
@ -137,7 +138,8 @@ pub enum Event {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ProjectPanel {
|
impl ProjectPanel {
|
||||||
pub fn new(project: ModelHandle<Project>, cx: &mut ViewContext<Workspace>) -> ViewHandle<Self> {
|
pub fn new(workspace: &mut Workspace, cx: &mut ViewContext<Workspace>) -> ViewHandle<Self> {
|
||||||
|
let project = workspace.project().clone();
|
||||||
let project_panel = cx.add_view(|cx: &mut ViewContext<Self>| {
|
let project_panel = cx.add_view(|cx: &mut ViewContext<Self>| {
|
||||||
cx.observe(&project, |this, _, cx| {
|
cx.observe(&project, |this, _, cx| {
|
||||||
this.update_visible_entries(None, cx);
|
this.update_visible_entries(None, cx);
|
||||||
@ -206,6 +208,7 @@ impl ProjectPanel {
|
|||||||
clipboard_entry: None,
|
clipboard_entry: None,
|
||||||
context_menu: cx.add_view(ContextMenu::new),
|
context_menu: cx.add_view(ContextMenu::new),
|
||||||
dragged_entry_destination: None,
|
dragged_entry_destination: None,
|
||||||
|
workspace: workspace.weak_handle(),
|
||||||
};
|
};
|
||||||
this.update_visible_entries(None, cx);
|
this.update_visible_entries(None, cx);
|
||||||
this
|
this
|
||||||
@ -1296,8 +1299,14 @@ impl View for ProjectPanel {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.on_click(MouseButton::Left, move |_, _, cx| {
|
.on_click(MouseButton::Left, move |_, this, cx| {
|
||||||
cx.dispatch_action(workspace::Open)
|
if let Some(workspace) = this.workspace.upgrade(cx) {
|
||||||
|
workspace.update(cx, |workspace, cx| {
|
||||||
|
if let Some(task) = workspace.open(&Default::default(), cx) {
|
||||||
|
task.detach_and_log_err(cx);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.with_cursor_style(CursorStyle::PointingHand),
|
.with_cursor_style(CursorStyle::PointingHand),
|
||||||
)
|
)
|
||||||
@ -1400,7 +1409,7 @@ mod tests {
|
|||||||
|
|
||||||
let project = Project::test(fs.clone(), ["/root1".as_ref(), "/root2".as_ref()], cx).await;
|
let project = Project::test(fs.clone(), ["/root1".as_ref(), "/root2".as_ref()], cx).await;
|
||||||
let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx));
|
let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx));
|
||||||
let panel = workspace.update(cx, |_, cx| ProjectPanel::new(project, cx));
|
let panel = workspace.update(cx, |workspace, cx| ProjectPanel::new(workspace, cx));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
visible_entries_as_strings(&panel, 0..50, cx),
|
visible_entries_as_strings(&panel, 0..50, cx),
|
||||||
&[
|
&[
|
||||||
@ -1492,7 +1501,7 @@ mod tests {
|
|||||||
|
|
||||||
let project = Project::test(fs.clone(), ["/root1".as_ref(), "/root2".as_ref()], cx).await;
|
let project = Project::test(fs.clone(), ["/root1".as_ref(), "/root2".as_ref()], cx).await;
|
||||||
let (window_id, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx));
|
let (window_id, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx));
|
||||||
let panel = workspace.update(cx, |_, cx| ProjectPanel::new(project, cx));
|
let panel = workspace.update(cx, |workspace, cx| ProjectPanel::new(workspace, cx));
|
||||||
|
|
||||||
select_path(&panel, "root1", cx);
|
select_path(&panel, "root1", cx);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@ -1785,7 +1794,7 @@ mod tests {
|
|||||||
|
|
||||||
let project = Project::test(fs.clone(), ["/root1".as_ref()], cx).await;
|
let project = Project::test(fs.clone(), ["/root1".as_ref()], cx).await;
|
||||||
let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx));
|
let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx));
|
||||||
let panel = workspace.update(cx, |_, cx| ProjectPanel::new(project, cx));
|
let panel = workspace.update(cx, |workspace, cx| ProjectPanel::new(workspace, cx));
|
||||||
|
|
||||||
panel.update(cx, |panel, cx| {
|
panel.update(cx, |panel, cx| {
|
||||||
panel.select_next(&Default::default(), cx);
|
panel.select_next(&Default::default(), cx);
|
||||||
|
@ -11,24 +11,24 @@ use highlighted_workspace_location::HighlightedWorkspaceLocation;
|
|||||||
use ordered_float::OrderedFloat;
|
use ordered_float::OrderedFloat;
|
||||||
use picker::{Picker, PickerDelegate, PickerEvent};
|
use picker::{Picker, PickerDelegate, PickerEvent};
|
||||||
use settings::Settings;
|
use settings::Settings;
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::Arc;
|
||||||
use workspace::{
|
use workspace::{
|
||||||
notifications::simple_message_notification::MessageNotification, AppState, Workspace,
|
notifications::simple_message_notification::MessageNotification, Workspace, WorkspaceLocation,
|
||||||
WorkspaceLocation, WORKSPACE_DB,
|
WORKSPACE_DB,
|
||||||
};
|
};
|
||||||
|
|
||||||
actions!(projects, [OpenRecent]);
|
actions!(projects, [OpenRecent]);
|
||||||
|
|
||||||
pub fn init(cx: &mut AppContext, app_state: Weak<AppState>) {
|
pub fn init(cx: &mut AppContext) {
|
||||||
cx.add_async_action(
|
cx.add_async_action(toggle);
|
||||||
move |_: &mut Workspace, _: &OpenRecent, cx: &mut ViewContext<Workspace>| {
|
|
||||||
toggle(app_state.clone(), cx)
|
|
||||||
},
|
|
||||||
);
|
|
||||||
RecentProjects::init(cx);
|
RecentProjects::init(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn toggle(app_state: Weak<AppState>, cx: &mut ViewContext<Workspace>) -> Option<Task<Result<()>>> {
|
fn toggle(
|
||||||
|
_: &mut Workspace,
|
||||||
|
_: &OpenRecent,
|
||||||
|
cx: &mut ViewContext<Workspace>,
|
||||||
|
) -> Option<Task<Result<()>>> {
|
||||||
Some(cx.spawn(|workspace, mut cx| async move {
|
Some(cx.spawn(|workspace, mut cx| async move {
|
||||||
let workspace_locations: Vec<_> = cx
|
let workspace_locations: Vec<_> = cx
|
||||||
.background()
|
.background()
|
||||||
@ -49,11 +49,7 @@ fn toggle(app_state: Weak<AppState>, cx: &mut ViewContext<Workspace>) -> Option<
|
|||||||
let workspace = cx.weak_handle();
|
let workspace = cx.weak_handle();
|
||||||
cx.add_view(|cx| {
|
cx.add_view(|cx| {
|
||||||
RecentProjects::new(
|
RecentProjects::new(
|
||||||
RecentProjectsDelegate::new(
|
RecentProjectsDelegate::new(workspace, workspace_locations),
|
||||||
workspace,
|
|
||||||
workspace_locations,
|
|
||||||
app_state.clone(),
|
|
||||||
),
|
|
||||||
cx,
|
cx,
|
||||||
)
|
)
|
||||||
.with_max_size(800., 1200.)
|
.with_max_size(800., 1200.)
|
||||||
@ -74,7 +70,6 @@ type RecentProjects = Picker<RecentProjectsDelegate>;
|
|||||||
struct RecentProjectsDelegate {
|
struct RecentProjectsDelegate {
|
||||||
workspace: WeakViewHandle<Workspace>,
|
workspace: WeakViewHandle<Workspace>,
|
||||||
workspace_locations: Vec<WorkspaceLocation>,
|
workspace_locations: Vec<WorkspaceLocation>,
|
||||||
app_state: Weak<AppState>,
|
|
||||||
selected_match_index: usize,
|
selected_match_index: usize,
|
||||||
matches: Vec<StringMatch>,
|
matches: Vec<StringMatch>,
|
||||||
}
|
}
|
||||||
@ -83,12 +78,10 @@ impl RecentProjectsDelegate {
|
|||||||
fn new(
|
fn new(
|
||||||
workspace: WeakViewHandle<Workspace>,
|
workspace: WeakViewHandle<Workspace>,
|
||||||
workspace_locations: Vec<WorkspaceLocation>,
|
workspace_locations: Vec<WorkspaceLocation>,
|
||||||
app_state: Weak<AppState>,
|
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
workspace,
|
workspace,
|
||||||
workspace_locations,
|
workspace_locations,
|
||||||
app_state,
|
|
||||||
selected_match_index: 0,
|
selected_match_index: 0,
|
||||||
matches: Default::default(),
|
matches: Default::default(),
|
||||||
}
|
}
|
||||||
@ -155,20 +148,16 @@ impl PickerDelegate for RecentProjectsDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn confirm(&mut self, cx: &mut ViewContext<RecentProjects>) {
|
fn confirm(&mut self, cx: &mut ViewContext<RecentProjects>) {
|
||||||
if let Some(((selected_match, workspace), app_state)) = self
|
if let Some((selected_match, workspace)) = self
|
||||||
.matches
|
.matches
|
||||||
.get(self.selected_index())
|
.get(self.selected_index())
|
||||||
.zip(self.workspace.upgrade(cx))
|
.zip(self.workspace.upgrade(cx))
|
||||||
.zip(self.app_state.upgrade())
|
|
||||||
{
|
{
|
||||||
let workspace_location = &self.workspace_locations[selected_match.candidate_id];
|
let workspace_location = &self.workspace_locations[selected_match.candidate_id];
|
||||||
workspace
|
workspace
|
||||||
.update(cx, |workspace, cx| {
|
.update(cx, |workspace, cx| {
|
||||||
workspace.open_workspace_for_paths(
|
workspace
|
||||||
workspace_location.paths().as_ref().clone(),
|
.open_workspace_for_paths(workspace_location.paths().as_ref().clone(), cx)
|
||||||
app_state,
|
|
||||||
cx,
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
.detach_and_log_err(cx);
|
.detach_and_log_err(cx);
|
||||||
cx.emit(PickerEvent::Dismiss);
|
cx.emit(PickerEvent::Dismiss);
|
||||||
|
@ -7,7 +7,11 @@ use gpui::{
|
|||||||
};
|
};
|
||||||
use settings::Settings;
|
use settings::Settings;
|
||||||
use std::any::TypeId;
|
use std::any::TypeId;
|
||||||
use workspace::{dock::FocusDock, item::ItemHandle, NewTerminal, StatusItemView, Workspace};
|
use workspace::{
|
||||||
|
dock::{Dock, FocusDock},
|
||||||
|
item::ItemHandle,
|
||||||
|
NewTerminal, StatusItemView, Workspace,
|
||||||
|
};
|
||||||
|
|
||||||
pub struct TerminalButton {
|
pub struct TerminalButton {
|
||||||
workspace: WeakViewHandle<Workspace>,
|
workspace: WeakViewHandle<Workspace>,
|
||||||
@ -80,7 +84,11 @@ impl View for TerminalButton {
|
|||||||
this.deploy_terminal_menu(cx);
|
this.deploy_terminal_menu(cx);
|
||||||
} else {
|
} else {
|
||||||
if !active {
|
if !active {
|
||||||
cx.dispatch_action(FocusDock);
|
if let Some(workspace) = this.workspace.upgrade(cx) {
|
||||||
|
workspace.update(cx, |workspace, cx| {
|
||||||
|
Dock::focus_dock(workspace, &Default::default(), cx)
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
|
@ -156,24 +156,7 @@ pub fn keystroke_label<V: View>(
|
|||||||
|
|
||||||
pub type ButtonStyle = Interactive<ContainedText>;
|
pub type ButtonStyle = Interactive<ContainedText>;
|
||||||
|
|
||||||
pub fn cta_button<L, A, V>(
|
pub fn cta_button<Tag, L, V, F>(
|
||||||
label: L,
|
|
||||||
action: A,
|
|
||||||
max_width: f32,
|
|
||||||
style: &ButtonStyle,
|
|
||||||
cx: &mut ViewContext<V>,
|
|
||||||
) -> MouseEventHandler<A, V>
|
|
||||||
where
|
|
||||||
L: Into<Cow<'static, str>>,
|
|
||||||
A: 'static + Action + Clone,
|
|
||||||
V: View,
|
|
||||||
{
|
|
||||||
cta_button_with_click::<A, _, _, _>(label, max_width, style, cx, move |_, _, cx| {
|
|
||||||
cx.dispatch_action(action.clone())
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn cta_button_with_click<Tag, L, V, F>(
|
|
||||||
label: L,
|
label: L,
|
||||||
max_width: f32,
|
max_width: f32,
|
||||||
style: &ButtonStyle,
|
style: &ButtonStyle,
|
||||||
|
@ -6,20 +6,18 @@ use staff_mode::StaffMode;
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use theme::{Theme, ThemeMeta, ThemeRegistry};
|
use theme::{Theme, ThemeMeta, ThemeRegistry};
|
||||||
use util::ResultExt;
|
use util::ResultExt;
|
||||||
use workspace::{AppState, Workspace};
|
use workspace::Workspace;
|
||||||
|
|
||||||
actions!(theme_selector, [Toggle, Reload]);
|
actions!(theme_selector, [Toggle, Reload]);
|
||||||
|
|
||||||
pub fn init(app_state: Arc<AppState>, cx: &mut AppContext) {
|
pub fn init(cx: &mut AppContext) {
|
||||||
cx.add_action({
|
cx.add_action(toggle);
|
||||||
let theme_registry = app_state.themes.clone();
|
|
||||||
move |workspace, _: &Toggle, cx| toggle(workspace, theme_registry.clone(), cx)
|
|
||||||
});
|
|
||||||
ThemeSelector::init(cx);
|
ThemeSelector::init(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn toggle(workspace: &mut Workspace, themes: Arc<ThemeRegistry>, cx: &mut ViewContext<Workspace>) {
|
pub fn toggle(workspace: &mut Workspace, _: &Toggle, cx: &mut ViewContext<Workspace>) {
|
||||||
workspace.toggle_modal(cx, |_, cx| {
|
workspace.toggle_modal(cx, |workspace, cx| {
|
||||||
|
let themes = workspace.app_state().themes.clone();
|
||||||
cx.add_view(|cx| ThemeSelector::new(ThemeSelectorDelegate::new(themes, cx), cx))
|
cx.add_view(|cx| ThemeSelector::new(ThemeSelectorDelegate::new(themes, cx), cx))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ pub fn init(cx: &mut AppContext) {
|
|||||||
BaseKeymapSelector::init(cx);
|
BaseKeymapSelector::init(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn toggle(
|
pub fn toggle(
|
||||||
workspace: &mut Workspace,
|
workspace: &mut Workspace,
|
||||||
_: &ToggleBaseKeymapSelector,
|
_: &ToggleBaseKeymapSelector,
|
||||||
cx: &mut ViewContext<Workspace>,
|
cx: &mut ViewContext<Workspace>,
|
||||||
|
@ -5,7 +5,7 @@ use std::{borrow::Cow, sync::Arc};
|
|||||||
use db::kvp::KEY_VALUE_STORE;
|
use db::kvp::KEY_VALUE_STORE;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
elements::{Flex, Label, ParentElement},
|
elements::{Flex, Label, ParentElement},
|
||||||
AnyElement, AppContext, Element, Entity, Subscription, View, ViewContext,
|
AnyElement, AppContext, Element, Entity, Subscription, View, ViewContext, WeakViewHandle,
|
||||||
};
|
};
|
||||||
use settings::{settings_file::SettingsFile, Settings};
|
use settings::{settings_file::SettingsFile, Settings};
|
||||||
|
|
||||||
@ -20,7 +20,7 @@ pub const FIRST_OPEN: &str = "first_open";
|
|||||||
|
|
||||||
pub fn init(cx: &mut AppContext) {
|
pub fn init(cx: &mut AppContext) {
|
||||||
cx.add_action(|workspace: &mut Workspace, _: &Welcome, cx| {
|
cx.add_action(|workspace: &mut Workspace, _: &Welcome, cx| {
|
||||||
let welcome_page = cx.add_view(WelcomePage::new);
|
let welcome_page = cx.add_view(|cx| WelcomePage::new(workspace, cx));
|
||||||
workspace.add_item(Box::new(welcome_page), cx)
|
workspace.add_item(Box::new(welcome_page), cx)
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -30,7 +30,7 @@ pub fn init(cx: &mut AppContext) {
|
|||||||
pub fn show_welcome_experience(app_state: &Arc<AppState>, cx: &mut AppContext) {
|
pub fn show_welcome_experience(app_state: &Arc<AppState>, cx: &mut AppContext) {
|
||||||
open_new(&app_state, cx, |workspace, cx| {
|
open_new(&app_state, cx, |workspace, cx| {
|
||||||
workspace.toggle_sidebar(SidebarSide::Left, cx);
|
workspace.toggle_sidebar(SidebarSide::Left, cx);
|
||||||
let welcome_page = cx.add_view(|cx| WelcomePage::new(cx));
|
let welcome_page = cx.add_view(|cx| WelcomePage::new(workspace, cx));
|
||||||
workspace.add_item_to_center(Box::new(welcome_page.clone()), cx);
|
workspace.add_item_to_center(Box::new(welcome_page.clone()), cx);
|
||||||
cx.focus(&welcome_page);
|
cx.focus(&welcome_page);
|
||||||
cx.notify();
|
cx.notify();
|
||||||
@ -43,6 +43,7 @@ pub fn show_welcome_experience(app_state: &Arc<AppState>, cx: &mut AppContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct WelcomePage {
|
pub struct WelcomePage {
|
||||||
|
workspace: WeakViewHandle<Workspace>,
|
||||||
_settings_subscription: Subscription,
|
_settings_subscription: Subscription,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,26 +98,46 @@ impl View for WelcomePage {
|
|||||||
)
|
)
|
||||||
.with_child(
|
.with_child(
|
||||||
Flex::column()
|
Flex::column()
|
||||||
.with_child(theme::ui::cta_button(
|
.with_child(theme::ui::cta_button::<theme_selector::Toggle, _, _, _>(
|
||||||
"Choose a theme",
|
"Choose a theme",
|
||||||
theme_selector::Toggle,
|
|
||||||
width,
|
width,
|
||||||
&theme.welcome.button,
|
&theme.welcome.button,
|
||||||
cx,
|
cx,
|
||||||
|
|_, this, cx| {
|
||||||
|
if let Some(workspace) = this.workspace.upgrade(cx) {
|
||||||
|
workspace.update(cx, |workspace, cx| {
|
||||||
|
theme_selector::toggle(workspace, &Default::default(), cx)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
))
|
))
|
||||||
.with_child(theme::ui::cta_button(
|
.with_child(theme::ui::cta_button::<ToggleBaseKeymapSelector, _, _, _>(
|
||||||
"Choose a keymap",
|
"Choose a keymap",
|
||||||
ToggleBaseKeymapSelector,
|
|
||||||
width,
|
width,
|
||||||
&theme.welcome.button,
|
&theme.welcome.button,
|
||||||
cx,
|
cx,
|
||||||
|
|_, this, cx| {
|
||||||
|
if let Some(workspace) = this.workspace.upgrade(cx) {
|
||||||
|
workspace.update(cx, |workspace, cx| {
|
||||||
|
base_keymap_picker::toggle(
|
||||||
|
workspace,
|
||||||
|
&Default::default(),
|
||||||
|
cx,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
))
|
))
|
||||||
.with_child(theme::ui::cta_button(
|
.with_child(theme::ui::cta_button::<install_cli::Install, _, _, _>(
|
||||||
"Install the CLI",
|
"Install the CLI",
|
||||||
install_cli::Install,
|
|
||||||
width,
|
width,
|
||||||
&theme.welcome.button,
|
&theme.welcome.button,
|
||||||
cx,
|
cx,
|
||||||
|
|_, _, cx| {
|
||||||
|
cx.app_context()
|
||||||
|
.spawn(|cx| async move { install_cli::install_cli(&cx).await })
|
||||||
|
.detach_and_log_err(cx);
|
||||||
|
},
|
||||||
))
|
))
|
||||||
.contained()
|
.contained()
|
||||||
.with_style(theme.welcome.button_group)
|
.with_style(theme.welcome.button_group)
|
||||||
@ -190,8 +211,9 @@ impl View for WelcomePage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl WelcomePage {
|
impl WelcomePage {
|
||||||
pub fn new(cx: &mut ViewContext<Self>) -> Self {
|
pub fn new(workspace: &Workspace, cx: &mut ViewContext<Self>) -> Self {
|
||||||
WelcomePage {
|
WelcomePage {
|
||||||
|
workspace: workspace.weak_handle(),
|
||||||
_settings_subscription: cx.observe_global::<Settings, _>(move |_, cx| cx.notify()),
|
_settings_subscription: cx.observe_global::<Settings, _>(move |_, cx| cx.notify()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -220,11 +242,15 @@ impl Item for WelcomePage {
|
|||||||
fn show_toolbar(&self) -> bool {
|
fn show_toolbar(&self) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clone_on_split(
|
fn clone_on_split(
|
||||||
&self,
|
&self,
|
||||||
_workspace_id: WorkspaceId,
|
_workspace_id: WorkspaceId,
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) -> Option<Self> {
|
) -> Option<Self> {
|
||||||
Some(WelcomePage::new(cx))
|
Some(WelcomePage {
|
||||||
|
workspace: self.workspace.clone(),
|
||||||
|
_settings_subscription: cx.observe_global::<Settings, _>(move |_, cx| cx.notify()),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -271,11 +271,11 @@ impl Dock {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn focus_dock(workspace: &mut Workspace, _: &FocusDock, cx: &mut ViewContext<Workspace>) {
|
pub fn focus_dock(workspace: &mut Workspace, _: &FocusDock, cx: &mut ViewContext<Workspace>) {
|
||||||
Self::set_dock_position(workspace, workspace.dock.position.show(), true, cx);
|
Self::set_dock_position(workspace, workspace.dock.position.show(), true, cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hide_dock(workspace: &mut Workspace, _: &HideDock, cx: &mut ViewContext<Workspace>) {
|
pub fn hide_dock(workspace: &mut Workspace, _: &HideDock, cx: &mut ViewContext<Workspace>) {
|
||||||
Self::set_dock_position(workspace, workspace.dock.position.hide(), true, cx);
|
Self::set_dock_position(workspace, workspace.dock.position.hide(), true, cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -374,8 +374,8 @@ impl Dock {
|
|||||||
.with_background_color(style.wash_color)
|
.with_background_color(style.wash_color)
|
||||||
})
|
})
|
||||||
.capture_all()
|
.capture_all()
|
||||||
.on_down(MouseButton::Left, |_, _, cx| {
|
.on_down(MouseButton::Left, |_, workspace, cx| {
|
||||||
cx.dispatch_action(HideDock);
|
Dock::hide_dock(workspace, &Default::default(), cx)
|
||||||
})
|
})
|
||||||
.with_cursor_style(CursorStyle::Arrow),
|
.with_cursor_style(CursorStyle::Arrow),
|
||||||
)
|
)
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
use super::{icon_for_dock_anchor, Dock, FocusDock, HideDock};
|
||||||
|
use crate::{handle_dropped_item, StatusItemView, Workspace};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
elements::{Empty, MouseEventHandler, Svg},
|
elements::{Empty, MouseEventHandler, Svg},
|
||||||
platform::CursorStyle,
|
platform::CursorStyle,
|
||||||
@ -6,10 +8,6 @@ use gpui::{
|
|||||||
};
|
};
|
||||||
use settings::Settings;
|
use settings::Settings;
|
||||||
|
|
||||||
use crate::{handle_dropped_item, StatusItemView, Workspace};
|
|
||||||
|
|
||||||
use super::{icon_for_dock_anchor, FocusDock, HideDock};
|
|
||||||
|
|
||||||
pub struct ToggleDockButton {
|
pub struct ToggleDockButton {
|
||||||
workspace: WeakViewHandle<Workspace>,
|
workspace: WeakViewHandle<Workspace>,
|
||||||
}
|
}
|
||||||
@ -82,8 +80,12 @@ impl View for ToggleDockButton {
|
|||||||
|
|
||||||
if dock_position.is_visible() {
|
if dock_position.is_visible() {
|
||||||
button
|
button
|
||||||
.on_click(MouseButton::Left, |_, _, cx| {
|
.on_click(MouseButton::Left, |_, this, cx| {
|
||||||
cx.dispatch_action(HideDock);
|
if let Some(workspace) = this.workspace.upgrade(cx) {
|
||||||
|
workspace.update(cx, |workspace, cx| {
|
||||||
|
Dock::hide_dock(workspace, &Default::default(), cx)
|
||||||
|
})
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.with_tooltip::<Self>(
|
.with_tooltip::<Self>(
|
||||||
0,
|
0,
|
||||||
@ -94,8 +96,12 @@ impl View for ToggleDockButton {
|
|||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
button
|
button
|
||||||
.on_click(MouseButton::Left, |_, _, cx| {
|
.on_click(MouseButton::Left, |_, this, cx| {
|
||||||
cx.dispatch_action(FocusDock);
|
if let Some(workspace) = this.workspace.upgrade(cx) {
|
||||||
|
workspace.update(cx, |workspace, cx| {
|
||||||
|
Dock::focus_dock(workspace, &Default::default(), cx)
|
||||||
|
})
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.with_tooltip::<Self>(
|
.with_tooltip::<Self>(
|
||||||
0,
|
0,
|
||||||
|
@ -278,8 +278,8 @@ pub mod simple_message_notification {
|
|||||||
.with_height(style.button_width)
|
.with_height(style.button_width)
|
||||||
})
|
})
|
||||||
.with_padding(Padding::uniform(5.))
|
.with_padding(Padding::uniform(5.))
|
||||||
.on_click(MouseButton::Left, move |_, _, cx| {
|
.on_click(MouseButton::Left, move |_, this, cx| {
|
||||||
cx.dispatch_action(CancelMessageNotification)
|
this.dismiss(&Default::default(), cx);
|
||||||
})
|
})
|
||||||
.with_cursor_style(CursorStyle::PointingHand)
|
.with_cursor_style(CursorStyle::PointingHand)
|
||||||
.aligned()
|
.aligned()
|
||||||
|
@ -2,7 +2,7 @@ mod dragged_item_receiver;
|
|||||||
|
|
||||||
use super::{ItemHandle, SplitDirection};
|
use super::{ItemHandle, SplitDirection};
|
||||||
use crate::{
|
use crate::{
|
||||||
dock::{icon_for_dock_anchor, AnchorDockBottom, AnchorDockRight, ExpandDock, HideDock},
|
dock::{icon_for_dock_anchor, AnchorDockBottom, AnchorDockRight, Dock, ExpandDock},
|
||||||
item::WeakItemHandle,
|
item::WeakItemHandle,
|
||||||
toolbar::Toolbar,
|
toolbar::Toolbar,
|
||||||
Item, NewFile, NewSearch, NewTerminal, Workspace,
|
Item, NewFile, NewSearch, NewTerminal, Workspace,
|
||||||
@ -259,6 +259,10 @@ impl Pane {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn workspace(&self) -> &WeakViewHandle<Workspace> {
|
||||||
|
&self.workspace
|
||||||
|
}
|
||||||
|
|
||||||
pub fn is_active(&self) -> bool {
|
pub fn is_active(&self) -> bool {
|
||||||
self.is_active
|
self.is_active
|
||||||
}
|
}
|
||||||
@ -1340,8 +1344,8 @@ impl Pane {
|
|||||||
cx,
|
cx,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.on_down(MouseButton::Left, move |_, _, cx| {
|
.on_down(MouseButton::Left, move |_, this, cx| {
|
||||||
cx.dispatch_action(ActivateItem(ix));
|
this.activate_item(ix, true, true, cx);
|
||||||
})
|
})
|
||||||
.on_click(MouseButton::Middle, {
|
.on_click(MouseButton::Middle, {
|
||||||
let item_id = item.id();
|
let item_id = item.id();
|
||||||
@ -1639,7 +1643,13 @@ impl Pane {
|
|||||||
3,
|
3,
|
||||||
"icons/x_mark_8.svg",
|
"icons/x_mark_8.svg",
|
||||||
cx,
|
cx,
|
||||||
|_, cx| cx.dispatch_action(HideDock),
|
|this, cx| {
|
||||||
|
if let Some(workspace) = this.workspace.upgrade(cx) {
|
||||||
|
workspace.update(cx, |workspace, cx| {
|
||||||
|
Dock::hide_dock(workspace, &Default::default(), cx)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
}))
|
}))
|
||||||
@ -1693,8 +1703,8 @@ impl View for Pane {
|
|||||||
})
|
})
|
||||||
.on_down(
|
.on_down(
|
||||||
MouseButton::Left,
|
MouseButton::Left,
|
||||||
move |_, _, cx| {
|
move |_, this, cx| {
|
||||||
cx.dispatch_action(ActivateItem(active_item_index));
|
this.activate_item(active_item_index, true, true, cx);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -1759,15 +1769,27 @@ impl View for Pane {
|
|||||||
})
|
})
|
||||||
.on_down(
|
.on_down(
|
||||||
MouseButton::Navigate(NavigationDirection::Back),
|
MouseButton::Navigate(NavigationDirection::Back),
|
||||||
move |_, _, cx| {
|
move |_, pane, cx| {
|
||||||
let pane = cx.weak_handle();
|
if let Some(workspace) = pane.workspace.upgrade(cx) {
|
||||||
cx.dispatch_action(GoBack { pane: Some(pane) });
|
let pane = cx.weak_handle();
|
||||||
|
cx.window_context().defer(move |cx| {
|
||||||
|
workspace.update(cx, |workspace, cx| {
|
||||||
|
Pane::go_back(workspace, Some(pane), cx).detach_and_log_err(cx)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.on_down(MouseButton::Navigate(NavigationDirection::Forward), {
|
.on_down(MouseButton::Navigate(NavigationDirection::Forward), {
|
||||||
move |_, _, cx| {
|
move |_, pane, cx| {
|
||||||
let pane = cx.weak_handle();
|
if let Some(workspace) = pane.workspace.upgrade(cx) {
|
||||||
cx.dispatch_action(GoForward { pane: Some(pane) })
|
let pane = cx.weak_handle();
|
||||||
|
cx.window_context().defer(move |cx| {
|
||||||
|
workspace.update(cx, |workspace, cx| {
|
||||||
|
Pane::go_forward(workspace, Some(pane), cx).detach_and_log_err(cx)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.into_any_named("pane")
|
.into_any_named("pane")
|
||||||
|
@ -279,9 +279,9 @@ impl View for SidebarButtons {
|
|||||||
.with_style(style.container)
|
.with_style(style.container)
|
||||||
})
|
})
|
||||||
.with_cursor_style(CursorStyle::PointingHand)
|
.with_cursor_style(CursorStyle::PointingHand)
|
||||||
.on_click(MouseButton::Left, {
|
.on_click(MouseButton::Left, move |_, this, cx| {
|
||||||
let action = action.clone();
|
this.sidebar
|
||||||
move |_, _, cx| cx.dispatch_action(action.clone())
|
.update(cx, |sidebar, cx| sidebar.toggle_item(ix, cx));
|
||||||
})
|
})
|
||||||
.with_tooltip::<Self>(
|
.with_tooltip::<Self>(
|
||||||
ix,
|
ix,
|
||||||
|
@ -130,8 +130,20 @@ impl View for Toolbar {
|
|||||||
tooltip_style.clone(),
|
tooltip_style.clone(),
|
||||||
enable_go_backward,
|
enable_go_backward,
|
||||||
spacing,
|
spacing,
|
||||||
super::GoBack {
|
{
|
||||||
pane: Some(pane.clone()),
|
let pane = pane.clone();
|
||||||
|
move |toolbar, cx| {
|
||||||
|
if let Some(workspace) = toolbar
|
||||||
|
.pane
|
||||||
|
.upgrade(cx)
|
||||||
|
.and_then(|pane| pane.read(cx).workspace().upgrade(cx))
|
||||||
|
{
|
||||||
|
workspace.update(cx, |workspace, cx| {
|
||||||
|
Pane::go_back(workspace, Some(pane.clone()), cx)
|
||||||
|
.detach_and_log_err(cx);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
super::GoBack { pane: None },
|
super::GoBack { pane: None },
|
||||||
"Go Back",
|
"Go Back",
|
||||||
@ -143,7 +155,21 @@ impl View for Toolbar {
|
|||||||
tooltip_style,
|
tooltip_style,
|
||||||
enable_go_forward,
|
enable_go_forward,
|
||||||
spacing,
|
spacing,
|
||||||
super::GoForward { pane: Some(pane) },
|
{
|
||||||
|
let pane = pane.clone();
|
||||||
|
move |toolbar, cx| {
|
||||||
|
if let Some(workspace) = toolbar
|
||||||
|
.pane
|
||||||
|
.upgrade(cx)
|
||||||
|
.and_then(|pane| pane.read(cx).workspace().upgrade(cx))
|
||||||
|
{
|
||||||
|
workspace.update(cx, |workspace, cx| {
|
||||||
|
Pane::go_forward(workspace, Some(pane.clone()), cx)
|
||||||
|
.detach_and_log_err(cx);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
super::GoForward { pane: None },
|
super::GoForward { pane: None },
|
||||||
"Go Forward",
|
"Go Forward",
|
||||||
cx,
|
cx,
|
||||||
@ -161,13 +187,13 @@ impl View for Toolbar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
fn nav_button<A: Action + Clone>(
|
fn nav_button<A: Action, F: 'static + Fn(&mut Toolbar, &mut ViewContext<Toolbar>)>(
|
||||||
svg_path: &'static str,
|
svg_path: &'static str,
|
||||||
style: theme::Interactive<theme::IconButton>,
|
style: theme::Interactive<theme::IconButton>,
|
||||||
tooltip_style: TooltipStyle,
|
tooltip_style: TooltipStyle,
|
||||||
enabled: bool,
|
enabled: bool,
|
||||||
spacing: f32,
|
spacing: f32,
|
||||||
action: A,
|
on_click: F,
|
||||||
tooltip_action: A,
|
tooltip_action: A,
|
||||||
action_name: &str,
|
action_name: &str,
|
||||||
cx: &mut ViewContext<Toolbar>,
|
cx: &mut ViewContext<Toolbar>,
|
||||||
@ -195,8 +221,8 @@ fn nav_button<A: Action + Clone>(
|
|||||||
} else {
|
} else {
|
||||||
CursorStyle::default()
|
CursorStyle::default()
|
||||||
})
|
})
|
||||||
.on_click(MouseButton::Left, move |_, _, cx| {
|
.on_click(MouseButton::Left, move |_, toolbar, cx| {
|
||||||
cx.dispatch_action(action.clone())
|
on_click(toolbar, cx)
|
||||||
})
|
})
|
||||||
.with_tooltip::<A>(
|
.with_tooltip::<A>(
|
||||||
0,
|
0,
|
||||||
|
@ -208,48 +208,7 @@ pub fn init(app_state: Arc<AppState>, cx: &mut AppContext) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
cx.add_action({
|
cx.add_async_action(Workspace::open);
|
||||||
let app_state = Arc::downgrade(&app_state);
|
|
||||||
move |_, _: &Open, cx: &mut ViewContext<Workspace>| {
|
|
||||||
let mut paths = cx.prompt_for_paths(PathPromptOptions {
|
|
||||||
files: true,
|
|
||||||
directories: true,
|
|
||||||
multiple: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
if let Some(app_state) = app_state.upgrade() {
|
|
||||||
cx.spawn(|this, mut cx| async move {
|
|
||||||
if let Some(paths) = paths.recv().await.flatten() {
|
|
||||||
if let Some(task) = this
|
|
||||||
.update(&mut cx, |this, cx| {
|
|
||||||
this.open_workspace_for_paths(paths, app_state, cx)
|
|
||||||
})
|
|
||||||
.log_err()
|
|
||||||
{
|
|
||||||
task.await.log_err();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.detach();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
cx.add_global_action({
|
|
||||||
let app_state = Arc::downgrade(&app_state);
|
|
||||||
move |_: &NewWindow, cx: &mut AppContext| {
|
|
||||||
if let Some(app_state) = app_state.upgrade() {
|
|
||||||
open_new(&app_state, cx, |_, cx| cx.dispatch_action(NewFile)).detach();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
cx.add_global_action({
|
|
||||||
let app_state = Arc::downgrade(&app_state);
|
|
||||||
move |_: &NewFile, cx: &mut AppContext| {
|
|
||||||
if let Some(app_state) = app_state.upgrade() {
|
|
||||||
open_new(&app_state, cx, |_, cx| cx.dispatch_action(NewFile)).detach();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
cx.add_async_action(Workspace::follow_next_collaborator);
|
cx.add_async_action(Workspace::follow_next_collaborator);
|
||||||
cx.add_async_action(Workspace::close);
|
cx.add_async_action(Workspace::close);
|
||||||
@ -913,7 +872,6 @@ impl Workspace {
|
|||||||
/// to the callback. Otherwise, a new empty window will be created.
|
/// to the callback. Otherwise, a new empty window will be created.
|
||||||
pub fn with_local_workspace<T, F>(
|
pub fn with_local_workspace<T, F>(
|
||||||
&mut self,
|
&mut self,
|
||||||
app_state: &Arc<AppState>,
|
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
callback: F,
|
callback: F,
|
||||||
) -> Task<Result<T>>
|
) -> Task<Result<T>>
|
||||||
@ -924,7 +882,7 @@ impl Workspace {
|
|||||||
if self.project.read(cx).is_local() {
|
if self.project.read(cx).is_local() {
|
||||||
Task::Ready(Some(Ok(callback(self, cx))))
|
Task::Ready(Some(Ok(callback(self, cx))))
|
||||||
} else {
|
} else {
|
||||||
let task = Self::new_local(Vec::new(), app_state.clone(), None, cx);
|
let task = Self::new_local(Vec::new(), self.app_state.clone(), None, cx);
|
||||||
cx.spawn(|_vh, mut cx| async move {
|
cx.spawn(|_vh, mut cx| async move {
|
||||||
let (workspace, _) = task.await;
|
let (workspace, _) = task.await;
|
||||||
workspace.update(&mut cx, callback)
|
workspace.update(&mut cx, callback)
|
||||||
@ -1093,10 +1051,29 @@ impl Workspace {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn open(&mut self, _: &Open, cx: &mut ViewContext<Self>) -> Option<Task<Result<()>>> {
|
||||||
|
let mut paths = cx.prompt_for_paths(PathPromptOptions {
|
||||||
|
files: true,
|
||||||
|
directories: true,
|
||||||
|
multiple: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
Some(cx.spawn(|this, mut cx| async move {
|
||||||
|
if let Some(paths) = paths.recv().await.flatten() {
|
||||||
|
if let Some(task) = this
|
||||||
|
.update(&mut cx, |this, cx| this.open_workspace_for_paths(paths, cx))
|
||||||
|
.log_err()
|
||||||
|
{
|
||||||
|
task.await?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn open_workspace_for_paths(
|
pub fn open_workspace_for_paths(
|
||||||
&mut self,
|
&mut self,
|
||||||
paths: Vec<PathBuf>,
|
paths: Vec<PathBuf>,
|
||||||
app_state: Arc<AppState>,
|
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) -> Task<Result<()>> {
|
) -> Task<Result<()>> {
|
||||||
let window_id = cx.window_id();
|
let window_id = cx.window_id();
|
||||||
@ -1108,6 +1085,7 @@ impl Workspace {
|
|||||||
} else {
|
} else {
|
||||||
Some(self.prepare_to_close(false, cx))
|
Some(self.prepare_to_close(false, cx))
|
||||||
};
|
};
|
||||||
|
let app_state = self.app_state.clone();
|
||||||
|
|
||||||
cx.spawn(|_, mut cx| async move {
|
cx.spawn(|_, mut cx| async move {
|
||||||
let window_id_to_replace = if let Some(close_task) = close_task {
|
let window_id_to_replace = if let Some(close_task) = close_task {
|
||||||
|
@ -10,6 +10,7 @@ use cli::{
|
|||||||
};
|
};
|
||||||
use client::{self, UserStore, ZED_APP_VERSION, ZED_SECRET_CLIENT_TOKEN};
|
use client::{self, UserStore, ZED_APP_VERSION, ZED_SECRET_CLIENT_TOKEN};
|
||||||
use db::kvp::KEY_VALUE_STORE;
|
use db::kvp::KEY_VALUE_STORE;
|
||||||
|
use editor::Editor;
|
||||||
use futures::{
|
use futures::{
|
||||||
channel::{mpsc, oneshot},
|
channel::{mpsc, oneshot},
|
||||||
FutureExt, SinkExt, StreamExt,
|
FutureExt, SinkExt, StreamExt,
|
||||||
@ -51,8 +52,7 @@ use staff_mode::StaffMode;
|
|||||||
use theme::ThemeRegistry;
|
use theme::ThemeRegistry;
|
||||||
use util::{channel::RELEASE_CHANNEL, paths, ResultExt, TryFutureExt};
|
use util::{channel::RELEASE_CHANNEL, paths, ResultExt, TryFutureExt};
|
||||||
use workspace::{
|
use workspace::{
|
||||||
self, dock::FocusDock, item::ItemHandle, notifications::NotifyResultExt, AppState, NewFile,
|
self, dock::FocusDock, item::ItemHandle, notifications::NotifyResultExt, AppState, Workspace,
|
||||||
Workspace,
|
|
||||||
};
|
};
|
||||||
use zed::{self, build_window_options, initialize_workspace, languages, menus, OpenSettings};
|
use zed::{self, build_window_options, initialize_workspace, languages, menus, OpenSettings};
|
||||||
|
|
||||||
@ -115,7 +115,10 @@ fn main() {
|
|||||||
.on_reopen(move |cx| {
|
.on_reopen(move |cx| {
|
||||||
if cx.has_global::<Weak<AppState>>() {
|
if cx.has_global::<Weak<AppState>>() {
|
||||||
if let Some(app_state) = cx.global::<Weak<AppState>>().upgrade() {
|
if let Some(app_state) = cx.global::<Weak<AppState>>().upgrade() {
|
||||||
workspace::open_new(&app_state, cx, |_, cx| cx.dispatch_action(NewFile)).detach();
|
workspace::open_new(&app_state, cx, |workspace, cx| {
|
||||||
|
Editor::new_file(workspace, &Default::default(), cx)
|
||||||
|
})
|
||||||
|
.detach();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -208,14 +211,14 @@ fn main() {
|
|||||||
auto_update::init(http, client::ZED_SERVER_URL.clone(), cx);
|
auto_update::init(http, client::ZED_SERVER_URL.clone(), cx);
|
||||||
|
|
||||||
workspace::init(app_state.clone(), cx);
|
workspace::init(app_state.clone(), cx);
|
||||||
recent_projects::init(cx, Arc::downgrade(&app_state));
|
recent_projects::init(cx);
|
||||||
|
|
||||||
journal::init(app_state.clone(), cx);
|
journal::init(app_state.clone(), cx);
|
||||||
language_selector::init(app_state.clone(), cx);
|
language_selector::init(cx);
|
||||||
theme_selector::init(app_state.clone(), cx);
|
theme_selector::init(cx);
|
||||||
zed::init(&app_state, cx);
|
zed::init(&app_state, cx);
|
||||||
collab_ui::init(&app_state, cx);
|
collab_ui::init(&app_state, cx);
|
||||||
feedback::init(app_state.clone(), cx);
|
feedback::init(cx);
|
||||||
welcome::init(cx);
|
welcome::init(cx);
|
||||||
|
|
||||||
cx.set_menus(menus::menus());
|
cx.set_menus(menus::menus());
|
||||||
@ -289,7 +292,10 @@ async fn restore_or_create_workspace(app_state: &Arc<AppState>, mut cx: AsyncApp
|
|||||||
cx.update(|cx| show_welcome_experience(app_state, cx));
|
cx.update(|cx| show_welcome_experience(app_state, cx));
|
||||||
} else {
|
} else {
|
||||||
cx.update(|cx| {
|
cx.update(|cx| {
|
||||||
workspace::open_new(app_state, cx, |_, cx| cx.dispatch_action(NewFile)).detach();
|
workspace::open_new(app_state, cx, |workspace, cx| {
|
||||||
|
Editor::new_file(workspace, &Default::default(), cx)
|
||||||
|
})
|
||||||
|
.detach();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ use gpui::{
|
|||||||
geometry::vector::vec2f,
|
geometry::vector::vec2f,
|
||||||
impl_actions,
|
impl_actions,
|
||||||
platform::{Platform, PromptLevel, TitlebarOptions, WindowBounds, WindowKind, WindowOptions},
|
platform::{Platform, PromptLevel, TitlebarOptions, WindowBounds, WindowKind, WindowOptions},
|
||||||
AssetSource, ViewContext,
|
AppContext, AssetSource, ViewContext,
|
||||||
};
|
};
|
||||||
use language::Rope;
|
use language::Rope;
|
||||||
pub use lsp;
|
pub use lsp;
|
||||||
@ -35,7 +35,7 @@ use terminal_view::terminal_button::TerminalButton;
|
|||||||
use util::{channel::ReleaseChannel, paths, ResultExt};
|
use util::{channel::ReleaseChannel, paths, ResultExt};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
pub use workspace;
|
pub use workspace;
|
||||||
use workspace::{sidebar::SidebarSide, AppState, Workspace};
|
use workspace::{open_new, sidebar::SidebarSide, AppState, NewFile, NewWindow, Workspace};
|
||||||
|
|
||||||
#[derive(Deserialize, Clone, PartialEq)]
|
#[derive(Deserialize, Clone, PartialEq)]
|
||||||
pub struct OpenBrowser {
|
pub struct OpenBrowser {
|
||||||
@ -147,10 +147,9 @@ pub fn init(app_state: &Arc<AppState>, cx: &mut gpui::AppContext) {
|
|||||||
})
|
})
|
||||||
.detach_and_log_err(cx);
|
.detach_and_log_err(cx);
|
||||||
});
|
});
|
||||||
cx.add_action({
|
cx.add_action(
|
||||||
let app_state = app_state.clone();
|
move |workspace: &mut Workspace, _: &OpenSettings, cx: &mut ViewContext<Workspace>| {
|
||||||
move |_: &mut Workspace, _: &OpenSettings, cx: &mut ViewContext<Workspace>| {
|
open_config_file(workspace, &paths::SETTINGS, cx, || {
|
||||||
open_config_file(&paths::SETTINGS, app_state.clone(), cx, || {
|
|
||||||
str::from_utf8(
|
str::from_utf8(
|
||||||
Assets
|
Assets
|
||||||
.load("settings/initial_user_settings.json")
|
.load("settings/initial_user_settings.json")
|
||||||
@ -160,73 +159,68 @@ pub fn init(app_state: &Arc<AppState>, cx: &mut gpui::AppContext) {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
.into()
|
.into()
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
});
|
);
|
||||||
cx.add_action({
|
cx.add_action(
|
||||||
let app_state = app_state.clone();
|
|
||||||
move |workspace: &mut Workspace, _: &OpenLog, cx: &mut ViewContext<Workspace>| {
|
move |workspace: &mut Workspace, _: &OpenLog, cx: &mut ViewContext<Workspace>| {
|
||||||
open_log_file(workspace, app_state.clone(), cx);
|
open_log_file(workspace, cx);
|
||||||
}
|
},
|
||||||
});
|
);
|
||||||
cx.add_action({
|
cx.add_action(
|
||||||
let app_state = app_state.clone();
|
move |workspace: &mut Workspace, _: &OpenLicenses, cx: &mut ViewContext<Workspace>| {
|
||||||
move |_: &mut Workspace, _: &OpenLicenses, cx: &mut ViewContext<Workspace>| {
|
|
||||||
open_bundled_file(
|
open_bundled_file(
|
||||||
app_state.clone(),
|
workspace,
|
||||||
"licenses.md",
|
"licenses.md",
|
||||||
"Open Source License Attribution",
|
"Open Source License Attribution",
|
||||||
"Markdown",
|
"Markdown",
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
});
|
);
|
||||||
cx.add_action({
|
cx.add_action(
|
||||||
let app_state = app_state.clone();
|
|
||||||
move |workspace: &mut Workspace, _: &OpenTelemetryLog, cx: &mut ViewContext<Workspace>| {
|
move |workspace: &mut Workspace, _: &OpenTelemetryLog, cx: &mut ViewContext<Workspace>| {
|
||||||
open_telemetry_log_file(workspace, app_state.clone(), cx);
|
open_telemetry_log_file(workspace, cx);
|
||||||
}
|
},
|
||||||
});
|
);
|
||||||
cx.add_action({
|
cx.add_action(
|
||||||
let app_state = app_state.clone();
|
move |workspace: &mut Workspace, _: &OpenKeymap, cx: &mut ViewContext<Workspace>| {
|
||||||
move |_: &mut Workspace, _: &OpenKeymap, cx: &mut ViewContext<Workspace>| {
|
open_config_file(workspace, &paths::KEYMAP, cx, Default::default);
|
||||||
open_config_file(&paths::KEYMAP, app_state.clone(), cx, Default::default);
|
},
|
||||||
}
|
);
|
||||||
});
|
cx.add_action(
|
||||||
cx.add_action({
|
move |workspace: &mut Workspace, _: &OpenDefaultKeymap, cx: &mut ViewContext<Workspace>| {
|
||||||
let app_state = app_state.clone();
|
|
||||||
move |_: &mut Workspace, _: &OpenDefaultKeymap, cx: &mut ViewContext<Workspace>| {
|
|
||||||
open_bundled_file(
|
open_bundled_file(
|
||||||
app_state.clone(),
|
workspace,
|
||||||
"keymaps/default.json",
|
"keymaps/default.json",
|
||||||
"Default Key Bindings",
|
"Default Key Bindings",
|
||||||
"JSON",
|
"JSON",
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
});
|
);
|
||||||
cx.add_action({
|
cx.add_action(
|
||||||
let app_state = app_state.clone();
|
move |workspace: &mut Workspace,
|
||||||
move |_: &mut Workspace, _: &OpenDefaultSettings, cx: &mut ViewContext<Workspace>| {
|
_: &OpenDefaultSettings,
|
||||||
|
cx: &mut ViewContext<Workspace>| {
|
||||||
open_bundled_file(
|
open_bundled_file(
|
||||||
app_state.clone(),
|
workspace,
|
||||||
"settings/default.json",
|
"settings/default.json",
|
||||||
"Default Settings",
|
"Default Settings",
|
||||||
"JSON",
|
"JSON",
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
});
|
);
|
||||||
cx.add_action({
|
cx.add_action({
|
||||||
let app_state = app_state.clone();
|
move |workspace: &mut Workspace, _: &DebugElements, cx: &mut ViewContext<Workspace>| {
|
||||||
move |_: &mut Workspace, _: &DebugElements, cx: &mut ViewContext<Workspace>| {
|
let app_state = workspace.app_state().clone();
|
||||||
let app_state = app_state.clone();
|
|
||||||
let markdown = app_state.languages.language_for_name("JSON");
|
let markdown = app_state.languages.language_for_name("JSON");
|
||||||
let content = to_string_pretty(&cx.debug_elements()).unwrap();
|
let content = to_string_pretty(&cx.debug_elements()).unwrap();
|
||||||
cx.spawn(|workspace, mut cx| async move {
|
cx.spawn(|workspace, mut cx| async move {
|
||||||
let markdown = markdown.await.log_err();
|
let markdown = markdown.await.log_err();
|
||||||
workspace
|
workspace
|
||||||
.update(&mut cx, |workspace, cx| {
|
.update(&mut cx, |workspace, cx| {
|
||||||
workspace.with_local_workspace(&app_state, cx, move |workspace, cx| {
|
workspace.with_local_workspace(cx, move |workspace, cx| {
|
||||||
let project = workspace.project().clone();
|
let project = workspace.project().clone();
|
||||||
|
|
||||||
let buffer = project
|
let buffer = project
|
||||||
@ -258,6 +252,28 @@ pub fn init(app_state: &Arc<AppState>, cx: &mut gpui::AppContext) {
|
|||||||
workspace.toggle_sidebar_item_focus(SidebarSide::Left, 0, cx);
|
workspace.toggle_sidebar_item_focus(SidebarSide::Left, 0, cx);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
cx.add_global_action({
|
||||||
|
let app_state = Arc::downgrade(&app_state);
|
||||||
|
move |_: &NewWindow, cx: &mut AppContext| {
|
||||||
|
if let Some(app_state) = app_state.upgrade() {
|
||||||
|
open_new(&app_state, cx, |workspace, cx| {
|
||||||
|
Editor::new_file(workspace, &Default::default(), cx)
|
||||||
|
})
|
||||||
|
.detach();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
cx.add_global_action({
|
||||||
|
let app_state = Arc::downgrade(&app_state);
|
||||||
|
move |_: &NewFile, cx: &mut AppContext| {
|
||||||
|
if let Some(app_state) = app_state.upgrade() {
|
||||||
|
open_new(&app_state, cx, |workspace, cx| {
|
||||||
|
Editor::new_file(workspace, &Default::default(), cx)
|
||||||
|
})
|
||||||
|
.detach();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
activity_indicator::init(cx);
|
activity_indicator::init(cx);
|
||||||
lsp_log::init(cx);
|
lsp_log::init(cx);
|
||||||
call::init(app_state.client.clone(), app_state.user_store.clone(), cx);
|
call::init(app_state.client.clone(), app_state.user_store.clone(), cx);
|
||||||
@ -275,7 +291,7 @@ pub fn initialize_workspace(
|
|||||||
if let workspace::Event::PaneAdded(pane) = event {
|
if let workspace::Event::PaneAdded(pane) = event {
|
||||||
pane.update(cx, |pane, cx| {
|
pane.update(cx, |pane, cx| {
|
||||||
pane.toolbar().update(cx, |toolbar, cx| {
|
pane.toolbar().update(cx, |toolbar, cx| {
|
||||||
let breadcrumbs = cx.add_view(|_| Breadcrumbs::new());
|
let breadcrumbs = cx.add_view(|_| Breadcrumbs::new(workspace));
|
||||||
toolbar.add_item(breadcrumbs, cx);
|
toolbar.add_item(breadcrumbs, cx);
|
||||||
let buffer_search_bar = cx.add_view(BufferSearchBar::new);
|
let buffer_search_bar = cx.add_view(BufferSearchBar::new);
|
||||||
toolbar.add_item(buffer_search_bar, cx);
|
toolbar.add_item(buffer_search_bar, cx);
|
||||||
@ -304,7 +320,7 @@ pub fn initialize_workspace(
|
|||||||
});
|
});
|
||||||
workspace.set_titlebar_item(collab_titlebar_item.into_any(), cx);
|
workspace.set_titlebar_item(collab_titlebar_item.into_any(), cx);
|
||||||
|
|
||||||
let project_panel = ProjectPanel::new(workspace.project().clone(), cx);
|
let project_panel = ProjectPanel::new(workspace, cx);
|
||||||
workspace.left_sidebar().update(cx, |sidebar, cx| {
|
workspace.left_sidebar().update(cx, |sidebar, cx| {
|
||||||
sidebar.add_item(
|
sidebar.add_item(
|
||||||
"icons/folder_tree_16.svg",
|
"icons/folder_tree_16.svg",
|
||||||
@ -317,12 +333,13 @@ pub fn initialize_workspace(
|
|||||||
let toggle_terminal = cx.add_view(|cx| TerminalButton::new(workspace_handle.clone(), cx));
|
let toggle_terminal = cx.add_view(|cx| TerminalButton::new(workspace_handle.clone(), cx));
|
||||||
let copilot = cx.add_view(|cx| copilot_button::CopilotButton::new(cx));
|
let copilot = cx.add_view(|cx| copilot_button::CopilotButton::new(cx));
|
||||||
let diagnostic_summary =
|
let diagnostic_summary =
|
||||||
cx.add_view(|cx| diagnostics::items::DiagnosticIndicator::new(workspace.project(), cx));
|
cx.add_view(|cx| diagnostics::items::DiagnosticIndicator::new(workspace, cx));
|
||||||
let activity_indicator =
|
let activity_indicator =
|
||||||
activity_indicator::ActivityIndicator::new(workspace, app_state.languages.clone(), cx);
|
activity_indicator::ActivityIndicator::new(workspace, app_state.languages.clone(), cx);
|
||||||
let active_buffer_language = cx.add_view(|_| language_selector::ActiveBufferLanguage::new());
|
let active_buffer_language =
|
||||||
|
cx.add_view(|_| language_selector::ActiveBufferLanguage::new(workspace));
|
||||||
let feedback_button =
|
let feedback_button =
|
||||||
cx.add_view(|_| feedback::deploy_feedback_button::DeployFeedbackButton::new());
|
cx.add_view(|_| feedback::deploy_feedback_button::DeployFeedbackButton::new(workspace));
|
||||||
let cursor_position = cx.add_view(|_| editor::items::CursorPosition::new());
|
let cursor_position = cx.add_view(|_| editor::items::CursorPosition::new());
|
||||||
workspace.status_bar().update(cx, |status_bar, cx| {
|
workspace.status_bar().update(cx, |status_bar, cx| {
|
||||||
status_bar.add_left_item(diagnostic_summary, cx);
|
status_bar.add_left_item(diagnostic_summary, cx);
|
||||||
@ -428,13 +445,13 @@ fn about(_: &mut Workspace, _: &About, cx: &mut gpui::ViewContext<Workspace>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn open_config_file(
|
fn open_config_file(
|
||||||
|
workspace: &mut Workspace,
|
||||||
path: &'static Path,
|
path: &'static Path,
|
||||||
app_state: Arc<AppState>,
|
|
||||||
cx: &mut ViewContext<Workspace>,
|
cx: &mut ViewContext<Workspace>,
|
||||||
default_content: impl 'static + Send + FnOnce() -> Rope,
|
default_content: impl 'static + Send + FnOnce() -> Rope,
|
||||||
) {
|
) {
|
||||||
|
let fs = workspace.app_state().fs.clone();
|
||||||
cx.spawn(|workspace, mut cx| async move {
|
cx.spawn(|workspace, mut cx| async move {
|
||||||
let fs = &app_state.fs;
|
|
||||||
if !fs.is_file(path).await {
|
if !fs.is_file(path).await {
|
||||||
fs.create_file(path, Default::default()).await?;
|
fs.create_file(path, Default::default()).await?;
|
||||||
fs.save(path, &default_content(), Default::default())
|
fs.save(path, &default_content(), Default::default())
|
||||||
@ -443,7 +460,7 @@ fn open_config_file(
|
|||||||
|
|
||||||
workspace
|
workspace
|
||||||
.update(&mut cx, |workspace, cx| {
|
.update(&mut cx, |workspace, cx| {
|
||||||
workspace.with_local_workspace(&app_state, cx, |workspace, cx| {
|
workspace.with_local_workspace(cx, |workspace, cx| {
|
||||||
workspace.open_paths(vec![path.to_path_buf()], false, cx)
|
workspace.open_paths(vec![path.to_path_buf()], false, cx)
|
||||||
})
|
})
|
||||||
})?
|
})?
|
||||||
@ -454,20 +471,15 @@ fn open_config_file(
|
|||||||
.detach_and_log_err(cx)
|
.detach_and_log_err(cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn open_log_file(
|
fn open_log_file(workspace: &mut Workspace, cx: &mut ViewContext<Workspace>) {
|
||||||
workspace: &mut Workspace,
|
|
||||||
app_state: Arc<AppState>,
|
|
||||||
cx: &mut ViewContext<Workspace>,
|
|
||||||
) {
|
|
||||||
const MAX_LINES: usize = 1000;
|
const MAX_LINES: usize = 1000;
|
||||||
|
|
||||||
workspace
|
workspace
|
||||||
.with_local_workspace(&app_state.clone(), cx, move |_, cx| {
|
.with_local_workspace(cx, move |workspace, cx| {
|
||||||
|
let fs = workspace.app_state().fs.clone();
|
||||||
cx.spawn(|workspace, mut cx| async move {
|
cx.spawn(|workspace, mut cx| async move {
|
||||||
let (old_log, new_log) = futures::join!(
|
let (old_log, new_log) =
|
||||||
app_state.fs.load(&paths::OLD_LOG),
|
futures::join!(fs.load(&paths::OLD_LOG), fs.load(&paths::LOG));
|
||||||
app_state.fs.load(&paths::LOG)
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut lines = VecDeque::with_capacity(MAX_LINES);
|
let mut lines = VecDeque::with_capacity(MAX_LINES);
|
||||||
for line in old_log
|
for line in old_log
|
||||||
@ -512,12 +524,9 @@ fn open_log_file(
|
|||||||
.detach();
|
.detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn open_telemetry_log_file(
|
fn open_telemetry_log_file(workspace: &mut Workspace, cx: &mut ViewContext<Workspace>) {
|
||||||
workspace: &mut Workspace,
|
workspace.with_local_workspace(cx, move |workspace, cx| {
|
||||||
app_state: Arc<AppState>,
|
let app_state = workspace.app_state().clone();
|
||||||
cx: &mut ViewContext<Workspace>,
|
|
||||||
) {
|
|
||||||
workspace.with_local_workspace(&app_state.clone(), cx, move |_, cx| {
|
|
||||||
cx.spawn(|workspace, mut cx| async move {
|
cx.spawn(|workspace, mut cx| async move {
|
||||||
async fn fetch_log_string(app_state: &Arc<AppState>) -> Option<String> {
|
async fn fetch_log_string(app_state: &Arc<AppState>) -> Option<String> {
|
||||||
let path = app_state.client.telemetry().log_file_path()?;
|
let path = app_state.client.telemetry().log_file_path()?;
|
||||||
@ -573,18 +582,18 @@ fn open_telemetry_log_file(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn open_bundled_file(
|
fn open_bundled_file(
|
||||||
app_state: Arc<AppState>,
|
workspace: &mut Workspace,
|
||||||
asset_path: &'static str,
|
asset_path: &'static str,
|
||||||
title: &'static str,
|
title: &'static str,
|
||||||
language: &'static str,
|
language: &'static str,
|
||||||
cx: &mut ViewContext<Workspace>,
|
cx: &mut ViewContext<Workspace>,
|
||||||
) {
|
) {
|
||||||
let language = app_state.languages.language_for_name(language);
|
let language = workspace.app_state().languages.language_for_name(language);
|
||||||
cx.spawn(|workspace, mut cx| async move {
|
cx.spawn(|workspace, mut cx| async move {
|
||||||
let language = language.await.log_err();
|
let language = language.await.log_err();
|
||||||
workspace
|
workspace
|
||||||
.update(&mut cx, |workspace, cx| {
|
.update(&mut cx, |workspace, cx| {
|
||||||
workspace.with_local_workspace(&app_state, cx, |workspace, cx| {
|
workspace.with_local_workspace(cx, |workspace, cx| {
|
||||||
let project = workspace.project();
|
let project = workspace.project();
|
||||||
let buffer = project.update(cx, |project, cx| {
|
let buffer = project.update(cx, |project, cx| {
|
||||||
let text = Assets::get(asset_path)
|
let text = Assets::get(asset_path)
|
||||||
@ -815,8 +824,12 @@ mod tests {
|
|||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
async fn test_new_empty_workspace(cx: &mut TestAppContext) {
|
async fn test_new_empty_workspace(cx: &mut TestAppContext) {
|
||||||
let app_state = init(cx);
|
let app_state = init(cx);
|
||||||
cx.update(|cx| open_new(&app_state, cx, |_, cx| cx.dispatch_action(NewFile)))
|
cx.update(|cx| {
|
||||||
.await;
|
open_new(&app_state, cx, |workspace, cx| {
|
||||||
|
Editor::new_file(workspace, &Default::default(), cx)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.await;
|
||||||
|
|
||||||
let window_id = *cx.window_ids().first().unwrap();
|
let window_id = *cx.window_ids().first().unwrap();
|
||||||
let workspace = cx
|
let workspace = cx
|
||||||
|
Loading…
Reference in New Issue
Block a user