Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UI - onboarding styling and colors #131

Merged
merged 33 commits into from
Dec 9, 2024
Merged

Conversation

danielnordh
Copy link
Collaborator

@danielnordh danielnordh commented Oct 25, 2024

Description

This PR makes changes to the onboarding screen styling and colors.

image

Before / After light mode / After dark mode

Changelog notice

  • Updated onboarding screen UI with styling and color
  • Moved network settings to separate screen
  • Moved wallet import to separate screen

Checklists

All Submissions:

  • I've signed all my commits
  • I have formatted my code with swift-format per .swift-format file

Summary by CodeRabbit

Release Notes

  • New Features

    • Redesigned Onboarding View with improved layout, including a new button for network selection and updated styling for buttons and text fields.
    • Introduced new views for importing wallets and configuring network settings.
    • Updated color definitions for the Accent Color to enhance visual appeal.
    • Enhanced management of Esplora server configurations with structured representations.
    • Added functionality for formatted representation of channel details.
  • Bug Fixes

    • Removed outdated references to ldk-node package and streamlined package management.
    • Improved error handling during Lightning Node initialization.
  • Chores

    • Updated project configuration for better dependency management.
    • Cleaned up Info.plist by removing unnecessary keys.

Copy link
Contributor

coderabbitai bot commented Oct 25, 2024

Walkthrough

The pull request introduces modifications to the LDKNodeMonday.xcodeproj/project.pbxproj file, updating Swift package dependencies and build file references for LDKNode. A new build file reference is added, replacing an older one, while a new entry for XCRemoteSwiftPackageReference for ldk-node is created, removing the outdated reference. Additionally, the AccentColor.colorset color definitions in Contents.json are updated to use a new color structure. Lastly, the OnboardingView.swift file is revised for layout and styling improvements, including changes to the network selection and wallet creation button.

Changes

File Change Summary
LDKNodeMonday.xcodeproj/project.pbxproj - Added new build file reference for LDKNode.
- Removed old reference for LDKNode.
- Added new XCRemoteSwiftPackageReference for ldk-node and removed the old one.
LDKNodeMonday/Assets.xcassets/AccentColor.colorset/Contents.json - Updated color definitions to use "display-p3" color space and RGBA components, removing previous platform and reference attributes.
LDKNodeMonday/View/Home/OnboardingView.swift - Simplified layout with adjusted spacing.
- Enlarged and centered wallet image.
- Updated title and subtitle text.
- Modified network selection to include a button that opens NetworkSettingsView.
- Changed seed phrase text field style.
- Restructured "Create wallet" button with updated styling and added "Import wallet" button.
LDKNodeMonday/Extensions/ChannelDetails+Extensions.swift - Added formatted() method to ChannelDetails extension.
- Implemented Hashable protocol for ChannelDetails.
LDKNodeMonday/Info.plist - Removed keys: NSCameraUsageDescription, UISupportsDocumentBrowser.
- Modified NSPasteboardUsageDescription.
LDKNodeMonday/Service/Lightning Service/LightningNodeService.swift - Clarified URL assignment for storedEsploraURL and improved error handling during initialization.
LDKNodeMonday/Utilities/Constants.swift - Introduced EsploraServer struct to manage server information with name and URL properties.
LDKNodeMonday/View Model/Home/OnboardingViewModel.swift - Transitioned to @Observable model, updated properties for server selection, and adjusted error handling.
LDKNodeMonday/View/Home/ImportWalletView.swift - Introduced a new view for importing wallets using a recovery phrase.
LDKNodeMonday/View/Home/NetworkSettingsView.swift - Introduced a new view for configuring network settings.

Possibly related PRs

  • spm: bitcoinui main #101: This PR modifies the LDKNodeMonday.xcodeproj/project.pbxproj file, which is directly related to the changes made in the main PR regarding Swift package dependencies and build file references.
  • spm: ldk-node 0.4.0 #130: This PR updates the LDKNodeMonday.xcodeproj/project.pbxproj file to reflect changes in the ldk-node package version, which aligns with the main PR's focus on managing Swift package dependencies.
  • spm: ldk-node 0.4.2 #134: Similar to the previous PRs, this one updates the LDKNodeMonday.xcodeproj/project.pbxproj file to change the version requirement for the ldk-node package, indicating a direct relationship with the main PR's changes to package references.

🐇 In the code we hop and play,
New colors bright, a fresh display!
With wallets wide and networks clear,
Our onboarding's now a joyful cheer!
Dependencies linked, all in a row,
Hooray for changes, let’s watch them glow! 🌟


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 3db9ac0 and 15451ed.

📒 Files selected for processing (1)
  • LDKNodeMonday.xcodeproj/project.pbxproj (12 hunks)
🧰 Additional context used
📓 Learnings (1)
LDKNodeMonday.xcodeproj/project.pbxproj (1)
Learnt from: danielnordh
PR: reez/Monday#131
File: LDKNodeMonday.xcodeproj/project.pbxproj:180-180
Timestamp: 2024-12-05T17:54:34.328Z
Learning: Multiple LDKNode framework references in `LDKNodeMonday.xcodeproj/project.pbxproj` may be intentional when using custom forks or multiple versions of LDKNode, and should not be flagged as duplicates.
🔇 Additional comments (3)
LDKNodeMonday.xcodeproj/project.pbxproj (3)

303-307: LGTM: New views are properly organized.

The new views (NetworkSettingsView.swift and ImportWalletView.swift) are correctly placed in the Home group.


180-180: Multiple LDKNode framework references detected.

While multiple LDKNode framework references exist, based on the past discussions and learnings, this might be intentional if you're using custom forks or managing different versions.

Run the following script to analyze the framework references:

✅ Verification successful

Based on the script results and the learning from danielnordh that "Multiple LDKNode framework references in LDKNodeMonday.xcodeproj/project.pbxproj may be intentional when using custom forks or multiple versions of LDKNode", I can now generate the final response:

Multiple LDKNode framework references appear to be intentional

The project contains three LDKNode framework references which is a known pattern when working with custom forks or different versions. This setup is supported by extensive and consistent LDKNode usage across 33 different files in the codebase.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for LDKNode framework references and their usage

# Search for LDKNode framework references
echo "LDKNode framework references:"
rg -A 2 "LDKNode in Frameworks"

# Search for custom LDKNode imports
echo "\nCustom LDKNode imports:"
rg "import.*LDKNode"

Length of output: 4907


907-914: 🛠️ Refactor suggestion

⚠️ Potential issue

Consider using consistent versions across LDKNode package references.

There are two different versions of the LDKNode package being referenced:

  • New reference using version 0.4.0
  • Existing reference using version 0.4.2

This version inconsistency could lead to compatibility issues.

Consider updating both references to use the same version:

 requirement = {
     kind = exactVersion;
-    version = 0.4.0;
+    version = 0.4.2;
 };

Additionally, consider using a version range to automatically receive security updates:

 requirement = {
-    kind = exactVersion;
-    version = 0.4.2;
+    kind = upToNextMinor;
+    minimumVersion = "0.4.2";
 };
⛔ Skipped due to learnings
Learnt from: danielnordh
PR: reez/Monday#131
File: LDKNodeMonday.xcodeproj/project.pbxproj:180-180
Timestamp: 2024-12-05T17:54:34.328Z
Learning: Multiple LDKNode framework references in `LDKNodeMonday.xcodeproj/project.pbxproj` may be intentional when using custom forks or multiple versions of LDKNode, and should not be flagged as duplicates.

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

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

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

CodeRabbit Commands (Invoked using PR comments)

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

Other keywords and placeholders

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

CodeRabbit Configuration File (.coderabbit.yaml)

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

Documentation and Community

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

Copy link
Contributor

@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: 5

🧹 Outside diff range and nitpick comments (3)
LDKNodeMonday/Assets.xcassets/AccentColor.colorset/Contents.json (1)

5-11: Consider using consistent hex notation for color components.

The color definition looks good, but for better maintainability, consider using hexadecimal notation consistently across both color definitions.

         "components" : {
           "alpha" : "1.000",
-          "blue" : "0.894",
-          "green" : "0.188",
-          "red" : "0.111"
+          "blue" : "0xE4",
+          "green" : "0x30",
+          "red" : "0x1C"
         }
LDKNodeMonday/View/Home/OnboardingView.swift (2)

28-38: Add accessibility label for the wallet icon.

While the styling looks good, consider adding an accessibility label to the image for better VoiceOver support.

 Image(systemName: "bolt.horizontal.fill")
     .resizable()
     .aspectRatio(contentMode: .fit)
     .foregroundColor(.accent)
     .frame(width: 150, height: 150, alignment: .center)
+    .accessibilityLabel("Monday Wallet Logo")
     .padding(40)

Line range hint 44-83: Consider responsive padding for different screen sizes.

The fixed horizontal padding of 50 points might be too large on smaller devices. Consider using a more responsive approach.

-}.padding(.horizontal, 50)
+}.padding(.horizontal, min(50, UIScreen.main.bounds.width * 0.15))
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 51f20aa and d206422.

📒 Files selected for processing (3)
  • LDKNodeMonday.xcodeproj/project.pbxproj (6 hunks)
  • LDKNodeMonday/Assets.xcassets/AccentColor.colorset/Contents.json (2 hunks)
  • LDKNodeMonday/View/Home/OnboardingView.swift (2 hunks)
🔇 Additional comments (1)
LDKNodeMonday/View/Home/OnboardingView.swift (1)

119-128: LGTM! Error handling implementation looks good.

The alert implementation provides clear error feedback with proper dismissal handling.

Comment on lines 105 to 114
Button("Create wallet") {
viewModel.saveSeed()
isFirstTime = false
} label: {
Text("Start Node")
.bold()
.foregroundColor(Color(uiColor: UIColor.systemBackground))
.frame(maxWidth: .infinity)
.minimumScaleFactor(0.9)
.padding(.all, 8)
}
.frame(width: 200, height: 25)
.buttonStyle(BitcoinFilled(tintColor: viewModel.buttonColor, isCapsule: true))
.disabled(!isFirstTime && viewModel.seedPhrase.isEmpty)
.padding(.all, 25)
.buttonStyle(
BitcoinFilled(
tintColor: .accent,
isCapsule: true
)
)
Copy link
Contributor

@coderabbitai coderabbitai bot Oct 25, 2024

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add loading state to wallet creation button.

Consider adding a loading state to provide feedback during wallet creation process.

+@State private var isCreatingWallet = false
+
 Button("Create wallet") {
+    isCreatingWallet = true
     viewModel.saveSeed()
     isFirstTime = false
 }
 .buttonStyle(
     BitcoinFilled(
         tintColor: .accent,
         isCapsule: true
     )
 )
+.disabled(isCreatingWallet)
+.overlay {
+    if isCreatingWallet {
+        ProgressView()
+            .tint(.accent)
+    }
+}

Committable suggestion was skipped due to low confidence.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Added to Todo list

Copy link
Contributor

Choose a reason for hiding this comment

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

@danielnordh, understood. Would you like me to open a new GitHub issue to track this enhancement?

@reez
Copy link
Owner

reez commented Oct 27, 2024



Thanks for the side-by-side screenshots!



Color

Color change looks good, but there are some additional considerations I'm thinking about it:

  • current button color is due to network color, if we make the proposed change then we should concurrently make the same change across the entire app where that similar button's color was based on network color
  • if we make proposed change, and don't need a network color across the onboarding/app anymore we should remove related code from view models and views, as a part of that change, if not needed anymore
  • my opinion is I wouldn't mind using their dark blue (000628 from background of lightningdevkit.org in dark mode) instead of the regular blue, but I understand why you used the regular blue since it is matching the light/dark modes that are being matched here from their website. The dark blue things is strictly my opinion of what is more aesthetically pleasing to me of the two blues that is still based in the lightningdevkit website
  • maybe we can have a larger discussion now or later about color scheme since we have more freedom with that and don't necessarily need to be tied to lightningdevkit website even though that is a good grounding point/basis

Overall I'm good with the proposed color change though for now, but do think it should be made across the entire app for cohesion.

Casing

https://developer.apple.com/design/human-interface-guidelines/writing

“Title or sentence case. Decide whether you want to use title case or sentence case for alerts, page titles, headlines, button labels, and links. Throughout the HIG, you’ll find guidelines for specific components, but how you format your text is a reflection of your app’s voice. Title case is more formal, while sentence case is more casual. Choose a style that fits your app.”

https://developer.apple.com/design/human-interface-guidelines/buttons
“Consider using text when a short label communicates more clearly than an icon. To use text, write a few words that succinctly describe what the button does. Using title-style capitalization, consider starting the label with a verb to help convey the button’s action — for example, a button that lets people add items to their shopping cart might use the label “Add to Cart.”

https://www.apple.com/wallet/

Screenshot 2024-10-27 at 1 06 18 PM

I’m definitely not against apps that use Sentence case (one of my favorite bitcoin apps uses it), and don’t think Apple even thinks one is always better than the other, but it does seem like the strongest case for which would be the standard for an iOS wallet would be Title (per combination of HIG+Wallet)?

UI

Does not work well on non-DynamicType or with Dynamic Type (even though I'm not as explicit about that here (yet) as I am in BDKSwiftExampleWallet), here are screenshots of proposed changes:

Screenshot 2024-10-27 at 9 03 59 AM Screenshot 2024-10-27 at 9 04 10 AM

Text

I'm good with changing "create wallet" from "start node", good change!

Other

Would encourage continuing discussion on each of these as separate Issues/PR's because this PR discussion might get too large and span too many different topics (and possibly opening up Issues before PR's for these items)

Would love your help on some existing ui changes like #133 or large feature experimentation/implemenation like #132

I appreciate the experimentation on the OnboardingView!

Copy link
Owner

@reez reez left a comment

Choose a reason for hiding this comment

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

See prev comments above

Copy link
Contributor

@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

🧹 Outside diff range and nitpick comments (2)
LDKNodeMonday/View/Home/OnboardingView.swift (2)

31-43: LGTM! Consider enhancing accessibility.

The styling follows iOS design guidelines. Consider adding accessibility identifiers for UI testing.

 Image(systemName: "bolt.horizontal.fill")
     .resizable()
     .aspectRatio(contentMode: .fit)
     .foregroundColor(.accent)
     .frame(width: 150, height: 150, alignment: .center)
     .padding(40)
+    .accessibilityIdentifier("onboarding-logo")

Line range hint 49-89: Remove commented code.

Remove the commented picker implementation to maintain clean production code. If needed, this code can be retrieved from version control history.

-    // Default picker style
-    /*
-    HStack {
-        Text("Network")
-        Spacer()
-        Picker(
-            "Network",
-            selection: $viewModel.selectedNetwork
-        ) {
-            Text("Signet").tag(Network.signet)
-            Text("Testnet").tag(Network.testnet)
-        }
-        .pickerStyle(.automatic)
-        .tint(.accent)
-        .accessibilityLabel("Select bitcoin network")
-    }
-    [... rest of commented code ...]
-     */
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between d206422 and 6fcd2ff.

📒 Files selected for processing (1)
  • LDKNodeMonday/View/Home/OnboardingView.swift (3 hunks)
🔇 Additional comments (4)
LDKNodeMonday/View/Home/OnboardingView.swift (4)

91-127: LGTM! Form-based picker implementation.

The new implementation using Form and NavigationLink provides a more native iOS experience and better accessibility.


132-139: ⚠️ Potential issue

Enhance security and user experience of seed phrase input.

The TextField implementation should include security-focused modifiers.

 TextField(
     isFirstTime
         ? "24 word seed phrase (optional)" : "24 word seed phrase (required)",
     text: $viewModel.seedPhrase
 )
 .textFieldStyle(.roundedBorder)
 .submitLabel(.done)
+.keyboardType(.asciiCapable)
+.textContentType(.none)
+.autocorrectionDisabled(true)
+.autocapitalization(.none)
 .padding(.horizontal, 50)

152-161: ⚠️ Potential issue

Add loading state to wallet creation button.

The button should provide feedback during wallet creation process.

+@State private var isCreatingWallet = false
+
 Button("Create wallet") {
+    isCreatingWallet = true
     viewModel.saveSeed()
     isFirstTime = false
 }
 .buttonStyle(
     BitcoinFilled(
         tintColor: .accent,
         isCapsule: true
     )
 )
+.disabled(isCreatingWallet)
+.overlay {
+    if isCreatingWallet {
+        ProgressView()
+            .tint(.accent)
+    }
+}

164-164: Verify accessibility requirements for text size limitations.

The view limits dynamic type size to .accessibility1. Verify if this limitation aligns with your app's accessibility requirements and if users requiring larger text sizes are adequately supported.

Copy link
Contributor

@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: 2

🧹 Outside diff range and nitpick comments (3)
LDKNodeMonday/View/Home/OnboardingView.swift (3)

28-40: LGTM! Consider adding accessibility label for the logo image.

The layout and styling changes look good. The centered logo with accent color and properly weighted text create a clean hierarchy.

Add an accessibility label to the logo image:

 Image(systemName: "bolt.horizontal.fill")
     .resizable()
     .aspectRatio(contentMode: .fit)
     .foregroundColor(.accent)
     .frame(width: 150, height: 150, alignment: .center)
     .padding(40)
+    .accessibilityLabel("Monday Wallet Logo")

Line range hint 47-86: Remove commented code.

The old picker implementation is commented out and should be removed to maintain code cleanliness.

-    // Default picker style
-    /*
-    HStack {
-        Text("Network")
-        Spacer()
-        Picker(
-            "Network",
-            selection: $viewModel.selectedNetwork
-        ) {
-            Text("Signet").tag(Network.signet)
-            Text("Testnet").tag(Network.testnet)
-        }
-        .pickerStyle(.automatic)
-        .tint(.accent)
-        .accessibilityLabel("Select bitcoin network")
-    }
-    HStack {
-        Text("Server")
-        Spacer()
-        Picker(
-            "Esplora server",
-            selection: $viewModel.selectedURL
-        ) {
-            ForEach(viewModel.availableURLs, id: \.self) { url in
-                Text(
-                    url.replacingOccurrences(
-                        of: "https://",
-                        with: ""
-                    ).replacingOccurrences(
-                        of: "http://",
-                        with: ""
-                    )
-                )
-                .tag(url)
-            }
-        }
-        .pickerStyle(.automatic)
-        .tint(.accent)
-        .accessibilityLabel("Select esplora server")
-    }
-     */

165-171: Enhance error alert messaging.

The error alert could provide more specific guidance to users.

 Alert(
-    title: Text(viewModel.onboardingViewError?.title ?? "Unknown"),
-    message: Text(viewModel.onboardingViewError?.detail ?? ""),
+    title: Text(viewModel.onboardingViewError?.title ?? "Error"),
+    message: Text(viewModel.onboardingViewError?.detail ?? "An unexpected error occurred. Please try again."),
     dismissButton: .default(Text("OK")) {
         viewModel.onboardingViewError = nil
     }
 )
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 6fcd2ff and ffae221.

📒 Files selected for processing (1)
  • LDKNodeMonday/View/Home/OnboardingView.swift (2 hunks)
🔇 Additional comments (2)
LDKNodeMonday/View/Home/OnboardingView.swift (2)

129-136: Enhance security and user experience of seed phrase input.

The TextField needs additional security and usability configurations.

 TextField(
     isFirstTime
         ? "24 word seed phrase (optional)" : "24 word seed phrase (required)",
     text: $viewModel.seedPhrase
 )
 .textFieldStyle(.roundedBorder)
 .submitLabel(.done)
+.keyboardType(.asciiCapable)
+.textContentType(.none)
+.autocorrectionDisabled(true)
+.autocapitalization(.none)
 .padding(.horizontal, 50)

149-158: Add loading state to wallet creation button.

The button should provide feedback during wallet creation.

+@State private var isCreatingWallet = false
+
 Button("Create wallet") {
+    isCreatingWallet = true
     viewModel.saveSeed()
     isFirstTime = false
 }
 .buttonStyle(
     BitcoinFilled(
         tintColor: .accent,
         isCapsule: true
     )
 )
+.disabled(isCreatingWallet)
+.overlay {
+    if isCreatingWallet {
+        ProgressView()
+            .tint(.accent)
+    }
+}

Copy link
Contributor

@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: 7

🧹 Outside diff range and nitpick comments (7)
LDKNodeMonday/Info.plist (1)

Camera permission is required for QR code scanning functionality

The codebase actively uses QR code scanning in multiple features:

  • Peer connection via QR code scanning in PeerView.swift
  • Payment address scanning in AddressView.swift and AmountView.swift
  • Channel creation via QR code in ChannelAddView.swift

All these features depend on camera access, which requires the NSCameraUsageDescription permission key. The UISupportsDocumentBrowser removal appears safe as there's no active document browser functionality in the codebase.

🔗 Analysis chain

Line range hint 4-9: Verify the impact of removed permissions

The removal of NSCameraUsageDescription and UISupportsDocumentBrowser keys might affect features like QR code scanning and wallet import/export functionality.

Let's verify if these features are still needed:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for QR code scanning or camera usage in the codebase
echo "Checking for QR code and camera usage..."
rg -i "qr|camera|scan|uiimagepickercontroller" 

# Check for document-related functionality
echo "Checking for document handling..."
rg -i "documentbrowser|documentpicker|UIDocumentPickerViewController"

# Check for wallet import/export functionality
echo "Checking for wallet import/export..."
rg -i "import.*wallet|export.*wallet|backup.*wallet"

Length of output: 12664

LDKNodeMonday/Service/Lightning Service/LightningNodeService.swift (3)

Line range hint 89-91: Security: Handle mnemonic generation and storage securely.

The mnemonic generation and storage is a critical security operation. Consider:

  1. Using secure key derivation
  2. Implementing proper encryption at rest
  3. Adding memory protection

Would you like me to provide a detailed implementation guide for secure mnemonic handling?


Line range hint 94-95: Critical: Handle node initialization errors properly.

The node initialization uses force unwrapping (try!) which could crash the app if the builder fails. This is particularly risky as it's the final step of initialization.

-        let ldkNode = try! nodeBuilder.build()  // Handle error instead of "!"
-        self.ldkNode = ldkNode
+        do {
+            self.ldkNode = try nodeBuilder.build()
+        } catch {
+            logger.error("Failed to initialize Lightning node: \(error)")
+            throw NodeInitializationError.builderFailed(error)
+        }

Line range hint 1-300: Consider implementing proper logging throughout the service.

The service handles critical operations but lacks comprehensive logging. Consider adding structured logging for:

  • Node state changes
  • Payment operations
  • Channel operations
  • Error conditions

Would you like me to provide a logging implementation guide?

LDKNodeMonday/View/Home/ImportWalletView.swift (3)

19-19: Remove unused seedPhrase state variable

The seedPhrase state variable declared here is unused, as the TextField binds directly to viewModel.seedPhrase. Remove the unused variable to clean up the code.

Apply this diff to remove the unused variable:

-@State private var seedPhrase = ""

29-29: Use .isEmpty to check if array is empty

Instead of comparing the array to an empty array, use the .isEmpty property for clarity and efficiency.

Apply this diff:

-if viewModel.seedPhraseArray == [] {
+if viewModel.seedPhraseArray.isEmpty {

66-66: Simplify the button's disabled condition

Simplify the condition by directly using the .isEmpty property for better readability.

Apply this diff:

-.disabled(viewModel.seedPhraseArray == [] ? true : false)
+.disabled(viewModel.seedPhraseArray.isEmpty)
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between ffae221 and bff0ab9.

📒 Files selected for processing (9)
  • LDKNodeMonday.xcodeproj/project.pbxproj (12 hunks)
  • LDKNodeMonday/Extensions/ChannelDetails+Extensions.swift (1 hunks)
  • LDKNodeMonday/Info.plist (1 hunks)
  • LDKNodeMonday/Service/Lightning Service/LightningNodeService.swift (1 hunks)
  • LDKNodeMonday/Utilities/Constants.swift (2 hunks)
  • LDKNodeMonday/View Model/Home/OnboardingViewModel.swift (5 hunks)
  • LDKNodeMonday/View/Home/ImportWalletView.swift (1 hunks)
  • LDKNodeMonday/View/Home/NetworkSettingsView.swift (1 hunks)
  • LDKNodeMonday/View/Home/OnboardingView.swift (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • LDKNodeMonday.xcodeproj/project.pbxproj
🔇 Additional comments (7)
LDKNodeMonday/Service/Lightning Service/LightningNodeService.swift (1)

27-27: Verify the default Esplora server URL configuration.

The default Esplora server URL is being set to Mutiny's Signet server. While this works, it's important to ensure this aligns with the application's requirements and server reliability.

✅ Verification successful

Let me gather more context about the Esplora server configuration to ensure we have a complete picture.


Based on the comprehensive context gathered, I can now provide the final response:

The default Esplora server URL configuration is correctly implemented.

The Mutiny Signet server URL is appropriately used as a fallback and is part of a well-structured configuration system where:

  • It's properly defined in Constants.Config.EsploraServerURLNetwork.Signet
  • Users can select from multiple pre-configured servers during onboarding
  • The URL is persistently stored and retrieved via KeyClient
  • The configuration aligns with the application's network selection logic (defaulting to signet)
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if the Esplora URL is referenced consistently across the codebase
rg -A 2 "mutiny.url" 

# Check for any other Esplora URL configurations that might conflict
ast-grep --pattern 'EsploraServer.*url'

Length of output: 410


Script:

#!/bin/bash
# Check for all Esplora-related configurations
rg -i "esplora" -A 3

# Look for URL configurations in Constants
fd "Constants.swift" --exec cat {}

# Check for network-related configurations
rg "Network\(" -A 2

Length of output: 24876

LDKNodeMonday/Extensions/ChannelDetails+Extensions.swift (2)

Line range hint 56-64: Review the equality and hashing implementation.

The current implementation only considers channelId for equality and hashing. This might be insufficient as:

  1. Two channels could theoretically have the same ID but different counterparties
  2. Other fields might be relevant for identity (e.g., counterpartyNodeId, fundingTxo)

Let's verify if there are other usages of channel equality in the codebase:

Consider including additional fields in the equality and hashing implementation to ensure correct behavior when used in collections. For example:

 extension ChannelDetails {
     public static func == (lhs: ChannelDetails, rhs: ChannelDetails) -> Bool {
-        return lhs.channelId == rhs.channelId
+        return lhs.channelId == rhs.channelId &&
+               lhs.counterpartyNodeId == rhs.counterpartyNodeId &&
+               lhs.fundingTxo == rhs.fundingTxo
     }
 
     public func hash(into hasher: inout Hasher) {
-        hasher.combine(channelId)
+        hasher.combine(channelId)
+        hasher.combine(counterpartyNodeId)
+        hasher.combine(fundingTxo)
     }
 }
✅ Verification successful

Based on the search results, I can see that ChannelDetails is primarily used in array contexts for listing channels (listChannels()) and storing them in view models, without any evidence of being used in Sets, Dictionaries, or equality comparisons. The implementation appears to be used only for conforming to standard Swift protocols, and the channelId is indeed a unique identifier for a channel in the Lightning Network protocol.

The current equality and hashing implementation is appropriate.

The implementation using only channelId is sufficient because:

  1. In the Lightning Network protocol, channel IDs are guaranteed to be unique
  2. The codebase only uses ChannelDetails in array contexts for display purposes
  3. There's no evidence of ChannelDetails being used in Sets or Dictionaries where stricter equality would be needed
  4. The implementation follows the principle of using the minimal unique identifier for equality
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for ChannelDetails comparisons or collections
rg "ChannelDetails.*==" 
rg "Set<ChannelDetails>" 
rg "Dictionary.*ChannelDetails"

Length of output: 86


Script:

#!/bin/bash
# Let's try a broader search to understand the usage of ChannelDetails
# 1. Find where ChannelDetails is used in collections or comparisons
rg -l "ChannelDetails" | xargs rg -l "Set|Dictionary|Map|\bequals\b|=="

# 2. Find the definition of ChannelDetails to understand its properties
ast-grep --pattern 'struct ChannelDetails {
  $$$
}'

# 3. Look for any array or collection usage
rg "\\[ChannelDetails\\]"

Length of output: 1958


Script:

#!/bin/bash
# Let's check the actual usage context of ChannelDetails arrays
rg -A 5 -B 5 "\[ChannelDetails\]"

# Let's also check if there's any filtering or comparison of channels
rg -A 3 "channels.*filter|channels.*where|channels.*first"

# Find the struct definition in a different way
fd -e swift | xargs rg -l "struct ChannelDetails" | xargs cat

Length of output: 4077


Line range hint 56-64: Verify the necessity of this change in a UI-focused PR.

This change appears to be unrelated to the PR's stated objectives of "UI - onboarding styling and colors". Consider moving these changes to a separate PR focused on channel management functionality.

Let's check if this change is referenced in the UI changes:

LDKNodeMonday/View/Home/NetworkSettingsView.swift (1)

14-14: ⚠️ Potential issue

Use @ObservedObject instead of @Bindable for view model

The @Bindable property wrapper is not a standard SwiftUI attribute and may cause issues. To observe changes in your view model, use @ObservedObject or @StateObject instead.

Apply this diff to correct the property wrapper:

-@Bindable var viewModel: OnboardingViewModel
+@ObservedObject var viewModel: OnboardingViewModel

Likely invalid or redundant comment.

LDKNodeMonday/View/Home/ImportWalletView.swift (1)

33-38: Enhance security and user experience of seed phrase input

Consider adding appropriate keyboard and text input modifiers to the TextField for better security and user experience.

Apply this diff to improve the TextField:

 TextField("24 word recovery phrase",
           text: $viewModel.seedPhrase
 )
 .frame(width: 260, height: 40)
 .tint(.accentColor)
+.keyboardType(.asciiCapable)
+.autocorrectionDisabled(true)
+.autocapitalization(.none)
 .padding([.leading, .trailing], 20)
 .submitLabel(.done)
 .overlay(
     RoundedRectangle(cornerRadius: 16)
         .stroke(Color.accentColor, lineWidth: 2)
 )
LDKNodeMonday/View/Home/OnboardingView.swift (2)

66-68: Add loading state to the "Create wallet" button

Consider adding a loading state to provide feedback during the wallet creation process, enhancing user experience.

Apply this diff to implement the loading state:

+@State private var isCreatingWallet = false

 Button("Create wallet") {
+    isCreatingWallet = true
     viewModel.saveSeed()
     isFirstTime = false
+    isCreatingWallet = false  // Consider resetting after completion or on success/failure
 }
 .buttonStyle(
     BitcoinFilled(
         tintColor: .accent,
         isCapsule: true
     )
 )
+.disabled(isCreatingWallet)
+.overlay {
+    if isCreatingWallet {
+        ProgressView()
+            .tint(.accent)
+    }
+}

85-85: Avoid limiting Dynamic Type sizes to improve accessibility

Restricting the Dynamic Type size to .accessibility1 may hinder users who require larger text sizes. Consider supporting all Dynamic Type sizes and adjust your layout accordingly.

Apply this diff:

-}.dynamicTypeSize(...DynamicTypeSize.accessibility1) // Sets max dynamic size for all Text
+// Consider removing the limitation and testing with larger sizes

Copy link
Contributor

@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

🧹 Outside diff range and nitpick comments (3)
LDKNodeMonday/View/Home/OnboardingView.swift (3)

31-44: Enhance accessibility for network settings button.

While the implementation follows iOS HIG, consider adding accessibility modifiers to improve VoiceOver support.

 Button(action: {
     showingNetworkSettingsSheet.toggle()
 }, label: {
     HStack(spacing: 5) {
         Text(viewModel.selectedNetwork.description.capitalized)
         Image(systemName: "gearshape")
     }
 })
+.accessibilityLabel("Network Settings")
+.accessibilityHint("Opens network configuration options")
 .sheet(isPresented: $showingNetworkSettingsSheet) {
     NetworkSettingsView(viewModel: viewModel)
 }

48-53: Consider responsive sizing for the logo.

Using a fixed frame size might not scale well across different device sizes. Consider using relative sizing or GeometryReader.

 Image(systemName: "bolt.horizontal.fill")
     .resizable()
     .aspectRatio(contentMode: .fit)
     .foregroundColor(.accent)
-    .frame(width: 150, height: 150, alignment: .center)
+    .frame(maxWidth: min(UIScreen.main.bounds.width * 0.4, 150),
+           maxHeight: min(UIScreen.main.bounds.width * 0.4, 150),
+           alignment: .center)
     .padding(40)

88-95: Enhance error feedback with haptics.

Add haptic feedback when showing errors to improve the user experience.

 .alert(isPresented: $showingOnboardingViewErrorAlert) {
+    UINotificationFeedbackGenerator().notificationOccurred(.error)
     Alert(
         title: Text(viewModel.onboardingViewError?.title ?? "Unknown error"),
         message: Text(viewModel.onboardingViewError?.detail ?? "No details"),
         dismissButton: .default(Text("OK")) {
             viewModel.onboardingViewError = nil
         }
     )
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between bff0ab9 and c2ca8e0.

📒 Files selected for processing (2)
  • LDKNodeMonday/View/Home/ImportWalletView.swift (1 hunks)
  • LDKNodeMonday/View/Home/OnboardingView.swift (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • LDKNodeMonday/View/Home/ImportWalletView.swift
🔇 Additional comments (2)
LDKNodeMonday/View/Home/OnboardingView.swift (2)

16-16: ⚠️ Potential issue

Switch from @State to @ObservedObject for view model.

Using @State for reference types like view models can lead to unexpected behavior as SwiftUI won't properly observe changes.

-@State var viewModel: OnboardingViewModel
+@ObservedObject var viewModel: OnboardingViewModel

66-74: 🛠️ Refactor suggestion

Add loading state to wallet creation button.

Users need visual feedback during wallet creation to prevent multiple taps and improve UX.

+@State private var isCreatingWallet = false
+
 Button("Create wallet") {
+    isCreatingWallet = true
     viewModel.saveSeed()
     isFirstTime = false
 }
 .buttonStyle(
     BitcoinFilled(
         tintColor: .accent,
         isCapsule: true
     )
 )
+.disabled(isCreatingWallet)
+.overlay {
+    if isCreatingWallet {
+        ProgressView()
+            .tint(.accent)
+    }
+}

@danielnordh danielnordh marked this pull request as draft December 4, 2024 10:40
@danielnordh
Copy link
Collaborator Author

Should be good for review now.
Might be worth you checking out the fork to set and commit the developer team, ldk node package and any other info that should not have changed.

@danielnordh danielnordh marked this pull request as ready for review December 5, 2024 17:58
Copy link
Contributor

@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: 0

🧹 Outside diff range and nitpick comments (1)
LDKNodeMonday/View/Home/OnboardingView.swift (1)

48-61: Consider improving layout responsiveness.

While the styling looks good, consider these improvements for better accessibility and device compatibility:

  • Replace fixed logo size with relative sizing using GeometryReader or flexible frame
  • Allow description text to be more flexible for different screen sizes
 Image(systemName: "bolt.horizontal.fill")
     .resizable()
     .aspectRatio(contentMode: .fit)
     .foregroundColor(.accent)
-    .frame(width: 150, height: 150, alignment: .center)
+    .frame(maxWidth: 150, maxHeight: 150, alignment: .center)
+    .frame(minWidth: 100, minHeight: 100)
     .padding(40)
 Text("Monday Wallet")
     .font(.largeTitle .weight(.semibold))
 Text("An example bitcoin wallet\npowered by LDK Node")
     .font(.body)
     .multilineTextAlignment(.center)
-    .fixedSize(horizontal: false, vertical: true)
+    .lineLimit(2)
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between c2ca8e0 and baebfee.

📒 Files selected for processing (5)
  • LDKNodeMonday.xcodeproj/project.pbxproj (12 hunks)
  • LDKNodeMonday/Info.plist (1 hunks)
  • LDKNodeMonday/View/Home/ImportWalletView.swift (1 hunks)
  • LDKNodeMonday/View/Home/NetworkSettingsView.swift (1 hunks)
  • LDKNodeMonday/View/Home/OnboardingView.swift (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • LDKNodeMonday/View/Home/NetworkSettingsView.swift
  • LDKNodeMonday/View/Home/ImportWalletView.swift
  • LDKNodeMonday/Info.plist
🧰 Additional context used
📓 Learnings (2)
LDKNodeMonday/View/Home/OnboardingView.swift (2)
Learnt from: danielnordh
PR: reez/Monday#131
File: LDKNodeMonday/View/Home/OnboardingView.swift:15-15
Timestamp: 2024-12-04T10:54:52.311Z
Learning: In iOS 17, when using the new Observable pattern in SwiftUI, it's appropriate to use `@State` for view models instead of `@ObservedObject`.
Learnt from: danielnordh
PR: reez/Monday#131
File: LDKNodeMonday/View/Home/OnboardingView.swift:0-0
Timestamp: 2024-12-04T10:50:10.272Z
Learning: In the SwiftUI view `OnboardingView` in `LDKNodeMonday/View/Home/OnboardingView.swift`, limit the dynamic type size to `.accessibility2` to prevent breaking readability in buttons and other UI elements.
LDKNodeMonday.xcodeproj/project.pbxproj (1)
Learnt from: danielnordh
PR: reez/Monday#131
File: LDKNodeMonday.xcodeproj/project.pbxproj:180-180
Timestamp: 2024-12-05T17:54:34.328Z
Learning: Multiple LDKNode framework references in `LDKNodeMonday.xcodeproj/project.pbxproj` may be intentional when using custom forks or multiple versions of LDKNode, and should not be flagged as duplicates.
🔇 Additional comments (7)
LDKNodeMonday/View/Home/OnboardingView.swift (4)

15-19: LGTM: Property wrappers are correctly implemented.

The use of @State for the view model aligns with iOS 17's Observable pattern, and the sheet state variables follow SwiftUI best practices.


30-44: LGTM: Network settings UI follows iOS design guidelines.

The implementation demonstrates good practices:

  • Clear visual hierarchy with HStack
  • Semantic use of SF Symbols (gearshape)
  • Proper text capitalization
  • Standard sheet presentation pattern

87-97: LGTM: Dynamic type and alert implementation are well-configured.

  • Dynamic type size limit to .accessibility2 is intentional to prevent breaking readability in buttons
  • Alert implementation follows SwiftUI best practices with proper error handling

68-85: 🛠️ Refactor suggestion

Add loading state to wallet creation button.

Consider adding a loading state to provide feedback during wallet creation process.

+@State private var isCreatingWallet = false
+
 Button("Create wallet") {
+    isCreatingWallet = true
     viewModel.saveSeed()
     isFirstTime = false
 }
 .buttonStyle(
     BitcoinFilled(
         tintColor: .accent,
         isCapsule: true
     )
 )
+.disabled(isCreatingWallet)
+.overlay {
+    if isCreatingWallet {
+        ProgressView()
+            .tint(.accent)
+    }
+}
LDKNodeMonday.xcodeproj/project.pbxproj (3)

96-97: LGTM: New view files are properly integrated.

NetworkSettingsView.swift and ImportWalletView.swift are correctly added to the project structure and organized in the Home group.

Also applies to: 306-307


180-180: LGTM: Framework references are configured as intended.

Multiple LDKNode framework references are present, which may be intentional for managing custom forks or different versions.


907-914: Consider using a version range for LDKNode dependency.

While pinning to exact version 0.4.0 provides stability, it may cause you to miss important security updates. Consider using a version range that allows minor updates.

 requirement = {
-    kind = exactVersion;
-    version = 0.4.0;
+    kind = upToNextMinor;
+    minimumVersion = "0.4.0";
 };

Copy link
Contributor

@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

🧹 Outside diff range and nitpick comments (2)
LDKNodeMonday/Utilities/Constants.swift (2)

31-31: Consider documenting the use of HTTP for local development

While using HTTP for localhost is common, it would be helpful to add a comment explaining why HTTPS isn't required in this case.

-                static let local = EsploraServer(name: "Local", url: "http://127.0.0.1:3002")
+                // Using HTTP for local development environment
+                static let local = EsploraServer(name: "Local", url: "http://127.0.0.1:3002")

118-121: Consider enhancing the EsploraServer struct with better type safety

The current implementation could benefit from using URL type instead of String for the url property and adding validation.

Here's a suggested improvement:

 struct EsploraServer: Hashable {
     var name: String
-    var url: String
+    var url: URL
+    
+    init(name: String, url: String) throws {
+        guard let validURL = URL(string: url) else {
+            throw URLError(.badURL)
+        }
+        self.name = name
+        self.url = validURL
+    }
 }

This change would:

  1. Ensure URL validity at initialization
  2. Provide better type safety with URL type
  3. Make it clear when URL parsing fails
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between baebfee and 1e16bf0.

📒 Files selected for processing (6)
  • LDKNodeMonday/Service/Lightning Service/LightningNodeService.swift (1 hunks)
  • LDKNodeMonday/Utilities/Constants.swift (2 hunks)
  • LDKNodeMonday/View Model/Home/OnboardingViewModel.swift (5 hunks)
  • LDKNodeMonday/View/Home/ImportWalletView.swift (1 hunks)
  • LDKNodeMonday/View/Home/NetworkSettingsView.swift (1 hunks)
  • LDKNodeMonday/View/Home/OnboardingView.swift (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • LDKNodeMonday/Service/Lightning Service/LightningNodeService.swift
  • LDKNodeMonday/View/Home/NetworkSettingsView.swift
  • LDKNodeMonday/View/Home/ImportWalletView.swift
🧰 Additional context used
📓 Learnings (2)
LDKNodeMonday/View/Home/OnboardingView.swift (2)
Learnt from: danielnordh
PR: reez/Monday#131
File: LDKNodeMonday/View/Home/OnboardingView.swift:15-15
Timestamp: 2024-12-04T10:54:52.311Z
Learning: In iOS 17, when using the new Observable pattern in SwiftUI, it's appropriate to use `@State` for view models instead of `@ObservedObject`.
Learnt from: danielnordh
PR: reez/Monday#131
File: LDKNodeMonday/View/Home/OnboardingView.swift:0-0
Timestamp: 2024-12-04T10:50:10.272Z
Learning: In the SwiftUI view `OnboardingView` in `LDKNodeMonday/View/Home/OnboardingView.swift`, limit the dynamic type size to `.accessibility2` to prevent breaking readability in buttons and other UI elements.
LDKNodeMonday/View Model/Home/OnboardingViewModel.swift (1)
Learnt from: danielnordh
PR: reez/Monday#131
File: LDKNodeMonday/View/Home/OnboardingView.swift:15-15
Timestamp: 2024-12-04T10:54:52.311Z
Learning: In iOS 17, when using the new Observable pattern in SwiftUI, it's appropriate to use `@State` for view models instead of `@ObservedObject`.
🔇 Additional comments (6)
LDKNodeMonday/Utilities/Constants.swift (3)

17-24: LGTM! Well-structured Bitcoin mainnet server configurations.

The implementation uses secure HTTPS URLs and provides a clear organization of server information.


37-37: Use HTTPS instead of HTTP for network URLs

The URL for the BDK Signet API uses http, which is insecure. Consider using https to ensure secure communication.


45-48: Use HTTPS instead of HTTP for network URLs

The URL for the Blockstream Testnet API uses http, which is insecure. Update it to use https to ensure secure communication.

LDKNodeMonday/View Model/Home/OnboardingViewModel.swift (3)

26-27: Avoid force unwrapping to prevent potential crashes

The use of availableEsploraServers.first! force unwraps an optional, which can lead to a runtime crash if the array is empty. Consider safely unwrapping using if let or guard let.


89-91: Handle optionals safely when retrieving Esplora server

Force unwrapping availableEsploraServers.first(where: { $0.url == esploraURL })! can cause a crash if there's no matching server. Use safe unwrapping to handle cases where the server is not found.


93-93: Avoid force unwrapping to prevent potential crashes

Using availableEsploraServers.first! without checking if the array is empty can lead to a crash. Safely unwrap to handle empty arrays gracefully.

Copy link
Owner

@reez reez left a comment

Choose a reason for hiding this comment

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

This is looking good, some comments about unimportant things, some comments about nice things, some changes requested: comments for changes I’m requesting.

Some of the changes requested are not even that what you have is wrong and what I have is far superior, but might just be that it breaks convention with the current codebase, and I don’t want you having to change it in other unrelated places in the code base if we are changing the convention right now (would rather just do that in follow up PR’s to allow us to not expand the size of the changes in this PR so this PR can be merged sooner rather than later).

danielnordh and others added 2 commits December 9, 2024 09:00
Co-authored-by: Matthew Ramsden <6657488+reez@users.noreply.github.com>
…tside classes, fix use in OnboardingViewModel
Copy link
Contributor

@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

🧹 Outside diff range and nitpick comments (3)
LDKNodeMonday/View Model/Home/OnboardingViewModel.swift (3)

Line range hint 38-53: Consider adding URL validation

While the EsploraServer management is well-structured, consider adding URL validation before saving to ensure the URL is well-formed and accessible.

     var selectedEsploraServer: EsploraServer = EsploraServer.mutiny_signet {
         didSet {
             do {
+                guard URL(string: selectedEsploraServer.url) != nil else {
+                    throw MondayError(
+                        title: "Invalid URL",
+                        detail: "The selected Esplora server URL is invalid"
+                    )
+                }
                 try KeyClient.live.saveEsploraURL(selectedEsploraServer.url)

106-109: Consider encapsulating UserDefaults access

Direct UserDefaults manipulation could be moved to a dedicated configuration service for better encapsulation and maintainability.

+    private let defaults: UserDefaults
+    
+    init(defaults: UserDefaults = .standard) {
+        self.defaults = defaults
+    }
+
+    private func setOnboardingComplete() {
+        defaults.set(false, forKey: "isOnboarding")
+    }

     func saveSeed() {
         do {
             let backupInfo = BackupInfo(mnemonic: seedPhrase)
             try KeyClient.live.saveBackupInfo(backupInfo)
             try KeyClient.live.saveNetwork(selectedNetwork.description)
             try KeyClient.live.saveEsploraURL(selectedEsploraServer.url)
             LightningNodeService.shared = LightningNodeService()
             DispatchQueue.main.async {
-                UserDefaults.standard.set(false, forKey: "isOnboarding")
+                setOnboardingComplete()
             }

13-13: Consider centralizing color management

Since this PR focuses on UI styling and colors, consider moving color management to a dedicated theme service that can handle both network colors and general UI colors consistently across the app.

This would:

  1. Improve maintainability of color schemes
  2. Make it easier to implement future theme changes
  3. Ensure consistency across the app
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between f79a99c and f71549c.

📒 Files selected for processing (2)
  • LDKNodeMonday/Utilities/Constants.swift (2 hunks)
  • LDKNodeMonday/View Model/Home/OnboardingViewModel.swift (5 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • LDKNodeMonday/Utilities/Constants.swift
🧰 Additional context used
📓 Learnings (1)
LDKNodeMonday/View Model/Home/OnboardingViewModel.swift (1)
Learnt from: danielnordh
PR: reez/Monday#131
File: LDKNodeMonday/View/Home/OnboardingView.swift:15-15
Timestamp: 2024-12-04T10:54:52.311Z
Learning: In iOS 17, when using the new Observable pattern in SwiftUI, it's appropriate to use `@State` for view models instead of `@ObservedObject`.
🔇 Additional comments (2)
LDKNodeMonday/View Model/Home/OnboardingViewModel.swift (2)

11-20: LGTM: Appropriate use of @observable macro

The transition from ObservableObject to @observable aligns with modern iOS 17 patterns and simplifies state management. The property observers are well-structured.


85-89: LGTM: Safe initialization of EsploraServer

The implementation properly handles potential nil values and follows best practices for optional handling.

Copy link
Contributor

@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: 0

🧹 Outside diff range and nitpick comments (4)
LDKNodeMonday/View/Home/OnboardingView.swift (4)

29-47: Add accessibility label to network settings button

While the network settings UI is well-structured, consider enhancing accessibility by adding an accessibility label that clearly describes the button's purpose.

 Button(
     action: {
         showingNetworkSettingsSheet.toggle()
     },
     label: {
         HStack(spacing: 5) {
             Text(viewModel.selectedNetwork.description.capitalized)
             Image(systemName: "gearshape")
         }
     }
 )
+.accessibilityLabel("Network settings: \(viewModel.selectedNetwork.description)")

52-57: Consider color scheme adaptation for logo

The logo currently uses .accent color. Consider adapting the color based on the color scheme to ensure optimal visibility in both light and dark modes.

 Image(systemName: "bolt.horizontal.fill")
     .resizable()
     .aspectRatio(contentMode: .fit)
-    .foregroundColor(.accent)
+    .foregroundColor(Color.accent.opacity(colorScheme == .dark ? 0.9 : 1.0))

70-79: Add haptic feedback for wallet creation

Consider adding haptic feedback to provide tactile confirmation when creating a wallet.

 Button("Create wallet") {
+    let impactMed = UIImpactFeedbackGenerator(style: .medium)
+    impactMed.impactOccurred()
     viewModel.saveSeed()
     isOnboarding = false
 }

93-99: Enhance alert accessibility

Consider adding more descriptive accessibility labels to the alert to improve the experience for VoiceOver users.

 Alert(
     title: Text(viewModel.onboardingViewError?.title ?? "Unknown error"),
     message: Text(viewModel.onboardingViewError?.detail ?? "No details"),
     dismissButton: .default(Text("OK")) {
         viewModel.onboardingViewError = nil
     }
 )
+.accessibilityLabel("\(viewModel.onboardingViewError?.title ?? "Error")")
+.accessibilityHint("\(viewModel.onboardingViewError?.detail ?? "")")
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between f71549c and 7c6e8e2.

📒 Files selected for processing (4)
  • LDKNodeMonday/Service/Lightning Service/LightningNodeService.swift (1 hunks)
  • LDKNodeMonday/View/Home/ImportWalletView.swift (1 hunks)
  • LDKNodeMonday/View/Home/NetworkSettingsView.swift (1 hunks)
  • LDKNodeMonday/View/Home/OnboardingView.swift (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • LDKNodeMonday/Service/Lightning Service/LightningNodeService.swift
  • LDKNodeMonday/View/Home/NetworkSettingsView.swift
  • LDKNodeMonday/View/Home/ImportWalletView.swift
🧰 Additional context used
📓 Learnings (1)
LDKNodeMonday/View/Home/OnboardingView.swift (2)
Learnt from: danielnordh
PR: reez/Monday#131
File: LDKNodeMonday/View/Home/OnboardingView.swift:15-15
Timestamp: 2024-12-04T10:54:52.311Z
Learning: In iOS 17, when using the new Observable pattern in SwiftUI, it's appropriate to use `@State` for view models instead of `@ObservedObject`.
Learnt from: danielnordh
PR: reez/Monday#131
File: LDKNodeMonday/View/Home/OnboardingView.swift:0-0
Timestamp: 2024-12-04T10:50:10.272Z
Learning: In the SwiftUI view `OnboardingView` in `LDKNodeMonday/View/Home/OnboardingView.swift`, limit the dynamic type size to `.accessibility2` to prevent breaking readability in buttons and other UI elements.
🔇 Additional comments (2)
LDKNodeMonday/View/Home/OnboardingView.swift (2)

15-18: LGTM: State management follows iOS 17 best practices

The use of @State for the view model aligns with iOS 17's Observable pattern, and the sheet state management follows SwiftUI best practices.


93-100: Alert may not be displayed when an error occurs

The alert tied to showingOnboardingViewErrorAlert may not appear because showingOnboardingViewErrorAlert is never set to true when viewModel.onboardingViewError is updated.

Copy link
Contributor

@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: 3

🧹 Outside diff range and nitpick comments (1)
LDKNodeMonday/View/Home/OnboardingView.swift (1)

15-15: Use @State instead of @ObservedObject for viewModel

In iOS 17, when using the new Observable pattern in SwiftUI, it's appropriate to use @State for view models instead of @ObservedObject. This ensures proper state management and view updates.

As per your previous learnings:

In iOS 17, when using the new Observable pattern in SwiftUI, it's appropriate to use @State for view models instead of @ObservedObject.

Consider updating the property wrapper:

-    @ObservedObject var viewModel: OnboardingViewModel
+    @State var viewModel: OnboardingViewModel
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 7c6e8e2 and cda09fe.

📒 Files selected for processing (8)
  • LDKNodeMonday.xcodeproj/project.pbxproj (12 hunks)
  • LDKNodeMonday.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved (1 hunks)
  • LDKNodeMonday/Service/Lightning Service/LightningNodeService.swift (1 hunks)
  • LDKNodeMonday/Utilities/Constants.swift (2 hunks)
  • LDKNodeMonday/View Model/Home/OnboardingViewModel.swift (5 hunks)
  • LDKNodeMonday/View/Home/ImportWalletView.swift (1 hunks)
  • LDKNodeMonday/View/Home/NetworkSettingsView.swift (1 hunks)
  • LDKNodeMonday/View/Home/OnboardingView.swift (2 hunks)
✅ Files skipped from review due to trivial changes (1)
  • LDKNodeMonday.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
🚧 Files skipped from review as they are similar to previous changes (3)
  • LDKNodeMonday/View/Home/NetworkSettingsView.swift
  • LDKNodeMonday/Service/Lightning Service/LightningNodeService.swift
  • LDKNodeMonday/View/Home/ImportWalletView.swift
🧰 Additional context used
📓 Learnings (2)
LDKNodeMonday/View/Home/OnboardingView.swift (2)
Learnt from: danielnordh
PR: reez/Monday#131
File: LDKNodeMonday/View/Home/OnboardingView.swift:15-15
Timestamp: 2024-12-04T10:54:52.311Z
Learning: In iOS 17, when using the new Observable pattern in SwiftUI, it's appropriate to use `@State` for view models instead of `@ObservedObject`.
Learnt from: danielnordh
PR: reez/Monday#131
File: LDKNodeMonday/View/Home/OnboardingView.swift:0-0
Timestamp: 2024-12-04T10:50:10.272Z
Learning: In the SwiftUI view `OnboardingView` in `LDKNodeMonday/View/Home/OnboardingView.swift`, limit the dynamic type size to `.accessibility2` to prevent breaking readability in buttons and other UI elements.
LDKNodeMonday.xcodeproj/project.pbxproj (1)
Learnt from: danielnordh
PR: reez/Monday#131
File: LDKNodeMonday.xcodeproj/project.pbxproj:180-180
Timestamp: 2024-12-05T17:54:34.328Z
Learning: Multiple LDKNode framework references in `LDKNodeMonday.xcodeproj/project.pbxproj` may be intentional when using custom forks or multiple versions of LDKNode, and should not be flagged as duplicates.
🔇 Additional comments (5)
LDKNodeMonday.xcodeproj/project.pbxproj (1)

910-917: 🛠️ Refactor suggestion

Consider using a version range for LDKNode dependency

While pinning to exact version 0.4.0 provides stability, it may cause you to miss important security updates. Consider using a version range that allows minor updates.

Update the package requirement to allow minor version updates:

 requirement = {
-    kind = exactVersion;
-    version = 0.4.0;
+    kind = upToNextMinor;
+    minimumVersion = "0.4.0";
 };
LDKNodeMonday/View Model/Home/OnboardingViewModel.swift (1)

26-28: ⚠️ Potential issue

Handle absence of available Esplora servers appropriately

Currently, if availableEsploraServers is empty, selectedEsploraServer is set to an EsploraServer with empty name and url, which could lead to unexpected behavior elsewhere in the application. It's better to handle this case explicitly, perhaps by notifying the user or providing a valid default server.

Consider modifying the code as follows:

-                    self.selectedEsploraServer =
-                        availableEsploraServers.first ?? EsploraServer(name: "", url: "")
+                    if let firstServer = availableEsploraServers.first {
+                        self.selectedEsploraServer = firstServer
+                    } else {
+                        // Handle the case when no servers are available
+                        self.onboardingViewError = .init(
+                            title: "No Esplora Servers Available",
+                            detail: "Please check your network settings."
+                        )
+                    }

Likely invalid or redundant comment.

LDKNodeMonday/Utilities/Constants.swift (2)

109-109: Use HTTPS instead of HTTP for network URLs

The URL for the BDK Signet API uses http, which is insecure. Consider updating it to use https to ensure secure communication.

Apply this diff to update the URL:

-    static let bdk_signet = EsploraServer(name: "BDK", url: "http://signet.bitcoindevkit.net")
+    static let bdk_signet = EsploraServer(name: "BDK", url: "https://signet.bitcoindevkit.net")

115-115: Use HTTPS instead of HTTP for network URLs

The URL for the Blockstream Testnet API uses http, which is insecure. Update it to use https to ensure secure communication.

Apply this diff to update the URL:

-            url: "http://blockstream.info/testnet/api"
+            url: "https://blockstream.info/testnet/api"
LDKNodeMonday/View/Home/OnboardingView.swift (1)

90-91: Reconsider dynamic type size limitation for better accessibility

Limiting the dynamic type size to .accessibility2 might prevent users who require larger text sizes from comfortably using the app. Consider adjusting the layout to support larger dynamic type sizes instead of capping it.

@danielnordh
Copy link
Collaborator Author

danielnordh commented Dec 9, 2024

Thanks for the review, good points.
Given the history is getting long and unwieldy with all these CodeRabbit comments, here is what I've changed:

  • Went back to @observableobject for OnboardingViewModel
  • Replaced the "< Back" Toolbar pattern on the left with Done/Cancel on the right
  • Replaced ! with ?? as requested
  • Removed unnecessary isFirstTime variable

@reez
Copy link
Owner

reez commented Dec 9, 2024

Yes this looks good! only thing left for approval is the merge conflict, once that is resolved I will approve and merge-

@reez reez merged commit 53ee3b4 into reez:main Dec 9, 2024
1 check passed
@danielnordh danielnordh deleted the ux/onboarding branch December 11, 2024 15:23
@coderabbitai coderabbitai bot mentioned this pull request Feb 11, 2025
@coderabbitai coderabbitai bot mentioned this pull request Feb 26, 2025
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