Skip to content

feat: setting UI redesign#721

Merged
Syn-McJ merged 15 commits into
dashpay:masterfrom
Syn-McJ:feat/settings-ui
Jul 28, 2025
Merged

feat: setting UI redesign#721
Syn-McJ merged 15 commits into
dashpay:masterfrom
Syn-McJ:feat/settings-ui

Conversation

@Syn-McJ
Copy link
Copy Markdown
Member

@Syn-McJ Syn-McJ commented Jul 25, 2025

Issue being fixed or feature implemented

We want to update the UI for the menu screens.

What was done?

  • Refactor from Objective-C to Swift
  • Implement new UI in SwiftUI
  • Simplify navigation graph across redesigned screens

How Has This Been Tested?

Breaking Changes

Checklist:

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated relevant unit/integration/functional/e2e tests
  • I have made corresponding changes to the documentation

For repository code-owners and collaborators only

  • I have assigned this pull request to a milestone

Summary by CodeRabbit

  • New Features

    • Introduced redesigned main menu, security, settings, and tools screens using SwiftUI for a more modern and consistent user experience.
    • Added new menu icons and updated several image assets for improved visual clarity.
    • Enhanced CSV export functionality, including new export options in settings and tools menus.
    • Improved biometric authentication and balance hiding controls in security settings.
    • Expanded localization support with new and updated translations.
  • Bug Fixes

    • Ensured consistent minimum height for transaction preview items in transaction lists.
  • Refactor

    • Migrated main menu, security, settings, and tools menus from legacy Objective-C to Swift/SwiftUI, streamlining codebase and UI components.
    • Updated menu navigation and delegate protocols for improved maintainability and Swift interoperability.
  • Style

    • Refreshed UI layouts and styles for menu items and screens.
  • Documentation

    • Updated localization files with clearer biometric access instructions and new feature strings.
  • Chores

    • Updated marketing version for watchOS targets.
    • Cleaned up and reorganized project structure and asset catalogs.

@Syn-McJ Syn-McJ requested a review from HashEngineering July 25, 2025 11:08
@Syn-McJ Syn-McJ self-assigned this Jul 25, 2025
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jul 25, 2025

Walkthrough

This update performs a major refactor of the DashWallet app's menu and settings architecture. It migrates main menu, security, settings, and tools components from Objective-C and UIKit-based implementations to new Swift and SwiftUI-based files and view models. Numerous legacy Objective-C classes, protocols, and XIBs are removed, replaced by SwiftUI screens and observable view models. Asset catalog entries and localization files are also updated, with new images and revised translation strings.

Changes

