Skip to content

feat: update csv export and zenledger#762

Open
ross-dash wants to merge 5 commits intomasterfrom
feat/update-csv-export-and-zenledger
Open

feat: update csv export and zenledger#762
ross-dash wants to merge 5 commits intomasterfrom
feat/update-csv-export-and-zenledger

Conversation

@ross-dash
Copy link
Copy Markdown
Contributor

@ross-dash ross-dash commented Mar 24, 2026

  • Export CSV
  • Zenledger

Changed the navigation bar for sheet "Import private key"

Issue being fixed or feature implemented

What was done?

How Has This Been Tested?

Breaking Changes

Checklist:

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

For repository code-owners and collaborators only

  • I have assigned this pull request to a milestone

Summary by CodeRabbit

  • New Features

    • CSV export available via a new sheet-based interface.
    • New illustration assets for CSV export and integrations.
  • Improvements

    • Updated ZenLedger sheet layout and presentation behavior.
    • Improved sheet visuals on iOS 16.4+ and standardized sheet handling.
    • Replaced inline close controls with a unified close component across views.
  • Version

    • Updated app version to 8.5.6.

- Export CSV
- Zenledger

Changed the navigation bar for sheet "Import private key"
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 24, 2026

📝 Walkthrough

Walkthrough

Adds a CSV export SwiftUI sheet and related assets, updates Tools menu to present the sheet with iOS-version-specific detents, refactors several sheets to use a shared NavBarClose, and bumps MARKETING_VERSION from 8.5.5 to 8.5.6 in the Xcode project.

Changes

Cohort / File(s) Summary
Project Configuration & Version
DashWallet.xcodeproj/project.pbxproj
Added CSVExportSheet.swift to build phases and updated MARKETING_VERSION from 8.5.5 to 8.5.6 across targets.
Asset Catalog Illustrations
DashWallet/Resources/AppAssets.xcassets/Illustration/Contents.json, DashWallet/Resources/AppAssets.xcassets/Illustration/csv-export-large.imageset/Contents.json, DashWallet/Resources/AppAssets.xcassets/Illustration/zenledger-large.imageset/Contents.json
Added asset catalog metadata and two new image sets (csv-export-large, zenledger-large) with 1x/2x/3x variants.
New CSV Export Sheet
DashWallet/Sources/UI/Menu/Tools/CSVExportSheet.swift
New SwiftUI view presenting CSV export UI (grabber, NavBarClose, explanatory text, Export button) that calls an injected onExport closure and dismisses.
Tools Menu & Sheet Presentation
DashWallet/Sources/UI/Menu/Tools/ToolsMenuScreen.swift
Replaced CSV export alert with a sheet (showCSVExportSheet) and added iOS 16.4+ conditional .presentationDetents([.large]) and .presentationCornerRadius(32) modifiers; adjusted ZenLedger sheet detents similarly.
Sheet Refactors & NavBarClose Adoption
DashWallet/Sources/UI/Menu/Tools/ImportPrivateKeySheet.swift, DashWallet/Sources/UI/Menu/Tools/ZenLedger/ZenLedgerInfoSheet.swift
Replaced manual close-button implementations with NavBarClose; ZenLedgerInfoSheet reworked to a custom VStack layout with theme-aware grabber and updated button/link handling.
Minor Whitespace
DashWallet/Sources/UI/SwiftUI Components/NavigationBar.swift
Whitespace adjustment in header comment only.
Localization
DashWallet/en.lproj/Localizable.strings
Added string: "The full transaction history will be exported as a CSV file".

Sequence Diagram(s)

