feat: update tool menu items and components#758
Conversation
Replace full-page navigation with SwiftUI bottom sheet presentation for Import Private Key feature. Includes custom grabber, close button, and updated layout matching design specifications. Sheet height set to 460px with proper spacing and content positioning. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Remove AtmDetailsView.swift references from project file - Set build configuration to Debug - Disable implicit dependencies to avoid WatchApp build issues Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Created scripts/prepare-dapi-grpc.sh to pre-generate proto files - Workaround for DAPI-GRPC submodule initialization issue in CocoaPods - Script handles both Release and External cache locations - Modifies podspec to skip failing prepare_command - Updated Podfile.lock with all 49 successfully installed pods - Requires CocoaPods 1.15.2 Usage: Run ./scripts/prepare-dapi-grpc.sh before pod install Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Replace --quiet with --silent flag (1.15.2 doesn't support --quiet) - Fix cd platform command to prevent script errors - Update Podfile.lock checksum from regeneration Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
…ary version - Changed TodayExtension platform from iOS 13.0 to iOS 14.0 - Fixes library mismatch error (was looking for DSDynamicOptions-iOS13.0, now uses DSDynamicOptions) - Consistent with post_install script that sets all iOS targets to 14.0 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add PIGGYCARDS_ENABLED compiler flag to all build configurations (Debug, Testnet, Testflight, Release) - Add GeoRestrictionService.swift to Xcode project with proper build file and group references - Remove hardcoded DSDynamicOptions-iOS14.0 linker flags that prevented successful builds - Add Gray1000 color asset to SharedAssets These changes fix compilation errors introduced when master (with PiggyCards geo-restriction feature) was merged into this branch. The GeoRestrictionService file existed on disk but wasn't in the Xcode project, and the hardcoded linker flags conflicted with CocoaPods configuration. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
feat: add "Import private key" sheet and colors
feat: Update components and "Extend public keys" page
feat: update sheet for the "Extend public key" on the "Tools" page
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds many new xcassets (images and a broad color palette), replaces legacy font tokens with semantic fonts, introduces new button styles and navigation bar components, migrates multiple screens/controllers to SwiftUI hosting and sheets (extended public keys, masternode keys, import private key), updates localization pluralization, and adds UI constants. Changes
Sequence Diagram(s)sequenceDiagram
participant User as User
participant ToolsMenu as ToolsMenuScreen (SwiftUI)
participant Sheet as ImportPrivateKeySheet
participant Host as UIViewController (hosting sheet)
participant Scanner as DWQRScanViewController
User->>ToolsMenu: tap "Import Private Key"
ToolsMenu->>Sheet: set onScanPrivateKey callback
ToolsMenu->>Host: present sheet (UIHostingController)
User->>Sheet: tap "Scan private key"
Sheet->>Host: dismiss sheet
Host->>Scanner: present DWQRScanViewController
Scanner->>Host: didScan / didCancel
Host->>ToolsMenu: notify scan result (via callback)
sequenceDiagram
participant User as User
participant EPV as ExtendedPublicKeysView (SwiftUI)
participant EPVM as ExtendedPublicKeysViewModel
participant Model as ExtendedPublicKeysModel
participant CIF as CIFilter/CIContext
participant System as System Share/Pasteboard
User->>EPV: open "Extended public key (BIP44)"
EPV->>EPVM: request derivation paths
EPVM->>Model: load keys
EPVM->>CIF: generate QR from key string
CIF-->>EPVM: UIImage (qrImage)
EPVM->>EPV: deliver key string + qrImage
User->>EPV: tap copy
EPV->>System: copy to pasteboard
User->>EPV: tap share
EPV->>System: present UIActivityViewController
Estimated code review effort🎯 4 (Complex) | ⏱️ ~75 minutes Possibly related PRs
Poem
✨ Finishing Touches
🧪 Generate unit tests (beta)
|
There was a problem hiding this comment.
Actionable comments posted: 9
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (4)
DashWallet/Sources/UI/DashPay/Setup/CreateUsername/CreateUsernameViewController.swift (1)
249-250:⚠️ Potential issue | 🟡 MinorStale hardcoded date in user-facing string.
The date "March 14, 2024" is now in the past (current date is March 2026). The TODO comment indicates awareness, but this user-facing text should be updated or made dynamic.
Would you like me to help implement a dynamic date calculation based on voting period rules, or open an issue to track this?
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/Sources/UI/DashPay/Setup/CreateUsername/CreateUsernameViewController.swift` around lines 249 - 250, The user-facing string in CreateUsernameViewController (case .warning) contains a stale hardcoded date ("March 14, 2024"); replace it with either a dynamic, computed date or a timeless phrasing: add a votingEndDate property or compute the date from your voting rules inside CreateUsernameViewController, format it with DateFormatter.localizedString(for:dateStyle:timeStyle:) (or use RelativeDateTimeFormatter) and inject that formatted date into the NSLocalizedString placeholder (e.g. NSLocalizedString("The Dash network will vote on this username. We will notify you of the results on %@.", comment: "Usernames")), or change the copy to avoid a date entirely (e.g. "We will notify you when voting concludes."). Update the case .warning branch to use the chosen approach and ensure the string remains localized and tested.DashWallet/Sources/UI/Tx/Details/Views/BlockExplorerSelectionView.swift (1)
3-76:⚠️ Potential issue | 🔴 CriticalRemove the duplicate
BlockExplorerSelectionViewandBlockExplorerdefinitions to fix the compilation error.Two files define these types:
DashWallet/Sources/UI/Tx/Details/BlockExplorerSelectionView.swiftandDashWallet/Sources/UI/Tx/Details/Views/BlockExplorerSelectionView.swift. Swift does not allow duplicate type definitions in the same module and the build will fail.The implementations differ significantly (title text, image sizes, Insight icon name, button styling), so carefully determine which version should be retained and remove the other file or consolidate them.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/Sources/UI/Tx/Details/Views/BlockExplorerSelectionView.swift` around lines 3 - 76, There are duplicate type definitions causing a compile error: remove or consolidate the duplicated BlockExplorerSelectionView and BlockExplorer definitions so only one source of truth remains; decide which implementation to keep (or merge desired differences such as title text, image frame sizing, Insight icon name, button styling, and background/shadow behavior) then delete the other file or move unique changes into the retained BlockExplorerSelectionView and BlockExplorer (refer to the symbols BlockExplorerSelectionView, BlockExplorer, BlockExplorer.title, BlockExplorer.iconName, and the Button/Image layout properties) ensuring the final file exports a single CaseIterable/Identifiable BlockExplorer and one View implementation.DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayScreen.swift (1)
89-121:⚠️ Potential issue | 🟠 MajorLet the status row grow vertically.
These texts are now larger, but the container is still hard-capped to 20pt at Line 121. That makes localized limit strings and especially multiline
error.localizedDescriptionmuch easier to clip, which can hide why the purchase action is unavailable.📐 Suggested fix
- .frame(height: 20) + .frame(minHeight: 20, alignment: .top)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/Sources/UI/Explore` Dash/Views/DashSpend/DashSpendPayScreen.swift around lines 89 - 121, The status row is constrained to .frame(height: 20) which clips multiline status texts (e.g. error.localizedDescription, viewModel.costMessage, viewModel.maximumLimitMessage); remove the hard-coded .frame(height: 20) (or replace it with a flexible minHeight if needed) on the container that holds the texts so the VStack/HStack containing the conditional Text views (where viewModel.error, viewModel.showCost, viewModel.showLimits are used) can grow vertically to fit localized/multiline content.DashWallet/Sources/UI/SwiftUI Components/Color+DWStyle.swift (1)
37-218:⚠️ Potential issue | 🔴 CriticalFive color tokens lack corresponding .colorset assets and will fail at runtime.
Missing colorsets:
Gray300Alpha60,Gray300Alpha70,Gray300Alpha80,Gray300Alpha90, andTransparent. Add these to the design system before merging. Additionally, refactor thebackgroundalias to forward tosecondaryBackgroundinstead of duplicating the asset lookup—this prevents desynchronization if the underlying asset changes.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/Sources/UI/SwiftUI` Components/Color+DWStyle.swift around lines 37 - 218, The code references five missing Color assets (Gray300Alpha60, Gray300Alpha70, Gray300Alpha80, Gray300Alpha90, Transparent) which will crash at runtime—add .colorset assets with those exact names to the design system; also change the background alias to forward to secondaryBackground (i.e., have background return the same Color as static var secondaryBackground) instead of calling Color("BackgroundColor") directly so it stays in sync with secondaryBackground/primaryBackground mapping (see static vars gray300Alpha60, gray300Alpha70, gray300Alpha80, gray300Alpha90, Transparent, primaryBackground, secondaryBackground, background).
🧹 Nitpick comments (21)
Shared/Resources/SharedAssets.xcassets/Colors/System/GreenColor.colorset/Contents.json (1)
3-14: Consider adding dark mode appearance variants.The color currently uses only the "universal" idiom, meaning it will appear the same in both light and dark modes. If the app supports dark mode, consider adding appearance-specific variants to ensure proper contrast and visual hierarchy.
💡 Example with dark mode variant
{ "colors" : [ { "color" : { "color-space" : "srgb", "components" : { "alpha" : "1.000", "blue" : "0x89", "green" : "0xB4", "red" : "0x3E" } }, - "idiom" : "universal" + "idiom" : "universal", + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "light" + } + ] + }, + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xA0", + "green" : "0xC8", + "red" : "0x5A" + } + }, + "idiom" : "universal", + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ] }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@Shared/Resources/SharedAssets.xcassets/Colors/System/GreenColor.colorset/Contents.json` around lines 3 - 14, The Contents.json for GreenColor.colorset currently only defines a single "universal" color entry; add an appearance-specific variant for dark mode by replacing/augmenting the existing item with an array of color entries that include the original light (or universal) definition and a second entry with "appearance":"luminosity" (value "dark") that provides the adjusted color components for dark mode; update the "color" object for the dark entry with appropriate RGB/alpha values to preserve contrast and keep the same "idiom":"universal" and matching asset name (GreenColor.colorset).DashWallet/Sources/UI/Menu/Tools/Masternode Keys/DerivationPathKeys/Views/DerivationPathKeysCell.swift (1)
106-109: Consider clearer constraint naming.The property
trailingConstraint(line 109) is actually thecopyButton's trailing constraint, notmainStackView's. This could cause confusion during future maintenance. Consider renaming for clarity:♻️ Suggested naming improvement
- private var trailingConstraint: NSLayoutConstraint! + private var copyButtonTrailingConstraint: NSLayoutConstraint!And update references in
applyMenuSpacingandconfigureHierarchyaccordingly.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/Sources/UI/Menu/Tools/Masternode` Keys/DerivationPathKeys/Views/DerivationPathKeysCell.swift around lines 106 - 109, The trailingConstraint property is misnamed because it references copyButton.trailingAnchor rather than mainStackView; rename trailingConstraint to copyButtonTrailingConstraint (or similar) and update all usages, including in configureHierarchy and applyMenuSpacing, to use the new property name so intent is clear and future maintenance is less error-prone; ensure the property declaration and any assignments or activations are renamed consistently.DashWallet/Resources/AppAssets.xcassets/Navigation bar/toolbar-back.imageset/Contents.json (1)
1-23: Consider addingtemplate-rendering-intentfor toolbar back icon.The similar
controls-back.imagesetincludes"template-rendering-intent": "template", but thistoolbar-back.imagesetdoes not. For generic UI navigation icons, template rendering allows the icon to inherit the system tint color, which is useful for supporting different color schemes.If this icon should match the parent view's tint (standard behavior for toolbar icons), consider adding:
Suggested change
"info" : { "author" : "xcode", "version" : 1 - } + }, + "properties" : { + "template-rendering-intent" : "template" + } }If the icon has intentionally baked-in colors that should be preserved, this can be ignored.
Based on learnings: "set template-rendering-intent to 'template' for generic/system UI icons that should inherit the system tint."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/Resources/AppAssets.xcassets/Navigation` bar/toolbar-back.imageset/Contents.json around lines 1 - 23, The toolbar-back.imageset Contents.json is missing the template-rendering-intent field so the back icon won't inherit tint; add a top-level "template-rendering-intent": "template" entry in the JSON (same placement as in controls-back.imageset) so the toolbar-back asset renders as a template image and respects the parent view/system tint; update the Contents.json for toolbar-back.imageset accordingly.DashWallet/Resources/AppAssets.xcassets/Menu/icon-close-sheet-white.imageset/Contents.json (1)
1-23: Consider addingtemplate-rendering-intentfor consistency with other toolbar icons.Other toolbar icons in this PR (toolbar-plus, toolbar-close) include
template-rendering-intent: "template"to enable dynamic tinting. If this close icon should inherit the system tint color, consider adding the properties section:Suggested addition
"info" : { "author" : "xcode", "version" : 1 - } + }, + "properties" : { + "template-rendering-intent" : "template" + } }If this icon is intentionally designed to always render as white (not tinted), this can be ignored. Based on learnings: for generic/system UI icons that should inherit the system tint, set template-rendering-intent to 'template'.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/Resources/AppAssets.xcassets/Menu/icon-close-sheet-white.imageset/Contents.json` around lines 1 - 23, The Contents.json for the icon-close-sheet-white.imageset is missing a template-rendering-intent entry used by other toolbar icons; if this asset should tint like toolbar-plus/toolbar-close, add a "properties" object with "template-rendering-intent": "template" to the asset's Contents.json (inside the existing JSON root) for icon-close-sheet-white; if the icon must remain always white, leave as-is.DashWallet/Sources/UI/SwiftUI Components/Button.swift (1)
134-143: Consider consolidating duplicate foreground color cases.The
.filledand.filledBluecases both returnColor.white. These could be combined for maintainability:Optional refactor
switch style { - case .filled: - return Color.white - case .filledBlue: + case .filled, .filledBlue: return Color.white case .tintedBlue: return Color.blue🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/Sources/UI/SwiftUI` Components/Button.swift around lines 134 - 143, The switch in the foreground-color logic repeats Color.white for .filled and .filledBlue; update the switch in the Button component so the .filled and .filledBlue cases are consolidated (e.g., use a single case with multiple patterns or a fallthrough) and return Color.white once, keeping other cases (.tintedBlue, default) unchanged; touch the switch that references style (cases: .filled, .filledBlue, .tintedBlue, default) to reduce duplication and improve maintainability.DashWallet/Sources/UI/SwiftUI Components/NavigationBar.swift (3)
100-102: SwiftLint: Move@Environmentattribute to its own line.Same issue as in
NavBarBack- the attribute should be on a separate line.🔧 Proposed fix
struct NavBarBackPlus: View { + `@Environment`(\.colorScheme) + private var colorScheme - `@Environment`(\.colorScheme) private var colorScheme let onBack: () -> Void🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/Sources/UI/SwiftUI` Components/NavigationBar.swift around lines 100 - 102, The `@Environment` attribute in the NavBarBackPlus view is on the same line as the property declaration, violating SwiftLint style; update NavBarBackPlus (and mirror the fix used in NavBarBack) so that the `@Environment`(\.colorScheme) attribute is placed on its own line directly above the property declaration (retain the private var name colorScheme and the onBack closure signature unchanged).
176-204: Consider adding dark mode support toNavBarClosefor consistency.
NavBarBackandNavBarBackPlususe@Environment(\.colorScheme)to switch icons based on color scheme, butNavBarClosedoesn't. Iftoolbar-closehas a dark mode variant, consider adding the same pattern for consistency.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/Sources/UI/SwiftUI` Components/NavigationBar.swift around lines 176 - 204, NavBarClose currently always uses Image("toolbar-close") and doesn't adapt to dark mode; add an `@Environment`(\.colorScheme) private var colorScheme to the NavBarClose view and switch the asset name based on colorScheme (e.g., "toolbar-close" vs "toolbar-close-dark" or whatever dark variant exists) where Image("toolbar-close") is used, mirroring the pattern in NavBarBack/NavBarBackPlus so the close icon uses the appropriate asset for light and dark themes.
43-45: SwiftLint: Move@Environmentattribute to its own line.The
@Environmentattribute should be on its own line per project SwiftLint configuration.🔧 Proposed fix
struct NavBarBack: View { + `@Environment`(\.colorScheme) + private var colorScheme - `@Environment`(\.colorScheme) private var colorScheme let onBack: () -> Void🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/Sources/UI/SwiftUI` Components/NavigationBar.swift around lines 43 - 45, Move the SwiftUI environment attribute onto its own line to satisfy SwiftLint: in the NavBarBack struct, separate the attribute and property so that the `@Environment`(\.colorScheme) attribute is on its own line followed by the declaration of private var colorScheme; keep the onBack: () -> Void property unchanged.DashWallet/Sources/UI/Menu/Tools/Masternode Keys/DerivationPathKeys/DerivationPathKeysView.swift (4)
198-199: SwiftLint: Move@ViewBuilderattribute to its own line.Per the static analysis hint, attributes should be on their own lines in functions.
🔧 Proposed fix
+ `@ViewBuilder` - `@ViewBuilder` private var copiedBackground: some View {(Move
@ViewBuilderto a separate line aboveprivate var)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/Sources/UI/Menu/Tools/Masternode` Keys/DerivationPathKeys/DerivationPathKeysView.swift around lines 198 - 199, Move the `@ViewBuilder` attribute to its own line above the property declaration for copiedBackground to satisfy SwiftLint; locate the private computed view var named copiedBackground and place the `@ViewBuilder` attribute on a separate line immediately above "private var copiedBackground: some View" so the attribute is not on the same line as the declaration.
58-58: SwiftLint: Remove redundant= nilinitialization.Optionals are implicitly initialized to
nil.🔧 Proposed fix
- `@State` private var copiedValue: String? = nil + `@State` private var copiedValue: String?🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/Sources/UI/Menu/Tools/Masternode` Keys/DerivationPathKeys/DerivationPathKeysView.swift at line 58, The `@State` property copiedValue in DerivationPathKeysView (symbol: copiedValue) is redundantly initialized to nil; remove the explicit "= nil" so the declaration becomes an optional without initializer (e.g., `@State` private var copiedValue: String?) to satisfy SwiftLint and rely on implicit nil initialization. Ensure you update only the copiedValue declaration in DerivationPathKeysView.swift.
145-147: SwiftLint: Move@Environmentattribute to its own line.🔧 Proposed fix
- `@Environment`(\.colorScheme) private var colorScheme + `@Environment`(\.colorScheme) + private var colorScheme🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/Sources/UI/Menu/Tools/Masternode` Keys/DerivationPathKeys/DerivationPathKeysView.swift around lines 145 - 147, Move the `@Environment` attribute onto its own line to satisfy SwiftLint: locate the property declaration "private var colorScheme" in the DerivationPathKeysView (the line with "@Environment(\\.colorScheme) private var colorScheme") and split it into two lines so the attribute sits above the property (i.e., place "@Environment(\\.colorScheme)" on its own line immediately before "private var colorScheme"). Ensure formatting matches surrounding attributes style.
131-137: Hardcoded dark blur style may not suit light mode.
BackgroundBlurViewuses.systemUltraThinMaterialDarkregardless of color scheme. Consider parameterizing the blur style or using a color-scheme-aware material.🔧 Proposed fix
struct BackgroundBlurView: UIViewRepresentable { + var style: UIBlurEffect.Style = .systemUltraThinMaterial + func makeUIView(context: Context) -> UIVisualEffectView { - UIVisualEffectView(effect: UIBlurEffect(style: .systemUltraThinMaterialDark)) + UIVisualEffectView(effect: UIBlurEffect(style: style)) }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/Sources/UI/Menu/Tools/Masternode` Keys/DerivationPathKeys/DerivationPathKeysView.swift around lines 131 - 137, BackgroundBlurView currently hardcodes .systemUltraThinMaterialDark in makeUIView which ignores light/dark modes; update it to pick a color-scheme-aware material instead by either adding a configurable property (e.g., init(style: UIBlurEffect.Style) or material: UIBlurEffect.Style) and applying that in makeUIView, or detect the current trait collection in updateUIView (use uiView.traitCollection.userInterfaceStyle) and set uiView.effect = UIBlurEffect(style: appropriateMaterial) so the blur switches between dark and light-appropriate UIBlurEffect styles; adjust the BackgroundBlurView initializer and the makeUIView/updateUIView methods accordingly.DashWallet/Sources/UI/Explore Dash/Views/DashSpend/GiftCardDetailsView.swift (1)
399-403: Consider caching theDateFormatterto avoid repeated allocations.Creating a
DateFormatteris expensive. As a computed property, a new formatter is created on every access. Consider making it a static property or lazy var.🔧 Proposed fix
- private var dateFormatter: DateFormatter { - let formatter = DateFormatter() - formatter.dateFormat = "MMMM dd, yyyy 'at' h:mm a" - return formatter + private static let dateFormatter: DateFormatter = { + let formatter = DateFormatter() + formatter.dateFormat = "MMMM dd, yyyy 'at' h:mm a" + return formatter + }()Then update the usage on line 76 to
Self.dateFormatter.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/Sources/UI/Explore` Dash/Views/DashSpend/GiftCardDetailsView.swift around lines 399 - 403, The computed property dateFormatter currently allocates a new DateFormatter on every access; change it to a shared cached formatter (e.g., make dateFormatter a private static let initialized via a closure or a private lazy var) and preserve the same dateFormat "MMMM dd, yyyy 'at' h:mm a"; then update all call sites to reference the cached formatter (use Self.dateFormatter where appropriate) so the formatter is reused instead of re-created on each access.DashWallet/Sources/UI/Menu/Tools/ImportWallet/ImportPrivateKeySheet.swift (3)
21-22: Move@Environmentattributes to separate lines.SwiftLint prefers attributes with arguments on their own lines for readability.
♻️ Suggested fix
- `@Environment`(\.presentationMode) private var presentationMode - `@Environment`(\.colorScheme) private var colorScheme + `@Environment`(\.presentationMode) + private var presentationMode + + `@Environment`(\.colorScheme) + private var colorScheme🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/Sources/UI/Menu/Tools/ImportWallet/ImportPrivateKeySheet.swift` around lines 21 - 22, The two `@Environment` attributes on ImportPrivateKeySheet (presentationMode and colorScheme) are on the same line as other code; split them so each attribute with arguments sits alone on its own line above the property declaration (i.e., place `@Environment`(\.presentationMode) on its own line immediately above the private var presentationMode declaration and likewise put `@Environment`(\.colorScheme) on its own line immediately above the private var colorScheme declaration) to satisfy SwiftLint formatting rules.
69-80: Consider using semantic font tokens for consistency.The PR introduces semantic font tokens (e.g.,
.title1,.subhead) in other files, but this sheet uses raw.system(size:weight:)calls. Consider using the new design tokens for consistency.♻️ Suggested fix example
Text(NSLocalizedString("Import private key", comment: "")) - .font(.system(size: 28, weight: .bold)) + .font(.title1) .foregroundColor(Color.primaryText) .multilineTextAlignment(.center) .fixedSize(horizontal: false, vertical: true) Text(NSLocalizedString("This action will move all coins from the Dash paper wallet to your DashPay app on this device.", comment: "")) - .font(.system(size: 15)) + .font(.subhead) .foregroundColor(Color.secondaryText)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/Sources/UI/Menu/Tools/ImportWallet/ImportPrivateKeySheet.swift` around lines 69 - 80, The two Text views in ImportPrivateKeySheet.swift use raw .font(.system(size:weight:)) calls; replace them with the app's semantic tokens (e.g., use .font(.title1) for the "Import private key" header and .font(.subhead) or the appropriate body token for the descriptive paragraph) so typography matches the rest of the app; update any weight/size-specific styling by choosing the semantic token that preserves the intended emphasis and remove the explicit .system(...) usages to ensure consistency with other components using .title1/.subhead.
38-51: Use modern Button initializer syntax.SwiftLint flags the trailing closure usage. The modern SwiftUI Button syntax with explicit
label:parameter is cleaner.♻️ Suggested fix
- Button(action: { + Button { presentationMode.wrappedValue.dismiss() - }) { + } label: { Image(colorScheme == .dark ? "icon-close-sheet-white" : "icon-close-sheet") .resizable() .aspectRatio(contentMode: .fit) .frame(width: 9, height: 9) .foregroundColor(Color.primaryText) .frame(width: 34, height: 34) .overlay( Circle() .stroke(Color.gray300.opacity(0.3), lineWidth: 1.5) ) }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/Sources/UI/Menu/Tools/ImportWallet/ImportPrivateKeySheet.swift` around lines 38 - 51, Replace the trailing-closure Button usage with the modern explicit label initializer to satisfy SwiftLint: change the current Button(action: { presentationMode.wrappedValue.dismiss() }) { ... } to use Button(action: { presentationMode.wrappedValue.dismiss() }, label: { Image(colorScheme == .dark ? "icon-close-sheet-white" : "icon-close-sheet") ... }) so the action remains the same (presentationMode.wrappedValue.dismiss()) and the existing Image/overlay/Circle styling is moved into the label closure; locate this Button in ImportPrivateKeySheet and update the initializer accordingly.DashWallet/Sources/UI/Menu/Main/MainMenuViewController.swift (3)
622-644: Wrap debug print statements in#if DEBUGblocks in QRScanDelegate.The debug print statements in the
QRScanDelegateclass should also be wrapped for consistency and performance.♻️ Suggested fix
init(viewController: UIViewController) { self.viewController = viewController + `#if` DEBUG print("🔍 DEBUG: QRScanDelegate initialized") + `#endif` } func qrScanModel(_ viewModel: DWQRScanModel, didScanPaymentInput paymentInput: DWPaymentInput) { + `#if` DEBUG print("🔍 DEBUG: didScanPaymentInput called") + `#endif` // Handle scanned private key if needed viewController?.dismiss(animated: true, completion: { + `#if` DEBUG print("🔍 DEBUG: Scanner dismissed after scan") + `#endif` }) } func qrScanModelDidCancel(_ viewModel: DWQRScanModel) { + `#if` DEBUG print("🔍 DEBUG: qrScanModelDidCancel called - X button pressed") + `#endif` // User pressed X button - just dismiss viewController?.dismiss(animated: true, completion: { + `#if` DEBUG print("🔍 DEBUG: Scanner dismissed after cancel") + `#endif` }) }As per coding guidelines: "Wrap debug print statements in
#ifDEBUG blocks or use conditional compilation to prevent performance impact from excessive logging."🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/Sources/UI/Menu/Main/MainMenuViewController.swift` around lines 622 - 644, Wrap the debug print statements in QRScanDelegate inside conditional compilation so they only run in debug builds: update init(viewController:), qrScanModel(_:didScanPaymentInput:), and qrScanModelDidCancel(_:) to enclose each print call (or the whole debug block) in `#if` DEBUG ... `#endif`; ensure you preserve existing dismiss/completion behavior and weak viewController usage while removing plain print calls from release builds.
145-145: Remove explicitnilinitialization for optional.SwiftLint correctly flags this: optionals are implicitly initialized to
nil.♻️ Suggested fix
- `@State` private var qrScanDelegate: MainMenuScreen.QRScanDelegate? = nil + `@State` private var qrScanDelegate: MainMenuScreen.QRScanDelegate?🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/Sources/UI/Menu/Main/MainMenuViewController.swift` at line 145, Remove the explicit "= nil" initializer from the optional state property to satisfy SwiftLint and Swift conventions: update the `@State` property declaration for qrScanDelegate (type MainMenuScreen.QRScanDelegate?) in MainMenuViewController.swift so it is declared without an explicit nil assignment (leave it as an optional without initialization).
324-346: Wrap debug print statements in#if DEBUGblocks.Per coding guidelines, debug print statements should be wrapped in
#if DEBUGblocks to prevent performance impact in release builds.♻️ Suggested fix
- print("🔍 DEBUG: onImportPrivateKey called from Tools menu") + `#if` DEBUG + print("🔍 DEBUG: onImportPrivateKey called from Tools menu") + `#endif` // Present scanner directly without switching tabs let scannerVC = DWQRScanViewController() scannerVC.modalPresentationStyle = .fullScreen // Create and set delegate to handle dismissal let delegate = MainMenuScreen.QRScanDelegate(viewController: scannerVC) self.qrScanDelegate = delegate scannerVC.model.delegate = delegate - print("🔍 DEBUG: About to present scanner from vc: \(self.vc)") + `#if` DEBUG + print("🔍 DEBUG: About to present scanner from vc: \(self.vc)") + `#endif` // Present from the topmost view controller if let topVC = self.vc.topViewController { - print("🔍 DEBUG: Presenting from top VC: \(topVC)") + `#if` DEBUG + print("🔍 DEBUG: Presenting from top VC: \(topVC)") + `#endif` topVC.present(scannerVC, animated: true, completion: { - print("🔍 DEBUG: Scanner presented successfully") + `#if` DEBUG + print("🔍 DEBUG: Scanner presented successfully") + `#endif` }) } else { - print("🔍 DEBUG: No top VC, presenting from nav controller") + `#if` DEBUG + print("🔍 DEBUG: No top VC, presenting from nav controller") + `#endif` self.vc.present(scannerVC, animated: true, completion: nil) }As per coding guidelines: "Wrap debug print statements in
#ifDEBUG blocks or use conditional compilation to prevent performance impact from excessive logging."🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/Sources/UI/Menu/Main/MainMenuViewController.swift` around lines 324 - 346, There are unguarded debug print statements in the onImportPrivateKey flow inside MainMenuViewController (prints around creating DWQRScanViewController, assigning MainMenuScreen.QRScanDelegate, and presenting from self.vc/topViewController). Wrap each print(...) call in a `#if` DEBUG / `#endif` conditional so they are compiled out of release builds; locate the prints near the creation of scannerVC, delegate assignment (qrScanDelegate and scannerVC.model.delegate), and the presentation branches (topVC.present(...) and self.vc.present(...)) and surround them with the debug-only compilation block.DashWallet/Sources/UI/Menu/Tools/ToolsMenuScreen.swift (1)
231-255: Keep the scanner debug logs out of release builds.These
#if DEBUGor move them onto the repo’s debug-only logger.As per coding guidelines "Wrap debug print statements in
#ifDEBUG blocks or use conditional compilation to prevent performance impact from excessive logging."Also applies to: 283-299
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/Sources/UI/Menu/Tools/ToolsMenuScreen.swift` around lines 231 - 255, The debug print statements in presentScanner (e.g., the prints referencing presentScanner, scannerVC, scannerDelegate, DWQRScanViewController, vc.topViewController) must be excluded from release builds—wrap each print in a conditional compilation block (`#if` DEBUG ... `#endif`) or replace them with a debug-only logger so they only run in DEBUG builds; apply the same change to the other debug prints later in this file (the similar scanner lifecycle logs around the scanner presentation/unwrapping) to avoid shipping sensitive or noisy logs in production.DashWallet/Sources/UI/SwiftUI Components/Color+DWStyle.swift (1)
215-218: Make the compatibility alias forward tosecondaryBackground.Line 216 says this is an alias, but the implementation repeats the raw asset name instead of reusing
secondaryBackground. That creates a second mapping to keep in sync if the background token wiring changes again.♻️ Proposed fix
// Alias for secondaryBackground for backwards compatibility static var background: Color { - Color("BackgroundColor") + secondaryBackground }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/Sources/UI/SwiftUI` Components/Color+DWStyle.swift around lines 215 - 218, The compatibility alias static var background currently constructs Color("BackgroundColor") directly; change it to forward to the existing secondaryBackground accessor instead (i.e., have background return secondaryBackground) so there’s a single source of truth for the background color mapping and no duplicate asset references.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@DashWallet/Sources/UI/Menu/Tools/ExtendedKeys/ExtendedPublicKeySheet.swift`:
- Around line 33-37: loadKey() currently uses derivationPaths.first which can
return the wrong entry; update it to locate the BIP44 entry from
ExtendedPublicKeysModel.derivationPaths (e.g., filter for an entry whose
derivation path indicates purpose 44 or whose item/label identifies "BIP44"),
fall back to the first entry only if no BIP44 match is found, and then set
keyValue and qrImage from that located entry; reference the loadKey() method and
ExtendedPublicKeysModel.derivationPaths/ item to make the selection
deterministic for the "Extended public key (BIP 44)" sheet.
In
`@DashWallet/Sources/UI/Menu/Tools/ExtendedKeys/ExtendedPublicKeysViewController.swift`:
- Around line 247-255: Replace the force-unwrapped UIKit image initializer with
SwiftUI's literal Image initializer: locate the Image(uiImage: UIImage(named:
"icon_copy_outline")!) inside the ZStack and change it to
Image("icon_copy_outline") while keeping the existing modifiers (.resizable(),
.aspectRatio(...), .frame(...), .foregroundColor(...)); remove the force-unwrap
and UIKit dependency so the asset is loaded via SwiftUI's Image initializer.
In `@DashWallet/Sources/UI/Menu/Tools/ImportWallet/ImportPrivateKeySheet.swift`:
- Around line 97-100: The action closure calls
presentationMode.wrappedValue.dismiss() then immediately invokes
onScanPrivateKey(), which can race with the async sheet dismissal; change the
closure to defer calling onScanPrivateKey until after the dismissal completes
(e.g., schedule the callback on the main queue in the next runloop or with a
short DispatchQueue.main.async/asyncAfter) so the sheet finishes dismissing
before onScanPrivateKey runs; update the action in ImportPrivateKeySheet to use
presentationMode and onScanPrivateKey with this deferred invocation pattern.
In `@DashWallet/Sources/UI/Menu/Tools/Masternode`
Keys/DerivationPathKeys/Views/DerivationPathKeysCell.swift:
- Line 57: The code sets topConstraint.constant using an undefined legacy
constant kMenuVGap; update the expression in DerivationPathKeysCell where
topConstraint.constant is computed (referencing isFirst, sectionPadding,
cellVerticalPadding) to remove kMenuVGap and use a defined spacing value—either
substitute a literal (e.g., 8 or 12) or replace it with an existing defined
constant (e.g., menuVerticalGap or cellSpacing) from your UI constants; ensure
the chosen value matches the surrounding UI spacing conventions and compile-time
symbols are referenced instead of kMenuVGap.
In `@DashWallet/Sources/UI/Menu/Tools/Masternode`
Keys/Overview/KeysOverviewView.swift:
- Around line 39-41: The UI labels in KeysOverviewView (the "Masternode keys"
title and the "%d key(s)" / "%ld used(s)" count labels) are hardcoded and not
plural-aware; move these strings into localization resources and add
plural-aware entries in a .stringsdict (e.g., keys like "masternode_keys_title",
"masternode_key_count", "masternode_used_count"). Replace the hardcoded
Text("Masternode keys") with a localized lookup (NSLocalizedString or
LocalizedStringKey for SwiftUI) using "masternode_keys_title", and format the
count labels using plural-aware formatting (String.localizedStringWithFormat +
NSLocalizedString or .stringsdict entries) in the view code where key count and
used count are displayed (KeysOverviewView) so pluralization/localization is
handled correctly across locales.
In `@DashWallet/Sources/UI/Menu/Tools/Masternode`
Keys/Overview/KeysOverviewViewController.swift:
- Around line 84-87: The custom back button added in KeysOverviewViewController
(backButton added to navigationContainer and wired to backButtonTapped) is
missing accessibility metadata; set a descriptive accessibilityLabel (e.g.,
"Back" or "Back to Tools") and an appropriate accessibilityHint and/or
accessibilityTraits (e.g., .button) on backButton so VoiceOver users can
identify and activate it, ensuring the label matches the screen flow and
localization where applicable.
In `@DashWallet/Sources/UI/Menu/Tools/Masternode`
Keys/Overview/Model/WalletKeysOverviewModel.swift:
- Around line 30-39: The NSLocalizedString keys used by the
WalletKeysOverviewModel.title computed property and its enum cases (.owner,
.voting, .operator, .hpmnOperator) were changed to lowercase; update all
Localizable.strings entries in each DashWallet/{locale}.lproj to match the new
keys so lookups succeed: change "Owner Keys" → "Owner keys", "Voting Keys" →
"Voting keys", "Operator Keys" → "Operator keys", and "HPMN Operator Keys" →
"HPMN Operator keys" (preserve translations/values exactly, only rename the
keys).
In `@DashWallet/Sources/UI/Menu/Tools/ToolsMenuScreen.swift`:
- Around line 280-299: The QRScannerDelegate currently discards the scanned
DWPaymentInput and leaves debug prints unguarded; update
qrScanModel(_:didScanPaymentInput:) to forward the scanned paymentInput to the
same processing path used elsewhere (call the view controller's
processPaymentInput(paymentInput) — e.g., cast viewController to
DWBasePayViewController or the appropriate type used in PayViewController —
before or after dismissing), implement the cancel behavior in
qrScanModelDidCancel unchanged, and wrap all print(...) calls in
presentScanner() and inside QRScannerDelegate in `#if` DEBUG / `#endif` blocks so
they are only included in debug builds.
In
`@Shared/Resources/SharedAssets.xcassets/Colors/Gray/Gray100.colorset/Contents.json`:
- Around line 6-11: Gray50, Gray100, and Gray200 currently share identical RGB
hex values in their "components" blocks (red: 0xF5, green: 0xF6, blue: 0xF7);
update each colorset's "components" red/green/blue values to the correct
distinct gray hex values for Gray50, Gray100 and Gray200 to restore intended
visual differentiation—locate the "components" object in the Gray50.colorset,
Gray100.colorset, and Gray200.colorset (the entries with "red", "green", "blue",
"alpha") and replace the duplicated 0xF5/0xF6/0xF7 values with the correct hex
codes for each shade.
---
Outside diff comments:
In
`@DashWallet/Sources/UI/DashPay/Setup/CreateUsername/CreateUsernameViewController.swift`:
- Around line 249-250: The user-facing string in CreateUsernameViewController
(case .warning) contains a stale hardcoded date ("March 14, 2024"); replace it
with either a dynamic, computed date or a timeless phrasing: add a votingEndDate
property or compute the date from your voting rules inside
CreateUsernameViewController, format it with
DateFormatter.localizedString(for:dateStyle:timeStyle:) (or use
RelativeDateTimeFormatter) and inject that formatted date into the
NSLocalizedString placeholder (e.g. NSLocalizedString("The Dash network will
vote on this username. We will notify you of the results on %@.", comment:
"Usernames")), or change the copy to avoid a date entirely (e.g. "We will notify
you when voting concludes."). Update the case .warning branch to use the chosen
approach and ensure the string remains localized and tested.
In `@DashWallet/Sources/UI/Explore` Dash/Views/DashSpend/DashSpendPayScreen.swift:
- Around line 89-121: The status row is constrained to .frame(height: 20) which
clips multiline status texts (e.g. error.localizedDescription,
viewModel.costMessage, viewModel.maximumLimitMessage); remove the hard-coded
.frame(height: 20) (or replace it with a flexible minHeight if needed) on the
container that holds the texts so the VStack/HStack containing the conditional
Text views (where viewModel.error, viewModel.showCost, viewModel.showLimits are
used) can grow vertically to fit localized/multiline content.
In `@DashWallet/Sources/UI/SwiftUI` Components/Color+DWStyle.swift:
- Around line 37-218: The code references five missing Color assets
(Gray300Alpha60, Gray300Alpha70, Gray300Alpha80, Gray300Alpha90, Transparent)
which will crash at runtime—add .colorset assets with those exact names to the
design system; also change the background alias to forward to
secondaryBackground (i.e., have background return the same Color as static var
secondaryBackground) instead of calling Color("BackgroundColor") directly so it
stays in sync with secondaryBackground/primaryBackground mapping (see static
vars gray300Alpha60, gray300Alpha70, gray300Alpha80, gray300Alpha90,
Transparent, primaryBackground, secondaryBackground, background).
In `@DashWallet/Sources/UI/Tx/Details/Views/BlockExplorerSelectionView.swift`:
- Around line 3-76: There are duplicate type definitions causing a compile
error: remove or consolidate the duplicated BlockExplorerSelectionView and
BlockExplorer definitions so only one source of truth remains; decide which
implementation to keep (or merge desired differences such as title text, image
frame sizing, Insight icon name, button styling, and background/shadow behavior)
then delete the other file or move unique changes into the retained
BlockExplorerSelectionView and BlockExplorer (refer to the symbols
BlockExplorerSelectionView, BlockExplorer, BlockExplorer.title,
BlockExplorer.iconName, and the Button/Image layout properties) ensuring the
final file exports a single CaseIterable/Identifiable BlockExplorer and one View
implementation.
---
Nitpick comments:
In
`@DashWallet/Resources/AppAssets.xcassets/Menu/icon-close-sheet-white.imageset/Contents.json`:
- Around line 1-23: The Contents.json for the icon-close-sheet-white.imageset is
missing a template-rendering-intent entry used by other toolbar icons; if this
asset should tint like toolbar-plus/toolbar-close, add a "properties" object
with "template-rendering-intent": "template" to the asset's Contents.json
(inside the existing JSON root) for icon-close-sheet-white; if the icon must
remain always white, leave as-is.
In `@DashWallet/Resources/AppAssets.xcassets/Navigation`
bar/toolbar-back.imageset/Contents.json:
- Around line 1-23: The toolbar-back.imageset Contents.json is missing the
template-rendering-intent field so the back icon won't inherit tint; add a
top-level "template-rendering-intent": "template" entry in the JSON (same
placement as in controls-back.imageset) so the toolbar-back asset renders as a
template image and respects the parent view/system tint; update the
Contents.json for toolbar-back.imageset accordingly.
In `@DashWallet/Sources/UI/Explore`
Dash/Views/DashSpend/GiftCardDetailsView.swift:
- Around line 399-403: The computed property dateFormatter currently allocates a
new DateFormatter on every access; change it to a shared cached formatter (e.g.,
make dateFormatter a private static let initialized via a closure or a private
lazy var) and preserve the same dateFormat "MMMM dd, yyyy 'at' h:mm a"; then
update all call sites to reference the cached formatter (use Self.dateFormatter
where appropriate) so the formatter is reused instead of re-created on each
access.
In `@DashWallet/Sources/UI/Menu/Main/MainMenuViewController.swift`:
- Around line 622-644: Wrap the debug print statements in QRScanDelegate inside
conditional compilation so they only run in debug builds: update
init(viewController:), qrScanModel(_:didScanPaymentInput:), and
qrScanModelDidCancel(_:) to enclose each print call (or the whole debug block)
in `#if` DEBUG ... `#endif`; ensure you preserve existing dismiss/completion
behavior and weak viewController usage while removing plain print calls from
release builds.
- Line 145: Remove the explicit "= nil" initializer from the optional state
property to satisfy SwiftLint and Swift conventions: update the `@State` property
declaration for qrScanDelegate (type MainMenuScreen.QRScanDelegate?) in
MainMenuViewController.swift so it is declared without an explicit nil
assignment (leave it as an optional without initialization).
- Around line 324-346: There are unguarded debug print statements in the
onImportPrivateKey flow inside MainMenuViewController (prints around creating
DWQRScanViewController, assigning MainMenuScreen.QRScanDelegate, and presenting
from self.vc/topViewController). Wrap each print(...) call in a `#if` DEBUG /
`#endif` conditional so they are compiled out of release builds; locate the prints
near the creation of scannerVC, delegate assignment (qrScanDelegate and
scannerVC.model.delegate), and the presentation branches (topVC.present(...) and
self.vc.present(...)) and surround them with the debug-only compilation block.
In `@DashWallet/Sources/UI/Menu/Tools/ImportWallet/ImportPrivateKeySheet.swift`:
- Around line 21-22: The two `@Environment` attributes on ImportPrivateKeySheet
(presentationMode and colorScheme) are on the same line as other code; split
them so each attribute with arguments sits alone on its own line above the
property declaration (i.e., place `@Environment`(\.presentationMode) on its own
line immediately above the private var presentationMode declaration and likewise
put `@Environment`(\.colorScheme) on its own line immediately above the private
var colorScheme declaration) to satisfy SwiftLint formatting rules.
- Around line 69-80: The two Text views in ImportPrivateKeySheet.swift use raw
.font(.system(size:weight:)) calls; replace them with the app's semantic tokens
(e.g., use .font(.title1) for the "Import private key" header and
.font(.subhead) or the appropriate body token for the descriptive paragraph) so
typography matches the rest of the app; update any weight/size-specific styling
by choosing the semantic token that preserves the intended emphasis and remove
the explicit .system(...) usages to ensure consistency with other components
using .title1/.subhead.
- Around line 38-51: Replace the trailing-closure Button usage with the modern
explicit label initializer to satisfy SwiftLint: change the current
Button(action: { presentationMode.wrappedValue.dismiss() }) { ... } to use
Button(action: { presentationMode.wrappedValue.dismiss() }, label: {
Image(colorScheme == .dark ? "icon-close-sheet-white" : "icon-close-sheet") ...
}) so the action remains the same (presentationMode.wrappedValue.dismiss()) and
the existing Image/overlay/Circle styling is moved into the label closure;
locate this Button in ImportPrivateKeySheet and update the initializer
accordingly.
In `@DashWallet/Sources/UI/Menu/Tools/Masternode`
Keys/DerivationPathKeys/DerivationPathKeysView.swift:
- Around line 198-199: Move the `@ViewBuilder` attribute to its own line above the
property declaration for copiedBackground to satisfy SwiftLint; locate the
private computed view var named copiedBackground and place the `@ViewBuilder`
attribute on a separate line immediately above "private var copiedBackground:
some View" so the attribute is not on the same line as the declaration.
- Line 58: The `@State` property copiedValue in DerivationPathKeysView (symbol:
copiedValue) is redundantly initialized to nil; remove the explicit "= nil" so
the declaration becomes an optional without initializer (e.g., `@State` private
var copiedValue: String?) to satisfy SwiftLint and rely on implicit nil
initialization. Ensure you update only the copiedValue declaration in
DerivationPathKeysView.swift.
- Around line 145-147: Move the `@Environment` attribute onto its own line to
satisfy SwiftLint: locate the property declaration "private var colorScheme" in
the DerivationPathKeysView (the line with "@Environment(\\.colorScheme) private
var colorScheme") and split it into two lines so the attribute sits above the
property (i.e., place "@Environment(\\.colorScheme)" on its own line immediately
before "private var colorScheme"). Ensure formatting matches surrounding
attributes style.
- Around line 131-137: BackgroundBlurView currently hardcodes
.systemUltraThinMaterialDark in makeUIView which ignores light/dark modes;
update it to pick a color-scheme-aware material instead by either adding a
configurable property (e.g., init(style: UIBlurEffect.Style) or material:
UIBlurEffect.Style) and applying that in makeUIView, or detect the current trait
collection in updateUIView (use uiView.traitCollection.userInterfaceStyle) and
set uiView.effect = UIBlurEffect(style: appropriateMaterial) so the blur
switches between dark and light-appropriate UIBlurEffect styles; adjust the
BackgroundBlurView initializer and the makeUIView/updateUIView methods
accordingly.
In `@DashWallet/Sources/UI/Menu/Tools/Masternode`
Keys/DerivationPathKeys/Views/DerivationPathKeysCell.swift:
- Around line 106-109: The trailingConstraint property is misnamed because it
references copyButton.trailingAnchor rather than mainStackView; rename
trailingConstraint to copyButtonTrailingConstraint (or similar) and update all
usages, including in configureHierarchy and applyMenuSpacing, to use the new
property name so intent is clear and future maintenance is less error-prone;
ensure the property declaration and any assignments or activations are renamed
consistently.
In `@DashWallet/Sources/UI/Menu/Tools/ToolsMenuScreen.swift`:
- Around line 231-255: The debug print statements in presentScanner (e.g., the
prints referencing presentScanner, scannerVC, scannerDelegate,
DWQRScanViewController, vc.topViewController) must be excluded from release
builds—wrap each print in a conditional compilation block (`#if` DEBUG ... `#endif`)
or replace them with a debug-only logger so they only run in DEBUG builds; apply
the same change to the other debug prints later in this file (the similar
scanner lifecycle logs around the scanner presentation/unwrapping) to avoid
shipping sensitive or noisy logs in production.
In `@DashWallet/Sources/UI/SwiftUI` Components/Button.swift:
- Around line 134-143: The switch in the foreground-color logic repeats
Color.white for .filled and .filledBlue; update the switch in the Button
component so the .filled and .filledBlue cases are consolidated (e.g., use a
single case with multiple patterns or a fallthrough) and return Color.white
once, keeping other cases (.tintedBlue, default) unchanged; touch the switch
that references style (cases: .filled, .filledBlue, .tintedBlue, default) to
reduce duplication and improve maintainability.
In `@DashWallet/Sources/UI/SwiftUI` Components/Color+DWStyle.swift:
- Around line 215-218: The compatibility alias static var background currently
constructs Color("BackgroundColor") directly; change it to forward to the
existing secondaryBackground accessor instead (i.e., have background return
secondaryBackground) so there’s a single source of truth for the background
color mapping and no duplicate asset references.
In `@DashWallet/Sources/UI/SwiftUI` Components/NavigationBar.swift:
- Around line 100-102: The `@Environment` attribute in the NavBarBackPlus view is
on the same line as the property declaration, violating SwiftLint style; update
NavBarBackPlus (and mirror the fix used in NavBarBack) so that the
`@Environment`(\.colorScheme) attribute is placed on its own line directly above
the property declaration (retain the private var name colorScheme and the onBack
closure signature unchanged).
- Around line 176-204: NavBarClose currently always uses Image("toolbar-close")
and doesn't adapt to dark mode; add an `@Environment`(\.colorScheme) private var
colorScheme to the NavBarClose view and switch the asset name based on
colorScheme (e.g., "toolbar-close" vs "toolbar-close-dark" or whatever dark
variant exists) where Image("toolbar-close") is used, mirroring the pattern in
NavBarBack/NavBarBackPlus so the close icon uses the appropriate asset for light
and dark themes.
- Around line 43-45: Move the SwiftUI environment attribute onto its own line to
satisfy SwiftLint: in the NavBarBack struct, separate the attribute and property
so that the `@Environment`(\.colorScheme) attribute is on its own line followed by
the declaration of private var colorScheme; keep the onBack: () -> Void property
unchanged.
In
`@Shared/Resources/SharedAssets.xcassets/Colors/System/GreenColor.colorset/Contents.json`:
- Around line 3-14: The Contents.json for GreenColor.colorset currently only
defines a single "universal" color entry; add an appearance-specific variant for
dark mode by replacing/augmenting the existing item with an array of color
entries that include the original light (or universal) definition and a second
entry with "appearance":"luminosity" (value "dark") that provides the adjusted
color components for dark mode; update the "color" object for the dark entry
with appropriate RGB/alpha values to preserve contrast and keep the same
"idiom":"universal" and matching asset name (GreenColor.colorset).
HashEngineering
left a comment
There was a problem hiding this comment.
Looks OK.
There was a problem hiding this comment.
Actionable comments posted: 6
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (8)
DashWallet/fil.lproj/Localizable.stringsdict (1)
15-18:⚠️ Potential issue | 🟡 MinorPre-existing typo:
%Idshould be%ld.The format specifier uses capital
Iinstead of lowercasel. This mismatch with theldvalue type on line 14 would prevent the number from displaying correctly at runtime. Consider fixing this while editing the file.Proposed fix
<key>one</key> - <string>%Id ginamit</string> + <string>%ld ginamit</string> <key>other</key> - <string>%Id ginamit</string> + <string>%ld ginamit</string>🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/fil.lproj/Localizable.stringsdict` around lines 15 - 18, Fix the format specifier typo in the Localizable.stringsdict entries for the plural keys "one" and "other": replace the incorrect "%Id" with the correct "%ld" so the numeric value (signed long) renders correctly at runtime; update both the <string> value for the "one" key and the <string> value for the "other" key accordingly.DashWallet/th.lproj/Localizable.stringsdict (1)
5-16:⚠️ Potential issue | 🟡 MinorThai
usedstring is missing the count placeholder.The
otherformรหัสที่ใช้ไปแล้วlacks%ldor%d, so when the code callsString.localizedStringWithFormat(NSLocalizedString("%ld used", ...), used), the count value will not be displayed to Thai users.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/th.lproj/Localizable.stringsdict` around lines 5 - 16, The Thai plural entry for key "%ld used" is missing the count placeholder; update the 'other' string under the 'used' plural (NSStringLocalizedFormatKey / NSStringFormatValueTypeKey "ld") to include the %ld placeholder (e.g., "%ld รหัสที่ใช้ไปแล้ว") so that String.localizedStringWithFormat(NSLocalizedString("%ld used", ...), used) displays the numeric count correctly.DashWallet/pl.lproj/Localizable.stringsdict (1)
98-98:⚠️ Potential issue | 🟡 MinorTypo in format specifier:
d%should be%d.The Polish "few" plural form for keys has the format specifier characters swapped. This will display literal "d%" instead of the number count.
🐛 Proposed fix
<key>few</key> - <string>d% klucze</string> + <string>%d klucze</string>🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/pl.lproj/Localizable.stringsdict` at line 98, Replace the incorrect format specifier in the plural string: find the entry containing "d% klucze" and swap the characters to use a proper printf-style integer placeholder so it reads "%d klucze" (i.e., change "d% klucze" to "%d klucze").DashWallet/it.lproj/Localizable.stringsdict (1)
15-21:⚠️ Potential issue | 🟠 MajorInvalid format specifiers will break number display.
Lines 16, 18, and 20 contain incorrect format specifiers:
- Line 16:
%lD(capital D)- Line 18:
%ID(capital I instead of lowercase L, and capital D)- Line 20:
%lD(capital D)The correct format specifier is
%ld(lowercase). These typos will prevent the number from being displayed properly.🐛 Proposed fix
<key>one</key> - <string>%lD in uso</string> + <string>%ld in uso</string> <key>many</key> - <string>%ID in uso</string> + <string>%ld in uso</string> <key>other</key> - <string>%lD in uso </string> + <string>%ld in uso</string>🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/it.lproj/Localizable.stringsdict` around lines 15 - 21, The pluralization strings under keys "one", "many", and "other" use incorrect format specifiers (%lD and %ID) which will break number rendering; update each specifier to the correct lowercase "%ld" so the localized number prints properly (fix the values for the "one", "many", and "other" entries in the Localizable.stringsdict).DashWallet/mk.lproj/Localizable.stringsdict (1)
5-9:⚠️ Potential issue | 🟡 MinorIncomplete plural definitions (same issue as sl.lproj).
Like the Slovenian file, this Macedonian localization references plural variables (
%#@used@,%#@merchants@, etc.) without defining the corresponding dictionaries with plural rules. The key rename is correct, but the underlying structure needs plural form definitions to work properly.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/mk.lproj/Localizable.stringsdict` around lines 5 - 9, The Macedonian stringsdict entries reference plural placeholders like %#@used@, %#@merchants@ and %#@addresses@ but lack corresponding plural rule dictionaries; add a <dict> for each referenced variable (e.g., a "used" dict, "merchants" dict, "addresses" dict) that defines NSStringLocalizedFormatValueType = "d" and provides the plural form keys (one, few, other, etc.) with appropriate localized strings, and update the NSStringLocalizedFormatKey entries (such as in the "%ld used" key) to point to these plural dict names (e.g., %#@used@) so the pluralization rules are fully defined for the keys referenced in the file.DashWallet/ca.lproj/Localizable.stringsdict (1)
5-9:⚠️ Potential issue | 🟡 MinorIncomplete plural definitions (same issue as other minimal locale files).
Like several other locales in this PR (sl, mk, ar), this file references plural variables without defining the actual plural rules. The key rename is correct, but consider adding proper Catalan plural form definitions.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/ca.lproj/Localizable.stringsdict` around lines 5 - 9, The plural entry for "%ld used" is incomplete: update the "%ld used" dictionary to define a plural rule for the "used" variable (the %#@used@ placeholder) by adding the necessary NSStringFormatSpecTypeKey ("NSStringPluralRuleType"), NSStringFormatValueTypeKey ("d"), and concrete plural form keys (at minimum "one" and "other") with localized strings for Catalan; ensure the inner key names match the placeholder "used" exactly and provide correct localized messages (e.g., singular for "one" and plural for "other") so the NSStringLocalizedFormatKey can resolve %#@used@ properly.DashWallet/ar.lproj/Localizable.stringsdict (1)
5-9:⚠️ Potential issue | 🟡 MinorIncomplete plural definitions (same issue as sl.lproj and mk.lproj).
Arabic has complex pluralization rules requiring up to six forms (zero, one, two, few, many, other), but this file only references plural variables without defining them. The key rename is correct, but pluralization won't work properly.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/ar.lproj/Localizable.stringsdict` around lines 5 - 9, The plural definitions are missing for the "%ld used" entry: update its "%#@used@" variable by adding a plural spec dictionary named "used" that sets NSStringFormatSpecTypeKey to "NSStringPluralRuleType" and NSStringFormatValueTypeKey to "d", then provide Arabic plural keys "zero", "one", "two", "few", "many", and "other" with appropriate localized strings (each including the numeric placeholder) so the "%ld used" key uses the full six-form Arabic pluralization.DashWallet/de.lproj/Localizable.stringsdict (1)
31-35:⚠️ Potential issue | 🟠 MajorInvalid format specifier
&@will break string interpolation.Lines 32 and 34 use
&@instead of%@. The ampersand is incorrect—%@is the format specifier for strings in Objective-C/Swift. This will display the literal text "&@" instead of the location name.🐛 Proposed fix
<key>one</key> - <string>%d Händler in &@</string> + <string>%d Händler in %@</string> <key>other</key> - <string>%d Händler in &@</string> + <string>%d Händler in %@</string>🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/de.lproj/Localizable.stringsdict` around lines 31 - 35, The plural entries with keys "one" and "other" in Localizable.stringsdict use the invalid format specifier "&@" which will render literally; replace "&@" with the correct Objective‑C/Swift string specifier "%@" in both "%d Händler in &@" occurrences (preserve the %d) so the location name interpolates properly, and verify the resulting strings remain valid XML/stringsdict entries.
♻️ Duplicate comments (1)
DashWallet/Sources/UI/Menu/Tools/ToolsMenuScreen.swift (1)
270-284:⚠️ Potential issue | 🔴 CriticalScanned private key is discarded — import flow is broken.
QRScannerDelegate.didScanPaymentInputreceivespaymentInputbut only dismisses the scanner without processing the scanned data. Compare withPayViewController(Context snippet 3) which correctly callsperformPayment(with: paymentInput). The scanned private key is lost and the import never completes.You need to forward the
paymentInputto the actual import handler. TheonImportPrivateKeycallback exists but isn't wired here, and it doesn't accept the payment input. Consider passing a callback that acceptsDWPaymentInputor invoking the appropriate import logic.🐛 Potential approach
class QRScannerDelegate: NSObject, DWQRScanModelDelegate { weak var viewController: UIViewController? + var onScanComplete: ((DWPaymentInput) -> Void)? - init(viewController: UIViewController) { + init(viewController: UIViewController, onScanComplete: ((DWPaymentInput) -> Void)? = nil) { self.viewController = viewController + self.onScanComplete = onScanComplete } func qrScanModel(_ viewModel: DWQRScanModel, didScanPaymentInput paymentInput: DWPaymentInput) { - viewController?.dismiss(animated: true) + viewController?.dismiss(animated: true) { [weak self] in + self?.onScanComplete?(paymentInput) + } } func qrScanModelDidCancel(_ viewModel: DWQRScanModel) { viewController?.dismiss(animated: true) } }Then in
presentScanner(), wire the callback to actually process the private key import.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/Sources/UI/Menu/Tools/ToolsMenuScreen.swift` around lines 270 - 284, The QR scanner delegate currently drops scanned data; update QRScannerDelegate (class QRScannerDelegate) so didScanPaymentInput(_ viewModel:didScanPaymentInput:) forwards the DWPaymentInput to the import flow instead of only dismissing the view controller: add a callback/closure property (e.g., onImportPaymentInput: (DWPaymentInput) -> Void) or update the existing onImportPrivateKey handler to accept a DWPaymentInput, call that handler from didScanPaymentInput before/after dismissing the scanner, and wire that handler where presentScanner() creates the QRScannerDelegate so the scanned private key is handed to the import logic (analogous to performPayment(with:) usage in PayViewController).
🧹 Nitpick comments (7)
DashWallet/Sources/UI/Menu/Tools/Masternode Keys/Overview/KeysOverviewView.swift (1)
141-142: Consider usingletfor static data.Since
itemsis initialized withMNKey.allCasesand never mutates,@Published varadds unnecessary overhead. A simpleletwould be cleaner.♻️ Suggested simplification
class KeysOverviewViewModel: ObservableObject { - `@Published` var items: [MNKey] = MNKey.allCases + let items: [MNKey] = MNKey.allCases🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/Sources/UI/Menu/Tools/Masternode` Keys/Overview/KeysOverviewView.swift around lines 141 - 142, The items property in KeysOverviewViewModel is initialized to MNKey.allCases and never mutated, so replace the mutable `@Published` var items with an immutable constant (let items: [MNKey] = MNKey.allCases) to remove unnecessary Combine overhead; update any code that referenced the published publisher (if any) to read the plain property directly from KeysOverviewViewModel.DashWallet/Sources/UI/Menu/Tools/ToolsMenuScreen.swift (2)
261-267: SwiftLint: Use-> Voidinstead of-> ()and place@objcon its own line.Minor style adjustments per SwiftLint rules.
♻️ Suggested fix
class DelegateInternal: NSObject, DWImportWalletInfoViewControllerDelegate { - let onImportPrivateKey: () -> () + let onImportPrivateKey: () -> Void - init(onImportPrivateKey: `@escaping` () -> ()) { + init(onImportPrivateKey: `@escaping` () -> Void) { self.onImportPrivateKey = onImportPrivateKey } - `@objc` func importWalletInfoViewControllerScanPrivateKeyAction(_ controller: DWImportWalletInfoViewController) { onImportPrivateKey() } + `@objc` + func importWalletInfoViewControllerScanPrivateKeyAction(_ controller: DWImportWalletInfoViewController) { + onImportPrivateKey() + } }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/Sources/UI/Menu/Tools/ToolsMenuScreen.swift` around lines 261 - 267, Change the closure type from () to Void for the onImportPrivateKey property and initializer (update the declaration let onImportPrivateKey: () -> () and init parameter to use -> Void), and move the `@objc` attribute to its own line above the method declaration for importWalletInfoViewControllerScanPrivateKeyAction(_:) so the method reads with `@objc` on a separate line and the closure invocation remains the same (refer to onImportPrivateKey, init(onImportPrivateKey:), and importWalletInfoViewControllerScanPrivateKeyAction(_:)).
33-33: SwiftLint: Remove explicitnilinitialization.The
implicit_optional_initializationrule suggests that optionals should be implicitly initialized without= nil.♻️ Suggested fix
- `@State` private var scannerDelegate: QRScannerDelegate? = nil + `@State` private var scannerDelegate: QRScannerDelegate?🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/Sources/UI/Menu/Tools/ToolsMenuScreen.swift` at line 33, Remove the explicit nil initializer for the `@State` optional: change the declaration of scannerDelegate so it relies on Swift's implicit optional initialization (i.e., update `@State` private var scannerDelegate: QRScannerDelegate? by removing " = nil"); this fixes the SwiftLint implicit_optional_initialization warning for the scannerDelegate property.DashWallet/Sources/UI/Menu/Tools/ImportWallet/ImportPrivateKeySheet.swift (3)
21-22: SwiftLint: Place property wrapper attributes on their own lines.Per SwiftLint's
attributesrule,@Environmentwith arguments should be on a separate line from the property declaration.♻️ Suggested fix
- `@Environment`(\.presentationMode) private var presentationMode - `@Environment`(\.colorScheme) private var colorScheme + `@Environment`(\.presentationMode) + private var presentationMode + `@Environment`(\.colorScheme) + private var colorScheme🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/Sources/UI/Menu/Tools/ImportWallet/ImportPrivateKeySheet.swift` around lines 21 - 22, Move the property wrapper attributes onto their own lines to satisfy SwiftLint's attributes rule: split the combined lines declaring `@Environment`(\.presentationMode) private var presentationMode and `@Environment`(\.colorScheme) private var colorScheme so each `@Environment`(...) is on a line above its corresponding property declaration; update the declarations in ImportPrivateKeySheet (the two `@Environment` usages) so the attribute is isolated from the property line.
97-102: Consider usingasyncAfterwith a small delay for reliable sheet dismissal.The current
DispatchQueue.main.asyncschedules the callback immediately on the next run loop iteration, butpresentationMode.wrappedValue.dismiss()is asynchronous and the sheet animation may not have completed. The previous review suggested a 0.3s delay to ensure the sheet fully dismisses before presenting the scanner.♻️ Suggested fix
action: { presentationMode.wrappedValue.dismiss() - DispatchQueue.main.async { + DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { onScanPrivateKey() } }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/Sources/UI/Menu/Tools/ImportWallet/ImportPrivateKeySheet.swift` around lines 97 - 102, The sheet dismissal is asynchronous so replace the immediate DispatchQueue.main.async call in the action closure with DispatchQueue.main.asyncAfter using a short delay (e.g., 0.3s) to ensure presentationMode.wrappedValue.dismiss() completes before invoking onScanPrivateKey(); update the action closure that currently calls onScanPrivateKey() to schedule it with asyncAfter and a small delay to reliably present the scanner after the sheet animation finishes.
38-51: SwiftLint: Avoid trailing closure syntax when passing action to Button.The
multiple_closures_with_trailing_closurerule flags this pattern. Use explicitlabel:parameter instead.♻️ Suggested fix
- Button(action: { - presentationMode.wrappedValue.dismiss() - }) { + Button( + action: { + presentationMode.wrappedValue.dismiss() + }, + label: { Image(colorScheme == .dark ? "icon-close-sheet-white" : "icon-close-sheet") .resizable() .aspectRatio(contentMode: .fit) .frame(width: 9, height: 9) .foregroundColor(Color.primaryText) .frame(width: 34, height: 34) .overlay( Circle() .stroke(Color.gray300.opacity(0.3), lineWidth: 1.5) ) - } + } + )🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/Sources/UI/Menu/Tools/ImportWallet/ImportPrivateKeySheet.swift` around lines 38 - 51, The Button uses trailing-closure syntax for its label which triggers SwiftLint's multiple_closures_with_trailing_closure rule; change the Button initializer to supply the label via the explicit label: parameter (i.e. Button(action: { presentationMode.wrappedValue.dismiss() }, label: { /* existing Image view */ })) so keep the same action (presentationMode.wrappedValue.dismiss()) and the same Image overlay content but move it into the label closure referenced by label: to avoid the trailing-closure form.DashWallet/it.lproj/Localizable.stringsdict (1)
92-92: Minor: Trailing whitespace in localized string.Line 92 has trailing spaces after "chiavi". This is a cosmetic issue but could affect text alignment.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/it.lproj/Localizable.stringsdict` at line 92, Remove the trailing whitespace in the localized string value "%d chiavi " inside Localizable.stringsdict (the duplicate-space after "chiavi"); update the entry so the string becomes "%d chiavi" to avoid cosmetic/alignment issues in UI rendering.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@DashWallet/en.lproj/Localizable.strings`:
- Line 1737: The localization lookup fails because the strings file contains
"Operator Keys" (capital K) but the code calls NSLocalizedString("Operator
keys", comment: "") in WalletKeysOverviewModel; add a matching lowercase entry
to the Localizable.strings file (i.e., add "Operator keys" = "Operator keys";)
or normalize the existing key name to match the code, and verify the lowercase
key is present in the same lowercase normalization group alongside "Owner keys"
so NSLocalizedString("Operator keys", ...) resolves correctly.
In `@DashWallet/sl_SI.lproj/Localizable.stringsdict`:
- Around line 5-8: The "%ld used" NSLocalizedString entry is missing its
substitution dictionary called "used", which breaks pluralization; add a
dictionary named "used" under that key (with NSStringFormatSpecTypeKey set to
the plural type, NSStringFormatValueTypeKey set to "ld" or the numeric type, and
include plural form keys such as "one" and "other" with the proper localized
strings) and do the same for the similar "%ld merchants", "%ld transactions",
and "%ld keys" entries across all locale .stringsdict files so each %#@...@
placeholder has a corresponding substitution dict.
In `@DashWallet/zh-Hans.lproj/Localizable.strings`:
- Line 1734: Rename the existing localized string key "Operator Keys" to
"Operator keys" in the zh-Hans Localizable.strings so it exactly matches the
lookup used in WalletKeysOverviewModel.swift (NSLocalizedString("Operator keys",
comment: "")). Locate the entry currently spelled "Operator Keys" and change the
right-hand value to use the lowercase 'k' in "keys" so the direct zh-Hans lookup
resolves correctly.
In `@DashWallet/zh-Hans.lproj/Localizable.stringsdict`:
- Around line 5-18: Change the plural entry to use platform-sized integer format
and translate the output: update the dictionary key from "%d key(s)" to "%ld
key(s)", change NSStringFormatValueTypeKey from "d" to "ld" to match
NSInteger/Int formatting, and replace the English plural string ("other") with a
Simplified Chinese translation such as "%ld 个密钥" so the localized UI is fully
Chinese.
In `@DashWallet/zh-Hant-TW.lproj/Localizable.strings`:
- Line 1106: The file contains overrides for Traditional Chinese (zh-Hant-TW)
where the values remain English (e.g., the key "HPMN Operator keys" and the
other overrides referenced at lines 1491, 1734, 2833); replace each English
value with an appropriate zh-Hant-TW translation for the corresponding key (or
remove the override entries if translations are not yet available) so the UI
won’t show mixed-language labels—locate the entries by their keys (e.g., "HPMN
Operator keys") in Localizable.strings and update their right-hand side values
to proper Traditional Chinese strings or delete the line.
In `@DashWallet/zh-Hant-TW.lproj/Localizable.stringsdict`:
- Around line 5-18: Update the plural entry in Localizable.stringsdict: change
the format specifier from "%d" to "%ld" for the key currently labeled "%d
key(s)" so it matches the platform-sized Int used by callers in
KeysOverviewCell.swift (line ~36) and KeysOverviewView.swift (line ~131); also
replace the English "other" string "%d keys" with the appropriate Traditional
Chinese translation while keeping the "%ld" placeholder (e.g., use a Traditional
Chinese phrase like "%ld 個金鑰" or equivalent) so the localization and type
specifier both match.
---
Outside diff comments:
In `@DashWallet/ar.lproj/Localizable.stringsdict`:
- Around line 5-9: The plural definitions are missing for the "%ld used" entry:
update its "%#@used@" variable by adding a plural spec dictionary named "used"
that sets NSStringFormatSpecTypeKey to "NSStringPluralRuleType" and
NSStringFormatValueTypeKey to "d", then provide Arabic plural keys "zero",
"one", "two", "few", "many", and "other" with appropriate localized strings
(each including the numeric placeholder) so the "%ld used" key uses the full
six-form Arabic pluralization.
In `@DashWallet/ca.lproj/Localizable.stringsdict`:
- Around line 5-9: The plural entry for "%ld used" is incomplete: update the
"%ld used" dictionary to define a plural rule for the "used" variable (the
%#@used@ placeholder) by adding the necessary NSStringFormatSpecTypeKey
("NSStringPluralRuleType"), NSStringFormatValueTypeKey ("d"), and concrete
plural form keys (at minimum "one" and "other") with localized strings for
Catalan; ensure the inner key names match the placeholder "used" exactly and
provide correct localized messages (e.g., singular for "one" and plural for
"other") so the NSStringLocalizedFormatKey can resolve %#@used@ properly.
In `@DashWallet/de.lproj/Localizable.stringsdict`:
- Around line 31-35: The plural entries with keys "one" and "other" in
Localizable.stringsdict use the invalid format specifier "&@" which will render
literally; replace "&@" with the correct Objective‑C/Swift string specifier "%@"
in both "%d Händler in &@" occurrences (preserve the %d) so the location name
interpolates properly, and verify the resulting strings remain valid
XML/stringsdict entries.
In `@DashWallet/fil.lproj/Localizable.stringsdict`:
- Around line 15-18: Fix the format specifier typo in the
Localizable.stringsdict entries for the plural keys "one" and "other": replace
the incorrect "%Id" with the correct "%ld" so the numeric value (signed long)
renders correctly at runtime; update both the <string> value for the "one" key
and the <string> value for the "other" key accordingly.
In `@DashWallet/it.lproj/Localizable.stringsdict`:
- Around line 15-21: The pluralization strings under keys "one", "many", and
"other" use incorrect format specifiers (%lD and %ID) which will break number
rendering; update each specifier to the correct lowercase "%ld" so the localized
number prints properly (fix the values for the "one", "many", and "other"
entries in the Localizable.stringsdict).
In `@DashWallet/mk.lproj/Localizable.stringsdict`:
- Around line 5-9: The Macedonian stringsdict entries reference plural
placeholders like %#@used@, %#@merchants@ and %#@addresses@ but lack
corresponding plural rule dictionaries; add a <dict> for each referenced
variable (e.g., a "used" dict, "merchants" dict, "addresses" dict) that defines
NSStringLocalizedFormatValueType = "d" and provides the plural form keys (one,
few, other, etc.) with appropriate localized strings, and update the
NSStringLocalizedFormatKey entries (such as in the "%ld used" key) to point to
these plural dict names (e.g., %#@used@) so the pluralization rules are fully
defined for the keys referenced in the file.
In `@DashWallet/pl.lproj/Localizable.stringsdict`:
- Line 98: Replace the incorrect format specifier in the plural string: find the
entry containing "d% klucze" and swap the characters to use a proper
printf-style integer placeholder so it reads "%d klucze" (i.e., change "d%
klucze" to "%d klucze").
In `@DashWallet/th.lproj/Localizable.stringsdict`:
- Around line 5-16: The Thai plural entry for key "%ld used" is missing the
count placeholder; update the 'other' string under the 'used' plural
(NSStringLocalizedFormatKey / NSStringFormatValueTypeKey "ld") to include the
%ld placeholder (e.g., "%ld รหัสที่ใช้ไปแล้ว") so that
String.localizedStringWithFormat(NSLocalizedString("%ld used", ...), used)
displays the numeric count correctly.
---
Duplicate comments:
In `@DashWallet/Sources/UI/Menu/Tools/ToolsMenuScreen.swift`:
- Around line 270-284: The QR scanner delegate currently drops scanned data;
update QRScannerDelegate (class QRScannerDelegate) so didScanPaymentInput(_
viewModel:didScanPaymentInput:) forwards the DWPaymentInput to the import flow
instead of only dismissing the view controller: add a callback/closure property
(e.g., onImportPaymentInput: (DWPaymentInput) -> Void) or update the existing
onImportPrivateKey handler to accept a DWPaymentInput, call that handler from
didScanPaymentInput before/after dismissing the scanner, and wire that handler
where presentScanner() creates the QRScannerDelegate so the scanned private key
is handed to the import logic (analogous to performPayment(with:) usage in
PayViewController).
---
Nitpick comments:
In `@DashWallet/it.lproj/Localizable.stringsdict`:
- Line 92: Remove the trailing whitespace in the localized string value "%d
chiavi " inside Localizable.stringsdict (the duplicate-space after "chiavi");
update the entry so the string becomes "%d chiavi" to avoid cosmetic/alignment
issues in UI rendering.
In `@DashWallet/Sources/UI/Menu/Tools/ImportWallet/ImportPrivateKeySheet.swift`:
- Around line 21-22: Move the property wrapper attributes onto their own lines
to satisfy SwiftLint's attributes rule: split the combined lines declaring
`@Environment`(\.presentationMode) private var presentationMode and
`@Environment`(\.colorScheme) private var colorScheme so each `@Environment`(...) is
on a line above its corresponding property declaration; update the declarations
in ImportPrivateKeySheet (the two `@Environment` usages) so the attribute is
isolated from the property line.
- Around line 97-102: The sheet dismissal is asynchronous so replace the
immediate DispatchQueue.main.async call in the action closure with
DispatchQueue.main.asyncAfter using a short delay (e.g., 0.3s) to ensure
presentationMode.wrappedValue.dismiss() completes before invoking
onScanPrivateKey(); update the action closure that currently calls
onScanPrivateKey() to schedule it with asyncAfter and a small delay to reliably
present the scanner after the sheet animation finishes.
- Around line 38-51: The Button uses trailing-closure syntax for its label which
triggers SwiftLint's multiple_closures_with_trailing_closure rule; change the
Button initializer to supply the label via the explicit label: parameter (i.e.
Button(action: { presentationMode.wrappedValue.dismiss() }, label: { /* existing
Image view */ })) so keep the same action
(presentationMode.wrappedValue.dismiss()) and the same Image overlay content but
move it into the label closure referenced by label: to avoid the
trailing-closure form.
In `@DashWallet/Sources/UI/Menu/Tools/Masternode`
Keys/Overview/KeysOverviewView.swift:
- Around line 141-142: The items property in KeysOverviewViewModel is
initialized to MNKey.allCases and never mutated, so replace the mutable
`@Published` var items with an immutable constant (let items: [MNKey] =
MNKey.allCases) to remove unnecessary Combine overhead; update any code that
referenced the published publisher (if any) to read the plain property directly
from KeysOverviewViewModel.
In `@DashWallet/Sources/UI/Menu/Tools/ToolsMenuScreen.swift`:
- Around line 261-267: Change the closure type from () to Void for the
onImportPrivateKey property and initializer (update the declaration let
onImportPrivateKey: () -> () and init parameter to use -> Void), and move the
`@objc` attribute to its own line above the method declaration for
importWalletInfoViewControllerScanPrivateKeyAction(_:) so the method reads with
`@objc` on a separate line and the closure invocation remains the same (refer to
onImportPrivateKey, init(onImportPrivateKey:), and
importWalletInfoViewControllerScanPrivateKeyAction(_:)).
- Line 33: Remove the explicit nil initializer for the `@State` optional: change
the declaration of scannerDelegate so it relies on Swift's implicit optional
initialization (i.e., update `@State` private var scannerDelegate:
QRScannerDelegate? by removing " = nil"); this fixes the SwiftLint
implicit_optional_initialization warning for the scannerDelegate property.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 997fb054-1d33-49f8-97ce-d8958178a675
📒 Files selected for processing (85)
DashWallet/Sources/UI/Menu/Tools/ImportWallet/ImportPrivateKeySheet.swiftDashWallet/Sources/UI/Menu/Tools/Masternode Keys/Overview/Cell/KeysOverviewCell.swiftDashWallet/Sources/UI/Menu/Tools/Masternode Keys/Overview/KeysOverviewView.swiftDashWallet/Sources/UI/Menu/Tools/ToolsMenuScreen.swiftDashWallet/ar.lproj/Localizable.stringsDashWallet/ar.lproj/Localizable.stringsdictDashWallet/bg.lproj/Localizable.stringsDashWallet/bg.lproj/Localizable.stringsdictDashWallet/ca.lproj/Localizable.stringsDashWallet/ca.lproj/Localizable.stringsdictDashWallet/cs.lproj/Localizable.stringsDashWallet/cs.lproj/Localizable.stringsdictDashWallet/da.lproj/Localizable.stringsDashWallet/da.lproj/Localizable.stringsdictDashWallet/de.lproj/Localizable.stringsDashWallet/de.lproj/Localizable.stringsdictDashWallet/el.lproj/Localizable.stringsdictDashWallet/en.lproj/Localizable.stringsDashWallet/en.lproj/Localizable.stringsdictDashWallet/eo.lproj/Localizable.stringsDashWallet/eo.lproj/Localizable.stringsdictDashWallet/es.lproj/Localizable.stringsDashWallet/es.lproj/Localizable.stringsdictDashWallet/et.lproj/Localizable.stringsDashWallet/et.lproj/Localizable.stringsdictDashWallet/fa.lproj/Localizable.stringsDashWallet/fa.lproj/Localizable.stringsdictDashWallet/fi.lproj/Localizable.stringsDashWallet/fi.lproj/Localizable.stringsdictDashWallet/fil.lproj/Localizable.stringsDashWallet/fil.lproj/Localizable.stringsdictDashWallet/fr.lproj/Localizable.stringsDashWallet/fr.lproj/Localizable.stringsdictDashWallet/hr.lproj/Localizable.stringsDashWallet/hr.lproj/Localizable.stringsdictDashWallet/hu.lproj/Localizable.stringsDashWallet/hu.lproj/Localizable.stringsdictDashWallet/id.lproj/Localizable.stringsdictDashWallet/it.lproj/Localizable.stringsDashWallet/it.lproj/Localizable.stringsdictDashWallet/ja.lproj/Localizable.stringsDashWallet/ja.lproj/Localizable.stringsdictDashWallet/ko.lproj/Localizable.stringsDashWallet/ko.lproj/Localizable.stringsdictDashWallet/mk.lproj/Localizable.stringsDashWallet/mk.lproj/Localizable.stringsdictDashWallet/ms.lproj/Localizable.stringsDashWallet/ms.lproj/Localizable.stringsdictDashWallet/nb.lproj/Localizable.stringsDashWallet/nb.lproj/Localizable.stringsdictDashWallet/nl.lproj/Localizable.stringsDashWallet/nl.lproj/Localizable.stringsdictDashWallet/pl.lproj/Localizable.stringsDashWallet/pl.lproj/Localizable.stringsdictDashWallet/pt.lproj/Localizable.stringsDashWallet/pt.lproj/Localizable.stringsdictDashWallet/ro.lproj/Localizable.stringsDashWallet/ro.lproj/Localizable.stringsdictDashWallet/ru.lproj/Localizable.stringsdictDashWallet/sk.lproj/Localizable.stringsDashWallet/sk.lproj/Localizable.stringsdictDashWallet/sl.lproj/Localizable.stringsDashWallet/sl.lproj/Localizable.stringsdictDashWallet/sl_SI.lproj/Localizable.stringsDashWallet/sl_SI.lproj/Localizable.stringsdictDashWallet/sq.lproj/Localizable.stringsDashWallet/sq.lproj/Localizable.stringsdictDashWallet/sr.lproj/Localizable.stringsDashWallet/sr.lproj/Localizable.stringsdictDashWallet/sv.lproj/Localizable.stringsDashWallet/sv.lproj/Localizable.stringsdictDashWallet/th.lproj/Localizable.stringsDashWallet/th.lproj/Localizable.stringsdictDashWallet/tr.lproj/Localizable.stringsDashWallet/tr.lproj/Localizable.stringsdictDashWallet/uk.lproj/Localizable.stringsDashWallet/uk.lproj/Localizable.stringsdictDashWallet/vi.lproj/Localizable.stringsDashWallet/vi.lproj/Localizable.stringsdictDashWallet/zh-Hans.lproj/Localizable.stringsDashWallet/zh-Hans.lproj/Localizable.stringsdictDashWallet/zh-Hant-TW.lproj/Localizable.stringsDashWallet/zh-Hant-TW.lproj/Localizable.stringsdictDashWallet/zh.lproj/Localizable.stringsdictDashWallet/zh_TW.lproj/Localizable.stringsdict
✅ Files skipped from review due to trivial changes (1)
- DashWallet/nl.lproj/Localizable.stringsdict
There was a problem hiding this comment.
Actionable comments posted: 13
Note
Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
DashWallet/eo.lproj/Localizable.stringsdict (1)
1-85:⚠️ Potential issue | 🟡 MinorPluralization structure is correct, but Esperanto translations are missing.
The
.stringsdictpluralization dictionaries are properly structured. However, this is the Esperanto (eo) locale file, yet all user-facing strings remain in English:
%ld used/%d merchant/%d merchants/%d transaction/%d transactions/%d key/%d keysIn Esperanto, these would typically be translated with proper plural forms (e.g., "vendisto"/"vendistoj" for merchant/merchants). If Esperanto support is intentional, consider adding proper translations. If this locale is meant to fall back to English, this is acceptable but the locale folder may be unnecessary.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/eo.lproj/Localizable.stringsdict` around lines 1 - 85, The pluralization dictionaries are correct but the Esperanto locale file contains English strings; update the values for keys like "%ld used", "%d merchant(s) in %@", "%d merchant(s)", "%d transaction(s)", and "%d key(s)" to proper Esperanto pluralized strings (e.g., translate "merchant"/"merchants" to "vendisto"/"vendistoj", "transaction"/"transactions" to "transakcio"/"transakcioj", adjust "%ld used" accordingly) inside each plural "one"/"other" entry so the NSLocalizedStringPluralization uses Esperanto text, or remove the eo.lproj file if you intend to fall back to English.DashWallet/nb.lproj/Localizable.stringsdict (1)
1-86:⚠️ Potential issue | 🟠 MajorPlural strings are in English instead of Norwegian.
This file is in
nb.lproj(Norwegian Bokmål) but all plural string values remain in English (e.g., "merchant", "transaction", "key"). For proper localization, these should be translated to Norwegian (e.g., "forhandler"/"forhandlere", "transaksjon"/"transaksjoner", "nøkkel"/"nøkler").Please verify whether this is intentional (e.g., placeholder until translations are ready) or if Norwegian translations should be added.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/nb.lproj/Localizable.stringsdict` around lines 1 - 86, The plural entries in nb.lproj/Localizable.stringsdict are still in English—update the "one" and "other" string values for the keys "%ld used", "%d merchant(s) in %@", "%d merchant(s)", "%d transaction(s)", and "%d key(s)" to their Norwegian Bokmål translations (e.g., "forhandler"/"forhandlere", "transaksjon"/"transaksjoner", "nøkkel"/"nøkler", and appropriate translation for "used"), ensuring the plural forms remain under the same plural-rule structure (NSStringLocalizedFormatKey -> %#@...@ and NSStringFormatSpecTypeKey = NSStringPluralRuleType) and preserve the format specifiers (%ld/%d/%@) exactly; if these English strings are intentional placeholders, add a comment or TODO nearby to indicate that translation is pending instead of replacing them silently.DashWallet/hr.lproj/Localizable.stringsdict (1)
1-86:⚠️ Potential issue | 🟠 MajorAdd the
fewplural category to Croatian plural rules.The Croatian (
hr) locale file is missing thefewplural category required by CLDR rules. According to CLDR, Croatian plurals require three categories:
one(v = 0 and i % 10 = 1 and i % 100 ≠ 11)few(v = 0 and i % 10 = 2..4 and i % 100 ≠ 12..14)other(remaining cases)All other Slavic locale files (
pl,ru,uk,sk) already include the full set of plural categories. Thefewcategory must be added to each plural entry in the Croatian file to match the language's actual grammatical rules.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/hr.lproj/Localizable.stringsdict` around lines 1 - 86, The Croatian stringsdict is missing the CLDR "few" plural category for each pluralized key; update each plural entry for "%ld used", "%d merchant(s) in %@", "%d merchant(s)", "%d transaction(s)", and "%d key(s)" by adding a <key>few</key> entry inside the corresponding plural dict (the same dict that contains NSStringFormatSpecTypeKey/NSStringFormatValueTypeKey) and provide the correct Croatian "few" form string for that key (mirror the existing pattern used for "one" and "other" but with the appropriate localized text); ensure you keep NSStringFormatSpecTypeKey as NSStringPluralRuleType and NSStringFormatValueTypeKey unchanged.
🟡 Minor comments (10)
DashWallet/ro.lproj/Localizable.stringsdict-15-18 (1)
15-18:⚠️ Potential issue | 🟡 MinorThese new plural variants are still English in the Romanian bundle.
Because this is
ro.lproj, theseone/othervalues should be Romanian. As written, Romanian users will still see English strings for all of these pluralized messages.Also applies to: 31-34, 47-50, 63-66, 79-82
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/ro.lproj/Localizable.stringsdict` around lines 15 - 18, The plural variants in the Romanian stringsdict are still English; update each plural "one"/"other" entry in DashWallet/ro.lproj/Localizable.stringsdict so the values are Romanian translations (e.g., replace "%ld used" with the correct Romanian equivalents for singular and plural forms) for the affected plural keys shown (the block with "%ld used" and the other blocks at the ranges you noted). Locate the plural dictionaries by their keys (the "one" and "other" entries) and replace the English text with proper Romanian phrases that match the numeric substitution ("%ld") and Romanian plural rules.DashWallet/hr.lproj/Localizable.stringsdict-41-51 (1)
41-51:⚠️ Potential issue | 🟡 MinorMissing "few" plural forms for remaining entries.
The same pattern applies to
%d merchant(s),%d transaction(s), and%d key(s)—all need a "few" key added for correct Croatian pluralization.Also applies to: 57-67, 73-83
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/hr.lproj/Localizable.stringsdict` around lines 41 - 51, The Croatian stringsdict entries (e.g., the "merchants" plural dict and the similar "transactions" and "keys" plural dicts) are missing the "few" plural form; update each plural dictionary (look for keys named merchants, transactions, keys) to include a <key>few</key> with the correct localized string for the few form (e.g., the appropriate Croatian "%d ..." phrasing), ensuring the plist uses NSStringPluralRuleType and keeps NSStringFormatValueTypeKey "d" unchanged; apply the same addition to the other plural entries mentioned so all plural rules (one, few, other) are present.DashWallet/hr.lproj/Localizable.stringsdict-9-19 (1)
9-19:⚠️ Potential issue | 🟡 MinorCroatian locale requires "few" plural form.
Croatian is a Slavic language with CLDR plural rules that include
one,few, andothercategories. The "few" form applies to numbers ending in 2-4 (excluding 12-14). Without it, counts like 2, 3, or 4 will incorrectly fall back to "other".Additionally, both "one" and "other" have identical English strings—these should be translated to Croatian (e.g., "korišteno" with appropriate inflection).
Proposed fix to add the missing "few" plural form
<key>one</key> <string>%ld used</string> + <key>few</key> + <string>%ld used</string> <key>other</key> <string>%ld used</string>🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/hr.lproj/Localizable.stringsdict` around lines 9 - 19, The "used" plural entry is missing the Croatian "few" category and currently uses English strings for "one" and "other"; update the plural dict for key "used" (the NSStringPluralRuleType block with NSStringFormatValueTypeKey "ld") to include a "few" key and supply Croatian translations for "one", "few", and "other" (use correct inflections of "korišteno"/"korištena"/"korišteni" as appropriate for the intended noun), ensuring the "few" form covers numbers ending in 2–4 excluding 12–14 and the existing "one" and "other" entries are replaced with proper Croatian text.DashWallet/hr.lproj/Localizable.stringsdict-25-35 (1)
25-35:⚠️ Potential issue | 🟡 MinorMissing "few" plural form for merchants.
Same issue as above—Croatian requires a "few" category for proper pluralization of 2, 3, 4 merchants.
Proposed fix
<key>one</key> <string>%d merchant</string> + <key>few</key> + <string>%d merchants</string> <key>other</key> <string>%d merchants</string>🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/hr.lproj/Localizable.stringsdict` around lines 25 - 35, The "merchants" pluralization dictionary is missing the Croatian "few" category; update the <key>merchants</key> dict to include a <key>few</key> entry with the appropriate Croatian translation for 2–4 merchants (matching the existing pattern for <key>one</key> and <key>other</key>) so the plural rules handle 2, 3, 4 correctly; locate the "merchants" dictionary and add the <key>few</key> string with the correct localized text.DashWallet/zh-Hans.lproj/Localizable.strings-1106-1106 (1)
1106-1106:⚠️ Potential issue | 🟡 MinorLocalize the zh-Hans values, not just the keys.
The key renames look right, but the right-hand values are still English, so Simplified Chinese users will still see untranslated labels for these updated tool menu items. Please replace the value side with actual zh-Hans copy for each entry.
Also applies to: 1491-1491, 1719-1719, 1734-1734, 2833-2833
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/zh-Hans.lproj/Localizable.strings` at line 1106, Replace the English RHS values with Simplified Chinese translations for the localized entries—e.g., change the value for the key "HPMN Operator keys" to an appropriate zh-Hans string—and do the same for the other renamed keys referenced in the comment (the entries at the other specified locations). Keep the original key, quoting, spacing and trailing semicolon format intact, ensure UTF-8 encoding, and verify the translated strings match the app’s tone/terminology for consistency.DashWallet/mk.lproj/Localizable.stringsdict-9-84 (1)
9-84:⚠️ Potential issue | 🟡 MinorMissing Macedonian translations - English text used as placeholders.
The plural dictionaries contain English text (
used,merchant,merchants,transaction,transactions,key,keys) instead of Macedonian translations. This will display English strings to Macedonian users.Ensure proper Macedonian translations are provided for:
- Lines 16-18: "used" → Macedonian equivalent
- Lines 32-34, 48-50: "merchant/merchants" → Macedonian equivalent
- Lines 64-66: "transaction/transactions" → Macedonian equivalent
- Lines 80-82: "key/keys" → Macedonian equivalent
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/mk.lproj/Localizable.stringsdict` around lines 9 - 84, Replace the English placeholder strings in the Macedonian .stringsdict entries with proper Macedonian translations: update the "one" and "other" values under the "used" plural key and under the plural groups for "%d merchant(s) in %@", "%d merchant(s)", "%d transaction(s)", and "%d key(s)"; ensure you edit the entries named merchants, transactions, keys and the top-level "used" key (their NSStringLocalizedFormatKey and NSStringFormatValueTypeKey can stay) and provide correct Macedonian singular/plural text for the "one" and "other" variants so Macedonian users see localized strings instead of English.DashWallet/da.lproj/Localizable.stringsdict-9-83 (1)
9-83:⚠️ Potential issue | 🟡 MinorMissing Danish translations - English text used as placeholders.
All plural dictionaries contain English text instead of Danish translations. Danish users will see English strings for:
used(lines 16-18)merchant/merchants(lines 32-34, 48-50)transaction/transactions(lines 64-66)key/keys(lines 80-82)Please provide proper Danish translations.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/da.lproj/Localizable.stringsdict` around lines 9 - 83, Plural entries currently contain English placeholders; update the string values for the plural keys "used", "%d merchant(s) in %@", "%d merchant(s)", "%d transaction(s)", and "%d key(s)" to Danish equivalents in their respective <key>one</key> and <key>other</key> nodes. Locate the plural dicts for those identifiers (e.g., the "used" dict and the "merchants"/"transactions"/"keys" dicts referenced by their NSStringLocalizedFormatKey) and replace the English singular and plural phrases with correct Danish translations for both the "one" and "other" forms.DashWallet/ca.lproj/Localizable.stringsdict-9-83 (1)
9-83:⚠️ Potential issue | 🟡 MinorMissing Catalan translations - English text used as placeholders.
All plural dictionaries contain English text instead of Catalan translations. Catalan users will see English strings for:
used(lines 16-18)merchant/merchants(lines 32-34, 48-50)transaction/transactions(lines 64-66)key/keys(lines 80-82)Please provide proper Catalan translations.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/ca.lproj/Localizable.stringsdict` around lines 9 - 83, Replace the English placeholder strings inside the plural dictionaries for keys "used", "%d merchant(s) in %@", "%d merchant(s)", "%d transaction(s)" and "%d key(s)" with Catalan equivalents: update the "one" and "other" values for "used" to use "%ld utilitzat" and "%ld utilitzats"; for merchants use "%d comerç" and "%d comerços" (both "%d merchant(s) in %@" and "%d merchant(s)" entries); for transactions use "%d transacció" and "%d transaccions"; and for keys use "%d clau" and "%d claus". Ensure you only change the string values under the corresponding plural dictionaries (e.g., the "one" and "other" entries inside the "merchants", "transactions", "keys", and "used" dicts).DashWallet/sv.lproj/Localizable.stringsdict-9-83 (1)
9-83:⚠️ Potential issue | 🟡 MinorMissing Swedish translations - English text used as placeholders.
All plural dictionaries contain English text instead of Swedish translations. Swedish users will see English strings for:
used(lines 16-18)merchant/merchants(lines 32-34, 48-50)transaction/transactions(lines 64-66)key/keys(lines 80-82)Please provide proper Swedish translations.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/sv.lproj/Localizable.stringsdict` around lines 9 - 83, Replace the English placeholder strings in the Swedish .stringsdict plural entries with proper Swedish translations: update the "used" entry values to "%ld använt" (one) and "%ld använda" (other); update "%d merchant(s) in %@" and "%d merchant(s)" entries (merchants) to "%d handlare" for both singular and plural forms; update "%d transaction(s)" (transactions) to "%d transaktion" (one) and "%d transaktioner" (other); and update "%d key(s)" (keys) to "%d nyckel" (one) and "%d nycklar" (other) so the keys "used", "%d merchant(s) in %@", "%d merchant(s)", "%d transaction(s)", and "%d key(s)" all contain Swedish strings instead of English.DashWallet/ar.lproj/Localizable.stringsdict-15-18 (1)
15-18:⚠️ Potential issue | 🟡 MinorPlural strings in Arabic localization file contain English text instead of Arabic translations.
The strings in the Arabic localization file (ar.lproj) at the specified locations are in English (e.g.,
%ld used,%d merchant,%d merchants,%d transaction,%d key) rather than Arabic. Other language files in the repository (French, German, Spanish, etc.) contain properly localized strings, confirming that the Arabic file should include Arabic translations with appropriate grammatical forms for each plural category.Affected lines: 15-18, 31-34, 47-50, 63-66, 80-82
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/ar.lproj/Localizable.stringsdict` around lines 15 - 18, The Arabic .stringsdict entries currently contain English text (e.g., "%ld used", "%d merchant", "%d merchants", "%d transaction", "%d key"); replace those English values with proper Arabic translations and ensure you supply all Arabic plural forms expected by .stringsdict (zero, one, two, few, many, other) for each pluralized key so NSLocalizedString can pick the correct form; update the entries for the specific plural keys whose values are "%ld used", "%d merchant"/"%d merchants", "%d transaction", and "%d key" to Arabic phrases with the same format specifiers (e.g., keep %d/%ld) and correct Arabic grammar for each plural category.
🧹 Nitpick comments (1)
DashWallet/fa.lproj/Localizable.stringsdict (1)
15-18: Identical singular and plural forms for "used".Both
oneandotherforms are%ld used. If this is intentional (e.g., "used" doesn't change based on count in this context), this is fine. Otherwise, consider whether distinct forms are needed.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/fa.lproj/Localizable.stringsdict` around lines 15 - 18, The pluralization entries for the key variants "one" and "other" both use the identical string "%ld used" which may be incorrect; update the Localizable.stringsdict so the "one" form uses the singular wording (e.g., "%ld used" or a singular variant like "%ld used" adjusted to your language rules) and the "other" form uses the correct plural wording (e.g., "%ld used" pluralized appropriately), or confirm and document that identical forms are intentional; locate the "one" and "other" keys in the Localizable.stringsdict and make the singular/plural strings distinct or add a comment indicating intentional parity.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@DashWallet/ar.lproj/Localizable.stringsdict`:
- Around line 21-35: The NSStringLocalizedFormatKey currently only references
the "merchants" plural and omits the location placeholder from the format for
the "%d merchant(s) in %@" key; update NSStringLocalizedFormatKey to include
both the plural placeholder and the location placeholder in the correct Arabic
order (i.e., reference the merchants plural placeholder first and then the
location placeholder with positional indexing), and update the plural strings
inside the "merchants" dict to use the matching positional index for the numeric
value so the final localized output includes both the count and the location
(and include the appropriate Arabic preposition/word order as suggested).
- Around line 9-19: Replace the English strings and the missing plural keys with
full Arabic plural dictionaries for each plural entry: for the "used" key
(original "%ld used") add keys zero, one, two, few, many, other and use Arabic
forms (e.g. zero: "لا مستخدم", one: "%ld مستخدم", two: "%ld مستخدمان", few: "%ld
مستخدمون", many: "%ld مستخدمًا", other: "%ld مستخدم"); for the "%d merchant(s)
in %@" entry add the six Arabic forms (e.g. zero: "لا تاجر في %@", one: "%d متجر
في %@", two: "%d متجران في %@", few: "%d متاجر في %@", many: "%d متجرًا في %@",
other: "%d متجر في %@"); for the "%d merchant(s)" entry add six forms (e.g.
zero: "لا متاجر", one: "%d متجر", two: "%d متجران", few: "%d متاجر", many: "%d
متجرًا", other: "%d متجر"); for "%d transaction(s)" add six Arabic forms (e.g.
zero: "لا معاملات", one: "%d معاملة", two: "%d معاملتان", few: "%d معاملات",
many: "%d معاملةً", other: "%d معاملة"); and for "%d key(s)" add six Arabic
forms (e.g. zero: "لا مفاتيح", one: "%d مفتاح", two: "%d مفتاحان", few: "%d
مفاتيح", many: "%d مفتاحًا", other: "%d مفتاح"); ensure you replace the existing
"one" and "other" English strings in the ar.lproj Localizable.stringsdict with
these full Arabic plural dictionaries using the same keys ("used" and the
merchant/transaction/key entries) so Arabic CLDR plural rules are satisfied.
In `@DashWallet/cs.lproj/Localizable.stringsdict`:
- Around line 29-87: The merchants, transactions and keys plural dictionaries
currently contain English strings and only two plural forms; update each
dictionary (keys "merchants", "transactions", "keys") to use Czech translations
and the full Czech plural set (one, few, many, other) mirroring the structure
used by the "used" dictionary: keep NSStringFormatSpecTypeKey =
NSStringPluralRuleType and NSStringFormatValueTypeKey = d, then provide Czech
strings for each category (examples: merchants -> one: "%d obchod", few: "%d
obchody", many: "%d obchodů", other: "%d obchodů"; transactions and keys
similarly using Czech forms: transactions one/few/many/other and keys one: "%d
klíč", few: "%d klíče", many/other: "%d klíčů") so pluralization behaves
correctly for Czech.
In `@DashWallet/fa.lproj/Localizable.stringsdict`:
- Around line 21-35: The localized plural entry for "%d merchant(s) in %@" only
wires the count through "merchants" but omits the location placeholder; update
NSStringLocalizedFormatKey to include the location placeholder (e.g.
"%#@merchants@ in %@") and add a corresponding "location" entry in the dict with
NSStringFormatValueTypeKey set to "@" so the second argument (the location
string) is inserted; keep the existing "merchants" plural dict unchanged and
reference both "%#@merchants@" and "%@" in the top-level format.
- Around line 5-84: Replace the English plural strings in
fa.lproj/Localizable.stringsdict with Persian equivalents for the keys "%ld
used", "%d merchant(s) in %@", "%d merchant(s)", "%d transaction(s)", and "%d
key(s)": update the "one" and "other" values inside each plural dict (and keep
the NSStringFormat keys intact) — for example use Persian phrases such as "%ld
استفادهشده" for "%ld used", "%d فروشنده" (one) and "%d فروشندگان" (other) for
merchants, "%d تراکنش" (one) and "%d تراکنشها" (other) for transactions, and
"%d کلید" (one) and "%d کلیدها" (other) for keys; ensure the
NSStringFormatValueTypeKey values remain unchanged (ld/d) and that plural rule
structure (NSStringPluralRuleType) is preserved.
In `@DashWallet/hu.lproj/Localizable.stringsdict`:
- Around line 5-84: Update the Hungarian plural strings so they are translated:
for keys "%ld used", "%d merchant(s) in %@", "%d merchant(s)", "%d
transaction(s)", and "%d key(s)" replace the English "used",
"merchant"/"merchants", "transaction"/"transactions", and "key"/"keys" in both
the "one" and "other" entries with the Hungarian equivalents ("használt" for
used; "kereskedő" for merchant; "tranzakció" for transaction; "kulcs" for key),
preserving the numeric placeholders (%ld/%d) and the existing
NSStringPluralRuleType structure.
- Around line 21-36: Update the plural entries for the key "%d merchant(s) in
%@" so the location placeholder is preserved: modify the 'one' and 'other'
values inside the 'merchants' plural dict to include " in %@" (e.g., "%d
merchant in %@" and "%d merchants in %@"), and also provide the Hungarian
translations for those two strings; locate the strings by the top-level key "%d
merchant(s) in %@" and the nested 'merchants' plural dictionary to make the
changes.
In `@DashWallet/ms.lproj/Localizable.stringsdict`:
- Around line 21-35: The plural stringsdict entry for key "%d merchant(s) in %@"
drops the location argument used by callers in MerchantListViewController.swift;
update the "one" and "other" plural strings inside the "merchants" dict to
include the location placeholder (e.g. "%d merchant in %@" and "%d merchants in
%@") so the format consumes both the integer (NSStringFormatValueTypeKey 'd')
and the location string argument passed from MerchantListViewController. Ensure
the outer NSStringLocalizedFormatKey still references %#@merchants@ so
pluralization remains driven by the merchants spec.
In `@DashWallet/nb.lproj/Localizable.stringsdict`:
- Around line 21-35: The plural mappings for the NSLocalizedString key "%d
merchant(s) in %@" omit the location placeholder, so formatted output drops the
second argument; update the "one" and "other" entries inside the "%d merchant(s)
in %@" dict to include the " in %@" suffix (e.g., change "%d merchant" -> "%d
merchant in %@" and "%d merchants" -> "%d merchants in %@") so both the count
and location arguments are preserved when using this key.
In `@DashWallet/ro.lproj/Localizable.stringsdict`:
- Around line 21-35: The pluralized entry for the key "%d merchant(s) in %@"
currently only references the "merchants" plural token via
NSStringLocalizedFormatKey ("%#@merchants@") which drops the trailing %@
argument; update the NSStringLocalizedFormatKey value to include both tokens
(the plural token and the trailing string placeholder) so the format preserves
the second %@ argument, and ensure the "merchants" dict
(NSStringFormatSpecTypeKey/NSStringFormatValueTypeKey and 'one'/'other' forms)
remains unchanged; locate the entry by the key "%d merchant(s) in %@" and update
its NSStringLocalizedFormatKey to reference both the merchants token and the
trailing context placeholder.
In `@DashWallet/sl_SI.lproj/Localizable.stringsdict`:
- Around line 25-35: The NSLocalized plural entry for the "merchants" key is
currently using NSStringLocalizedFormatKey that only expands the plural
placeholder and drops the second argument; update the NSStringLocalizedFormatKey
value to include the second placeholder so the entry reads "%#@merchants@ in
%@", ensuring the plural rule defined under the "merchants" dict supplies the
first (%d) value while the trailing "%@" preserves the location/string argument.
- Around line 15-18: Replace the English plural strings in
sl_SI.lproj/Localizable.stringsdict for the affected entries (currently using
keys "one" and "other") with Slovenian translations and add the missing CLDR
plural keys "two" and "few" so Slovenian inflection is complete; for each
pluralized resource (the entries shown around keys "one"/"other" at lines
indicated) provide four forms: "one", "two", "few", and "other" with appropriate
Slovenian text (e.g., "1 uporabljen", "2 uporabljena", "3–4 uporabljeni", and
fallback "uporabljeno" or similar) so counts 1, 2, 3–4, and other numbers
display correctly. Ensure you update every plural block that currently only has
"one" and "other" (the blocks around the shown diffs and the other occurrences
mentioned) and keep the same key names for the strings dict entries.
In `@DashWallet/sq.lproj/Localizable.stringsdict`:
- Around line 21-35: The pluralization entry for the key "%d merchant(s) in %@"
omits the location placeholder in both the 'one' and 'other' strings so the
second format argument is dropped; update the 'one' and 'other' values inside
the "%d merchant(s) in %@" dict (the 'merchants' plural dict) to include the
location placeholder (e.g., "%d merchant in %@" and "%d merchants in %@") so
both the count and the location argument are preserved when using
NSLocalizedString with two format args.
---
Outside diff comments:
In `@DashWallet/eo.lproj/Localizable.stringsdict`:
- Around line 1-85: The pluralization dictionaries are correct but the Esperanto
locale file contains English strings; update the values for keys like "%ld
used", "%d merchant(s) in %@", "%d merchant(s)", "%d transaction(s)", and "%d
key(s)" to proper Esperanto pluralized strings (e.g., translate
"merchant"/"merchants" to "vendisto"/"vendistoj", "transaction"/"transactions"
to "transakcio"/"transakcioj", adjust "%ld used" accordingly) inside each plural
"one"/"other" entry so the NSLocalizedStringPluralization uses Esperanto text,
or remove the eo.lproj file if you intend to fall back to English.
In `@DashWallet/hr.lproj/Localizable.stringsdict`:
- Around line 1-86: The Croatian stringsdict is missing the CLDR "few" plural
category for each pluralized key; update each plural entry for "%ld used", "%d
merchant(s) in %@", "%d merchant(s)", "%d transaction(s)", and "%d key(s)" by
adding a <key>few</key> entry inside the corresponding plural dict (the same
dict that contains NSStringFormatSpecTypeKey/NSStringFormatValueTypeKey) and
provide the correct Croatian "few" form string for that key (mirror the existing
pattern used for "one" and "other" but with the appropriate localized text);
ensure you keep NSStringFormatSpecTypeKey as NSStringPluralRuleType and
NSStringFormatValueTypeKey unchanged.
In `@DashWallet/nb.lproj/Localizable.stringsdict`:
- Around line 1-86: The plural entries in nb.lproj/Localizable.stringsdict are
still in English—update the "one" and "other" string values for the keys "%ld
used", "%d merchant(s) in %@", "%d merchant(s)", "%d transaction(s)", and "%d
key(s)" to their Norwegian Bokmål translations (e.g.,
"forhandler"/"forhandlere", "transaksjon"/"transaksjoner", "nøkkel"/"nøkler",
and appropriate translation for "used"), ensuring the plural forms remain under
the same plural-rule structure (NSStringLocalizedFormatKey -> %#@...@ and
NSStringFormatSpecTypeKey = NSStringPluralRuleType) and preserve the format
specifiers (%ld/%d/%@) exactly; if these English strings are intentional
placeholders, add a comment or TODO nearby to indicate that translation is
pending instead of replacing them silently.
---
Minor comments:
In `@DashWallet/ar.lproj/Localizable.stringsdict`:
- Around line 15-18: The Arabic .stringsdict entries currently contain English
text (e.g., "%ld used", "%d merchant", "%d merchants", "%d transaction", "%d
key"); replace those English values with proper Arabic translations and ensure
you supply all Arabic plural forms expected by .stringsdict (zero, one, two,
few, many, other) for each pluralized key so NSLocalizedString can pick the
correct form; update the entries for the specific plural keys whose values are
"%ld used", "%d merchant"/"%d merchants", "%d transaction", and "%d key" to
Arabic phrases with the same format specifiers (e.g., keep %d/%ld) and correct
Arabic grammar for each plural category.
In `@DashWallet/ca.lproj/Localizable.stringsdict`:
- Around line 9-83: Replace the English placeholder strings inside the plural
dictionaries for keys "used", "%d merchant(s) in %@", "%d merchant(s)", "%d
transaction(s)" and "%d key(s)" with Catalan equivalents: update the "one" and
"other" values for "used" to use "%ld utilitzat" and "%ld utilitzats"; for
merchants use "%d comerç" and "%d comerços" (both "%d merchant(s) in %@" and "%d
merchant(s)" entries); for transactions use "%d transacció" and "%d
transaccions"; and for keys use "%d clau" and "%d claus". Ensure you only change
the string values under the corresponding plural dictionaries (e.g., the "one"
and "other" entries inside the "merchants", "transactions", "keys", and "used"
dicts).
In `@DashWallet/da.lproj/Localizable.stringsdict`:
- Around line 9-83: Plural entries currently contain English placeholders;
update the string values for the plural keys "used", "%d merchant(s) in %@", "%d
merchant(s)", "%d transaction(s)", and "%d key(s)" to Danish equivalents in
their respective <key>one</key> and <key>other</key> nodes. Locate the plural
dicts for those identifiers (e.g., the "used" dict and the
"merchants"/"transactions"/"keys" dicts referenced by their
NSStringLocalizedFormatKey) and replace the English singular and plural phrases
with correct Danish translations for both the "one" and "other" forms.
In `@DashWallet/hr.lproj/Localizable.stringsdict`:
- Around line 41-51: The Croatian stringsdict entries (e.g., the "merchants"
plural dict and the similar "transactions" and "keys" plural dicts) are missing
the "few" plural form; update each plural dictionary (look for keys named
merchants, transactions, keys) to include a <key>few</key> with the correct
localized string for the few form (e.g., the appropriate Croatian "%d ..."
phrasing), ensuring the plist uses NSStringPluralRuleType and keeps
NSStringFormatValueTypeKey "d" unchanged; apply the same addition to the other
plural entries mentioned so all plural rules (one, few, other) are present.
- Around line 9-19: The "used" plural entry is missing the Croatian "few"
category and currently uses English strings for "one" and "other"; update the
plural dict for key "used" (the NSStringPluralRuleType block with
NSStringFormatValueTypeKey "ld") to include a "few" key and supply Croatian
translations for "one", "few", and "other" (use correct inflections of
"korišteno"/"korištena"/"korišteni" as appropriate for the intended noun),
ensuring the "few" form covers numbers ending in 2–4 excluding 12–14 and the
existing "one" and "other" entries are replaced with proper Croatian text.
- Around line 25-35: The "merchants" pluralization dictionary is missing the
Croatian "few" category; update the <key>merchants</key> dict to include a
<key>few</key> entry with the appropriate Croatian translation for 2–4 merchants
(matching the existing pattern for <key>one</key> and <key>other</key>) so the
plural rules handle 2, 3, 4 correctly; locate the "merchants" dictionary and add
the <key>few</key> string with the correct localized text.
In `@DashWallet/mk.lproj/Localizable.stringsdict`:
- Around line 9-84: Replace the English placeholder strings in the Macedonian
.stringsdict entries with proper Macedonian translations: update the "one" and
"other" values under the "used" plural key and under the plural groups for "%d
merchant(s) in %@", "%d merchant(s)", "%d transaction(s)", and "%d key(s)";
ensure you edit the entries named merchants, transactions, keys and the
top-level "used" key (their NSStringLocalizedFormatKey and
NSStringFormatValueTypeKey can stay) and provide correct Macedonian
singular/plural text for the "one" and "other" variants so Macedonian users see
localized strings instead of English.
In `@DashWallet/ro.lproj/Localizable.stringsdict`:
- Around line 15-18: The plural variants in the Romanian stringsdict are still
English; update each plural "one"/"other" entry in
DashWallet/ro.lproj/Localizable.stringsdict so the values are Romanian
translations (e.g., replace "%ld used" with the correct Romanian equivalents for
singular and plural forms) for the affected plural keys shown (the block with
"%ld used" and the other blocks at the ranges you noted). Locate the plural
dictionaries by their keys (the "one" and "other" entries) and replace the
English text with proper Romanian phrases that match the numeric substitution
("%ld") and Romanian plural rules.
In `@DashWallet/sv.lproj/Localizable.stringsdict`:
- Around line 9-83: Replace the English placeholder strings in the Swedish
.stringsdict plural entries with proper Swedish translations: update the "used"
entry values to "%ld använt" (one) and "%ld använda" (other); update "%d
merchant(s) in %@" and "%d merchant(s)" entries (merchants) to "%d handlare" for
both singular and plural forms; update "%d transaction(s)" (transactions) to "%d
transaktion" (one) and "%d transaktioner" (other); and update "%d key(s)" (keys)
to "%d nyckel" (one) and "%d nycklar" (other) so the keys "used", "%d
merchant(s) in %@", "%d merchant(s)", "%d transaction(s)", and "%d key(s)" all
contain Swedish strings instead of English.
In `@DashWallet/zh-Hans.lproj/Localizable.strings`:
- Line 1106: Replace the English RHS values with Simplified Chinese translations
for the localized entries—e.g., change the value for the key "HPMN Operator
keys" to an appropriate zh-Hans string—and do the same for the other renamed
keys referenced in the comment (the entries at the other specified locations).
Keep the original key, quoting, spacing and trailing semicolon format intact,
ensure UTF-8 encoding, and verify the translated strings match the app’s
tone/terminology for consistency.
---
Nitpick comments:
In `@DashWallet/fa.lproj/Localizable.stringsdict`:
- Around line 15-18: The pluralization entries for the key variants "one" and
"other" both use the identical string "%ld used" which may be incorrect; update
the Localizable.stringsdict so the "one" form uses the singular wording (e.g.,
"%ld used" or a singular variant like "%ld used" adjusted to your language
rules) and the "other" form uses the correct plural wording (e.g., "%ld used"
pluralized appropriately), or confirm and document that identical forms are
intentional; locate the "one" and "other" keys in the Localizable.stringsdict
and make the singular/plural strings distinct or add a comment indicating
intentional parity.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: bd71a44b-6103-450c-91bf-f8230d048271
📒 Files selected for processing (59)
DashWallet/ar.lproj/Localizable.stringsDashWallet/ar.lproj/Localizable.stringsdictDashWallet/bg.lproj/Localizable.stringsDashWallet/bg.lproj/Localizable.stringsdictDashWallet/ca.lproj/Localizable.stringsDashWallet/ca.lproj/Localizable.stringsdictDashWallet/cs.lproj/Localizable.stringsDashWallet/cs.lproj/Localizable.stringsdictDashWallet/da.lproj/Localizable.stringsDashWallet/da.lproj/Localizable.stringsdictDashWallet/de.lproj/Localizable.stringsDashWallet/de.lproj/Localizable.stringsdictDashWallet/en.lproj/Localizable.stringsDashWallet/eo.lproj/Localizable.stringsDashWallet/eo.lproj/Localizable.stringsdictDashWallet/et.lproj/Localizable.stringsDashWallet/et.lproj/Localizable.stringsdictDashWallet/fa.lproj/Localizable.stringsDashWallet/fa.lproj/Localizable.stringsdictDashWallet/fi.lproj/Localizable.stringsDashWallet/fi.lproj/Localizable.stringsdictDashWallet/fil.lproj/Localizable.stringsDashWallet/fr.lproj/Localizable.stringsDashWallet/hr.lproj/Localizable.stringsDashWallet/hr.lproj/Localizable.stringsdictDashWallet/hu.lproj/Localizable.stringsDashWallet/hu.lproj/Localizable.stringsdictDashWallet/it.lproj/Localizable.stringsDashWallet/ja.lproj/Localizable.stringsDashWallet/ko.lproj/Localizable.stringsDashWallet/mk.lproj/Localizable.stringsDashWallet/mk.lproj/Localizable.stringsdictDashWallet/ms.lproj/Localizable.stringsDashWallet/ms.lproj/Localizable.stringsdictDashWallet/nb.lproj/Localizable.stringsDashWallet/nb.lproj/Localizable.stringsdictDashWallet/nl.lproj/Localizable.stringsDashWallet/pl.lproj/Localizable.stringsDashWallet/pt.lproj/Localizable.stringsDashWallet/ro.lproj/Localizable.stringsDashWallet/ro.lproj/Localizable.stringsdictDashWallet/sk.lproj/Localizable.stringsDashWallet/sl.lproj/Localizable.stringsDashWallet/sl.lproj/Localizable.stringsdictDashWallet/sl_SI.lproj/Localizable.stringsDashWallet/sl_SI.lproj/Localizable.stringsdictDashWallet/sq.lproj/Localizable.stringsDashWallet/sq.lproj/Localizable.stringsdictDashWallet/sr.lproj/Localizable.stringsDashWallet/sr.lproj/Localizable.stringsdictDashWallet/sv.lproj/Localizable.stringsDashWallet/sv.lproj/Localizable.stringsdictDashWallet/th.lproj/Localizable.stringsDashWallet/tr.lproj/Localizable.stringsDashWallet/uk.lproj/Localizable.stringsDashWallet/vi.lproj/Localizable.stringsDashWallet/vi.lproj/Localizable.stringsdictDashWallet/zh-Hans.lproj/Localizable.stringsDashWallet/zh-Hant-TW.lproj/Localizable.strings
🚧 Files skipped from review as they are similar to previous changes (6)
- DashWallet/vi.lproj/Localizable.stringsdict
- DashWallet/sr.lproj/Localizable.stringsdict
- DashWallet/fi.lproj/Localizable.stringsdict
- DashWallet/sl.lproj/Localizable.stringsdict
- DashWallet/zh-Hant-TW.lproj/Localizable.strings
- DashWallet/bg.lproj/Localizable.stringsdict
There was a problem hiding this comment.
Actionable comments posted: 9
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
DashWallet/et.lproj/Localizable.stringsdict (1)
1-84:⚠️ Potential issue | 🟠 MajorStrings are in English, not Estonian.
This file is located in
et.lproj(Estonian locale), but all the plural form strings are in English rather than Estonian translations. For example:
- "merchant" / "merchants" should be Estonian equivalents
- "transaction" / "transactions" should be Estonian equivalents
- "key" / "keys" should be Estonian equivalents
- "used" should be the Estonian equivalent
Other locales in the repository (e.g., Russian) have proper translations for these strings, confirming that localization is expected in this file. Please provide proper Estonian translations for all strings in this file.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/et.lproj/Localizable.stringsdict` around lines 1 - 84, Replace the English plural strings in the Estonian Localizable.stringsdict entries with proper Estonian terms: for key "%ld used" use "kasutatud" (so singular/other -> "%ld kasutatud"); for "%d merchant(s) in %@" and "%d merchant(s)" use "kaupmees" (one) and "kaupmehed" (other); for "%d transaction(s)" use "tehing" (one) and "tehingud" (other); for "%d key(s)" use "võti" (one) and "võtmed" (other). Update the string values under the corresponding plist keys ("%ld used", "%d merchant(s) in %@", "%d merchant(s)", "%d transaction(s)", "%d key(s)") so the NSStringLocalizedFormatKey and the plural "one"/"other" entries contain the Estonian phrases while preserving all numeric/placeholders (%d, %ld, %@).
♻️ Duplicate comments (1)
DashWallet/ar.lproj/Localizable.stringsdict (1)
15-18:⚠️ Potential issue | 🟠 MajorArabic plural values are still untranslated.
This is
ar.lproj, but every plural branch here still renders English copy (used,merchant,transaction,key). Even if the lookup succeeds, Arabic users will see untranslated strings, and the dictionary still only models singular vs. generic plural instead of Arabic-specific plural forms. Please replace these branches with proper Arabic translations and the full set of Arabic plural categories before shipping.For Apple Localizable.stringsdict using NSStringPluralRuleType, what plural categories does Arabic (ar) require according to CLDR, and how should they be represented in a stringsdict file?Also applies to: 31-34, 47-50, 63-66, 79-82
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/ar.lproj/Localizable.stringsdict` around lines 15 - 18, The Arabic stringsdict entries currently use English text and only "one"/"other" keys; update each plural block (e.g., the entries containing the keys "one" and "other" and strings like "%ld used", "%ld merchant", "%ld transaction", "%ld key") to provide Arabic translations and include the full CLDR Arabic plural categories: "zero", "one", "two", "few", "many", and "other", using NSStringPluralRuleType keys in the .stringsdict. Replace the English words with appropriate Arabic strings for each category and replicate this fix for the other occurrences noted (the blocks at the other ranges). Ensure format placeholders (%ld) remain intact and that each plural category has a localized Arabic phrase.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@DashWallet/ca.lproj/Localizable.stringsdict`:
- Around line 5-19: The Catalan stringsdict entries currently use English
phrases; update the plural "one" and "other" values for the plural keys (e.g.
"%ld used", "%d merchant(s)", "%d transaction(s)", "%d key(s)") to Catalan
equivalents and keep the existing NSStringPluralRuleType and value types intact;
for example replace "used" with "usada/usades" (or proper singular/plural
Catalan forms), "merchant(s)" with "comerciant/comerciants", "transaction(s)"
with "transacció/transaccions", and "key(s)" with "clau/claus" in their
respective <key>one</key> and <key>other</key> entries so the pluralized strings
are localized to Catalan.
- Around line 21-35: Replace the String(format: ...) calls that are formatting
the plurals so NSLocalizedString's stringsdict rules are applied: locate the two
String(format:) usages in MerchantListViewController (the calls that format "%d
merchant(s) in %@") and the two String(format:) usages in HomeView (the calls
that format "%d transaction(s)"), and change each to use
String.localizedStringWithFormat(NSLocalizedString(...), ...) passing the same
arguments and comment; keep the same NSLocalizedString key and parameters but
swap the initializer to String.localizedStringWithFormat to enable pluralization
via the .stringsdict.
In `@DashWallet/et.lproj/Localizable.stringsdict`:
- Around line 15-18: The Estonian pluralization entries for the key with
variants "one" and "other" currently use identical English text "%ld used";
verify whether Estonian requires different singular/plural wording and, if so,
replace the "one" and/or "other" values with the correct Estonian translations
(or confirm intentional sameness). Locate the entries for the pluralized key
(the <key>one</key> and <key>other</key> values holding "%ld used") and update
the strings to the proper Estonian singular and plural forms (or add a
comment/confirmation if the identical form is deliberate).
In `@DashWallet/fi.lproj/Localizable.stringsdict`:
- Around line 15-18: Replace the English strings under the plural keys "one" and
"other" in Localizable.stringsdict with Finnish translations while preserving
all placeholders (%ld, %d, %@) and their order; update every plural block that
uses these keys (e.g., the blocks shown and the other similar blocks) so the
Finnish text is correct for the singular "one" form and the plural "other" form
and retains the exact placeholder tokens.
In `@DashWallet/mk.lproj/Localizable.stringsdict`:
- Around line 5-83: The plural entries for "%ld used", "%d merchant(s) in %@",
"%d merchant(s)", "%d transaction(s)", and "%d key(s)" currently contain English
user-facing strings in the Macedonian .stringsdict; replace the "one" and
"other" string values with proper Macedonian translations while preserving the
format specifiers and placeholder order (e.g., keep %ld, %d and %@ where
present) so the NSLocalizedString pluralization works correctly for the keys
"%ld used", "%d merchant(s) in %@", "%d merchant(s)", "%d transaction(s)", and
"%d key(s)"; verify the translations match Macedonian plural rules and that
NSStringFormatValueTypeKey and NSStringFormatSpecTypeKey entries remain
unchanged.
In `@DashWallet/nb.lproj/Localizable.stringsdict`:
- Around line 16-18: The nb (Norwegian Bokmål) plural entries currently contain
English strings ("%ld used") for the plural variants; update the <key>one</key>
and <key>other</key> string values in the Localizable.stringsdict entries (the
plural blocks containing "%ld used") to Norwegian Bokmål translations (e.g.,
adjust "%ld brukt" or appropriate phrasing), or remove the nb.lproj override
entirely until proper translations exist; ensure you update all occurrences
referenced (the plural blocks around the "%ld used" entries and the other groups
noted) and keep the plural key names ("one"/"other") unchanged.
In `@DashWallet/sl.lproj/Localizable.stringsdict`:
- Around line 10-18: Add the missing Slovenian plural categories `two` and `few`
to each plural dictionary for the five pluralized strings so they follow CLDR
rules: the dictionaries for "%ld used", "%d merchant(s) in %@", "%d
merchant(s)", "%d transaction(s)", and "%d key(s)" must each include
<key>two</key> and <key>few</key> entries with the correct Slovenian plural
forms (noting they differ from `one` and `other`); update the respective <dict>
blocks (the ones containing NSStringPluralRuleType and the existing
`one`/`other` keys) to add those two keys and their localized string values.
In `@DashWallet/sv.lproj/Localizable.stringsdict`:
- Around line 5-18: The plural branches for keys like "%ld used"
(NSStringLocalizedFormatKey -> "%#@used@", and the nested 'used' dict with
NSStringFormatSpecTypeKey/NSStringFormatValueTypeKey) currently contain English
strings in the Swedish bundle; update the 'one' and 'other' values to the
correct Swedish translations (not English) for each affected plural key (e.g.,
"%ld used", merchant(s), transaction(s), key(s)) so the sv.lproj
Localizable.stringsdict returns Swedish text for both singular and plural forms
while keeping the existing pluralization structure intact.
In `@DashWallet/vi.lproj/Localizable.stringsdict`:
- Around line 23-33: The Vietnamese .stringsdict contains English plural strings
for keys like "merchants" (and likewise for "transactions" and "keys"); update
the plural forms for these keys to Vietnamese while preserving placeholders %d
and %@ and plural-rule structure
(NSStringFormatSpecTypeKey/NSStringFormatValueTypeKey); specifically replace the
"one" and "other" English values for the "merchants" dict and the corresponding
"transactions" and "keys" dicts with correct Vietnamese translations that keep
%d and %@ intact so the pluralization works in the vi.lproj bundle.
---
Outside diff comments:
In `@DashWallet/et.lproj/Localizable.stringsdict`:
- Around line 1-84: Replace the English plural strings in the Estonian
Localizable.stringsdict entries with proper Estonian terms: for key "%ld used"
use "kasutatud" (so singular/other -> "%ld kasutatud"); for "%d merchant(s) in
%@" and "%d merchant(s)" use "kaupmees" (one) and "kaupmehed" (other); for "%d
transaction(s)" use "tehing" (one) and "tehingud" (other); for "%d key(s)" use
"võti" (one) and "võtmed" (other). Update the string values under the
corresponding plist keys ("%ld used", "%d merchant(s) in %@", "%d merchant(s)",
"%d transaction(s)", "%d key(s)") so the NSStringLocalizedFormatKey and the
plural "one"/"other" entries contain the Estonian phrases while preserving all
numeric/placeholders (%d, %ld, %@).
---
Duplicate comments:
In `@DashWallet/ar.lproj/Localizable.stringsdict`:
- Around line 15-18: The Arabic stringsdict entries currently use English text
and only "one"/"other" keys; update each plural block (e.g., the entries
containing the keys "one" and "other" and strings like "%ld used", "%ld
merchant", "%ld transaction", "%ld key") to provide Arabic translations and
include the full CLDR Arabic plural categories: "zero", "one", "two", "few",
"many", and "other", using NSStringPluralRuleType keys in the .stringsdict.
Replace the English words with appropriate Arabic strings for each category and
replicate this fix for the other occurrences noted (the blocks at the other
ranges). Ensure format placeholders (%ld) remain intact and that each plural
category has a localized Arabic phrase.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: dbbfb735-c2a5-4efa-9b0f-4dbe1900ec7f
📒 Files selected for processing (21)
DashWallet/ar.lproj/Localizable.stringsdictDashWallet/bg.lproj/Localizable.stringsdictDashWallet/ca.lproj/Localizable.stringsdictDashWallet/cs.lproj/Localizable.stringsdictDashWallet/da.lproj/Localizable.stringsdictDashWallet/eo.lproj/Localizable.stringsdictDashWallet/et.lproj/Localizable.stringsdictDashWallet/fa.lproj/Localizable.stringsdictDashWallet/fi.lproj/Localizable.stringsdictDashWallet/hr.lproj/Localizable.stringsdictDashWallet/hu.lproj/Localizable.stringsdictDashWallet/mk.lproj/Localizable.stringsdictDashWallet/ms.lproj/Localizable.stringsdictDashWallet/nb.lproj/Localizable.stringsdictDashWallet/ro.lproj/Localizable.stringsdictDashWallet/sl.lproj/Localizable.stringsdictDashWallet/sl_SI.lproj/Localizable.stringsdictDashWallet/sq.lproj/Localizable.stringsdictDashWallet/sr.lproj/Localizable.stringsdictDashWallet/sv.lproj/Localizable.stringsdictDashWallet/vi.lproj/Localizable.stringsdict
✅ Files skipped from review due to trivial changes (1)
- DashWallet/fa.lproj/Localizable.stringsdict
🚧 Files skipped from review as they are similar to previous changes (7)
- DashWallet/hu.lproj/Localizable.stringsdict
- DashWallet/sl_SI.lproj/Localizable.stringsdict
- DashWallet/hr.lproj/Localizable.stringsdict
- DashWallet/eo.lproj/Localizable.stringsdict
- DashWallet/sr.lproj/Localizable.stringsdict
- DashWallet/bg.lproj/Localizable.stringsdict
- DashWallet/ro.lproj/Localizable.stringsdict
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
DashWallet/Sources/UI/Explore Dash/Merchants & ATMs/List/MerchantListViewController.swift (1)
214-221: Good localization improvement; fix parameter alignment for SwiftLint compliance.The switch to
String.localizedStringWithFormatis the correct approach for locale-aware pluralization. However, SwiftLint flags vertical parameter alignment.🔧 Proposed fix for parameter alignment
if Locale.current.usesMetricSystem { - return String.localizedStringWithFormat(NSLocalizedString("%d merchant(s) in %@", comment: "#bc-ignore!"), items.count, - ExploreDash.distanceFormatter - .string(from: Measurement(value: model.currentRadius, unit: UnitLength.meters))) + return String.localizedStringWithFormat( + NSLocalizedString("%d merchant(s) in %@", comment: "#bc-ignore!"), + items.count, + ExploreDash.distanceFormatter.string(from: Measurement(value: model.currentRadius, unit: UnitLength.meters)) + ) } else { - return String.localizedStringWithFormat(NSLocalizedString("%d merchant(s) in %@", comment: "#bc-ignore!"), items.count, - ExploreDash.distanceFormatter - .string(from: Measurement(value: model.currentRadiusMiles, unit: UnitLength.miles))) + return String.localizedStringWithFormat( + NSLocalizedString("%d merchant(s) in %@", comment: "#bc-ignore!"), + items.count, + ExploreDash.distanceFormatter.string(from: Measurement(value: model.currentRadiusMiles, unit: UnitLength.miles)) + ) }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/Sources/UI/Explore` Dash/Merchants & ATMs/List/MerchantListViewController.swift around lines 214 - 221, The localized string call in MerchantListViewController uses String.localizedStringWithFormat with vertically aligned parameters causing a SwiftLint violation; fix it by reformatting the call to avoid vertical parameter alignment—either place all arguments on a single line or break after the opening parenthesis and indent subsequent arguments consistently (not column-aligned). Update both branches that use String.localizedStringWithFormat with ExploreDash.distanceFormatter and model.currentRadius/model.currentRadiusMiles so the arguments (items.count and the formatter.string(...) expression) follow the chosen non-vertically-aligned style while preserving the same localized key and expressions.DashWallet/Sources/UI/Menu/Tools/ToolsMenuScreen.swift (1)
243-249: Address SwiftLint warnings (if this code is retained).SwiftLint flags two issues:
- Line 243, 245: Prefer
-> Voidover-> ()- Line 249:
@objcattribute should be on its own lineIf
DelegateInternalis kept, apply these fixes:♻️ Proposed fix
class DelegateInternal: NSObject, DWImportWalletInfoViewControllerDelegate { - let onImportPrivateKey: () -> () + let onImportPrivateKey: () -> Void - init(onImportPrivateKey: `@escaping` () -> ()) { + init(onImportPrivateKey: `@escaping` () -> Void) { self.onImportPrivateKey = onImportPrivateKey } - `@objc` func importWalletInfoViewControllerScanPrivateKeyAction(_ controller: DWImportWalletInfoViewController) { onImportPrivateKey() } + `@objc` + func importWalletInfoViewControllerScanPrivateKeyAction(_ controller: DWImportWalletInfoViewController) { + onImportPrivateKey() + } }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/Sources/UI/Menu/Tools/ToolsMenuScreen.swift` around lines 243 - 249, Update the closure type annotations from () to Void and place the `@objc` attribute on its own line: change the stored property signature and initializer parameter from "onImportPrivateKey: () -> ()" to "onImportPrivateKey: () -> Void" (keeping `@escaping` in init), and move "@objc" to its own line immediately above the method declaration for "importWalletInfoViewControllerScanPrivateKeyAction(_:)"; these edits touch the declarations for onImportPrivateKey, init(onImportPrivateKey:), and importWalletInfoViewControllerScanPrivateKeyAction(_:) in DelegateInternal.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@DashWallet/Sources/UI/Menu/Tools/ToolsMenuScreen.swift`:
- Line 24: Remove the unused dead property delegateInternal from
ToolsMenuScreen: locate the declaration private let delegateInternal:
DelegateInternal and delete it (and any unused initializer/store references) so
ToolsMenuScreen no longer holds an unassigned instance; ensure
createController() and DelegateInternal usages remain unaffected (they are used
elsewhere, e.g., HomeViewController+Shortcuts.swift), and keep behavior
consistent with other screens that assign delegateInternal only where needed.
---
Nitpick comments:
In `@DashWallet/Sources/UI/Explore` Dash/Merchants &
ATMs/List/MerchantListViewController.swift:
- Around line 214-221: The localized string call in MerchantListViewController
uses String.localizedStringWithFormat with vertically aligned parameters causing
a SwiftLint violation; fix it by reformatting the call to avoid vertical
parameter alignment—either place all arguments on a single line or break after
the opening parenthesis and indent subsequent arguments consistently (not
column-aligned). Update both branches that use String.localizedStringWithFormat
with ExploreDash.distanceFormatter and
model.currentRadius/model.currentRadiusMiles so the arguments (items.count and
the formatter.string(...) expression) follow the chosen non-vertically-aligned
style while preserving the same localized key and expressions.
In `@DashWallet/Sources/UI/Menu/Tools/ToolsMenuScreen.swift`:
- Around line 243-249: Update the closure type annotations from () to Void and
place the `@objc` attribute on its own line: change the stored property signature
and initializer parameter from "onImportPrivateKey: () -> ()" to
"onImportPrivateKey: () -> Void" (keeping `@escaping` in init), and move "@objc"
to its own line immediately above the method declaration for
"importWalletInfoViewControllerScanPrivateKeyAction(_:)"; these edits touch the
declarations for onImportPrivateKey, init(onImportPrivateKey:), and
importWalletInfoViewControllerScanPrivateKeyAction(_:) in DelegateInternal.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 73ff48cd-0bf5-4f7e-a14f-14f0d4cae7c1
📒 Files selected for processing (4)
DashWallet/Sources/UI/Explore Dash/Merchants & ATMs/List/MerchantListViewController.swiftDashWallet/Sources/UI/Home/Views/HomeView.swiftDashWallet/Sources/UI/Menu/Main/MainMenuViewController.swiftDashWallet/Sources/UI/Menu/Tools/ToolsMenuScreen.swift
✅ Files skipped from review due to trivial changes (1)
- DashWallet/Sources/UI/Menu/Main/MainMenuViewController.swift
bfoss765
left a comment
There was a problem hiding this comment.
This builds on my machine after doing a podinstall.
Issue being fixed or feature implemented
What was done?
How Has This Been Tested?
Breaking Changes
Checklist:
For repository code-owners and collaborators only
Summary by CodeRabbit
New Features
UI/UX Improvements
Localization