commit 5888af48e2a36555fc273c795d75aba44f26039e
parent 0d64bb263df61730fb202f0dde55e79476c8359d
Author: triesap <tyson@radroots.org>
Date: Sat, 21 Mar 2026 12:58:12 +0000
ios: add remove-key action for local identities
- add the remove-key action to the ios backend and remove the selected local account back to setup
- add an ios unit test covering the generate-then-remove transition
- scope eframe features per launcher crate so the ios host build stays on the intended renderer path
- keep desktop and android launcher validation green after the feature split
Diffstat:
5 files changed, 51 insertions(+), 5 deletions(-)
diff --git a/Cargo.toml b/Cargo.toml
@@ -22,7 +22,7 @@ readme = "README.md"
[workspace.dependencies]
android_logger = "0.15.1"
directories = "6"
-eframe = { version = "0.33.3", default-features = false, features = ["android-game-activity", "default_fonts", "glow", "wgpu", "wayland", "x11"] }
+eframe = { version = "0.33.3", default-features = false, features = ["default_fonts"] }
egui = { version = "0.33.3", features = ["serde"] }
image = { version = "0.25.10", default-features = false, features = ["ico", "png"] }
jni = "0.21.1"
diff --git a/crates/android/Cargo.toml b/crates/android/Cargo.toml
@@ -15,7 +15,7 @@ path = "src/lib.rs"
crate-type = ["cdylib", "rlib"]
[dependencies]
-eframe.workspace = true
+eframe = { workspace = true, features = ["android-game-activity", "glow"] }
log.workspace = true
radroots-app-core = { path = "../core" }
radroots-identity.workspace = true
diff --git a/crates/desktop/Cargo.toml b/crates/desktop/Cargo.toml
@@ -16,7 +16,7 @@ workspace = true
[dependencies]
directories.workspace = true
-eframe.workspace = true
+eframe = { workspace = true, features = ["wgpu", "wayland", "x11"] }
egui.workspace = true
image.workspace = true
radroots-app-core = { path = "../core" }
diff --git a/crates/ios/Cargo.toml b/crates/ios/Cargo.toml
@@ -15,7 +15,7 @@ path = "src/lib.rs"
crate-type = ["staticlib", "rlib"]
[dependencies]
-eframe.workspace = true
+eframe = { workspace = true, features = ["wgpu"] }
radroots-app-apple-security.workspace = true
radroots-app-core = { path = "../core" }
radroots-identity.workspace = true
diff --git a/crates/ios/src/lib.rs b/crates/ios/src/lib.rs
@@ -5,7 +5,9 @@ use eframe::egui::ViewportBuilder;
#[cfg(any(target_os = "ios", test))]
use radroots_app_core::IdentityGateState;
#[cfg(target_os = "ios")]
-use radroots_app_core::{APP_NAME, RadrootsApp, RadrootsAppBackend, SetupActionState};
+use radroots_app_core::{
+ HomeActionState, RadrootsApp, RadrootsAppBackend, SetupActionState, APP_NAME,
+};
#[cfg(any(target_os = "ios", test))]
use radroots_nostr_accounts::prelude::{
RadrootsNostrAccountsManager, RadrootsNostrSelectedAccountStatus,
@@ -52,6 +54,22 @@ impl IosBackend {
.map_err(|source| source.to_string())?;
Self::identity_state_from_manager(manager)
}
+
+ fn remove_selected_local_identity(
+ manager: &RadrootsNostrAccountsManager,
+ ) -> Result<IdentityGateState, String> {
+ let Some(account_id) = manager
+ .selected_account_id()
+ .map_err(|source| source.to_string())?
+ else {
+ return Ok(IdentityGateState::Missing);
+ };
+
+ manager
+ .remove_account(&account_id)
+ .map_err(|source| source.to_string())?;
+ Self::identity_state_from_manager(manager)
+ }
}
#[cfg(target_os = "ios")]
@@ -73,6 +91,19 @@ impl RadrootsAppBackend for IosBackend {
let manager = Self::accounts_manager()?;
Self::generate_local_identity(&manager).map(Some)
}
+
+ fn home_remove_action_state(&self) -> Option<HomeActionState> {
+ Some(HomeActionState {
+ label: "Remove Key From This Device".to_owned(),
+ enabled: true,
+ pending: false,
+ })
+ }
+
+ fn request_home_remove_action(&self) -> Result<Option<IdentityGateState>, String> {
+ let manager = Self::accounts_manager()?;
+ Self::remove_selected_local_identity(&manager).map(Some)
+ }
}
#[cfg(target_os = "ios")]
@@ -152,4 +183,19 @@ mod tests {
assert!(!account_id.is_empty());
assert!(npub.starts_with("npub1"));
}
+
+ #[test]
+ fn local_identity_removal_transitions_back_to_missing() {
+ let manager = RadrootsNostrAccountsManager::new_in_memory();
+
+ IosBackend::generate_local_identity(&manager).expect("generate identity");
+ let state =
+ IosBackend::remove_selected_local_identity(&manager).expect("remove selected account");
+
+ assert_eq!(state, IdentityGateState::Missing);
+ assert_eq!(
+ manager.selected_account_id().expect("selected account"),
+ None
+ );
+ }
}