diff --git a/proto/anki/launcher.proto b/proto/anki/launcher.proto index e3f2e2eb9..3e4f3cadb 100644 --- a/proto/anki/launcher.proto +++ b/proto/anki/launcher.proto @@ -18,6 +18,8 @@ service LauncherService { rpc WindowReady(generic.Empty) returns (generic.Empty); rpc ZoomWebview(ZoomWebviewRequest) returns (generic.Empty); + rpc GetState(generic.Empty) returns (State); + rpc GetAvailableVersions(generic.Empty) returns (Versions); rpc GetExistingVersions(generic.Empty) returns (ExistingVersions); @@ -109,3 +111,16 @@ message ExistingVersions { optional Version previous = 2; bool pyproject_modified_by_user = 3; } + +message NormalState { + Options options = 1; +} + +message State { + oneof kind { + string os_unsupported = 1; + string unknown_error = 2; + NormalState normal = 3; + google.protobuf.Empty uninstall = 4; + } +} diff --git a/qt/launcher-gui/src-tauri/src/app.rs b/qt/launcher-gui/src-tauri/src/app.rs index 578ae8c32..862f2932e 100644 --- a/qt/launcher-gui/src-tauri/src/app.rs +++ b/qt/launcher-gui/src-tauri/src/app.rs @@ -20,7 +20,7 @@ use crate::uv; pub const PROTOCOL: &str = "anki"; pub fn init() -> Option { - let mut state = State::init().unwrap_or_else(State::Error); + let mut state = State::init().unwrap_or_else(State::UnknownError); match state { State::Normal(ref mut state) => state.check_versions(), diff --git a/qt/launcher-gui/src-tauri/src/commands.rs b/qt/launcher-gui/src-tauri/src/commands.rs index faa97330f..21f3ddad8 100644 --- a/qt/launcher-gui/src-tauri/src/commands.rs +++ b/qt/launcher-gui/src-tauri/src/commands.rs @@ -4,13 +4,16 @@ use anki_proto::generic; use anki_proto::launcher::get_langs_response; use anki_proto::launcher::get_mirrors_response; +use anki_proto::launcher::state::Kind as StateProtoKind; use anki_proto::launcher::ChooseVersionRequest; use anki_proto::launcher::ChooseVersionResponse; use anki_proto::launcher::GetLangsResponse; use anki_proto::launcher::GetMirrorsResponse; use anki_proto::launcher::I18nResourcesRequest; use anki_proto::launcher::Mirror; +use anki_proto::launcher::NormalState as NormalStateProto; use anki_proto::launcher::Options; +use anki_proto::launcher::State as StateProto; use anki_proto::launcher::ZoomWebviewRequest; use anyhow::anyhow; use anyhow::Context; @@ -88,6 +91,23 @@ pub async fn set_lang( Ok(()) } +pub async fn get_state( + app: AppHandle, + _window: WebviewWindow, +) -> Result { + let state = app.state::(); + let kind = match &*state { + State::LaunchAnki(_) => unreachable!(), + State::OsUnsupported(e) => StateProtoKind::OsUnsupported(format!("{e:?}")), + State::UnknownError(e) => StateProtoKind::UnknownError(format!("{e:?}")), + State::Uninstall(_) => StateProtoKind::Uninstall(()), + State::Normal(normal) => StateProtoKind::Normal(NormalStateProto { + options: Some((&normal.initial_options).into()), + }), + }; + Ok(StateProto { kind: Some(kind) }) +} + pub async fn get_mirrors( app: AppHandle, _window: WebviewWindow, diff --git a/qt/launcher-gui/src-tauri/src/state.rs b/qt/launcher-gui/src-tauri/src/state.rs index f56a23447..794bb2fab 100644 --- a/qt/launcher-gui/src-tauri/src/state.rs +++ b/qt/launcher-gui/src-tauri/src/state.rs @@ -73,8 +73,8 @@ impl From for State { pub enum State { LaunchAnki(Arc), - #[allow(dead_code)] // TODO: use - Error(anyhow::Error), + OsUnsupported(anyhow::Error), + UnknownError(anyhow::Error), Uninstall(Arc), Normal(NormalState), } diff --git a/qt/launcher-gui/src-tauri/src/uv.rs b/qt/launcher-gui/src-tauri/src/uv.rs index 227bf3f3f..daf33c464 100644 --- a/qt/launcher-gui/src-tauri/src/uv.rs +++ b/qt/launcher-gui/src-tauri/src/uv.rs @@ -734,7 +734,9 @@ impl crate::state::State { let _ = remove_file(&paths.launcher_trigger_file); } - ensure_os_supported()?; + if let Err(e) = ensure_os_supported() { + return Ok(Self::OsUnsupported(e)); + } Ok(Self::Normal(paths.into())) }