Files/Paths Change Summary
DashWallet.xcodeproj/project.pbxproj Remove legacy Objective-C menu/settings files; add new Swift/SwiftUI files; update groups; bump watchOS version
.../AppAssets.xcassets/Menu/image.*.imageset/Contents.json Add or update asset catalog JSON for new menu icons at multiple scales
.../Models/Voting/VotingPrefs.swift Remove Objective-C wrapper class for voting preferences
.../UI/CrowdNode/Tx Details/GroupedTransactionsScreen.swift Add minHeight constraint to transaction preview
.../UI/DashPay/Menu/DWMainMenuViewController+DashPay.swift Remove extension handling profile editing and credit logic
.../UI/DashPay/Profile/Edit Profile/RootEditProfileViewController.swift Remove @objc annotations from protocol/class declarations
.../UI/DashPay/Voting/UsernameVoting.storyboard Update filter icon image and color precision
.../UI/Home/HomeViewController+Shortcuts.swift Remove syncNow shortcut; switch network actions to async/await
.../UI/Home/Views/Home Balance View/BalanceModel.swift Sync isBalanceHidden with global option on reload
.../UI/Home/Views/HomeView.swift Add minHeight constraint to transaction preview
.../UI/Home/Views/Shortcuts/Models/ShortcutAction.swift Remove syncNow case from shortcut actions
.../UI/Main/MainTabbarController.swift Migrate to new MainMenuViewController and delegate; update method signatures
.../UI/Menu/Main/DWMainMenuViewController.{h,m} Remove main menu Objective-C controller implementation and interface
.../UI/Menu/Main/DWMainMenuViewControllerDelegate.h Remove main menu delegate protocol definition
.../UI/Menu/Main/MainMenuViewController.swift Add new SwiftUI-based MainMenuViewController and screen
.../UI/Menu/Main/MainMenuViewControllerDelegate.swift Add new Swift protocol for main menu delegate
.../UI/Menu/Main/MainMenuViewModel.swift Add new SwiftUI observable view model for main menu
.../UI/Menu/Main/Views/Cells/DWMainMenuTableViewCell.{m,xib} Remove main menu cell implementation and XIB
.../UI/Menu/Main/Views/MainMenuContentView.swift Remove main menu content view (UIKit/UITableView)
.../UI/Menu/Main/Views/Model/DWMainMenuItem.h Remove main menu item protocol and enum
.../UI/Menu/Main/Views/Model/DWMainMenuModel.{h,m} Remove main menu model implementation and interface
.../UI/Menu/MenuItemModel.swift Update to Hashable; remove showChevron; adjust isToggled property
.../UI/Menu/Security/DWSecurityMenuModel.{h,m} Remove security menu model implementation and interface
.../UI/Menu/Security/DWSecurityMenuViewController.{h,m} Remove security menu controller implementation and interface
.../UI/Menu/Security/ResetWalletInfo/DWResetWalletInfoViewController.h Add NS_SWIFT_NAME(make()) to controller method
.../UI/Menu/Security/SecurityMenuScreen.swift Add new SwiftUI security menu screen
.../UI/Menu/Security/SecurityMenuViewModel.swift Add new SwiftUI observable view model for security menu
.../UI/Menu/Settings/DWSettingsMenuModel.{h,m} Remove settings menu model implementation and interface
.../UI/Menu/Settings/SettingsMenuViewController.swift Remove UIKit/SwiftUI hybrid settings menu controller
.../UI/Menu/Settings/SettingsMenuViewModel.swift Rename to SettingsMenuViewModel; refactor for async/await and CSV export
.../UI/Menu/Settings/SettingsScreen.swift Add new SwiftUI settings screen with navigation and alerts
.../UI/Menu/Tools/ToolsMenuViewController.swift Remove tools menu controller and SwiftUI content
.../UI/Menu/Tools/ToolsMenuScreen.swift Add new SwiftUI tools menu screen
.../UI/Menu/Tools/ToolsMenuViewModel.swift Add new SwiftUI observable view model for tools menu
.../UI/SwiftUI Components/MenuItem.swift Refactor MenuItem view to use Button; update layout and interaction logic
DashWallet/*.lproj/Localizable.strings Update localization: add/remove/refine strings for biometric access, menu, and support
dashwallet-Bridging-Header.h Remove menu/settings Objective-C imports; add new security/auth headers

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant MainMenuViewController (SwiftUI)
    participant MainMenuViewModel
    participant UIKitViewController

    User->>MainMenuViewController (SwiftUI): Tap menu item
    MainMenuViewController (SwiftUI)->>MainMenuViewModel: Handle menu action
    MainMenuViewModel->>MainMenuViewController (SwiftUI): Set navigationDestination
    MainMenuViewController (SwiftUI)->>UIKitViewController: Push/present corresponding screen
Loading
sequenceDiagram
    participant User
    participant SecurityMenuScreen (SwiftUI)
    participant SecurityMenuViewModel
    participant UIKitViewController

    User->>SecurityMenuScreen (SwiftUI): Tap security option
    SecurityMenuScreen (SwiftUI)->>SecurityMenuViewModel: Handle action
    SecurityMenuViewModel->>SecurityMenuScreen (SwiftUI): Set navigationDestination or show alert
    SecurityMenuScreen (SwiftUI)->>UIKitViewController: Push/present corresponding screen
Loading
sequenceDiagram
    participant User
    participant SettingsScreen (SwiftUI)
    participant SettingsMenuViewModel
    participant UIKitViewController

    User->>SettingsScreen (SwiftUI): Tap settings item
    SettingsScreen (SwiftUI)->>SettingsMenuViewModel: Handle action
    SettingsMenuViewModel->>SettingsScreen (SwiftUI): Set navigationDestination or show alert
    SettingsScreen (SwiftUI)->>UIKitViewController: Push/present corresponding screen or show activity sheet
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~75–120 minutes

Poem

Oh what a hop, what a leap, what a bound,
From Objective-C roots to new SwiftUI ground!
Menus and settings now fresh as the dew,
With icons and strings all sparkling and new.
The codebase is lighter, the future is bright—
This bunny approves, and hops with delight!
🐇✨

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 204

🔭 Outside diff range comments (3)
DashWallet/Resources/AppAssets.xcassets/Menu/image.change.pin.imageset/Contents.json (1)

1-24: Repeated generic filename pattern needs attention.

The JSON structure is technically correct, but using "Layer_1" as the filename for multiple different menu icons (also seen in recovery phrase asset) creates confusion. Each asset should have descriptive filenames that reflect their purpose, such as "change.pin" for this icon.

DashWallet/Sources/UI/DashPay/Voting/UsernameVoting.storyboard (1)

40-47: Ensure new image resource exists and size matches auto-layout.

The UIImageView now uses icon_filter_button, but the runtime resources section (line 623) declares the bitmap as 13×11.67 pt.
On @3x screens this becomes a non-integer pixel size → blurry rendering.

Consider supplying a 15×12 pt (or other even-pixel) base asset, or constrain the view with integer dimensions.

DashWallet/dashwallet-Bridging-Header.h (1)

61-61: Remove duplicate import of DWSecureWalletDelegate.h

The header file DWSecureWalletDelegate.h is imported twice - once on line 61 and again on line 176. Please remove one of these duplicate imports to maintain clean code organization.

Also applies to: 176-176

♻️ Duplicate comments (5)
DashWallet/sl_SI.lproj/Localizable.strings (5)

1000-1002: Same localisation gap as above – value left in English.
See comment on lines 334-336.


2051-2053: Same localisation gap as above – value left in English.
See comment on lines 334-336.


2072-2074: Same localisation gap as above – value left in English.
See comment on lines 334-336.


2371-2376: Same localisation gap as above – values left in English.
See comment on lines 334-336.


2814-2816: Same localisation gap as above – value left in English.
See comment on lines 334-336.

🧹 Nitpick comments (98)
DashWallet/sl.lproj/Localizable.strings (7)

17-24: New biometric-denial messages remain untranslated

Both updated strings keep the original English text. Consider providing proper Slovenian translations so the UX is consistent with the rest of the file.


334-336: Missing Slovenian translation for new key Biometrics Access Required

Add a localized value – for example:

-"Biometrics Access Required" = "Biometrics Access Required";
+"Biometrics Access Required" = "Potrebna je biometrična avtentikacija";

1001-1002: Full Resync key lacks localization

-"Full Resync" = "Full Resync";
+"Full Resync" = "Popolna ponovna sinhronizacija";

2051-2053: Provide translation for “Rescan Transactions (Suggested)”

-"Rescan Transactions (Suggested)" = "Rescan Transactions (Suggested)";
+"Rescan Transactions (Suggested)" = "Ponovno skeniranje transakcij (priporočeno)";

2072-2074: Resync Masternode List added without Slovenian copy

-"Resync Masternode List" = "Resync Masternode List";
+"Resync Masternode List" = "Ponovno sinhroniziraj seznam masternodov";

2371-2376: Successful purchase / Support keys untranslated

-"Successful purchase" = "Successful purchase";
-"Support" = "Support";
+"Successful purchase" = "Nakup uspešen";
+"Support" = "Podpora";

2815-2816: Generic “Voting” label untranslated

-"Voting" = "Voting";
+"Voting" = "Glasovanje";
DashWallet/Resources/AppAssets.xcassets/Menu/image.notifications.imageset/Contents.json (1)

1-24: Asset catalog structure is correct.

The JSON follows proper iOS asset catalog conventions with appropriate scale variants (1x, 2x, 3x) and universal idiom. The structure integrates well with the SwiftUI menu refactor.

Consider using more descriptive filenames like "notifications.png" instead of "Layer 1.png" to better reflect the asset's purpose, though the current naming is functional.

DashWallet/Resources/AppAssets.xcassets/Menu/image.network.monitor.imageset/Contents.json (1)

1-24: Asset structure is correct but naming is inconsistent.

The JSON follows proper iOS asset catalog conventions. However, the "Layer_1" filename pattern is inconsistent with other assets in this PR (some use "Layer 1" with spaces) and doesn't clearly describe the network monitor purpose.

Consider standardizing filename conventions across all menu assets and using descriptive names like "network_monitor.png" for better maintainability.

DashWallet/Resources/AppAssets.xcassets/Menu/image.advanced.security.imageset/Contents.json (1)

1-24: Good asset structure with descriptive naming.

The JSON structure is correct and uses descriptive filenames ("advanced security") that clearly indicate the asset's purpose. This is a good example of meaningful asset naming.

While this asset uses good descriptive naming, consider standardizing filename conventions across all menu assets in this PR (some use generic "Layer" names, others use underscores vs. spaces).

DashWallet/Resources/AppAssets.xcassets/Menu/image.masternode.keys.imageset/Contents.json (1)

4-16: Prefer descriptive filenames for easier asset maintenance

Using generic names like Layer_1.png, Layer_1@2x.png, etc. makes it harder to search or reason about assets later. Consider renaming the underlying files to something meaningful (e.g. masternode_keys.png, masternode_keys@2x.png, …) and updating the JSON accordingly.

DashWallet/Resources/AppAssets.xcassets/Menu/image.security.imageset/Contents.json (1)

4-16: Use a more explicit base filename than Vector.png

Vector.png does not convey the icon’s purpose. Renaming to something like security.png (and the scaled variants) will improve clarity when browsing the asset catalog.

DashWallet/Resources/AppAssets.xcassets/Menu/image.settings.imageset/Contents.json (1)

4-16: Optional: simplify encoded characters in filenames

The current filenames (Iconly_x2F_Bold_x2F_Setting.png, …) include the encoded slash marker x2F, which can be slightly noisy.
If project-wide searchability matters, consider shortening to settings.png, settings@2x.png, … while keeping the icon source reference in Git history.

DashWallet/Resources/AppAssets.xcassets/Menu/image.recovery.phrase.imageset/Contents.json (1)

1-24: Consider more descriptive asset filenames.

The JSON structure is correct, but the "Layer_1" filename pattern is generic and doesn't clearly indicate this is for the recovery phrase feature. Consider using more descriptive names like "recovery.phrase" for better maintainability.

DashWallet/Resources/AppAssets.xcassets/Menu/Image.face.id.imageset/Contents.json (1)

4-14: Consider more descriptive filenames for better maintainability.

While the JSON structure is correct, the generic filename "Layer 1.png" doesn't convey the icon's purpose. Consider using more descriptive names like "face-id.png" or "biometric-face-id.png" to improve code maintainability and reduce confusion during future updates.

-      "filename" : "Layer 1.png",
+      "filename" : "face-id.png",
-      "filename" : "Layer 1@2x.png",
+      "filename" : "face-id@2x.png",
-      "filename" : "Layer 1@3x.png",
+      "filename" : "face-id@3x.png",
DashWallet/Resources/AppAssets.xcassets/Menu/image.autohide.balance.imageset/Contents.json (1)

1-18: Mark icon as template for system tinting (optional).

Most menu glyphs in the project rely on system tint to match the current theme. Add

"template-rendering-intent" : "template"

to instruct Xcode to export the PDF/PNG as a template image.
Otherwise the icon will be rendered with its source colour and won’t follow dark-/light-mode tints.

DashWallet/Resources/AppAssets.xcassets/Menu/image.rescan.imageset/Contents.json (1)

1-18: Minor: make name consistent with other menu icons.

Other menu image sets use the pattern image.<feature>.imageset, but the filename inside this set is rescan.blockchain*.png.
Sticking to a single naming convention (e.g. prefix all files with image.) keeps asset folders searchable and avoids collisions.

DashWallet/Resources/AppAssets.xcassets/Menu/image.coinjoin.menu.imageset/Contents.json (1)

1-23: Consider more descriptive filenames.

The asset catalog structure is correct, but the generic "Layer_1" filenames are less descriptive than other menu assets (e.g., "Explore-Blue"). Consider using more descriptive names like "Coinjoin-Menu" for better asset management.

-      "filename" : "Layer_1.png",
+      "filename" : "Coinjoin-Menu.png",
-      "filename" : "Layer_1@2x.png",
+      "filename" : "Coinjoin-Menu@2x.png",
-      "filename" : "Layer_1@3x.png",
+      "filename" : "Coinjoin-Menu@3x.png",
DashWallet/mk.lproj/Localizable.strings (7)

333-337: New label “Biometrics Access Required” left in English
UI consistency suffers when headings are not translated. Supply a Macedonian value (e.g. "Потребен е пристап до биометрија").


1000-1002: “Full Resync” untranslated
End-user maintenance dialogs should appear in the selected locale. Please add a Macedonian translation.


2051-2053: “Rescan Transactions (Suggested)” still English
Translate the full label; avoid parentheses if not idiomatic in Macedonian.


2073-2074: “Resync Masternode List” not localised
Provide Macedonian wording (e.g. "Ресинхронизирај листа на мастернодови").


2371-2376: “Successful purchase” & “Support” remain English
Translate both strings to avoid fragments of English in success toasts and menu entries.


2814-2816: “Voting” header untranslated
This label appears in the new menu; translate it to keep the navigation consistent.


1-3176: General note on consistency
Roughly half of the file is already localised, but all newly added keys default to English. Establish a process so that every added string is passed through localisation before merge to prevent regression in UX quality.

DashWallet/hr.lproj/Localizable.strings (4)

17-18: Extended Face ID denial message still untranslated

Good to see the more descriptive sentence, but the Croatian .lproj continues to ship the English text ("%@ is not allowed to access Face ID. Allow Face ID access in Settings").
If the intent is to localise, this line needs translation; otherwise users on the hr locale will read English while the rest of the UI may be Croatian.


334-336: New key “Biometrics Access Required” is identical in key/value

Key and value are identical and English. If this string will be surfaced to end-users, please add the actual Croatian translation or mark it for later localisation to avoid appearing untranslated.


2051-2053: “Rescan Transactions (Suggested)” missing translation

If this appears in settings or an alert, consider adding the Croatian equivalent — e.g. “Ponovno skeniraj transakcije (preporučeno)”.


2371-2376: New strings “Successful purchase” / “Support”

  1. “Successful purchase” — consider “Kupnja uspješna”.
  2. “Support” — there are already longer variants (“Contact Support”, etc.). Re-verify that a single-word string doesn’t lead to inconsistent wording across the app.
DashWallet/nb.lproj/Localizable.strings (2)

334-336: Missing translation & potential duplication

"Biometrics Access Required" is added in English and may duplicate the meaning of the existing "Enable Face ID" / "Enable Touch ID" prompts.
Consider either translating it or re-using an existing key to avoid string proliferation.


2372-2376: Granularity of generic labels

“Successful purchase” and “Support” are generic labels. Check that they are not already present elsewhere under slightly different wording (“Purchase successful”, “Contact Support”) to keep the localisation file DRY and reduce translator workload.

DashWallet/sr.lproj/Localizable.strings (9)

17-18: Translate the updated Face ID denial message to Serbian

The key now shows the same English text on both sides, unlike the existing camera-permission string just below (line 20) which is translated.
For consistency across the UI, add a proper Serbian translation.

-"%@ is not allowed to access Face ID. Allow Face ID access in Settings" = "%@ is not allowed to access Face ID. Allow Face ID access in Settings";
+"%@ is not allowed to access Face ID. Allow Face ID access in Settings" = "%@ nema dozvolu za korišćenje Face ID. Dozvolite Face ID u Podešavanjima";

23-24: Translate the updated Touch ID denial message to Serbian

Same issue as above – English appears on both sides. Provide a localized string.

-"%@ is not allowed to access Touch ID. Allow Touch ID access in Settings" = "%@ is not allowed to access Touch ID. Allow Touch ID access in Settings";
+"%@ is not allowed to access Touch ID. Allow Touch ID access in Settings" = "%@ nema dozvolu za korišćenje Touch ID. Dozvolite Touch ID u Podešavanjima";

334-336: Add Serbian translation for the new biometrics string

-"Biometrics Access Required" = "Biometrics Access Required";
+"Biometrics Access Required" = "Potreban je biometrijski pristup";

1000-1002: Add Serbian translation for “Full Resync”

-"Full Resync" = "Full Resync";
+"Full Resync" = "Potpuna resinkronizacija";

2051-2053: Add Serbian translation for “Rescan Transactions (Suggested)”

-"Rescan Transactions (Suggested)" = "Rescan Transactions (Suggested)";
+"Rescan Transactions (Suggested)" = "Ponovo skeniraj transakcije (preporučeno)";

2072-2074: Add Serbian translation for “Resync Masternode List”

-"Resync Masternode List" = "Resync Masternode List";
+"Resync Masternode List" = "Ponovo sinhronizuj listu masternoda";

2372-2373: Add Serbian translation for “Successful purchase”

-"Successful purchase" = "Successful purchase";
+"Successful purchase" = "Uspešna kupovina";

2375-2376: Add Serbian translation for “Support”

-"Support" = "Support";
+"Support" = "Podrška";

2815-2816: Add Serbian translation for “Voting”

-"Voting" = "Voting";
+"Voting" = "Glasanje";
DashWallet/sl_SI.lproj/Localizable.strings (1)

334-336: New key is still English – localisation missing

"Biometrics Access Required" is added for the Slovene bundle but the value is left in English.
Unless English is the intended fallback, please provide the Slovene wording before shipping.

DashWallet/en.lproj/Localizable.strings (4)

16-24: Add missing terminal period and keep wording consistent

Both Face ID/Touch ID denial messages end without a full stop, breaking the general “sentence-ends-with-period” style used elsewhere (e.g. line 20). Append “.” to the last sentence.

-"%@ is not allowed to access Face ID. Allow Face ID access in Settings"
+"%@ is not allowed to access Face ID. Allow Face ID access in Settings."-"%@ is not allowed to access Touch ID. Allow Touch ID access in Settings"
+"%@ is not allowed to access Touch ID. Allow Touch ID access in Settings."

1000-1002: Consider hyphenating “Re-sync” for readability

Very minor, but “Full Re-sync” reads slightly clearer than “Full Resync”.


2050-2053: Parenthetical “(Suggested)” may look UI-noisy

“Rescan Transactions (Suggested)” will be rendered verbatim; consider moving the hint to separate help text or using “Rescan Suggested Transactions” to avoid parentheses in the button/row label.


2072-2074: Spell-check “Resync” vs “Re-sync”

Same naming-consistency note as for “Full Resync”. Choose one spelling across all new keys.

DashWallet/ms.lproj/Localizable.strings (3)

17-17: Terminate the sentences with proper punctuation

Most alert strings in this file end with a period to read as a complete sentence. These two new biometric-denial messages are missing it, which introduces inconsistency.

-"%@ is not allowed to access Face ID. Allow Face ID access in Settings"
+"%@ is not allowed to access Face ID. Allow Face ID access in Settings."
-
-"%@ is not allowed to access Touch ID. Allow Touch ID access in Settings"
+"%@ is not allowed to access Touch ID. Allow Touch ID access in Settings."

Also applies to: 23-23


2051-2053: Avoid parenthetical hints inside the key – keep the UI label short

In product UIs, additional guidance such as “Suggested” is usually presented via subtitled text or secondary labels, not inside the primary action title. Consider dropping the parenthetical to avoid visual noise:

-"Rescan Transactions (Suggested)" = "Rescan Transactions (Suggested)";
+"Rescan Transactions" = "Rescan Transactions";

If the “Suggested” qualifier is required, surface it in the explanatory text that accompanies the action instead.


2372-2373: Use title-case to match neighbouring action labels

Neighbouring entries such as "Preview" and "Reset" capitalise every significant word. Align this new key for visual consistency:

-"Successful purchase" = "Successful purchase";
+"Successful Purchase" = "Successful Purchase";
DashWallet/hu.lproj/Localizable.strings (7)

17-23: Missing HU translations for Face ID / Touch ID denial messages

Both new biometric-access messages remain in English on the HU table. Consider supplying proper Hungarian translations to avoid a mixed-language UI.

-"%@ is not allowed to access Face ID. Allow Face ID access in Settings" = "%@ is not allowed to access Face ID. Allow Face ID access in Settings";
+"%@ is not allowed to access Face ID. Allow Face ID access in Settings" = "%@ nem férhet hozzá a Face ID-hoz. Engedélyezze a Face ID-hozzáférést a Beállításokban";

-"%@ is not allowed to access Touch ID. Allow Touch ID access in Settings" = "%@ is not allowed to access Touch ID. Allow Touch ID access in Settings";
+"%@ is not allowed to access Touch ID. Allow Touch ID access in Settings" = "%@ nem férhet hozzá a Touch ID-hoz. Engedélyezze a Touch ID-hozzáférést a Beállításokban";

334-336: “Biometrics Access Required” left untranslated

Provide a HU translation to stay consistent.

-"Biometrics Access Required" = "Biometrics Access Required";
+"Biometrics Access Required" = "Biometrikus azonosítás szükséges";

1001-1002: String still English: “Full Resync”

Add Hungarian equivalent.

-"Full Resync" = "Full Resync";
+"Full Resync" = "Teljes újraszinkronizálás";

2051-2053: Untranslated: “Rescan Transactions (Suggested)”

-"Rescan Transactions (Suggested)" = "Rescan Transactions (Suggested)";
+"Rescan Transactions (Suggested)" = "Tranzakciók újraolvasása (javasolt)";

2072-2074: Untranslated: “Resync Masternode List”

-"Resync Masternode List" = "Resync Masternode List";
+"Resync Masternode List" = "Masternode-lista újraszinkronizálása";

2372-2376: Untranslated: “Successful purchase” & “Support”

-"Successful purchase" = "Successful purchase";
+"Successful purchase" = "Sikeres vásárlás";

-"Support" = "Support";
+"Support" = "Támogatás";

2815-2816: Untranslated: “Voting”

-"Voting" = "Voting";
+"Voting" = "Szavazás";
DashWallet/Sources/UI/SwiftUI Components/MenuItem.swift (1)

125-125: Remove trailing whitespace

Multiple lines have trailing whitespace that should be removed to maintain code cleanliness. Please clean up the trailing spaces on these lines.

Also applies to: 143-143, 153-153, 160-160, 166-166, 168-168, 181-181, 185-185, 196-196, 203-203

DashWallet/de.lproj/Localizable.strings (1)

2375-2376: Generic “Support” string not localised

Earlier you translated similar variants (“Contact Support”). To keep consistency:

-"Support" = "Support";
+"Support" = "Support / Hilfe";
DashWallet/Sources/UI/Menu/Security/SecurityMenuScreen.swift (5)

21-33: Consider memory management and architecture patterns.

The initialization pattern looks good overall, but there are a few considerations:

  1. Potential retain cycle: The delegateInternal captures vc in its closure, which could create a retain cycle if not handled properly.

  2. UINavigationController storage: Storing the UINavigationController as a property in a SwiftUI view is unusual. Consider if this coupling is necessary or if navigation could be handled differently.

The StateObject initialization for the view model follows SwiftUI best practices.

Consider using weak references or alternative navigation patterns:

 private let delegateInternal: DelegateInternal
 
 init(vc: UINavigationController) {
     self.vc = vc
-    self.delegateInternal = DelegateInternal(onHide: {
-        vc.popViewController(animated: true)
-    })
+    self.delegateInternal = DelegateInternal(onHide: { [weak vc] in
+        vc?.popViewController(animated: true)
+    })
 }

35-106: Well-structured SwiftUI implementation with minor accessibility concerns.

The view body follows SwiftUI best practices with proper layout, styling, and reactive patterns. The custom back button and navigation handling work well for the design requirements.

Minor suggestion: Consider accessibility improvements for the custom back button:

 Button(action: {
     vc.popViewController(animated: true)
 }) {
     Image(systemName: "chevron.left")
         .font(.system(size: 18, weight: .medium))
         .foregroundColor(.black)
         .frame(width: 36, height: 36)
         .overlay(
             Circle().stroke(Color.gray300.opacity(0.3), lineWidth: 1)
         )
 }
+.accessibilityLabel("Back")
+.accessibilityRole(.button)

25-25: Consider using @ObservedObject instead of @StateObject.

Since the SecurityMenuViewModel is created in this view and doesn't need to persist across view recreation, @StateObject is appropriate. However, if this view model could be injected from a parent, consider using @ObservedObject for better testability.


111-140: Consider extracting authentication logic to reduce duplication.

The authentication pattern is repeated for multiple navigation destinations. Consider creating a helper method to reduce code duplication.

+    private func authenticateAndNavigate(to destination: SecurityMenuNavigationDestination, action: @escaping () -> Void) {
+        viewModel.authenticate { authenticated in
+            if authenticated {
+                action()
+            }
+        }
+    }

Then simplify the cases:

     case .viewRecoveryPhrase:
-        viewModel.authenticate { authenticated in
-            if authenticated {
-                let model = DWPreviewSeedPhraseModel()
-                model.getOrCreateNewWallet()
-                let controller = DWPreviewSeedPhraseViewController(model: model)
-                controller.delegate = delegateInternal
-                controller.hidesBottomBarWhenPushed = true
-                self.vc.pushViewController(controller, animated: true)
-            }
-        }
+        authenticateAndNavigate(to: destination) {
+            let model = DWPreviewSeedPhraseModel()
+            model.getOrCreateNewWallet()
+            let controller = DWPreviewSeedPhraseViewController(model: model)
+            controller.delegate = delegateInternal
+            controller.hidesBottomBarWhenPushed = true
+            self.vc.pushViewController(controller, animated: true)
+        }

162-162: Consider localizing the fallback biometrics message.

The fallback message "Biometrics access required" should be localized for consistency with the rest of the app.

-            return "Biometrics access required"
+            return NSLocalizedString("Biometrics access required", comment: "")
DashWallet/zh.lproj/Localizable.strings (1)

1-3177: Suggest process improvements for localization management.

This major UI refactor has introduced several translation gaps that will negatively impact Chinese users. Consider implementing:

  1. Translation verification: Add automated checks to ensure new strings are translated before merging
  2. Localization workflow: Establish a process for handling translations during major refactors
  3. String freeze periods: Consider freezing new string additions close to release to ensure proper translation

The current changes should not be merged until all untranslated strings are properly localized to maintain consistency in the user experience.

DashWallet/zh_TW.lproj/Localizable.strings (8)

17-17: Missing Traditional-Chinese translation for critical biometric denial messages

Both Face ID and Touch ID denial strings fall back to English. These are shown in system permission alerts and should be localised.

-"%@ is not allowed to access Face ID. Allow Face ID access in Settings" = "%@ is not allowed to access Face ID. Allow Face ID access in Settings";
+"%@ is not allowed to access Face ID. Allow Face ID access in Settings" = "%@ 無法使用 Face ID。請在「設定」中允許 Face ID 存取權";
-
-"%@ is not allowed to access Touch ID. Allow Touch ID access in Settings" = "%@ is not allowed to access Touch ID. Allow Touch ID access in Settings";
+"%@ is not allowed to access Touch ID. Allow Touch ID access in Settings" = "%@ 無法使用 Touch ID。請在「設定」中允許 Touch ID 存取權";

Leaving them untranslated will degrade UX for zh-TW users.

Also applies to: 23-23


335-336: String added with no translation

"Biometrics Access Required" is displayed in the new security‐flow sheet but remains English. Provide a Chinese version or mark TODO for localisation to avoid mixed-language UI.


357-358: Regression: existing translation overwritten with English

"Buy & Sell Dash" previously had a Chinese value ("購買與出售達世幣" or similar) but is now English. This looks accidental and breaks consistency with surrounding strings.


1001-1002: Untranslated maintenance action

"Full Resync" appears in the new Settings > Tools screen. Add a translation (e.g. "完全重新同步") to keep maintenance actions localised.


2051-2053: Untranslated tool-action string

"Rescan Transactions (Suggested)" is user-visible. Provide zh-TW translation (e.g. "重新掃描交易(建議)").


2072-2074: Untranslated masternode maintenance string

"Resync Masternode List" still English; suggest "重新同步主節點列表".


2371-2376: Two new strings lack translations

"Successful purchase" and "Support" introduced for the new menu remain English. Add appropriate Chinese (e.g. "購買成功", "支援").


2814-2816: Core navigation label left in English

"Voting" is now a main-menu item in the SwiftUI redesign. Translate (e.g. "投票") to align with other menu titles.

DashWallet/Sources/UI/Menu/Settings/SettingsScreen.swift (3)

18-21: Sort imports alphabetically

+import Combine
+import SwiftUI
 import UIKit
-import SwiftUI
-import Combine

116-133: Consider extracting alert configuration to improve readability

The inline alert configuration with multiple buttons and async operations makes the view body harder to read.

Consider extracting the alert logic:

private var networkAlert: Alert {
    Alert(
        title: Text(NSLocalizedString("Network", comment: "")),
        message: nil,
        primaryButton: .default(Text(NSLocalizedString("Mainnet", comment: ""))) {
            Task { await switchToMainnet() }
        },
        secondaryButton: .default(Text(NSLocalizedString("Testnet", comment: ""))) {
            Task { await switchToTestnet() }
        }
    )
}

private func switchToMainnet() async {
    let success = await viewModel.switchToMainnet()
    if success { updateView() }
}

private func switchToTestnet() async {
    let success = await viewModel.switchToTestnet()
    if success { updateView() }
}

261-269: Consider adding completion handlers to ActivityView

The ActivityView doesn't handle completion or cancellation callbacks, which might be needed for analytics or cleanup.

 struct ActivityView: UIViewControllerRepresentable {
     let activityItems: [Any]
+    var onCompletion: ((UIActivity.ActivityType?, Bool, [Any]?, Error?) -> Void)?
     
     func makeUIViewController(context: Context) -> UIActivityViewController {
-        return UIActivityViewController(activityItems: activityItems, applicationActivities: nil)
+        let controller = UIActivityViewController(activityItems: activityItems, applicationActivities: nil)
+        controller.completionWithItemsHandler = onCompletion
+        return controller
     }
     
     func updateUIViewController(_ uiViewController: UIActivityViewController, context: Context) {}
 }
DashWallet/fi.lproj/Localizable.strings (8)

17-23: New biometric-denial strings remain untranslated

All newly-added biometric denial messages are still in English, which breaks the Finnish locale consistency.

-"%@ is not allowed to access Face ID. Allow Face ID access in Settings"
+"%@-sovelluksella ei ole lupaa käyttää Face ID:tä. Salli Face ID ‑käyttö Asetuksissa"-"%@ is not allowed to access Touch ID. Allow Touch ID access in Settings"
+"%@-sovelluksella ei ole lupaa käyttää Touch ID:tä. Salli Touch ID ‑käyttö Asetuksissa"

At minimum, add a TODO so the localization team can pick this up.


334-335: String missing Finnish translation

"Biometrics Access Required" is a user-visible title but kept in English.

-"Biometrics Access Required" = "Biometrics Access Required";
+"Biometrics Access Required" = "Biometrinen tunnistus vaaditaan";

1000-1001: Untranslated maintenance action

"Full Resync" should be localized.

-"Full Resync" = "Full Resync";
+"Full Resync" = "Täysi uudelleensynkronointi";

2051-2052: Untranslated troubleshooting label

"Rescan Transactions (Suggested)" still English.

-"Rescan Transactions (Suggested)" = "Rescan Transactions (Suggested)";
+"Rescan Transactions (Suggested)" = "Skannaa tapahtumat uudelleen (suositeltu)";

2072-2073: Untranslated masternode utility string

-"Resync Masternode List" = "Resync Masternode List";
+"Resync Masternode List" = "Synkronoi masternodelista uudelleen";

2371-2372: Untranslated purchase confirmation

-"Successful purchase" = "Successful purchase";
+"Successful purchase" = "Osto onnistui";

2374-2375: Single-word menu entry not localized

-"Support" = "Support";
+"Support" = "Tuki";

2814-2815: “Voting” still English

-"Voting" = "Voting";
+"Voting" = "Äänestys";
DashWallet/ro.lproj/Localizable.strings (1)

334-336: New keys added with no Romanian translation

The following newly-introduced strings appear untranslated (English on both sides). Please supply proper Romanian equivalents to maintain UX consistency:

• Biometrics Access Required → „Acces biometric necesar”
• Full Resync → „Resincronizare completă”
• Rescan Transactions (Suggested) → „Rescanare tranzacții (recomandat)”
• Resync Masternode List → „Resincronizează lista Masternode-urilor”
• Successful purchase → „Achiziție reușită”
• Support → „Asistență”
• Voting → „Votare”

Example patch:

-"Biometrics Access Required" = "Biometrics Access Required";
+"Biometrics Access Required" = "Acces biometric necesar";

-"Full Resync" = "Full Resync";
+"Full Resync" = "Resincronizare completă";

-"Rescan Transactions (Suggested)" = "Rescan Transactions (Suggested)";
+"Rescan Transactions (Suggested)" = "Rescanare tranzacții (recomandat)";

-"Resync Masternode List" = "Resync Masternode List";
+"Resync Masternode List" = "Resincronizează lista Masternode-urilor";

-"Successful purchase" = "Successful purchase";
+"Successful purchase" = "Achiziție reușită";

-"Support" = "Support";
+"Support" = "Asistență";

-"Voting" = "Voting";
+"Voting" = "Votare";

Ensure diacritics are correct and length fits UI constraints.

Also applies to: 1000-1002, 2051-2053, 2072-2074, 2372-2376, 2814-2816

DashWallet/Sources/UI/Main/MainTabbarController.swift (2)

242-247: Fix line length violation while maintaining correct instantiation logic.

The instantiation logic correctly handles conditional compilation and passes appropriate model parameters. However, line 244 exceeds the 120-character limit.

Apply this diff to fix the line length issue:

-        menuVC = MainMenuViewController(dashPayModel: homeModel.dashPayModel, receiveModel: homeModel.receiveModel, dashPayReady: homeModel, userProfileModel: homeModel.dashPayModel.userProfile)
+        menuVC = MainMenuViewController(
+            dashPayModel: homeModel.dashPayModel,
+            receiveModel: homeModel.receiveModel,
+            dashPayReady: homeModel,
+            userProfileModel: homeModel.dashPayModel.userProfile
+        )

340-352: Fix trailing whitespace while maintaining correct delegate method signatures.

The delegate method implementations correctly reflect the new Swift protocol design with simplified signatures and improved type safety. However, there are trailing whitespace issues on lines 343 and 347.

Apply this diff to remove trailing whitespace:

     func mainMenuViewControllerImportPrivateKey() {
         performScanQRCodeAction()
     }
-    
+
     func mainMenuViewControllerOpenHomeScreen() {
         selectedIndex = MainTabbarTabs.home.rawValue
     }
-    
+
     func showGiftCard(_ txId: Data) {
DashWallet/Sources/UI/Menu/Tools/ToolsMenuViewModel.swift (2)

18-20: Sort imports alphabetically for consistency.

-import Foundation
 import Combine
+import Foundation

36-36: Remove trailing whitespace for code consistency.

Multiple lines have trailing whitespace that should be removed.

Also applies to: 40-40, 81-81, 88-88, 94-94

DashWallet/Sources/UI/Menu/Tools/ToolsMenuScreen.swift (4)

18-21: Sort imports alphabetically.

-import UIKit
-import SwiftUI
 import SafariServices
+import SwiftUI
+import UIKit

85-85: Fix closure indentation.

The closing brace should align with the opening statement.

-            }
+                }

123-130: Break up long alert message for better readability.

The message text exceeds the line length limit and should be split.

 .alert(NSLocalizedString("CSV Export", comment: ""), isPresented: $showCSVExportAlert) {
     Button(NSLocalizedString("Continue", comment: "")) {
         handleCSVExport()
     }
     Button(NSLocalizedString("Cancel", comment: ""), role: .cancel) { }
 } message: {
-    Text(NSLocalizedString("All payments will be considered as an Expense and all incoming transactions will be Income. The owner of this wallet is responsible for making any cost basis adjustments in their chosen tax reporting system.", comment: ""))
+    Text(NSLocalizedString("All payments will be considered as an Expense and all incoming transactions will be Income. " +
+                          "The owner of this wallet is responsible for making any cost basis adjustments in their chosen tax reporting system.", 
+                          comment: ""))
 }

226-226: Move attribute to its own line.

-        @objc func importWalletInfoViewControllerScanPrivateKeyAction(_ controller: DWImportWalletInfoViewController) { onImportPrivateKey() }
+        @objc 
+        func importWalletInfoViewControllerScanPrivateKeyAction(_ controller: DWImportWalletInfoViewController) { 
+            onImportPrivateKey() 
+        }
DashWallet/Sources/UI/Menu/Security/SecurityMenuViewModel.swift (3)

18-21: Sort imports alphabetically.

-import Foundation
 import Combine
-import LocalAuthentication
+import Foundation
+import LocalAuthentication

73-73: Break up long ternary expression for readability.

-            let title = hasTouchID ? NSLocalizedString("Enable Touch ID", comment: "") : NSLocalizedString("Enable Face ID", comment: "")
+            let title = hasTouchID 
+                ? NSLocalizedString("Enable Touch ID", comment: "") 
+                : NSLocalizedString("Enable Face ID", comment: "")

146-146: Replace unused closure parameters with underscores.

-        ) { [weak self] authenticatedOrSuccess, usedBiometrics, cancelled in
+        ) { [weak self] authenticatedOrSuccess, _, _ in
DashWallet/Sources/UI/Menu/Main/MainMenuViewController.swift (2)

133-381: Consider breaking down this large SwiftUI view.

The MainMenuScreen view has many responsibilities and is quite large. Consider:

  1. Moving it to a separate file
  2. Extracting menu sections into separate view components
  3. Extracting sheet presentations into separate view modifiers

572-589: Break up long message string and clarify mock code status.

 if MOCK_DASHPAY.boolValue {
+    // TODO: Remove mock credits logic when real implementation is ready
     BuyCreditsModel.currentCredits -= 0.25
     let heading: String
     let message: String
     
     if BuyCreditsModel.currentCredits <= 0 {
         heading = NSLocalizedString("Your credit balance has been fully depleted", comment: "")
-        message = NSLocalizedString("You can continue to use DashPay for payments but you cannot update your profile or add more contacts until you top up your credit balance", comment: "")
+        message = NSLocalizedString("You can continue to use DashPay for payments but you cannot update " +
+                                   "your profile or add more contacts until you top up your credit balance", 
+                                   comment: "")
     } else if BuyCreditsModel.currentCredits <= 0.25 {
DashWallet/Sources/UI/Menu/Settings/SettingsMenuViewModel.swift (2)

30-31: Consider thread safety for view model properties

While @MainActor ensures UI updates happen on the main thread, the view model interacts with services like CoinJoinService that may operate on background threads. Consider using @Published with thread-safe access patterns or actor isolation for properties that might be updated from multiple threads.


101-170: Extract icon names and consider breaking up menu creation

The refreshMenuItems method is quite long and uses hard-coded icon names. Consider extracting these to constants and potentially breaking up the menu creation into smaller methods.

+private enum MenuIcons {
+    static let currency = "image.currency"
+    static let notifications = "image.notifications"
+    static let network = "image.network.monitor"
+    static let rescan = "image.rescan"
+    static let about = "image.about"
+}
+
 private func refreshMenuItems() {
     self.items = [
         MenuItemModel(
             title: NSLocalizedString("Local Currency", comment: ""),
             subtitle: localCurrencyCode,
-            icon: .custom("image.currency", maxHeight: 22),
+            icon: .custom(MenuIcons.currency, maxHeight: 22),
             action: { [weak self] in
                 self?.navigationDestination = .currencySelector
             }
         ),

Consider also breaking this into smaller methods like createCurrencyMenuItem(), createNotificationMenuItem(), etc. for better maintainability.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e970fcb and e95bdcc.

⛔ Files ignored due to path filters (75)
  • DashWallet/Resources/AppAssets.xcassets/CoinJoin/image.coinjoin.menu.imageset/image.coinjoin.menu.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/CoinJoin/image.coinjoin.menu.imageset/image.coinjoin.menu@2x.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/CoinJoin/image.coinjoin.menu.imageset/image.coinjoin.menu@3x.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/Image.face.id.imageset/Layer 1.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/Image.face.id.imageset/Layer 1@2x.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/Image.face.id.imageset/Layer 1@3x.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.about.imageset/dash.logo.circle.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.about.imageset/dash.logo.circle@2x.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.about.imageset/dash.logo.circle@3x.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.advanced.security.imageset/advanced security.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.advanced.security.imageset/advanced security@2x.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.advanced.security.imageset/advanced security@3x.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.autohide.balance.imageset/eye.closed.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.autohide.balance.imageset/eye.closed@2x.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.autohide.balance.imageset/eye.closed@3x.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.buy.and.sell.imageset/buy.sell.dash.2.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.buy.and.sell.imageset/buy.sell.dash.2@2x.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.buy.and.sell.imageset/buy.sell.dash.2@3x.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.change.pin.imageset/Layer_1.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.change.pin.imageset/Layer_1@2x.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.change.pin.imageset/Layer_1@3x.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.coinjoin.menu.imageset/Layer_1.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.coinjoin.menu.imageset/Layer_1@2x.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.coinjoin.menu.imageset/Layer_1@3x.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.csv.export.imageset/csv.export.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.csv.export.imageset/csv.export@2x.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.csv.export.imageset/csv.export@3x.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.currency.imageset/cash.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.currency.imageset/cash@2x.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.currency.imageset/cash@3x.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.explore.imageset/Explore-Blue.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.explore.imageset/Explore-Blue@2x.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.explore.imageset/Explore-Blue@3x.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.extend.public.key.imageset/public.key.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.extend.public.key.imageset/public.key@2x.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.extend.public.key.imageset/public.key@3x.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.import.private.key.imageset/import.private.key.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.import.private.key.imageset/import.private.key@2x.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.import.private.key.imageset/import.private.key@3x.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.masternode.keys.imageset/Layer_1.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.masternode.keys.imageset/Layer_1@2x.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.masternode.keys.imageset/Layer_1@3x.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.network.monitor.imageset/Layer_1.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.network.monitor.imageset/Layer_1@2x.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.network.monitor.imageset/Layer_1@3x.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.notifications.imageset/Layer 1.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.notifications.imageset/Layer 1@2x.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.notifications.imageset/Layer 1@3x.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.recovery.phrase.imageset/Layer_1.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.recovery.phrase.imageset/Layer_1@2x.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.recovery.phrase.imageset/Layer_1@3x.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.rescan.imageset/rescan.blockchain.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.rescan.imageset/rescan.blockchain@2x.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.rescan.imageset/rescan.blockchain@3x.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.reset.wallet.imageset/reset wallet.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.reset.wallet.imageset/reset wallet@2x.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.reset.wallet.imageset/reset wallet@3x.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.security.imageset/Vector.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.security.imageset/Vector@2x.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.security.imageset/Vector@3x.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.settings.imageset/Iconly_x2F_Bold_x2F_Setting.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.settings.imageset/Iconly_x2F_Bold_x2F_Setting@2x.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.settings.imageset/Iconly_x2F_Bold_x2F_Setting@3x.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.support.imageset/Group.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.support.imageset/Group@2x.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.support.imageset/Group@3x.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.tools.imageset/Group.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.tools.imageset/Group@2x.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.tools.imageset/Group@3x.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.touch.id.imageset/fingerprint.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.touch.id.imageset/fingerprint@2x.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.touch.id.imageset/fingerprint@3x.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/icon_filter_horizontal.imageset/filters.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/icon_filter_horizontal.imageset/filters@2x.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/icon_filter_horizontal.imageset/filters@3x.png is excluded by !**/*.png