sequenceDiagram
    participant User as User
    participant Menu as ToolsMenuScreen
    participant Sheet as CSVExportSheet
    participant Exporter as ExportService
    User->>Menu: Tap "Export CSV"
    Menu->>Sheet: present sheet (showCSVExportSheet = true)
    User->>Sheet: Tap "Export CSV" button
    Sheet->>Sheet: dismiss sheet
    Sheet->>Exporter: call onExport()
    Exporter-->>User: export completes / shares CSV
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 A tiny sheet with CSV delight,
I nibble keys by soft lamplight,
New images sparkle, version climbs,
NavBarClose keeps tidy lines,
Export clicked — the carrots fly tonight. 🥕✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main changes: adding/updating CSV export and ZenLedger sheets, which are the primary focus across most modified files.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/update-csv-export-and-zenledger

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

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@ross-dash ross-dash changed the title Added two new bottom sheets: feat/CSV Export and Zenledger bottom sheets Mar 24, 2026
@ross-dash ross-dash changed the title feat/CSV Export and Zenledger bottom sheets feat/update-csv-export-and-zenledger Mar 24, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (6)
DashWallet/Sources/UI/Menu/Tools/CSVExportSheet.swift (2)

81-84: Consider deferring onExport() until after sheet dismissal completes.

Calling onExport() immediately after dismiss() works in this case because handleCSVExport in ToolsMenuScreen starts an async Task. However, for more predictable sequencing, you could use the sheet's onDismiss callback pattern (similar to how ZenLedgerInfoSheet handles safariLink).

Current behavior is functional, so this is just a consistency consideration.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@DashWallet/Sources/UI/Menu/Tools/CSVExportSheet.swift` around lines 81 - 84,
The CSVExportSheet currently calls presentationMode.wrappedValue.dismiss() then
immediately invokes onExport(), which can race with dismissal; update
CSVExportSheet to defer calling onExport() until the sheet's dismissal completes
by moving the export trigger into an onDismiss handler (similar to
ZenLedgerInfoSheet's safariLink pattern): store a local Bool (e.g.,
shouldTriggerExport) or set a closure to be called from onDismiss, set that
flag/closure in the current action instead of calling onExport() directly, and
then call onExport() from the sheet's onDismiss so
ToolsMenuScreen.handleCSVExport runs after dismissal.

22-25: Place @Environment attributes on separate lines per SwiftLint rule.

SwiftLint flags these attributes for placement on the same line as their property declarations.

♻️ Proposed fix
 struct CSVExportSheet: View {
-    `@Environment`(\.presentationMode) private var presentationMode
-    `@Environment`(\.colorScheme) private var colorScheme
+    `@Environment`(\.presentationMode)
+    private var presentationMode
+    `@Environment`(\.colorScheme)
+    private var colorScheme
     let onExport: () -> Void
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@DashWallet/Sources/UI/Menu/Tools/CSVExportSheet.swift` around lines 22 - 25,
The `@Environment` attributes in the CSVExportSheet struct are placed on the same
line as their property declarations which violates SwiftLint; move each
attribute to its own line directly above the corresponding property (i.e., place
`@Environment`(\.presentationMode) on its own line above private var
presentationMode and `@Environment`(\.colorScheme) on its own line above private
var colorScheme) while keeping the let onExport: () -> Void unchanged.
DashWallet/Sources/UI/Menu/Tools/ZenLedger/ZenLedgerInfoSheet.swift (2)

25-27: Place @Environment attributes on separate lines per SwiftLint rule.

The @Environment(\.colorScheme) attribute should be on its own line.

♻️ Proposed fix
     `@Environment`(\.presentationMode) private var presentationMode
-    `@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/ZenLedger/ZenLedgerInfoSheet.swift` around
lines 25 - 27, The two `@Environment` property wrappers are placed on the same
line; split them so each attribute is on its own line to satisfy SwiftLint.
Update the declarations in ZenLedgerInfoSheet (the
`@Environment`(\.presentationMode) private var presentationMode and
`@Environment`(\.colorScheme) private var colorScheme) so each `@Environment`(...)
is written on a separate line above its corresponding property.

70-78: Avoid trailing closure syntax with multiple closure arguments.

SwiftLint flags this Button because it uses trailing closure syntax when passing both action and label closures.

