Convert copilot popup to modal

This commit is contained in:
Piotr Osiewicz 2024-01-05 16:27:52 +01:00
parent 3e8e1c6404
commit 0ce94fc791
3 changed files with 39 additions and 87 deletions

View file

@ -13,6 +13,7 @@ use language::{
File, Language,
};
use settings::{update_settings_file, Settings, SettingsStore};
use sign_in::CopilotCodeVerification;
use std::{path::Path, sync::Arc};
use util::{paths, ResultExt};
use workspace::{
@ -27,10 +28,6 @@ const COPILOT_SETTINGS_URL: &str = "https://github.com/settings/copilot";
const COPILOT_STARTING_TOAST_ID: usize = 1337;
const COPILOT_ERROR_TOAST_ID: usize = 1338;
pub fn init(cx: &mut AppContext) {
sign_in::init(cx);
}
pub struct CopilotButton {
editor_subscription: Option<(Subscription, usize)>,
editor_enabled: Option<bool>,
@ -337,7 +334,9 @@ fn initiate_sign_in(cx: &mut WindowContext) {
return;
};
let status = copilot.read(cx).status();
let Some(workspace) = cx.window_handle().downcast::<Workspace>() else {
return;
};
match status {
Status::Starting { task } => {
let Some(workspace) = cx.window_handle().downcast::<Workspace>() else {
@ -376,9 +375,10 @@ fn initiate_sign_in(cx: &mut WindowContext) {
.detach();
}
_ => {
copilot
.update(cx, |copilot, cx| copilot.sign_in(cx))
.detach_and_log_err(cx);
copilot.update(cx, |this, cx| this.sign_in(cx)).detach();
workspace.update(cx, |this, cx| {
this.toggle_modal(cx, |cx| CopilotCodeVerification::new(&copilot, cx));
});
}
}
}

View file

@ -1,91 +1,49 @@
use copilot::{request::PromptUserDeviceFlow, Copilot, Status};
use gpui::{
div, size, svg, AppContext, Bounds, ClipboardItem, Element, GlobalPixels, InteractiveElement,
IntoElement, ParentElement, Point, Render, Styled, ViewContext, VisualContext, WindowBounds,
div, size, svg, AppContext, Bounds, ClipboardItem, DismissEvent, Element, EventEmitter,
FocusHandle, FocusableView, GlobalPixels, InteractiveElement, IntoElement, Model,
ParentElement, Point, Render, Styled, Subscription, ViewContext, VisualContext, WindowBounds,
WindowHandle, WindowKind, WindowOptions,
};
use ui::{prelude::*, Button, Icon, Label};
use workspace::ModalView;
const COPILOT_SIGN_UP_URL: &'static str = "https://github.com/features/copilot";
pub fn init(cx: &mut AppContext) {
if let Some(copilot) = Copilot::global(cx) {
let mut verification_window: Option<WindowHandle<CopilotCodeVerification>> = None;
cx.observe(&copilot, move |copilot, cx| {
let status = copilot.read(cx).status();
match &status {
crate::Status::SigningIn { prompt } => {
if let Some(window) = verification_window.as_mut() {
let updated = window
.update(cx, |verification, cx| {
verification.set_status(status.clone(), cx);
cx.activate_window();
})
.is_ok();
if !updated {
verification_window = Some(create_copilot_auth_window(cx, &status));
}
} else if let Some(_prompt) = prompt {
verification_window = Some(create_copilot_auth_window(cx, &status));
}
}
Status::Authorized | Status::Unauthorized => {
if let Some(window) = verification_window.as_ref() {
window
.update(cx, |verification, cx| {
verification.set_status(status, cx);
cx.activate(true);
cx.activate_window();
})
.ok();
}
}
_ => {
if let Some(code_verification) = verification_window.take() {
code_verification
.update(cx, |_, cx| cx.remove_window())
.ok();
}
}
}
})
.detach();
}
}
fn create_copilot_auth_window(
cx: &mut AppContext,
status: &Status,
) -> WindowHandle<CopilotCodeVerification> {
let window_size = size(GlobalPixels::from(400.), GlobalPixels::from(480.));
let window_options = WindowOptions {
bounds: WindowBounds::Fixed(Bounds::new(Point::default(), window_size)),
titlebar: None,
center: true,
focus: true,
show: true,
kind: WindowKind::PopUp,
is_movable: true,
display_id: None,
};
let window = cx.open_window(window_options, |cx| {
cx.new_view(|_| CopilotCodeVerification::new(status.clone()))
});
window
}
pub fn init(cx: &mut AppContext) {}
pub struct CopilotCodeVerification {
status: Status,
connect_clicked: bool,
focus_handle: FocusHandle,
_subscription: Subscription,
}
//impl ModalView for CopilotCodeVerification {}
impl FocusableView for CopilotCodeVerification {
fn focus_handle(&self, cx: &AppContext) -> gpui::FocusHandle {
self.focus_handle.clone()
}
}
impl EventEmitter<DismissEvent> for CopilotCodeVerification {}
impl ModalView for CopilotCodeVerification {}
impl CopilotCodeVerification {
pub fn new(status: Status) -> Self {
pub(crate) fn new(copilot: &Model<Copilot>, cx: &mut ViewContext<Self>) -> Self {
let status = copilot.read(cx).status();
Self {
status,
connect_clicked: false,
focus_handle: cx.focus_handle(),
_subscription: cx.observe(copilot, |this, copilot, cx| {
let status = copilot.read(cx).status();
match status {
Status::Authorized | Status::Unauthorized | Status::SigningIn { .. } => {
this.set_status(status, cx)
}
_ => cx.emit(DismissEvent),
}
}),
}
}
@ -159,10 +117,7 @@ impl CopilotCodeVerification {
.child(Label::new(
"You can update your settings or sign out from the Copilot menu in the status bar.",
))
.child(
Button::new("copilot-enabled-done-button", "Done")
.on_click(|_, cx| cx.remove_window()),
)
.child(Button::new("copilot-enabled-done-button", "Done").on_click(|_, cx| {}))
}
fn render_unauthorized_modal() -> impl Element {
@ -175,10 +130,8 @@ impl CopilotCodeVerification {
.color(Color::Warning),
)
.child(
Button::new("copilot-subscribe-button", "Subscibe on Github").on_click(|_, cx| {
cx.remove_window();
cx.open_url(COPILOT_SIGN_UP_URL)
}),
Button::new("copilot-subscribe-button", "Subscibe on Github")
.on_click(|_, cx| cx.open_url(COPILOT_SIGN_UP_URL)),
)
}
}

View file

@ -158,7 +158,6 @@ fn main() {
node_runtime.clone(),
cx,
);
copilot_button::init(cx);
assistant::init(cx);
cx.spawn(|_| watch_languages(fs.clone(), languages.clone()))