add an onboarding informing Windows of better support in WSL (#4697)

This commit is contained in:
iceweasel-oai
2025-10-04 17:41:40 -07:00
committed by GitHub
parent 0ad1b0782b
commit 6c2969d22d
7 changed files with 341 additions and 9 deletions

View File

@@ -19,6 +19,7 @@ use crate::onboarding::auth::SignInState;
use crate::onboarding::trust_directory::TrustDirectorySelection;
use crate::onboarding::trust_directory::TrustDirectoryWidget;
use crate::onboarding::welcome::WelcomeWidget;
use crate::onboarding::windows::WindowsSetupWidget;
use crate::tui::FrameRequester;
use crate::tui::Tui;
use crate::tui::TuiEvent;
@@ -28,6 +29,7 @@ use std::sync::RwLock;
#[allow(clippy::large_enum_variant)]
enum Step {
Windows(WindowsSetupWidget),
Welcome(WelcomeWidget),
Auth(AuthModeWidget),
TrustDirectory(TrustDirectoryWidget),
@@ -38,6 +40,7 @@ pub(crate) trait KeyboardHandler {
fn handle_paste(&mut self, _pasted: String) {}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum StepState {
Hidden,
InProgress,
@@ -52,9 +55,11 @@ pub(crate) struct OnboardingScreen {
request_frame: FrameRequester,
steps: Vec<Step>,
is_done: bool,
windows_install_selected: bool,
}
pub(crate) struct OnboardingScreenArgs {
pub show_windows_wsl_screen: bool,
pub show_trust_screen: bool,
pub show_login_screen: bool,
pub login_status: LoginStatus,
@@ -62,9 +67,15 @@ pub(crate) struct OnboardingScreenArgs {
pub config: Config,
}
pub(crate) struct OnboardingResult {
pub directory_trust_decision: Option<TrustDirectorySelection>,
pub windows_install_selected: bool,
}
impl OnboardingScreen {
pub(crate) fn new(tui: &mut Tui, args: OnboardingScreenArgs) -> Self {
let OnboardingScreenArgs {
show_windows_wsl_screen,
show_trust_screen,
show_login_screen,
login_status,
@@ -73,10 +84,14 @@ impl OnboardingScreen {
} = args;
let cwd = config.cwd.clone();
let codex_home = config.codex_home;
let mut steps: Vec<Step> = vec![Step::Welcome(WelcomeWidget::new(
let mut steps: Vec<Step> = Vec::new();
if show_windows_wsl_screen {
steps.push(Step::Windows(WindowsSetupWidget::new(codex_home.clone())));
}
steps.push(Step::Welcome(WelcomeWidget::new(
!matches!(login_status, LoginStatus::NotAuthenticated),
tui.frame_requester(),
))];
)));
if show_login_screen {
steps.push(Step::Auth(AuthModeWidget {
request_frame: tui.frame_requester(),
@@ -110,6 +125,7 @@ impl OnboardingScreen {
request_frame: tui.frame_requester(),
steps,
is_done: false,
windows_install_selected: false,
}
}
@@ -163,6 +179,10 @@ impl OnboardingScreen {
})
.flatten()
}
pub fn windows_install_selected(&self) -> bool {
self.windows_install_selected
}
}
impl KeyboardHandler for OnboardingScreen {
@@ -200,6 +220,14 @@ impl KeyboardHandler for OnboardingScreen {
}
}
};
if self
.steps
.iter()
.any(|step| matches!(step, Step::Windows(widget) if widget.exit_requested()))
{
self.windows_install_selected = true;
self.is_done = true;
}
self.request_frame.schedule_frame();
}
@@ -281,6 +309,7 @@ impl WidgetRef for &OnboardingScreen {
impl KeyboardHandler for Step {
fn handle_key_event(&mut self, key_event: KeyEvent) {
match self {
Step::Windows(widget) => widget.handle_key_event(key_event),
Step::Welcome(widget) => widget.handle_key_event(key_event),
Step::Auth(widget) => widget.handle_key_event(key_event),
Step::TrustDirectory(widget) => widget.handle_key_event(key_event),
@@ -289,6 +318,7 @@ impl KeyboardHandler for Step {
fn handle_paste(&mut self, pasted: String) {
match self {
Step::Windows(_) => {}
Step::Welcome(_) => {}
Step::Auth(widget) => widget.handle_paste(pasted),
Step::TrustDirectory(widget) => widget.handle_paste(pasted),
@@ -299,6 +329,7 @@ impl KeyboardHandler for Step {
impl StepStateProvider for Step {
fn get_step_state(&self) -> StepState {
match self {
Step::Windows(w) => w.get_step_state(),
Step::Welcome(w) => w.get_step_state(),
Step::Auth(w) => w.get_step_state(),
Step::TrustDirectory(w) => w.get_step_state(),
@@ -309,6 +340,9 @@ impl StepStateProvider for Step {
impl WidgetRef for Step {
fn render_ref(&self, area: Rect, buf: &mut Buffer) {
match self {
Step::Windows(widget) => {
widget.render_ref(area, buf);
}
Step::Welcome(widget) => {
widget.render_ref(area, buf);
}
@@ -325,7 +359,7 @@ impl WidgetRef for Step {
pub(crate) async fn run_onboarding_app(
args: OnboardingScreenArgs,
tui: &mut Tui,
) -> Result<Option<crate::onboarding::TrustDirectorySelection>> {
) -> Result<OnboardingResult> {
use tokio_stream::StreamExt;
let mut onboarding_screen = OnboardingScreen::new(tui, args);
@@ -386,5 +420,8 @@ pub(crate) async fn run_onboarding_app(
}
}
}
Ok(onboarding_screen.directory_trust_decision())
Ok(OnboardingResult {
directory_trust_decision: onboarding_screen.directory_trust_decision(),
windows_install_selected: onboarding_screen.windows_install_selected(),
})
}