♻️ Proposed fix using explicit label parameter
-                    Button(action: {
+                    Button(
+                        action: {
                             safariLink = "https://app.zenledger.io/new_sign_up/"
                             presentationMode.wrappedValue.dismiss()
-                    }) {
-                        Text("zenledger.io")
-                            .font(.system(size: 13, weight: .semibold))
-                            .foregroundColor(.blue)
-                    }
+                        },
+                        label: {
+                            Text("zenledger.io")
+                                .font(.system(size: 13, weight: .semibold))
+                                .foregroundColor(.blue)
+                        }
+                    )
                     .padding(.top, 8)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@DashWallet/Sources/UI/Menu/Tools/ZenLedger/ZenLedgerInfoSheet.swift` around
lines 70 - 78, SwiftLint complains because the Button in ZenLedgerInfoSheet uses
trailing-closure syntax while supplying both an action and a label closure;
change the Button to the explicit two-argument form so the label is passed via
the label parameter (e.g. Button(action: { safariLink =
"https://app.zenledger.io/new_sign_up/"; presentationMode.wrappedValue.dismiss()
}, label: { Text("zenledger.io").font(.system(size: 13, weight:
.semibold)).foregroundColor(.blue) })). Keep the existing .padding(.top, 8)
modifier and references to safariLink and presentationMode as-is.
DashWallet/Sources/UI/Menu/Tools/ToolsMenuScreen.swift (2)

240-264: Wrap debug print statements in #if DEBUG blocks.

Multiple print() statements throughout this method and in QRScannerDelegate are not wrapped in conditional compilation, which can impact performance in release builds.

As per coding guidelines: "Wrap debug print statements in #if DEBUG blocks or use conditional compilation to prevent performance impact from excessive logging."

♻️ Proposed fix
 private func presentScanner() {
-    print("🔍 DEBUG: presentScanner called in ToolsMenuScreen")
+    `#if` DEBUG
+    print("🔍 DEBUG: presentScanner called in ToolsMenuScreen")
+    `#endif`

     // Wait for sheet dismissal animation to complete before presenting scanner
     DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
         let scannerVC = DWQRScanViewController()
         scannerVC.modalPresentationStyle = .fullScreen

         // Create and set delegate
         let delegate = QRScannerDelegate(viewController: scannerVC)
         self.scannerDelegate = 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 in the navigation stack
         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) {
-                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)
         }
     }
 }
🤖 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 240 -
264, The debug print statements in ToolsMenuScreen (the presentScanner block)
and in QRScannerDelegate should be conditionally compiled so they are omitted
from release builds; wrap each print(...) call inside a `#if` DEBUG / `#endif` block
(or replace with a debug-only logging helper) around the prints in the
presentScanner logic where DWQRScanViewController is created and presented and
also in QRScannerDelegate where similar prints exist, ensuring scannerDelegate,
scannerVC presentation logs, and any delegate debug logs are only executed in
DEBUG builds.

288-308: Wrap debug print statements in #if DEBUG blocks in QRScannerDelegate.

Same issue as above - the delegate class contains multiple unguarded print() statements.

♻️ Proposed fix
 init(viewController: UIViewController) {
     self.viewController = viewController
-    print("🔍 DEBUG: QRScannerDelegate initialized in ToolsMenuScreen")
+    `#if` DEBUG
+    print("🔍 DEBUG: QRScannerDelegate initialized in ToolsMenuScreen")
+    `#endif`
 }

 func qrScanModel(_ viewModel: DWQRScanModel, didScanPaymentInput paymentInput: DWPaymentInput) {
-    print("🔍 DEBUG: didScanPaymentInput called")
+    `#if` DEBUG
+    print("🔍 DEBUG: didScanPaymentInput called")
+    `#endif`
     viewController?.dismiss(animated: true) {
-        print("🔍 DEBUG: Scanner dismissed after scan")
+        `#if` DEBUG
+        print("🔍 DEBUG: Scanner dismissed after scan")
+        `#endif`
     }
 }

 func qrScanModelDidCancel(_ viewModel: DWQRScanModel) {
-    print("🔍 DEBUG: qrScanModelDidCancel called - X button pressed")
+    `#if` DEBUG
+    print("🔍 DEBUG: qrScanModelDidCancel called - X button pressed")
+    `#endif`
     viewController?.dismiss(animated: true) {
-        print("🔍 DEBUG: Scanner dismissed after cancel")
+        `#if` DEBUG
+        print("🔍 DEBUG: Scanner dismissed after cancel")
+        `#endif`
     }
 }
🤖 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 288 -
308, The QRScannerDelegate class currently contains unguarded print() debug
statements; wrap each debug print in a conditional compile block so they only
run in debug builds (use `#if` DEBUG / `#endif`). Specifically update the
initializer in QRScannerDelegate and the two delegate methods
qrScanModel(_:didScanPaymentInput:) and qrScanModelDidCancel(_:) to enclose
their print(...) calls inside `#if` DEBUG blocks, preserving existing behavior
otherwise and keeping the dismiss calls unchanged.
🤖 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/SwiftUI` Components/NavigationBar.swift:
- Line 1: Remove the leading whitespace from the header comment in
NavigationBar.swift (line 1) so the file starts with the comment marker at
column 0; update the top-of-file comment to have no leading space to satisfy the
leading_whitespace SwiftLint rule and ensure SwiftFormat/SwiftLint pass for this
file.

---

Nitpick comments:
In `@DashWallet/Sources/UI/Menu/Tools/CSVExportSheet.swift`:
- Around line 81-84: The CSVExportSheet currently calls
presentationMode.wrappedValue.dismiss() then immediately invokes onExport(),
which can race with dismissal; update CSVExportSheet to defer calling onExport()
until the sheet's dismissal completes by moving the export trigger into an
onDismiss handler (similar to ZenLedgerInfoSheet's safariLink pattern): store a
local Bool (e.g., shouldTriggerExport) or set a closure to be called from
onDismiss, set that flag/closure in the current action instead of calling
onExport() directly, and then call onExport() from the sheet's onDismiss so
ToolsMenuScreen.handleCSVExport runs after dismissal.
- Around line 22-25: The `@Environment` attributes in the CSVExportSheet struct
are placed on the same line as their property declarations which violates
SwiftLint; move each attribute to its own line directly above the corresponding
property (i.e., place `@Environment`(\.presentationMode) on its own line above
private var presentationMode and `@Environment`(\.colorScheme) on its own line
above private var colorScheme) while keeping the let onExport: () -> Void
unchanged.

In `@DashWallet/Sources/UI/Menu/Tools/ToolsMenuScreen.swift`:
- Around line 240-264: The debug print statements in ToolsMenuScreen (the
presentScanner block) and in QRScannerDelegate should be conditionally compiled
so they are omitted from release builds; wrap each print(...) call inside a `#if`
DEBUG / `#endif` block (or replace with a debug-only logging helper) around the
prints in the presentScanner logic where DWQRScanViewController is created and
presented and also in QRScannerDelegate where similar prints exist, ensuring
scannerDelegate, scannerVC presentation logs, and any delegate debug logs are
only executed in DEBUG builds.
- Around line 288-308: The QRScannerDelegate class currently contains unguarded
print() debug statements; wrap each debug print in a conditional compile block
so they only run in debug builds (use `#if` DEBUG / `#endif`). Specifically update
the initializer in QRScannerDelegate and the two delegate methods
qrScanModel(_:didScanPaymentInput:) and qrScanModelDidCancel(_:) to enclose
their print(...) calls inside `#if` DEBUG blocks, preserving existing behavior
otherwise and keeping the dismiss calls unchanged.

In `@DashWallet/Sources/UI/Menu/Tools/ZenLedger/ZenLedgerInfoSheet.swift`:
- Around line 25-27: The two `@Environment` property wrappers are placed on the
same line; split them so each attribute is on its own line to satisfy SwiftLint.
Update the declarations in ZenLedgerInfoSheet (the
`@Environment`(\.presentationMode) private var presentationMode and
`@Environment`(\.colorScheme) private var colorScheme) so each `@Environment`(...)
is written on a separate line above its corresponding property.
- Around line 70-78: SwiftLint complains because the Button in
ZenLedgerInfoSheet uses trailing-closure syntax while supplying both an action
and a label closure; change the Button to the explicit two-argument form so the
label is passed via the label parameter (e.g. Button(action: { safariLink =
"https://app.zenledger.io/new_sign_up/"; presentationMode.wrappedValue.dismiss()
}, label: { Text("zenledger.io").font(.system(size: 13, weight:
.semibold)).foregroundColor(.blue) })). Keep the existing .padding(.top, 8)
modifier and references to safariLink and presentationMode as-is.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 929eea99-ec61-4505-bdd2-101ee05c50f2

📥 Commits

Reviewing files that changed from the base of the PR and between 21e7860 and 37630af.

⛔ Files ignored due to path filters (6)
  • DashWallet/Resources/AppAssets.xcassets/Illustration/csv-export-large.imageset/export.csv.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Illustration/csv-export-large.imageset/export.csv@2x.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Illustration/csv-export-large.imageset/export.csv@3x.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Illustration/zenledger-large.imageset/zenledger-large.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Illustration/zenledger-large.imageset/zenledger-large@2x.png is excluded by !**/*.png
  • DashWallet/Resources/AppAssets.xcassets/Illustration/zenledger-large.imageset/zenledger-large@3x.png is excluded by !**/*.png
📒 Files selected for processing (9)
  • DashWallet.xcodeproj/project.pbxproj
  • DashWallet/Resources/AppAssets.xcassets/Illustration/Contents.json
  • DashWallet/Resources/AppAssets.xcassets/Illustration/csv-export-large.imageset/Contents.json
  • DashWallet/Resources/AppAssets.xcassets/Illustration/zenledger-large.imageset/Contents.json
  • DashWallet/Sources/UI/Menu/Tools/CSVExportSheet.swift
  • DashWallet/Sources/UI/Menu/Tools/ImportWallet/ImportPrivateKeySheet.swift
  • DashWallet/Sources/UI/Menu/Tools/ToolsMenuScreen.swift
  • DashWallet/Sources/UI/Menu/Tools/ZenLedger/ZenLedgerInfoSheet.swift
  • DashWallet/Sources/UI/SwiftUI Components/NavigationBar.swift

@@ -1,4 +1,4 @@
//
//
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Remove leading whitespace in the header comment.

Line 1 starts with a leading space and triggers the leading_whitespace lint warning.

[sraise]

Proposed fix
- //
+//

As per coding guidelines, "Use SwiftFormat and SwiftLint for Swift code formatting and linting as configured in .swiftformat and .swiftlint.yml files."

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
//
//
🧰 Tools
🪛 SwiftLint (0.63.2)

[Warning] 1-1: Files should not contain leading whitespace

(leading_whitespace)

🤖 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 at line 1,
Remove the leading whitespace from the header comment in NavigationBar.swift
(line 1) so the file starts with the comment marker at column 0; update the
top-of-file comment to have no leading space to satisfy the leading_whitespace
SwiftLint rule and ensure SwiftFormat/SwiftLint pass for this file.

@ross-dash ross-dash changed the title feat/update-csv-export-and-zenledger feat: update csv export and zenledger Mar 24, 2026
Comment thread DashWallet/Sources/UI/Menu/Tools/ZenLedger/ZenLedgerInfoSheet.swift
Comment thread DashWallet/Sources/UI/Menu/Tools/CSVExportSheet.swift
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
DashWallet/Sources/UI/Menu/Tools/ToolsMenuScreen.swift (1)

125-135: LGTM - Consider extracting repeated version-checking pattern.

The iOS version-aware sheet presentation is correct. The same pattern is repeated for CSV export, ZenLedger, ImportPrivateKey, and ExtendedPublicKey sheets (lines 125-182). This could be extracted into a reusable ViewModifier to reduce duplication.

💡 Optional: Extract to a reusable modifier
struct AdaptiveSheetModifier<SheetContent: View>: ViewModifier {
    `@Binding` var isPresented: Bool
    let detent: PresentationDetent
    let cornerRadius: CGFloat
    let content: () -> SheetContent
    
    func body(content: Content) -> some View {
        content.sheet(isPresented: $isPresented) {
            if `#available`(iOS 16.4, *) {
                self.content()
                    .presentationDetents([detent])
                    .presentationCornerRadius(cornerRadius)
            } else if `#available`(iOS 16.0, *) {
                self.content()
                    .presentationDetents([detent])
            } else {
                self.content()
            }
        }
    }
}

Usage:

.modifier(AdaptiveSheetModifier(
    isPresented: $showCSVExportSheet,
    detent: .large,
    cornerRadius: 32
) {
    CSVExportSheet(onExport: handleCSVExport)
})
🤖 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 125 -
135, Extract the repeated iOS-version sheet presentation logic in
ToolsMenuScreen (used for showCSVExportSheet with CSVExportSheet and similarly
for ZenLedger, ImportPrivateKey, ExtendedPublicKey) into a reusable ViewModifier
(e.g., AdaptiveSheetModifier) that accepts a Binding<Bool> isPresented, detent
and cornerRadius plus a content closure; replace each .sheet(...) block in
ToolsMenuScreen with .modifier(AdaptiveSheetModifier(isPresented:
$showCSVExportSheet, detent: .large, cornerRadius: 32) {
CSVExportSheet(onExport: handleCSVExport) }) and similarly for the
ZenLedger/ImportPrivateKey/ExtendedPublicKey handlers so the `#available` checks
live only inside the modifier and duplication is removed.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@DashWallet/Sources/UI/Menu/Tools/ToolsMenuScreen.swift`:
- Around line 125-135: Extract the repeated iOS-version sheet presentation logic
in ToolsMenuScreen (used for showCSVExportSheet with CSVExportSheet and
similarly for ZenLedger, ImportPrivateKey, ExtendedPublicKey) into a reusable
ViewModifier (e.g., AdaptiveSheetModifier) that accepts a Binding<Bool>
isPresented, detent and cornerRadius plus a content closure; replace each
.sheet(...) block in ToolsMenuScreen with
.modifier(AdaptiveSheetModifier(isPresented: $showCSVExportSheet, detent:
.large, cornerRadius: 32) { CSVExportSheet(onExport: handleCSVExport) }) and
similarly for the ZenLedger/ImportPrivateKey/ExtendedPublicKey handlers so the
`#available` checks live only inside the modifier and duplication is removed.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0cbf1d4c-a07f-4db9-803e-4f3cfac81dbf

📥 Commits

Reviewing files that changed from the base of the PR and between 37630af and 876d800.

📒 Files selected for processing (4)
  • DashWallet.xcodeproj/project.pbxproj
  • DashWallet/Sources/UI/Menu/Tools/ImportWallet/ImportPrivateKeySheet.swift
  • DashWallet/Sources/UI/Menu/Tools/ToolsMenuScreen.swift
  • DashWallet/en.lproj/Localizable.strings
✅ Files skipped from review due to trivial changes (1)
  • DashWallet/en.lproj/Localizable.strings
🚧 Files skipped from review as they are similar to previous changes (1)
  • DashWallet/Sources/UI/Menu/Tools/ImportWallet/ImportPrivateKeySheet.swift

Copy link
Copy Markdown
Contributor

@HashEngineering HashEngineering left a comment

Choose a reason for hiding this comment

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

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants