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

New Crowdin updates #1281

Merged
merged 11 commits into from
Aug 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
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
1 change: 1 addition & 0 deletions RadixWallet/Core/DesignSystem/Components/WarningView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public struct WarningErrorView: View {
HStack(spacing: spacing) {
Image(.error)
Text(text)
.lineSpacing(-.small3)
.textStyle(.body1Header)
.multilineTextAlignment(.leading)
}
Expand Down
260 changes: 240 additions & 20 deletions RadixWallet/Core/Resources/Generated/L10n.generated.swift

Large diffs are not rendered by default.

32 changes: 23 additions & 9 deletions RadixWallet/Core/Resources/Resources/en.lproj/Localizable.strings

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -45,19 +45,19 @@ extension DisplayEntitiesControlledByMnemonic {
switch type {
case .standard:
switch (personas, accounts) {
case (0, 0): L10n.SeedPhrases.SeedPhrase.noConnectedAccountsReveal
case (0, 1): L10n.SeedPhrases.SeedPhrase.oneConnectedAccountReveal
case (0, _): L10n.SeedPhrases.SeedPhrase.multipleConnectedAccountsReveal(accounts)
case (0, 0): L10n.SeedPhrases.SeedPhrase.noConnectedAccounts
case (0, 1): L10n.SeedPhrases.SeedPhrase.oneConnectedAccount
case (0, _): L10n.SeedPhrases.SeedPhrase.multipleConnectedAccounts(accounts)
case (_, 1): L10n.DisplayMnemonics.ConnectedAccountsPersonasLabel.one(accounts)
case (_, _): L10n.DisplayMnemonics.ConnectedAccountsPersonasLabel.many(accounts)
}
case .scanning:
if accounts == 0 {
L10n.SeedPhrases.SeedPhrase.noConnectedAccountsReveal
L10n.SeedPhrases.SeedPhrase.noConnectedAccounts
} else if accounts == 1 {
L10n.SeedPhrases.SeedPhrase.oneConnectedAccountReveal
L10n.SeedPhrases.SeedPhrase.oneConnectedAccount
} else {
L10n.SeedPhrases.SeedPhrase.multipleConnectedAccountsReveal(accounts)
L10n.SeedPhrases.SeedPhrase.multipleConnectedAccounts(accounts)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,64 +1,64 @@

extension CustomizeFees.State {
// Need to disable, since broken in swiftformat 0.52.7
// swiftformat:disable redundantClosure

var viewState: CustomizeFees.ViewState {
.init(
title: {
switch transactionFee.mode {
case .normal:
L10n.CustomizeNetworkFees.NormalMode.title
case .advanced:
L10n.CustomizeNetworkFees.AdvancedMode.title
}
}(),
description: {
switch transactionFee.mode {
case .normal:
L10n.CustomizeNetworkFees.NormalMode.subtitle
case .advanced:
L10n.CustomizeNetworkFees.AdvancedMode.subtitle
}
}(),
modeSwitchTitle: {
switch transactionFee.mode {
case .normal:
L10n.CustomizeNetworkFees.viewAdvancedModeButtonTitle
case .advanced:
L10n.CustomizeNetworkFees.viewNormalModeButtonTitle
}
}(),
feePayer: feePayer,
noFeePayerText: {
if transactionFee.totalFee.lockFee == .zero {
L10n.CustomizeNetworkFees.noneRequired
} else {
L10n.CustomizeNetworkFees.noAccountSelected
}
}(),
insufficientBalanceMessage: {
if let feePayer {
if feePayer.xrdBalance < transactionFee.totalFee.lockFee {
return L10n.CustomizeNetworkFees.Warning.insufficientBalance
}
}
return nil
}()
mode: transactionFee.mode,
feePayer: feePayer?.account,
feePayingValidation: feePayingValidation
)
}
}

extension CustomizeFees.ViewState {
var title: String {
switch mode {
case .normal:
L10n.CustomizeNetworkFees.NormalMode.title
case .advanced:
L10n.CustomizeNetworkFees.AdvancedMode.title
}
}

// swiftformat:enable redundantClosure
var description: String {
switch mode {
case .normal:
L10n.CustomizeNetworkFees.NormalMode.subtitle
case .advanced:
L10n.CustomizeNetworkFees.AdvancedMode.subtitle
}
}

var modeSwitchTitle: String {
switch mode {
case .normal:
L10n.CustomizeNetworkFees.viewAdvancedModeButtonTitle
case .advanced:
L10n.CustomizeNetworkFees.viewNormalModeButtonTitle
}
}

var noFeePayerText: String {
if feePayingValidation == .valid(.feePayerSuperfluous) {
L10n.CustomizeNetworkFees.noneRequired
} else {
L10n.CustomizeNetworkFees.noAccountSelected
}
}

var insufficientBalance: Bool {
feePayingValidation == .insufficientBalance
}

var linkingNewAccount: Bool {
feePayingValidation == .valid(.introducesNewAccount)
}
}

extension CustomizeFees {
public struct ViewState: Equatable {
let title: String
let description: String
let modeSwitchTitle: String
let feePayer: FeePayerCandidate?
let noFeePayerText: String
let insufficientBalanceMessage: String?
let mode: TransactionFee.Mode
let feePayer: Account?
let feePayingValidation: FeeValidationOutcome?
}

@MainActor
Expand Down Expand Up @@ -145,7 +145,7 @@ extension CustomizeFees {
.textStyle(.body1StandaloneLink)
.foregroundColor(.app.blue2)
}
if let feePayer = viewState.feePayer?.account {
if let feePayer = viewState.feePayer {
AccountCard(account: feePayer)
} else {
AppTextField(
Expand All @@ -155,8 +155,10 @@ extension CustomizeFees {
.disabled(true)
}

if let insufficientBalanceMessage = viewState.insufficientBalanceMessage {
WarningErrorView(text: insufficientBalanceMessage, type: .warning)
if viewState.insufficientBalance {
WarningErrorView(text: L10n.CustomizeNetworkFees.Warning.insufficientBalance, type: .error)
} else if viewState.linkingNewAccount {
WarningErrorView(text: L10n.TransactionReview.FeePayerValidation.linksNewAccount, type: .warning)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ public struct CustomizeFees: FeatureReducer, Sendable {
reviewedTransaction.transactionFee
}

var feePayingValidation: FeeValidationOutcome? {
reviewedTransaction.feePayingValidation.wrappedValue
}

@PresentationState
public var destination: Destination.State? = nil

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -973,11 +973,16 @@ public struct ReviewedTransaction: Hashable, Sendable {
}

// MARK: - FeeValidationOutcome
enum FeeValidationOutcome {
case valid(introducesNewAccount: Bool)
enum FeeValidationOutcome: Equatable {
case valid(Details?)
case needsFeePayer
case insufficientBalance

enum Details {
case introducesNewAccount
case feePayerSuperfluous
}

var isValid: Bool {
guard case .valid = self else { return false }
return true
Expand All @@ -991,53 +996,38 @@ extension ReviewedTransaction {

var feePayingValidation: Loadable<FeeValidationOutcome> {
feePayer.map { selected in
let introducesNewAccount = selected.map { !involvedAccounts.contains($0.account.address) } ?? false

guard let feePayer = selected,
let feePayerWithdraws = accountWithdraws[feePayer.account.address]
else {
return selected.validateBalance(forFee: transactionFee, introducesNewAccount: introducesNewAccount)
guard let selected else {
if transactionFee.totalFee.lockFee == .zero {
// No fee is required - no fee payer needed
return .valid(.feePayerSuperfluous)
} else {
// Fee is required, but no fee payer selected - invalid
return .needsFeePayer
}
}

let xrdAddress = ResourceAddress.xrd(on: networkID)

let xrdTotalTransfer: Decimal192 = feePayerWithdraws.reduce(.zero) { partialResult, resource in
let xrdAddress: ResourceAddress = .xrd(on: networkID)
let feePayerWithdraws = accountWithdraws[selected.account.address] ?? []
let xrdTransfer: Decimal192 = feePayerWithdraws.reduce(.zero) { partialResult, resource in
if case let .fungible(resourceAddress, indicator) = resource, resourceAddress == xrdAddress {
return partialResult + indicator.amount
}
return partialResult
}

let total = xrdTotalTransfer + transactionFee.totalFee.lockFee
let totalAmountNeeded = xrdTransfer + transactionFee.totalFee.lockFee

guard feePayer.xrdBalance >= total else {
guard selected.xrdBalance >= totalAmountNeeded else {
// Insufficient balance to pay for withdraws and transaction fee
return .insufficientBalance
}

return .valid(introducesNewAccount: false)
}
}
}

extension FeePayerCandidate? {
func validateBalance(forFee transactionFee: TransactionFee, introducesNewAccount: Bool) -> FeeValidationOutcome {
if transactionFee.totalFee.lockFee == .zero {
// If no fee is required - valid
return .valid(introducesNewAccount: introducesNewAccount)
}

guard let self else {
// If fee is required, but no fee payer selected - invalid
return .needsFeePayer
}

guard self.xrdBalance >= transactionFee.totalFee.lockFee else {
// If insufficient balance - invalid
return .insufficientBalance
if !involvedAccounts.contains(selected.account.address) {
return .valid(.introducesNewAccount)
} else {
return .valid(nil)
}
}

return .valid(introducesNewAccount: introducesNewAccount)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,12 @@ extension TransactionReviewNetworkFee {
loadable(viewStore.reviewedTransaction.feePayingValidation) { validation in
switch validation {
case .needsFeePayer:
WarningErrorView(text: L10n.TransactionReview.feePayerRequiredMessage, type: .warning)
WarningErrorView(text: L10n.TransactionReview.FeePayerValidation.feePayerRequired, type: .warning)
case .insufficientBalance:
WarningErrorView(text: L10n.TransactionReview.insufficientBalance, type: .warning)
case .valid(introducesNewAccount: true):
EmptyView() // TODO: Here we could show a warning, that this introduces a new account into the transaction - the link between the accounts will now be public
case .valid(introducesNewAccount: false):
WarningErrorView(text: L10n.TransactionReview.FeePayerValidation.insufficientBalance, type: .error)
case .valid(.introducesNewAccount):
WarningErrorView(text: L10n.TransactionReview.FeePayerValidation.linksNewAccount, type: .warning)
case .valid:
EmptyView()
}

Expand Down
Loading