Skip to content

Commit 71096fd

Browse files
Claudius-Maginificentlklimekclaude
authored
chore(ui): remove the superseded standalone identities screen (#971)
The Identity Hub covers everything the standalone identities list did, and the nav has not offered a way to reach that list for some time. Four live controls still routed to it, though, and `set_main_screen` persists the choice — so finishing a wallet import and choosing "Create Identity" parked the user on a screen with nothing highlighted in the nav, there and on every later launch. Those controls now point at the hub, and the screen is gone. Rerouted to `RootScreenIdentityHub`: "Create Platform Identity" after wallet creation, "Create Identity" / "Load Existing Identity" on the import success screen, "Register DPNS Name" on the add-identity success screen, and the Register-DPNS breadcrumb. The seven `add_left_panel` arguments that named the retired route highlighted nothing; they now name the hub, matching what `keys_screen` already did. Encoding 0 is retired and decodes to `None`, so a returning user's persisted value falls through to the settings default. That default was DashPay, which is itself absent from the nav — it becomes the hub, matching `app::FALLBACK_ROOT_SCREEN`, under a regression test. `OnboardingAction::ImportIdentity` is dropped: it is absent from `ONBOARDING_CARDS` and constructed nowhere. The `nav_button_specs` doc claimed the retired routes stayed reachable via deep links and MCP tools. Neither exists: there is no URI handler anywhere, and `src/mcp/` and `src/bin/` reference no UI screen type. The deleted kittest file's three app-shell tests move to `startup.rs`; a fourth duplicated `startup::test_app_startup`. Its two Keys-popup regressions are already covered on the live path by `keys_screen.rs` and at model level in `encrypted_key_storage.rs`. Co-authored-by: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
1 parent 1bcb20a commit 71096fd

27 files changed

Lines changed: 155 additions & 1677 deletions

docs/user-stories.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -814,7 +814,7 @@ As a masternode operator, I want my previously scheduled DPNS votes to survive a
814814

815815
As a user who has requested a username that is not yet awarded, I want to see that the request is pending so that I am not told to "pick a username" for a name I have already chosen.
816816

817-
- A requested-but-unawarded name shows a "Pending" pill next to the identity — on both the Identities list and the Identity Home hero card.
817+
- A requested-but-unawarded name shows a "Pending" pill next to the identity — on both the Identity Home hero card and the Identity Settings tab.
818818
- The hero card shows the requested name with the pill instead of the "No username yet — Pick a username" prompt.
819819
- The onboarding checklist counts the submitted request as completing "Pick a username" while clearly stating that Dash masternodes are voting.
820820
- The pill's tooltip explains that Dash masternodes decide who receives the username and, when the decision time is known, gives an estimated decision time.

src/app.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ use crate::ui::components::{BannerHandle, MessageBanner, OptionBannerExt, Progre
2525
use crate::ui::contracts_documents::contracts_documents_screen::DocumentQueryScreen;
2626
use crate::ui::dashpay::{DashPayScreen, DashPaySubscreen, ProfileSearchScreen};
2727
use crate::ui::dpns::dpns_contested_names_screen::{DPNSScreen, DPNSSubscreen};
28-
use crate::ui::identities::identities_screen::IdentitiesScreen;
2928
use crate::ui::identity::identity_pill::shorten_id;
3029
use crate::ui::network_chooser_screen::{NetworkChooserScreen, chooser_network_label};
3130
use crate::ui::theme::ThemeMode;
@@ -1504,7 +1503,6 @@ impl AppState {
15041503

15051504
// All screens are initialized with the active context (chosen_network).
15061505
// They will get the right context via change_context() on network switch.
1507-
let identities_screen = IdentitiesScreen::new(&active_context);
15081506
let dpns_active_contests_screen = DPNSScreen::new(&active_context, DPNSSubscreen::Active);
15091507
let dpns_past_contests_screen = DPNSScreen::new(&active_context, DPNSSubscreen::Past);
15101508
let dpns_my_usernames_screen = DPNSScreen::new(&active_context, DPNSSubscreen::Owned);
@@ -1613,10 +1611,6 @@ impl AppState {
16131611
};
16141612

16151613
let main_screens: BTreeMap<RootScreenType, Screen> = [
1616-
(
1617-
RootScreenType::RootScreenIdentities,
1618-
Screen::IdentitiesScreen(identities_screen),
1619-
),
16201614
(
16211615
RootScreenType::RootScreenDPNSActiveContests,
16221616
Screen::DPNSScreen(dpns_active_contests_screen),

src/model/settings.rs

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ pub enum ThemeMode {
3939
#[derive(Debug, Clone, Copy, Ord, PartialOrd, Eq, PartialEq, Hash)]
4040
#[allow(clippy::enum_variant_names)]
4141
pub enum RootScreenType {
42-
RootScreenIdentities,
4342
RootScreenDPNSActiveContests,
4443
RootScreenDPNSPastContests,
4544
RootScreenDPNSOwnedNames,
@@ -62,10 +61,10 @@ pub enum RootScreenType {
6261
RootScreenToolsGroveSTARKScreen,
6362
RootScreenToolsAddressBalanceScreen,
6463
RootScreenDashpay,
65-
/// New unified Identities hub (Home · Contacts · Activity · Settings).
66-
/// Coexists with `RootScreenIdentities` and the DashPay entries while the legacy
67-
/// screens are still wired. Distinct variant so user selection, persistence, and
68-
/// left-nav highlighting stay independent.
64+
/// The unified Identities hub (Home · Contacts · Activity · Settings), and
65+
/// the single user-facing `Identities` nav entry. Distinct variant so user
66+
/// selection, persistence, and left-nav highlighting stay independent of the
67+
/// DashPay entries it coexists with.
6968
RootScreenIdentityHub,
7069
/// Masternodes section (Expert-Mode gated). Node-operator surface for
7170
/// loading masternode/evonode identities, DPNS-contest voting, and
@@ -78,7 +77,7 @@ impl RootScreenType {
7877
/// Convert `RootScreenType` to an integer
7978
pub fn to_int(self) -> u32 {
8079
match self {
81-
RootScreenType::RootScreenIdentities => 0,
80+
// 0 used to be the standalone Identities screen
8281
RootScreenType::RootScreenDPNSActiveContests => 1,
8382
RootScreenType::RootScreenDPNSPastContests => 2,
8483
RootScreenType::RootScreenDPNSOwnedNames => 3,
@@ -113,7 +112,7 @@ impl RootScreenType {
113112
/// Convert an integer to a `RootScreenType`
114113
pub fn from_int(value: u32) -> Option<Self> {
115114
match value {
116-
0 => Some(RootScreenType::RootScreenIdentities),
115+
// 0 used to be the standalone Identities screen
117116
1 => Some(RootScreenType::RootScreenDPNSActiveContests),
118117
2 => Some(RootScreenType::RootScreenDPNSPastContests),
119118
3 => Some(RootScreenType::RootScreenDPNSOwnedNames),
@@ -180,6 +179,19 @@ mod root_screen_type_tests {
180179
fn from_int_returns_none_for_unknown_value() {
181180
assert!(RootScreenType::from_int(9999).is_none());
182181
}
182+
183+
/// Encoding 0 belonged to the standalone Identities screen, so it decodes
184+
/// to `None` and the settings default decides where those users land. That
185+
/// default must be the Identities hub: any other destination drops someone
186+
/// who was last on an identities screen onto an unrelated section.
187+
#[test]
188+
fn the_retired_identities_encoding_falls_back_to_the_hub() {
189+
assert!(RootScreenType::from_int(0).is_none());
190+
assert_eq!(
191+
super::AppSettings::default().root_screen_type,
192+
RootScreenType::RootScreenIdentityHub
193+
);
194+
}
183195
}
184196

185197
/// Application-level user preferences.
@@ -237,7 +249,9 @@ impl Default for AppSettings {
237249
fn default() -> Self {
238250
Self {
239251
network: Network::Mainnet,
240-
root_screen_type: RootScreenType::RootScreenDashpay,
252+
// Matches `app::FALLBACK_ROOT_SCREEN`: the one nav entry every
253+
// install has, and where an undecodable persisted value lands.
254+
root_screen_type: RootScreenType::RootScreenIdentityHub,
241255
dash_qt_path: detect_dash_qt_path(),
242256
overwrite_dash_conf: true,
243257
disable_zmq: false,
@@ -486,7 +500,7 @@ mod tests {
486500
fn settings_round_trip_through_wire() {
487501
let s = AppSettings {
488502
network: Network::Testnet,
489-
root_screen_type: RootScreenType::RootScreenIdentities,
503+
root_screen_type: RootScreenType::RootScreenIdentityHub,
490504
dash_qt_path: Some(PathBuf::from("/tmp/dash-qt")),
491505
overwrite_dash_conf: false,
492506
disable_zmq: true,

src/ui/components/left_panel.rs

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,9 @@ use std::sync::Arc;
1616
/// optional feature gate)`. Entries whose feature gate evaluates to false are
1717
/// filtered out at render time.
1818
///
19-
/// The former standalone `Identities` ([`RootScreenType::RootScreenIdentities`])
20-
/// and `Dashpay` ([`RootScreenType::RootScreenDashPayProfile`]) entries are
21-
/// intentionally hidden from the nav; their screens, routes, and backend paths
22-
/// stay intact and remain reachable through other means (deep links, MCP tools,
23-
/// direct screen construction). The Identities hub
19+
/// `Dashpay` ([`RootScreenType::RootScreenDashPayProfile`]) is intentionally
20+
/// absent: its screens and backend paths stay wired, reached from the Identity
21+
/// Hub rather than from the nav. The hub
2422
/// ([`RootScreenType::RootScreenIdentityHub`]) is the single user-facing
2523
/// `Identities` entry.
2624
fn nav_button_specs() -> &'static [(
@@ -370,18 +368,12 @@ pub fn add_left_panel(
370368
mod tests {
371369
use super::*;
372370

373-
/// The nav sidebar hides the legacy standalone `Identities` and `Dashpay`
374-
/// entries and surfaces the Identity Hub as the single `Identities` entry.
371+
/// The nav sidebar hides the `Dashpay` entry and surfaces the Identity Hub
372+
/// as the single `Identities` entry.
375373
#[test]
376-
fn nav_hides_legacy_identities_and_dashpay_and_labels_hub_as_identities() {
374+
fn nav_hides_dashpay_and_labels_hub_as_identities() {
377375
let specs = nav_button_specs();
378376

379-
assert!(
380-
!specs
381-
.iter()
382-
.any(|(_, screen, _, _)| *screen == RootScreenType::RootScreenIdentities),
383-
"the legacy standalone Identities entry must be hidden from the nav"
384-
);
385377
assert!(
386378
!specs
387379
.iter()

src/ui/identities/add_existing_identity_screen.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1033,7 +1033,7 @@ impl ScreenLike for AddExistingIdentityScreen {
10331033
action |= add_left_panel(
10341034
ui,
10351035
&self.app_context,
1036-
crate::ui::RootScreenType::RootScreenIdentities,
1036+
crate::ui::RootScreenType::RootScreenIdentityHub,
10371037
);
10381038

10391039
action |= island_central_panel(ui, |ui| {

src/ui/identities/add_new_identity_screen/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1609,7 +1609,7 @@ impl ScreenLike for AddNewIdentityScreen {
16091609
action |= add_left_panel(
16101610
ui,
16111611
&self.app_context,
1612-
crate::ui::RootScreenType::RootScreenIdentities,
1612+
crate::ui::RootScreenType::RootScreenIdentityHub,
16131613
);
16141614

16151615
let mut request_asset_lock_balance = false;

src/ui/identities/add_new_identity_screen/success_screen.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ impl AddNewIdentityScreen {
3636
screen.show_identity_selector = false;
3737
}
3838
return AppAction::PopThenAddScreenToMainScreen(
39-
RootScreenType::RootScreenIdentities,
39+
RootScreenType::RootScreenIdentityHub,
4040
Screen::RegisterDpnsNameScreen(screen),
4141
);
4242
}

0 commit comments

Comments
 (0)