📒 Files selected for processing (107)
  • DashWallet.xcodeproj/project.pbxproj (34 hunks)
  • DashWallet/Resources/AppAssets.xcassets/Menu/Image.face.id.imageset/Contents.json (1 hunks)
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.about.imageset/Contents.json (1 hunks)
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.advanced.security.imageset/Contents.json (1 hunks)
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.autohide.balance.imageset/Contents.json (1 hunks)
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.buy.and.sell.imageset/Contents.json (1 hunks)
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.change.pin.imageset/Contents.json (1 hunks)
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.coinjoin.menu.imageset/Contents.json (1 hunks)
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.csv.export.imageset/Contents.json (1 hunks)
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.currency.imageset/Contents.json (1 hunks)
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.explore.imageset/Contents.json (1 hunks)
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.extend.public.key.imageset/Contents.json (1 hunks)
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.import.private.key.imageset/Contents.json (1 hunks)
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.masternode.keys.imageset/Contents.json (1 hunks)
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.network.monitor.imageset/Contents.json (1 hunks)
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.notifications.imageset/Contents.json (1 hunks)
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.recovery.phrase.imageset/Contents.json (1 hunks)
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.rescan.imageset/Contents.json (1 hunks)
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.reset.wallet.imageset/Contents.json (1 hunks)
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.security.imageset/Contents.json (1 hunks)
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.settings.imageset/Contents.json (1 hunks)
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.support.imageset/Contents.json (1 hunks)
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.tools.imageset/Contents.json (1 hunks)
  • DashWallet/Resources/AppAssets.xcassets/Menu/image.touch.id.imageset/Contents.json (1 hunks)
  • DashWallet/Sources/Models/Voting/VotingPrefs.swift (0 hunks)
  • DashWallet/Sources/UI/CrowdNode/Tx Details/GroupedTransactionsScreen.swift (1 hunks)
  • DashWallet/Sources/UI/DashPay/Menu/DWMainMenuViewController+DashPay.swift (0 hunks)
  • DashWallet/Sources/UI/DashPay/Profile/Edit Profile/RootEditProfileViewController.swift (0 hunks)
  • DashWallet/Sources/UI/DashPay/Voting/UsernameVoting.storyboard (3 hunks)
  • DashWallet/Sources/UI/Home/HomeViewController+Shortcuts.swift (1 hunks)
  • DashWallet/Sources/UI/Home/Views/Home Balance View/BalanceModel.swift (1 hunks)
  • DashWallet/Sources/UI/Home/Views/HomeView.swift (1 hunks)
  • DashWallet/Sources/UI/Home/Views/Shortcuts/Models/ShortcutAction.swift (0 hunks)
  • DashWallet/Sources/UI/Main/MainTabbarController.swift (3 hunks)
  • DashWallet/Sources/UI/Menu/Main/DWMainMenuViewController.h (0 hunks)
  • DashWallet/Sources/UI/Menu/Main/DWMainMenuViewController.m (0 hunks)
  • DashWallet/Sources/UI/Menu/Main/DWMainMenuViewControllerDelegate.h (0 hunks)
  • DashWallet/Sources/UI/Menu/Main/MainMenuViewController.swift (1 hunks)
  • DashWallet/Sources/UI/Menu/Main/MainMenuViewControllerDelegate.swift (2 hunks)
  • DashWallet/Sources/UI/Menu/Main/MainMenuViewModel.swift (1 hunks)
  • DashWallet/Sources/UI/Menu/Main/Views/Cells/DWMainMenuTableViewCell.m (0 hunks)
  • DashWallet/Sources/UI/Menu/Main/Views/Cells/DWMainMenuTableViewCell.xib (0 hunks)
  • DashWallet/Sources/UI/Menu/Main/Views/MainMenuContentView.swift (0 hunks)
  • DashWallet/Sources/UI/Menu/Main/Views/Model/DWMainMenuItem.h (0 hunks)
  • DashWallet/Sources/UI/Menu/Main/Views/Model/DWMainMenuModel.h (0 hunks)
  • DashWallet/Sources/UI/Menu/Main/Views/Model/DWMainMenuModel.m (0 hunks)
  • DashWallet/Sources/UI/Menu/MenuItemModel.swift (1 hunks)
  • DashWallet/Sources/UI/Menu/Security/DWSecurityMenuModel.h (0 hunks)
  • DashWallet/Sources/UI/Menu/Security/DWSecurityMenuModel.m (0 hunks)
  • DashWallet/Sources/UI/Menu/Security/DWSecurityMenuViewController.h (0 hunks)
  • DashWallet/Sources/UI/Menu/Security/DWSecurityMenuViewController.m (0 hunks)
  • DashWallet/Sources/UI/Menu/Security/ResetWalletInfo/DWResetWalletInfoViewController.h (1 hunks)
  • DashWallet/Sources/UI/Menu/Security/SecurityMenuScreen.swift (1 hunks)
  • DashWallet/Sources/UI/Menu/Security/SecurityMenuViewModel.swift (1 hunks)
  • DashWallet/Sources/UI/Menu/Settings/DWSettingsMenuModel.h (0 hunks)
  • DashWallet/Sources/UI/Menu/Settings/DWSettingsMenuModel.m (0 hunks)
  • DashWallet/Sources/UI/Menu/Settings/SettingsMenuViewController.swift (0 hunks)
  • DashWallet/Sources/UI/Menu/Settings/SettingsMenuViewModel.swift (3 hunks)
  • DashWallet/Sources/UI/Menu/Settings/SettingsScreen.swift (1 hunks)
  • DashWallet/Sources/UI/Menu/Tools/ToolsMenuScreen.swift (1 hunks)
  • DashWallet/Sources/UI/Menu/Tools/ToolsMenuViewController.swift (0 hunks)
  • DashWallet/Sources/UI/Menu/Tools/ToolsMenuViewModel.swift (1 hunks)
  • DashWallet/Sources/UI/SwiftUI Components/MenuItem.swift (3 hunks)
  • DashWallet/ar.lproj/Localizable.strings (7 hunks)
  • DashWallet/bg.lproj/Localizable.strings (8 hunks)
  • DashWallet/ca.lproj/Localizable.strings (7 hunks)
  • DashWallet/cs.lproj/Localizable.strings (8 hunks)
  • DashWallet/da.lproj/Localizable.strings (7 hunks)
  • DashWallet/dashwallet-Bridging-Header.h (3 hunks)
  • DashWallet/de.lproj/Localizable.strings (8 hunks)
  • DashWallet/el.lproj/Localizable.strings (8 hunks)
  • DashWallet/en.lproj/Localizable.strings (7 hunks)
  • DashWallet/eo.lproj/Localizable.strings (7 hunks)
  • DashWallet/es.lproj/Localizable.strings (8 hunks)
  • DashWallet/et.lproj/Localizable.strings (7 hunks)
  • DashWallet/fa.lproj/Localizable.strings (7 hunks)
  • DashWallet/fi.lproj/Localizable.strings (7 hunks)
  • DashWallet/fil.lproj/Localizable.strings (8 hunks)
  • DashWallet/fr.lproj/Localizable.strings (8 hunks)
  • DashWallet/hr.lproj/Localizable.strings (7 hunks)
  • DashWallet/hu.lproj/Localizable.strings (7 hunks)
  • DashWallet/id.lproj/Localizable.strings (8 hunks)
  • DashWallet/it.lproj/Localizable.strings (8 hunks)
  • DashWallet/ja.lproj/Localizable.strings (8 hunks)
  • DashWallet/ko.lproj/Localizable.strings (8 hunks)
  • DashWallet/mk.lproj/Localizable.strings (7 hunks)
  • DashWallet/ms.lproj/Localizable.strings (7 hunks)
  • DashWallet/nb.lproj/Localizable.strings (7 hunks)
  • DashWallet/nl.lproj/Localizable.strings (8 hunks)
  • DashWallet/pl.lproj/Localizable.strings (8 hunks)
  • DashWallet/pt.lproj/Localizable.strings (8 hunks)
  • DashWallet/ro.lproj/Localizable.strings (7 hunks)
  • DashWallet/ru.lproj/Localizable.strings (8 hunks)
  • DashWallet/sk.lproj/Localizable.strings (8 hunks)
  • DashWallet/sl.lproj/Localizable.strings (7 hunks)
  • DashWallet/sl_SI.lproj/Localizable.strings (7 hunks)
  • DashWallet/sq.lproj/Localizable.strings (7 hunks)
  • DashWallet/sr.lproj/Localizable.strings (7 hunks)
  • DashWallet/sv.lproj/Localizable.strings (8 hunks)
  • DashWallet/th.lproj/Localizable.strings (8 hunks)
  • DashWallet/tr.lproj/Localizable.strings (8 hunks)
  • DashWallet/uk.lproj/Localizable.strings (8 hunks)
  • DashWallet/vi.lproj/Localizable.strings (8 hunks)
  • DashWallet/zh-Hans.lproj/Localizable.strings (7 hunks)
  • DashWallet/zh-Hant-TW.lproj/Localizable.strings (7 hunks)
  • DashWallet/zh.lproj/Localizable.strings (8 hunks)
  • DashWallet/zh_TW.lproj/Localizable.strings (8 hunks)
