Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -532,8 +532,14 @@ struct PayContactSheet: View {
@State private var sentTxid: Data? = nil
/// Exact network fee (duffs) of the broadcast transaction.
@State private var sentFeeDuffs: UInt64? = nil
/// Duffs actually broadcast, captured at send time.
///
/// The confirmation must state what was paid, not what was typed. Echoing
/// `amountText` back made any gap between the two — a locale separator, a
/// stray character, precision the parser drops — render as a truthful-looking
/// "sent" line for an amount that never left the wallet.
@State private var sentAmountDuffs: UInt64? = nil
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
@State private var errorMessage: String? = nil
@FocusState private var amountFocused: Bool

var body: some View {
NavigationStack {
Expand Down Expand Up @@ -568,22 +574,27 @@ struct PayContactSheet: View {
Text(errorMessage ?? "")
}
}
.presentationDetents([.medium])
// The sheet carries its own keypad now, so it needs the room the
// system keyboard used to occupy.
.presentationDetents([.large])
}

@ViewBuilder
private var form: some View {
Comment on lines 582 to 583

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Put @ViewBuilder on the property declaration line.

SwiftLint requires attributes on the same line as variable declarations.

Proposed fix
-    `@ViewBuilder`
-    private var form: some View {
+    `@ViewBuilder` private var form: some View {

As per coding guidelines, Swift files must follow SwiftFormat/SwiftLint.

📝 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
@ViewBuilder
private var form: some View {
`@ViewBuilder` private var form: some View {
🧰 Tools
🪛 SwiftLint (0.65.0)

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

(attributes)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@DashWallet/Sources/UI/DashPay/Contacts/SwiftUI/ContactProfileSheet.swift`
around lines 582 - 583, Move the `@ViewBuilder` attribute onto the same line as
the form property declaration in the form computed property, preserving its
existing behavior and body.

Sources: Coding guidelines, Linters/SAST tools

HStack(alignment: .firstTextBaseline, spacing: 8) {
TextField("0", text: $amountText)
.keyboardType(.decimalPad)
.font(.system(size: 40, weight: .semibold))
.multilineTextAlignment(.trailing)
.focused($amountFocused)
.onAppear { amountFocused = true }
Text("DASH")
.font(.system(size: 17, weight: .bold))
.foregroundColor(.dash.secondaryText)
}
// The shared amount surface every other send screen uses, over the
// app's own keypad. A raw `TextField` + `.decimalPad` accepted whatever
// the system keyboard allowed — a bare separator, a locale comma, more
// precision than DASH has — and left validation to the parser, so the
// typed text and the amount actually sent could disagree.
EnterAmountView(
primaryAmount: amountText.isEmpty ? "0" : amountText,
secondaryAmount: fiatAmountText,
primaryCurrency: .dash,
secondaryCurrency: .fiat(App.fiatCurrency),
isPrimarySelected: true,
isCurrencySelectorHidden: true,
onMax: { amountText = Self.dashString(duffs: maxSendable) }
)
.padding(.top, 12)

Text(String(
Expand All @@ -596,25 +607,23 @@ struct PayContactSheet: View {
.font(.system(size: 12))
.foregroundColor(.dash.tertiaryText)

if isSending {
SwiftUI.ProgressView()
.padding(.top, 8)
} else {
Button {
pay()
} label: {
Text(NSLocalizedString("Pay", comment: "DashPay Contacts"))
.font(.system(size: 14, weight: .semibold))
.foregroundColor(Color.dash.whiteText)
.frame(maxWidth: .infinity)
.frame(height: 46)
.background(
RoundedRectangle(cornerRadius: 8, style: .continuous)
.fill(parsedDuffs == nil ? Color.dash.gray300 : Color.dash.blue))
}
.buttonStyle(.plain)
.disabled(parsedDuffs == nil)
}
NumericKeyboardView(
value: $amountText,
showDecimalSeparator: true,
actionButtonText: NSLocalizedString("Pay", comment: "DashPay Contacts"),
actionEnabled: parsedDuffs != nil,
inProgress: isSending,
actionHandler: { pay() }
)
.padding(.top, 8)
}

/// Fiat equivalent of what is typed, for the secondary line. Empty while
/// the amount is unparseable or rates have not arrived.
private var fiatAmountText: String {
guard let duffs = parsedDuffs else { return "" }
let dash = Decimal(duffs) / Decimal(100_000_000)
return CurrencyExchanger.shared.fiatAmountString(for: dash)
}

private func success(txid: Data) -> some View {
Expand All @@ -627,7 +636,8 @@ struct PayContactSheet: View {
.foregroundColor(.dash.primaryText)
Text(String(
format: NSLocalizedString("%@ DASH sent to %@", comment: "DashPay Contacts"),
amountText, contact.displayTitle))
sentAmountDuffs.map { Self.dashString(duffs: $0) } ?? amountText,
contact.displayTitle))
.font(.system(size: 14))
.foregroundColor(.dash.secondaryText)
if let fee = sentFeeDuffs {
Expand Down Expand Up @@ -683,6 +693,7 @@ struct PayContactSheet: View {
amount: duffs)
sentTxid = txid
sentFeeDuffs = feeDuffs
sentAmountDuffs = duffs
// Project the freshly recorded Sent entry to SwiftData
// right away — the entry lives only in Rust memory
// until a projection runs, and an app kill before one
Expand Down
Loading