💤 Files with no reviewable changes (21)
  • DashWallet/Sources/Models/Voting/VotingPrefs.swift
  • DashWallet/Sources/UI/Home/Views/Shortcuts/Models/ShortcutAction.swift
  • DashWallet/Sources/UI/Menu/Main/Views/Model/DWMainMenuItem.h
  • DashWallet/Sources/UI/DashPay/Menu/DWMainMenuViewController+DashPay.swift
  • DashWallet/Sources/UI/Menu/Main/Views/Model/DWMainMenuModel.h
  • DashWallet/Sources/UI/Menu/Main/Views/Model/DWMainMenuModel.m
  • DashWallet/Sources/UI/Menu/Main/DWMainMenuViewControllerDelegate.h
  • DashWallet/Sources/UI/DashPay/Profile/Edit Profile/RootEditProfileViewController.swift
  • DashWallet/Sources/UI/Menu/Security/DWSecurityMenuModel.h
  • DashWallet/Sources/UI/Menu/Security/DWSecurityMenuViewController.h
  • DashWallet/Sources/UI/Menu/Main/Views/Cells/DWMainMenuTableViewCell.xib
  • DashWallet/Sources/UI/Menu/Main/DWMainMenuViewController.h
  • DashWallet/Sources/UI/Menu/Security/DWSecurityMenuModel.m
  • DashWallet/Sources/UI/Menu/Tools/ToolsMenuViewController.swift
  • DashWallet/Sources/UI/Menu/Main/DWMainMenuViewController.m
  • DashWallet/Sources/UI/Menu/Settings/DWSettingsMenuModel.h
  • DashWallet/Sources/UI/Menu/Settings/SettingsMenuViewController.swift
  • DashWallet/Sources/UI/Menu/Security/DWSecurityMenuViewController.m
  • DashWallet/Sources/UI/Menu/Main/Views/MainMenuContentView.swift
  • DashWallet/Sources/UI/Menu/Settings/DWSettingsMenuModel.m
  • DashWallet/Sources/UI/Menu/Main/Views/Cells/DWMainMenuTableViewCell.m
🧰 Additional context used
🧬 Code Graph Analysis (3)
DashWallet/Sources/UI/Home/HomeViewController+Shortcuts.swift (1)
DashWallet/Sources/UI/Menu/Settings/SettingsMenuViewModel.swift (2)
  • switchToTestnet (178-180)
  • switchToMainnet (174-176)
DashWallet/Sources/UI/Menu/Main/MainMenuViewControllerDelegate.swift (2)
DashWallet/Sources/UI/Menu/Main/MainMenuViewController.swift (4)
  • mainMenuViewControllerImportPrivateKey (538-542)
  • mainMenuViewControllerOpenHomeScreen (532-536)
  • showPaymentsController (544-546)
  • showGiftCard (548-550)
DashWallet/Sources/UI/Main/MainTabbarController.swift (5)
  • mainMenuViewControllerImportPrivateKey (340-342)
  • mainMenuViewControllerOpenHomeScreen (344-346)
  • showPaymentsController (396-398)
  • showPaymentsController (400-423)
  • showGiftCard (348-351)
DashWallet/Sources/UI/Menu/Main/MainMenuViewModel.swift (3)
DashWallet/Sources/UI/Menu/Main/MainMenuViewController.swift (2)
  • showPaymentsController (544-546)
  • showGiftCard (548-550)
DashWallet/Sources/UI/Main/MainTabbarController.swift (3)
  • showPaymentsController (396-398)
  • showPaymentsController (400-423)
  • showGiftCard (348-351)
DashWallet/Sources/UI/Menu/Settings/SettingsMenuViewModel.swift (1)
  • resetNavigation (60-64)
🪛 SwiftLint (0.57.0)
DashWallet/Sources/UI/SwiftUI Components/MenuItem.swift

[Warning] 118-118: Trailing closure syntax should not be used when passing more than one closure argument

(multiple_closures_with_trailing_closure)


[Warning] 125-125: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 143-143: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 153-153: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 160-160: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 166-166: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 168-168: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 181-181: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 185-185: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 196-196: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 203-203: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 214-214: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 232-232: Unused parameter in a closure should be replaced with _

(unused_closure_parameter)

DashWallet/Sources/UI/Main/MainTabbarController.swift

[Warning] 244-244: Line should be 120 characters or less; currently it has 194 characters

(line_length)


[Warning] 343-343: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 347-347: Lines should not have trailing whitespace

(trailing_whitespace)

DashWallet/Sources/UI/Menu/Security/SecurityMenuViewModel.swift

[Warning] 73-73: Line should be 120 characters or less; currently it has 137 characters

(line_length)


[Warning] 19-19: Imports should be sorted

(sorted_imports)


[Warning] 36-36: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 39-39: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 42-42: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 49-49: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 52-52: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 55-55: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 63-63: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 71-71: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 87-87: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 100-100: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 108-108: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 116-116: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 119-119: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 126-126: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 134-134: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 140-140: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 151-151: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 172-172: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 177-177: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 187-187: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 146-146: Unused parameter in a closure should be replaced with _

(unused_closure_parameter)


[Warning] 146-146: Unused parameter in a closure should be replaced with _

(unused_closure_parameter)

DashWallet/Sources/UI/Menu/Tools/ToolsMenuViewModel.swift

[Warning] 24-24: Declaration masternodeKeys contains the term "master" which is not considered inclusive

(inclusive_language)


[Warning] 19-19: Imports should be sorted

(sorted_imports)


[Warning] 36-36: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 40-40: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 81-81: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 88-88: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 94-94: Lines should not have trailing whitespace

(trailing_whitespace)

DashWallet/Sources/UI/Menu/Tools/ToolsMenuScreen.swift

[Warning] 226-226: Attributes should be on their own lines in functions and types, but on the same line as variables and imports

(attributes)


[Warning] 85-85: Closure end should have the same indentation as the line that started it; expected 16, got 12

(closure_end_indentation)


[Error] 212-212: Force casts should be avoided

(force_cast)


[Warning] 185-185: Declaration showMasternodeKeys contains the term "master" which is not considered inclusive

(inclusive_language)


[Error] 129-129: Line should be 200 characters or less; currently it has 259 characters

(line_length)


[Warning] 226-226: Line should be 120 characters or less; currently it has 142 characters

(line_length)


[Warning] 44-44: Trailing closure syntax should not be used when passing more than one closure argument

(multiple_closures_with_trailing_closure)


[Warning] 141-141: Trailing closure syntax should not be used when passing more than one closure argument

(multiple_closures_with_trailing_closure)


[Warning] 19-19: Imports should be sorted

(sorted_imports)


[Warning] 20-20: Imports should be sorted

(sorted_imports)


[Warning] 26-26: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 31-31: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 57-57: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 68-68: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 90-90: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 150-150: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 166-166: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 172-172: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 178-178: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 184-184: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 190-190: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 200-200: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 221-221: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 225-225: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 25-25: Prefer -> Void over -> ()

(void_return)


[Warning] 32-32: Prefer -> Void over -> ()

(void_return)


[Warning] 220-220: Prefer -> Void over -> ()

(void_return)


[Warning] 222-222: Prefer -> Void over -> ()

(void_return)

DashWallet/Sources/UI/Menu/Settings/SettingsScreen.swift

[Warning] 134-134: Line should be 120 characters or less; currently it has 153 characters

(line_length)


[Warning] 143-143: Line should be 120 characters or less; currently it has 164 characters

(line_length)


[Warning] 206-206: Line should be 120 characters or less; currently it has 132 characters

(line_length)


[Error] 234-234: Line should be 200 characters or less; currently it has 205 characters

(line_length)


[Warning] 254-254: Line should be 120 characters or less; currently it has 128 characters

(line_length)


[Warning] 47-47: Trailing closure syntax should not be used when passing more than one closure argument

(multiple_closures_with_trailing_closure)


[Warning] 19-19: Imports should be sorted

(sorted_imports)


[Warning] 20-20: Imports should be sorted

(sorted_imports)


[Warning] 26-26: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 32-32: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 60-60: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 71-71: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 103-103: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 168-168: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 186-186: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 192-192: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 195-195: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 204-204: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 210-210: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 215-215: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 225-225: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 230-230: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 249-249: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 253-253: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 254-254: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 255-255: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 263-263: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 267-267: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 25-25: Prefer -> Void over -> ()

(void_return)


[Warning] 33-33: Prefer -> Void over -> ()

(void_return)


[Warning] 248-248: Prefer -> Void over -> ()

(void_return)


[Warning] 250-250: Prefer -> Void over -> ()

(void_return)

DashWallet/Sources/UI/Menu/Main/MainMenuViewController.swift

[Warning] 89-89: Force unwrapping should be avoided

(force_unwrapping)


[Warning] 100-100: Force unwrapping should be avoided

(force_unwrapping)


[Warning] 28-28: Implicitly unwrapped optionals should be avoided when possible

(implicitly_unwrapped_optional)


[Warning] 128-128: Line should be 120 characters or less; currently it has 133 characters

(line_length)


[Warning] 525-525: Line should be 120 characters or less; currently it has 174 characters

(line_length)


[Warning] 570-570: Line should be 120 characters or less; currently it has 146 characters

(line_length)


[Error] 579-579: Line should be 200 characters or less; currently it has 201 characters

(line_length)


[Warning] 582-582: Line should be 120 characters or less; currently it has 146 characters

(line_length)


[Warning] 70-70: Method 'loadView()' should not call to super function

(prohibited_super_call)


[Warning] 19-19: Imports should be sorted

(sorted_imports)


[Warning] 20-20: Imports should be sorted

(sorted_imports)


[Warning] 23-23: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 25-25: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 27-27: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 29-29: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 36-36: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 38-38: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 46-46: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 49-49: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 59-59: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 63-63: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 67-67: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 69-69: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 74-74: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 79-79: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 83-83: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 85-85: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 107-107: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 109-109: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 113-113: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 137-137: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 145-145: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 148-148: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 176-176: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 195-195: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 196-196: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 210-210: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 228-228: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 250-250: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 272-272: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 275-275: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 284-284: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 288-288: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 289-289: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 310-310: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 320-320: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 330-330: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 362-362: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 373-373: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 382-382: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 396-396: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 406-406: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 410-410: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 420-420: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 444-444: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 450-450: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 452-452: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 458-458: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 465-465: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 472-472: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 478-478: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 486-486: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 492-492: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 495-495: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 503-503: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 506-506: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 524-524: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 531-531: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 537-537: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 543-543: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 547-547: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 551-551: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 555-555: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 559-559: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 563-563: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 571-571: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 576-576: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 586-586: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 592-592: Lines should not have trailing whitespace

(trailing_whitespace)


[Warning] 64-64: Unimplemented functions should be marked as unavailable

(unavailable_function)


[Warning] 75-75: Remove overridden functions that don't do anything except call their super

(unneeded_override)


[Warning] 221-221: Unused parameter in a closure should be replaced with _

(unused_closure_parameter)


[Warning] 52-52: Function parameters should be aligned vertically if they're in multiple lines in a declaration

(vertical_parameter_alignment)


[Warning] 53-53: Function parameters should be aligned vertically if they're in multiple lines in a declaration

(vertical_parameter_alignment)


[Warning] 54-54: Function parameters should be aligned vertically if they're in multiple lines in a declaration

(vertical_parameter_alignment)


[Warning] 566-566: Function parameters should be aligned vertically if they're in multiple lines in a declaration

(vertical_parameter_alignment)


[Warning] 567-567: Function parameters should be aligned vertically if they're in multiple lines in a declaration

(vertical_parameter_alignment)


[Warning] 568-568: Function parameters should be aligned vertically if they're in multiple lines in a declaration

(vertical_parameter_alignment)


[Warning] 124-124: Limit vertical whitespace to a single empty line; currently 2

(vertical_whitespace)


[Warning] 196-196: Limit vertical whitespace to a single empty line; currently 2

(vertical_whitespace)


[Warning] 517-517: Limit vertical whitespace to a single empty line; currently 2

(vertical_whitespace)


[Warning] 23-23: Don't include vertical whitespace (empty line) after opening braces

(vertical_whitespace_opening_braces)


[Warning] 136-136: Prefer -> Void over -> ()

(void_return)


[Warning] 156-156: Prefer -> Void over -> ()

(void_return)


[Warning] 181-181: Prefer -> Void over -> ()

(void_return)

🔇 Additional comments (82)
DashWallet/uk.lproj/Localizable.strings (1)

357-357: Inconsistent localization: "Buy & Sell Dash" reverted to English

According to the AI summary, this string was reverted from Ukrainian back to English. This creates inconsistency in the localization file.

Should this string remain in English for branding purposes, or should it be translated to Ukrainian like other similar strings in the file? Please clarify the localization strategy for feature names.

DashWallet/Sources/UI/CrowdNode/Tx Details/GroupedTransactionsScreen.swift (1)

108-108: LGTM! UI consistency improvement.

The minimum height constraint of 66 points ensures consistent sizing for transaction preview items and aligns with iOS Human Interface Guidelines for touch targets. This change maintains visual consistency across different transaction views in the app.

DashWallet/Resources/AppAssets.xcassets/Menu/image.touch.id.imageset/Contents.json (1)

1-24: Well-structured asset catalog with descriptive naming.

The JSON structure is correct for iOS asset catalogs with proper scale variants. The "fingerprint" filename convention is descriptive and clearly indicates the asset's purpose for biometric authentication features.

DashWallet/Resources/AppAssets.xcassets/Menu/image.buy.and.sell.imageset/Contents.json (1)

4-16: Asset entry looks good

The filenames are already self-descriptive and follow the 1x/2x/3x pattern consistently.

DashWallet/Resources/AppAssets.xcassets/Menu/image.csv.export.imageset/Contents.json (1)

4-16: Asset entry looks good

Descriptive filenames and correct 1x/2x/3x variants are present.

DashWallet/Sources/UI/Home/Views/Home Balance View/BalanceModel.swift (1)

75-75: State synchronization added for consistency.

The explicit synchronization of isBalanceHidden with the global setting ensures the UI stays consistent with user preferences, especially if the global setting can be modified elsewhere in the app.

DashWallet/Resources/AppAssets.xcassets/Menu/image.reset.wallet.imageset/Contents.json (1)

1-24: Standard asset catalog configuration looks correct.

The JSON structure follows proper Xcode asset catalog conventions with appropriate scale variants and universal idiom for cross-device compatibility.

DashWallet/Resources/AppAssets.xcassets/Menu/image.extend.public.key.imageset/Contents.json (1)

1-24: Asset catalog configuration is properly structured.

The JSON follows standard conventions. Note that the filename uses "public.key" pattern, which differs from other assets that use descriptive names with spaces. Both patterns are valid but consider consistency across the asset catalog.

DashWallet/Resources/AppAssets.xcassets/Menu/image.support.imageset/Contents.json (1)

1-23: LGTM! Standard asset catalog structure.

The JSON follows Apple's asset catalog conventions correctly with proper scale variants and universal idiom support for all device types.

DashWallet/Resources/AppAssets.xcassets/Menu/image.import.private.key.imageset/Contents.json (1)

1-23: LGTM! Well-structured asset catalog with descriptive naming.

The JSON structure is correct and the filename "import.private.key.png" provides clear semantic meaning for the icon's purpose.

DashWallet/Sources/UI/Home/Views/HomeView.swift (1)

445-445: LGTM! Good UI consistency improvement.

Adding a minimum height constraint ensures consistent visual sizing across transaction preview items, improving the overall user experience.

DashWallet/Resources/AppAssets.xcassets/Menu/image.currency.imageset/Contents.json (1)

1-23: LGTM! Proper asset catalog implementation.

The JSON structure follows Apple's conventions correctly, and the filename "cash.png" is appropriately descriptive for the currency menu icon.

DashWallet/Resources/AppAssets.xcassets/Menu/image.about.imageset/Contents.json (1)

4-17: Assets verified; decide on rendering intent

  • ✅ Located dash.logo.circle.png, dash.logo.circle@2x.png, and dash.logo.circle@3x.png in
    DashWallet/Resources/AppAssets.xcassets/Menu/image.about.imageset/.
  • ⚠️ Contents.json does not specify "template-rendering-intent".
    • If this icon should be tinted in code or Interface Builder, add
    "template-rendering-intent": "template" to each image dictionary.
    • Otherwise, omitting it will render the asset’s original colors as intended.
DashWallet/Sources/UI/DashPay/Voting/UsernameVoting.storyboard (1)

623-624: Add 3 × variant to avoid runtime up-scaling.

Only a single resolution is declared; add @2x and @3x PNGs in the corresponding xcassets entry or export the asset as a single PDF with “Preserve Vector Representation”.

DashWallet/Resources/AppAssets.xcassets/Menu/image.tools.imageset/Contents.json (1)

4-16: Confirm SF-symbol export vs raster PNGs.

If Group is an SF Symbol exported as PDF, prefer a single vector PDF with preserves-vector-representation to reduce repo weight.
If it must stay raster, ensure the 1× source is at least 24 pt to avoid blurry 3× scaling.

DashWallet/Resources/AppAssets.xcassets/Menu/image.explore.imageset/Contents.json (1)

1-23: LGTM! Asset catalog structure is correct.

The JSON follows Apple's standard format with proper scale variants and universal idiom configuration. The filename conventions with @2x and @3x suffixes are correct for iOS asset catalogs.

DashWallet/Sources/UI/Menu/Security/ResetWalletInfo/DWResetWalletInfoViewController.h (1)

28-28: Good Swift interoperability improvement.

Adding NS_SWIFT_NAME(make()) provides a more Swift-friendly API name while maintaining Objective-C compatibility. This aligns well with the PR's goal of improving Swift integration.

DashWallet/ca.lproj/Localizable.strings (2)

17-17: LGTM: Improved biometric access messaging

The extended biometric access denial messages now provide clearer guidance to users by including instructions to "Allow [Face/Touch] ID access in Settings". This improves the user experience by directly telling users how to resolve the issue.

Also applies to: 23-23


335-335: New feature strings added for UI redesign

The new localized strings align well with the settings UI redesign:

  • "Biometrics Access Required" - Clear security messaging
  • "Full Resync" - Wallet maintenance feature
  • "Rescan Transactions (Suggested)" - User-friendly suggestion
  • "Resync Masternode List" - Technical feature for masternode operators
  • "Successful purchase" - Transaction feedback
  • "Support" - Help feature
  • "Voting" - Governance feature

All strings appear properly formatted and contextually appropriate for the Catalan localization.

Also applies to: 1001-1001, 2052-2052, 2073-2073, 2372-2372, 2375-2375, 2815-2815

DashWallet/Sources/UI/Menu/Main/MainMenuViewControllerDelegate.swift (3)

2-3: LGTM! Header updated appropriately for the refactor.

The copyright header has been properly updated with the new author and year, maintaining consistency with the project's refactoring effort.


18-18: Efficient import usage.

Good practice using only Foundation import since the protocol methods only require basic Swift types (Int, Data).


20-25: Well-designed protocol following Swift best practices.

The protocol design is excellent:

  • Proper use of AnyObject constraint for the delegate pattern
  • Clear, descriptive method names following Swift conventions
  • Appropriate parameter types (Int for page index, Data for transaction ID)
  • Clean abstraction that decouples the SwiftUI main menu from the parent controller

The method signatures align perfectly with their implementations in the relevant code snippets.

DashWallet/hr.lproj/Localizable.strings (4)

23-24: Touch ID denial message same issue as above

The new, longer Touch ID sentence is also left in English. Confirm whether Croatian translation is expected before release.


1000-1002: “Full Resync” remains English

Same localisation concern. Double-check whether “Potpuna ponovna sinkronizacija” (or similar) should be provided now.


2072-2074: “Resync Masternode List” untranslated

As with previous new strings, supply Croatian copy or confirm intentional fallback to English.


2815-2816: “Voting” key/value duplicates existing context?

There are multiple voting-related strings; ensure this generic one is actually required and not a duplicate of an earlier entry (search for "Voting" = without the trailing comment). If duplicate, remove to avoid maintenance confusion.

DashWallet/nb.lproj/Localizable.strings (3)

17-24: English strings left untranslated – confirm intent

The newly-merged Face ID/Touch ID denial messages remain in English even though this is the Norwegian (nb) table.
If the plan is to localise later, please add a developer comment (/* TODO: translate */) so translators can track the outstanding work; otherwise confirm the UX should deliberately fall back to English here.


1000-1002: Check for functional wiring of new maintenance actions

Strings for “Full Resync”, “Rescan Transactions (Suggested)” and “Resync Masternode List” have been added.
Please verify that:

  1. Corresponding menu items/buttons in the new SwiftUI settings screens are wired to these keys (old Objective-C code referenced hard-coded titles).
  2. No obsolete keys with similar wording still exist in the file (e.g. "Rescan Blockchain"), otherwise users might see a mixture.

Also applies to: 2051-2053, 2072-2074


2815-2816: Ensure key uniqueness

A bare "Voting" key is easy to collide with other voting-related messages already in the file (there are >20). Run an automated duplicate-key check before merging to avoid runtime look-ups returning the wrong string.

DashWallet/sl_SI.lproj/Localizable.strings (1)

17-24: No references to removed standalone keys detected

I searched the entire codebase for calls to the old standalone keys (“Allow Face ID access in Settings” and “Allow Touch ID access in Settings”) and found no usages outside of the updated long-form messages in Localizable.strings. All view controllers now reference the combined error strings:

  • SecurityMenuScreen.swift (lines 158–160) uses the full messages via NSLocalizedString.
  • No calls to NSLocalizedString("Allow Face ID access in Settings", …) or NSLocalizedString("Allow Touch ID access in Settings", …) remain.

No further action is required.

DashWallet/en.lproj/Localizable.strings (3)

2370-2376: Ensure single-responsibility keys

“Successful purchase” and “Support” are fairly generic. Double-check no earlier identical keys exist; generic keys increase collision risk when other modules add similar phrases.


2814-2816: Possible duplicate key “Voting”

There are already many voting-related keys. If “Voting” as a bare title already exists, one of them will be ignored at run-time. Verify uniqueness.


334-336: ✅ “Biometrics Access Required” key is defined once and in use
Verified that there is exactly one entry of this key in each Localizable.strings file and it’s referenced in SecurityMenuScreen.swift (line 98). No duplicates found—safe to merge.

DashWallet/ms.lproj/Localizable.strings (4)

334-336: Looks good – clear and concise alert title

No issues spotted with the addition of "Biometrics Access Required". The phrasing is concise and matches Apple’s terminology for Face ID / Touch ID.


1001-1002: Addition approved

"Full Resync" is a useful, self-explanatory tool label and follows existing noun-phrase style.


2072-2074: No concerns

"Resync Masternode List" is clear and technically accurate. Implementation detail looks fine.


2815-2816: Entry approved

"Voting" key/value pair added without duplication elsewhere in the file and follows existing capitalization style.

DashWallet/eo.lproj/Localizable.strings (1)

334-336: New keys lack Esperanto translations

The newly added entries are still in English:

• “Biometrics Access Required”
• “Full Resync”
• “Rescan Transactions (Suggested)”
• “Resync Masternode List”
• “Successful purchase” / “Support”
• “Voting”

This file is for eo.lproj, so untranslated strings will surface in-app. Please supply Esperanto equivalents (or mark for later translation) before shipping.

Also applies to: 1000-1002, 2051-2053, 2072-2074, 2371-2376, 2814-2816

DashWallet/dashwallet-Bridging-Header.h (1)

27-28: Well-organized imports for the UI redesign

The new imports properly support the SwiftUI migration:

  • Chain management support with DSChainManager.h and DSChain.h
  • Comprehensive security UI components for the new architecture
  • Proper use of conditional compilation for platform-specific features

Also applies to: 137-137, 156-179

DashWallet/Sources/UI/SwiftUI Components/MenuItem.swift (1)

112-118: Good refactoring to improve component architecture

The refactoring properly encapsulates the interaction logic within a Button and makes the isToggled state private, which improves the component's architecture. The SwiftUI implementation follows best practices for state management.

Also applies to: 35-35

DashWallet/cs.lproj/Localizable.strings (2)

357-357: Verify if "Buy & Sell Dash" should remain in English

The string "Buy & Sell Dash" was reverted from Czech back to English. Please verify if this is intentional for branding consistency or if it should be translated to Czech like other UI strings.


335-335: New localization strings properly added for UI redesign

The new strings for biometrics access, resync options, support, voting, and purchase success are correctly formatted and align with the UI redesign objectives.

Also applies to: 1001-1001, 1052-1052, 1073-1073, 2372-2372, 2375-2375, 2815-2815

DashWallet/de.lproj/Localizable.strings (1)

2815-2816: “Voting” label untranslated

Several prior entries keep the English noun, but other German screens use “Abstimmung”. Pick one and stay consistent; recommendation:

-"Voting" = "Voting";
+"Voting" = "Abstimmung";

Confirm whether the product copy guidelines prefer the English term. If so, ignore; otherwise update for consistency.

DashWallet/sk.lproj/Localizable.strings (1)

357-358: Verify intention to revert “Buy & Sell Dash” to English

Earlier Slovak translation existed ("Kúpiť & Predať Dash").
If the UX spec indeed calls for English branding, ignore; otherwise restore the Slovak version.

DashWallet/Sources/UI/Menu/Security/SecurityMenuScreen.swift (6)

1-20: Clean file structure and appropriate imports.

The copyright header follows project conventions and the imports are minimal and appropriate for the mixed SwiftUI/UIKit architecture.


155-172: Helper methods are well-implemented.

The biometrics alert message computation handles different biometric types appropriately with proper fallback, and the settings opening method follows iOS conventions.


174-189: Delegate implementation follows correct patterns.

The nested delegate class properly conforms to the required Objective-C protocols and provides a clean callback mechanism for handling navigation dismissal.


92-97: Good reactive programming pattern.

The use of onReceive to handle view model state changes is a clean reactive programming approach that maintains proper separation between the view and view model.


175-189: Well-designed delegate pattern for UIKit integration.

The internal delegate class properly handles the bridge between SwiftUI and UIKit view controllers, providing clean completion callbacks.


74-74: showChevron parameter is valid
The MenuItem SwiftUI view still declares and uses a showChevron: Bool property, so passing showChevron: false in SecurityMenuScreen.swift is correct and requires no change.

DashWallet/zh.lproj/Localizable.strings (1)

1-10: File structure follows localization best practices.

The localization file maintains proper format and structure with appropriate comments and key-value organization.

DashWallet/zh-Hant-TW.lproj/Localizable.strings (1)

2375-2376: New key “Support” overlaps existing “Contact Support” and is untranslated

  1. Supply a Chinese translation.
  2. Verify no key-collision with any other "Support" entry in other lproj files.
-"Support" = "Support";
+"Support" = "支援";
DashWallet/Sources/UI/Menu/Settings/SettingsScreen.swift (1)

154-158: Debug-only feature verified

The resyncMasternodeList() API in SettingsMenuViewModel.swift and its corresponding button in SettingsScreen.swift are both enclosed in #if DEBUG blocks, so this option won’t be exposed in release builds.

No further changes are required if hiding this functionality in production is intentional. If you do want this available in production, remove or adjust the #if DEBUG guards around:

  • DashWallet/Sources/UI/Menu/Settings/SettingsScreen.swift (lines 154–158)
  • DashWallet/Sources/UI/Menu/Settings/SettingsMenuViewModel.swift (around the resyncMasternodeList() definition)
DashWallet/tr.lproj/Localizable.strings (2)

17-17: LGTM! Enhanced biometric access messages provide better user guidance.

The updated messages now include actionable instructions to allow access in Settings, which improves the user experience compared to simple denial messages.

Also applies to: 23-23


357-357: Verify the reversion from Turkish to English for "Buy & Sell Dash".

The translation has been reverted from Turkish ("Al & Sat") back to English. Please confirm if this is intentional, as it breaks localization consistency for Turkish users.

DashWallet/id.lproj/Localizable.strings (1)

357-357: Verify intentional reversion of "Buy & Sell Dash" translation.

This string was reverted from Indonesian translation back to English, creating inconsistency with the localization approach. Please confirm this is intentional.

If this reversion is unintentional, consider restoring the Indonesian translation:

-"Buy & Sell Dash" = "Buy & Sell Dash";
+"Buy & Sell Dash" = "Beli & Jual Dash";

If intentional (e.g., feature unavailable in Indonesia), consider documenting the reason for consistency.

DashWallet/ro.lproj/Localizable.strings (1)

17-24: Provide actual Romanian translations for the updated biometric-access strings

Both Face ID and Touch ID denial messages were extended with “Allow … access in Settings”, yet the translation side remains unchanged (English text duplicated). This defeats localisation and will surface English to Romanian users.

-"%@ is not allowed to access Face ID. Allow Face ID access in Settings" = "%@ is not allowed to access Face ID. Allow Face ID access in Settings";
+"%@ is not allowed to access Face ID. Allow Face ID access in Settings" = "%@ nu are permisiunea de a folosi Face ID. Permite accesul în Configurări";
-
-"%@ is not allowed to access Touch ID. Allow Touch ID access in Settings" = "%@ is not allowed to access Touch ID. Allow Touch ID access in Settings";
+"%@ is not allowed to access Touch ID. Allow Touch ID access in Settings" = "%@ nu are permisiunea de a folosi Touch ID. Permite accesul în Configurări";

(The key on the left must stay English; only the right-hand translation changes.)

DashWallet/Sources/UI/Main/MainTabbarController.swift (2)

86-86: LGTM: Property type correctly updated for Swift migration.

The property type change from DWMainMenuViewController? to MainMenuViewController? properly aligns with the migration from Objective-C to Swift implementation.


337-339: LGTM: Delegate protocol correctly updated for Swift migration.

The protocol conformance change from DWMainMenuViewControllerDelegate to MainMenuViewControllerDelegate properly aligns with the migration to the new Swift implementation.

DashWallet/Sources/UI/Menu/Tools/ToolsMenuViewModel.swift (3)

41-80: Well-structured menu initialization with proper memory management.

The menu items setup correctly uses weak self to prevent retain cycles and follows a consistent pattern.


82-87: Proper state cleanup implementation.

The reset method correctly clears all navigation-related state, following the same pattern used in other menu view models.


89-106: Excellent async/await implementation for legacy callback API.

The CSV export functionality correctly bridges the callback-based TaxReportGenerator to modern Swift concurrency using withCheckedThrowingContinuation.

DashWallet/Sources/UI/Menu/Main/MainMenuViewModel.swift (3)

21-71: Well-designed conditional compilation and delegate pattern.

The code properly separates DashPay-specific functionality and uses weak delegate references to prevent retain cycles.


75-146: Clean and consistent menu structure implementation.

The menu building properly handles conditional features and maintains a consistent pattern for all items.


150-171: Proper authentication flow for sensitive operations.

The code correctly requires authentication before accessing the buy/sell portal and handles the credits warning display.

DashWallet/Sources/UI/Menu/Main/MainMenuViewController.swift (1)

384-514: Well-structured DashPay integration with proper flow control.

The DashPay-specific navigation and join flow is properly implemented with appropriate null checks and completion handling.

DashWallet/Sources/UI/Menu/Settings/SettingsMenuViewModel.swift (4)

116-121: LGTM! Proper handling of toggle state

The notification toggle properly uses weak self capture, safely unwraps, and correctly updates both the local state and global options.


210-227: Well-implemented async CSV export with proper error handling

The CSV export functionality correctly bridges the callback-based API to async/await using withCheckedThrowingContinuation, properly handling both success and error cases.


53-58: Avoid force unwrapping singleton instances

The code uses force unwrapping (!) when accessing singleton instances. This could cause crashes if the singletons are not properly initialized.

Consider using optional chaining or guard statements:

-        self.notificationsEnabled = DWGlobalOptions.sharedInstance().localNotificationsEnabled
+        self.notificationsEnabled = DWGlobalOptions.sharedInstance()?.localNotificationsEnabled ?? false

Likely an incorrect or invalid review comment.


188-198: Safely access chainManager to prevent crashes

The blockchain rescan methods force unwrap the chainManager, which could crash if it's nil.

     func rescanTransactions() {
         DWGlobalOptions.sharedInstance().isResyncingWallet = true
-        let chainManager = DWEnvironment.sharedInstance().currentChainManager
-        chainManager.syncBlocksRescan()
+        guard let chainManager = DWEnvironment.sharedInstance()?.currentChainManager else {
+            // Log error or show alert
+            return
+        }
+        chainManager.syncBlocksRescan()
     }

Likely an incorrect or invalid review comment.

DashWallet.xcodeproj/project.pbxproj (9)

184-184: Standard file addition looks good.

The addition of SettingsScreen.swift to the build sources is properly configured.


504-505: Proper multi-target configuration.

The SettingsMenuViewModel.swift is correctly added to multiple build targets.


533-544: Menu system migration files properly configured.

All new Swift files for the menu system redesign are correctly added to the build phases for multiple targets.


625-626: ToolsMenuScreen properly added.

The Swift file is correctly configured in the build phases.


1056-1056: File references properly configured.

All new Swift files have correct file type declarations and path configurations.

Also applies to: 1956-1956, 2430-2430, 2450-2455, 2504-2504


4187-4230: Project structure well organized.

The new Swift files are properly organized into logical groups (Main, Security, Settings, Tools) following iOS project conventions.


8498-8498: Build phases correctly configured.

All new Swift files are properly added to their respective compile sources build phases ensuring correct compilation.

Also applies to: 8519-8519, 8571-8571, 8662-8662, 8849-8852, 8873-8874, 9023-9023, 9142-9142, 9237-9238, 9294-9294, 9513-9513, 9542-9543, 9872-9872, 9879-9879


180-11990: Verify complete migration from Objective-C to Swift.

The project file shows additions of new Swift menu components. Please ensure that:

  1. All references to removed Objective-C files have been cleaned up
  2. The bridging header has been updated appropriately
  3. No build settings reference the removed files

10670-10670: No action needed: watchOS version bump matches main app version

The MARKETING_VERSION for both watchOS targets and the main app is now consistently set to 8.4.1. No further changes are required.

DashWallet/Sources/UI/Menu/MenuItemModel.swift (3)

20-20: Good addition of Hashable conformance.

Adding Hashable conformance is excellent for SwiftUI list performance and state management, especially when used in ForEach loops.


29-29: Correct removal of @State property wrapper.

Removing @State from isToggled is the right approach. @State should only be used in SwiftUI Views, not in model classes. This change aligns with proper SwiftUI architecture patterns.


47-49: Proper Hashable implementation.

The hash(into:) method correctly uses the unique id property, which is consistent with the Equatable implementation. This ensures proper hash-based collection behavior.

Comment thread DashWallet/da.lproj/Localizable.strings
Comment thread DashWallet/da.lproj/Localizable.strings
Comment thread DashWallet/da.lproj/Localizable.strings
Comment thread DashWallet/da.lproj/Localizable.strings
Comment thread DashWallet/da.lproj/Localizable.strings
Comment thread DashWallet/uk.lproj/Localizable.strings
Comment thread DashWallet/uk.lproj/Localizable.strings
Comment thread DashWallet/uk.lproj/Localizable.strings
Comment thread DashWallet/uk.lproj/Localizable.strings
Comment thread DashWallet/uk.lproj/Localizable.strings
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review continued from previous batch...

Comment thread DashWallet/ar.lproj/Localizable.strings
Comment thread DashWallet/ar.lproj/Localizable.strings
Comment thread DashWallet/ar.lproj/Localizable.strings
Comment thread DashWallet/ar.lproj/Localizable.strings
Comment thread DashWallet/ar.lproj/Localizable.strings
Comment thread DashWallet/th.lproj/Localizable.strings
Comment thread DashWallet/th.lproj/Localizable.strings
Comment thread DashWallet/th.lproj/Localizable.strings
Comment thread DashWallet/th.lproj/Localizable.strings
Comment thread DashWallet/th.lproj/Localizable.strings
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review continued from previous batch...

Comment thread DashWallet/cs.lproj/Localizable.strings
Comment thread DashWallet/de.lproj/Localizable.strings
Comment thread DashWallet/de.lproj/Localizable.strings
Comment thread DashWallet/de.lproj/Localizable.strings
Comment thread DashWallet/de.lproj/Localizable.strings
Comment thread DashWallet/zh-Hant-TW.lproj/Localizable.strings
Comment thread DashWallet/zh-Hant-TW.lproj/Localizable.strings
Comment thread DashWallet/zh-Hant-TW.lproj/Localizable.strings
Comment thread DashWallet/zh.lproj/Localizable.strings
Comment thread DashWallet/zh.lproj/Localizable.strings
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review continued from previous batch...

Comment thread DashWallet/id.lproj/Localizable.strings
Comment thread DashWallet/it.lproj/Localizable.strings
Comment thread DashWallet/it.lproj/Localizable.strings
Comment thread DashWallet/it.lproj/Localizable.strings
Comment thread DashWallet/it.lproj/Localizable.strings
Comment thread DashWallet/zh-Hans.lproj/Localizable.strings
Comment thread DashWallet/zh-Hans.lproj/Localizable.strings
Comment thread DashWallet/zh-Hans.lproj/Localizable.strings
Comment thread DashWallet/zh-Hans.lproj/Localizable.strings
Comment thread DashWallet/zh-Hans.lproj/Localizable.strings
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review continued from previous batch...

Comment thread DashWallet/fr.lproj/Localizable.strings
Comment thread DashWallet/fr.lproj/Localizable.strings
Comment thread DashWallet/fr.lproj/Localizable.strings
Comment thread DashWallet/fr.lproj/Localizable.strings
Comment thread DashWallet/fr.lproj/Localizable.strings
Comment thread DashWallet/vi.lproj/Localizable.strings
Comment thread DashWallet/vi.lproj/Localizable.strings
Comment thread DashWallet/vi.lproj/Localizable.strings
Comment thread DashWallet/vi.lproj/Localizable.strings
Comment thread DashWallet/vi.lproj/Localizable.strings
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review continued from previous batch...

Comment thread DashWallet/pl.lproj/Localizable.strings
Comment thread DashWallet/pl.lproj/Localizable.strings
Comment thread DashWallet/pl.lproj/Localizable.strings
Comment thread DashWallet/Sources/UI/Menu/Settings/SettingsMenuViewModel.swift
Copy link
Copy Markdown
Contributor

@HashEngineering HashEngineering left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@Syn-McJ Syn-McJ merged commit 8a408d2 into dashpay:master Jul 28, 2025
3 checks passed
@Syn-McJ Syn-McJ deleted the feat/settings-ui branch July 28, 2025 14:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants