Skip to content

Commit 032d451

Browse files
vitnehasilclaude
andcommitted
Remove per-field QR scan buttons and add missing Czech translations
- Remove individual QR scan buttons from credential fields in AddExchangeView and ExchangeDetailView (keep only top-level Scan QR/Scan All buttons and per-field paste/clear) - Remove unused single-field QR scanner sheets - Add Czech translations for: portfolio chart messages, execution complete, import errors, credential form buttons (paste/clear, scan QR), experimental exchanges toggle and badge Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent a17aedf commit 032d451

3 files changed

Lines changed: 121 additions & 144 deletions

File tree

accbot-ios/AccBot/Presentation/Screens/Exchanges/AddExchangeView.swift

Lines changed: 37 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -94,14 +94,6 @@ struct AddExchangeView: View {
9494
}
9595
}
9696
}
97-
.sheet(isPresented: $credentials.showQrScanner) {
98-
QrScannerSheet(
99-
title: String(localized: "Scan Credential"),
100-
onScanned: { code in
101-
credentials.handleQrScan(code)
102-
}
103-
)
104-
}
10597
.sheet(isPresented: $credentials.showMultiFieldScanner) {
10698
if credentials.selectedExchange != nil {
10799
MultiFieldScannerSheet(
@@ -496,8 +488,7 @@ struct AddExchangeView: View {
496488
label: String(localized: "Client ID"),
497489
text: $credentials.clientId,
498490
placeholder: String(localized: "Enter your client ID"),
499-
isSecure: false,
500-
scanTarget: .clientId
491+
isSecure: false
501492
)
502493
}
503494

@@ -509,8 +500,7 @@ struct AddExchangeView: View {
509500
placeholder: exchange.requiresClientId
510501
? String(localized: "Enter your public key")
511502
: String(localized: "Enter your API key"),
512-
isSecure: false,
513-
scanTarget: .apiKey
503+
isSecure: false
514504
)
515505

516506
credentialField(
@@ -521,17 +511,15 @@ struct AddExchangeView: View {
521511
placeholder: exchange.requiresClientId
522512
? String(localized: "Enter your private key")
523513
: String(localized: "Enter your API secret"),
524-
isSecure: true,
525-
scanTarget: .apiSecret
514+
isSecure: true
526515
)
527516

528517
if exchange.requiresPassphrase {
529518
credentialField(
530519
label: String(localized: "Passphrase"),
531520
text: $credentials.passphrase,
532521
placeholder: String(localized: "Enter your passphrase"),
533-
isSecure: true,
534-
scanTarget: .passphrase
522+
isSecure: true
535523
)
536524
}
537525
}
@@ -590,73 +578,56 @@ struct AddExchangeView: View {
590578
label: String,
591579
text: Binding<String>,
592580
placeholder: String,
593-
isSecure: Bool,
594-
scanTarget: CredentialScanTarget? = nil
581+
isSecure: Bool
595582
) -> some View {
596583
VStack(alignment: .leading, spacing: Spacing.xs) {
597584
Text(label)
598585
.font(AccBotFonts.caption)
599586
.foregroundStyle(colors.onSurfaceVariant)
600587

601-
HStack(spacing: Spacing.sm) {
602-
HStack(spacing: 0) {
603-
Group {
604-
if isSecure {
605-
SecureField(placeholder, text: text)
606-
} else {
607-
TextField(placeholder, text: text)
608-
}
609-
}
610-
.font(AccBotFonts.mono)
611-
.foregroundStyle(colors.onSurface)
612-
.autocorrectionDisabled()
613-
.textInputAutocapitalization(.never)
614-
615-
// Paste (empty) or Clear (non-empty) button
616-
if text.wrappedValue.isEmpty {
617-
Button {
618-
if let clipboard = UIPasteboard.general.string {
619-
text.wrappedValue = clipboard.trimmingCharacters(in: .whitespacesAndNewlines)
620-
}
621-
} label: {
622-
Image(systemName: "doc.on.clipboard")
623-
.font(AccBotFonts.body)
624-
.foregroundStyle(colors.primary)
625-
}
626-
.buttonStyle(.plain)
627-
.padding(.leading, Spacing.sm)
628-
.accessibilityLabel(String(localized: "Paste"))
588+
HStack(spacing: 0) {
589+
Group {
590+
if isSecure {
591+
SecureField(placeholder, text: text)
629592
} else {
630-
Button {
631-
text.wrappedValue = ""
632-
} label: {
633-
Image(systemName: "xmark.circle.fill")
634-
.font(AccBotFonts.body)
635-
.foregroundStyle(colors.onSurfaceVariant)
636-
}
637-
.buttonStyle(.plain)
638-
.padding(.leading, Spacing.sm)
639-
.accessibilityLabel(String(localized: "Clear"))
593+
TextField(placeholder, text: text)
640594
}
641595
}
642-
.padding(Spacing.md)
643-
.background(colors.surfaceVariant.opacity(0.3))
644-
.clipShape(RoundedRectangle(cornerRadius: CornerRadius.sm))
596+
.font(AccBotFonts.mono)
597+
.foregroundStyle(colors.onSurface)
598+
.autocorrectionDisabled()
599+
.textInputAutocapitalization(.never)
645600

646-
if let target = scanTarget {
601+
// Paste (empty) or Clear (non-empty) button
602+
if text.wrappedValue.isEmpty {
647603
Button {
648-
credentials.qrScanTarget = target
649-
credentials.showQrScanner = true
604+
if let clipboard = UIPasteboard.general.string {
605+
text.wrappedValue = clipboard.trimmingCharacters(in: .whitespacesAndNewlines)
606+
}
650607
} label: {
651-
Image(systemName: "qrcode.viewfinder")
652-
.font(AccBotFonts.iconSmall)
608+
Image(systemName: "doc.on.clipboard")
609+
.font(AccBotFonts.body)
653610
.foregroundStyle(colors.primary)
654-
.frame(minWidth: 44, minHeight: 44)
655-
.contentShape(Rectangle())
656611
}
657612
.buttonStyle(.plain)
613+
.padding(.leading, Spacing.sm)
614+
.accessibilityLabel(String(localized: "Paste"))
615+
} else {
616+
Button {
617+
text.wrappedValue = ""
618+
} label: {
619+
Image(systemName: "xmark.circle.fill")
620+
.font(AccBotFonts.body)
621+
.foregroundStyle(colors.onSurfaceVariant)
622+
}
623+
.buttonStyle(.plain)
624+
.padding(.leading, Spacing.sm)
625+
.accessibilityLabel(String(localized: "Clear"))
658626
}
659627
}
628+
.padding(Spacing.md)
629+
.background(colors.surfaceVariant.opacity(0.3))
630+
.clipShape(RoundedRectangle(cornerRadius: CornerRadius.sm))
660631
}
661632
}
662633

accbot-ios/AccBot/Presentation/Screens/Exchanges/ExchangeDetailView.swift

Lines changed: 48 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -80,14 +80,6 @@ struct ExchangeDetailView: View {
8080
plans = (try? dependencies.activeDatabase.planDao.getPlansByExchange(exchange)) ?? []
8181
loadCachedBalances()
8282
}
83-
.sheet(isPresented: $credentials.showQrScanner) {
84-
QrScannerSheet(
85-
title: String(localized: "Scan Credential"),
86-
onScanned: { code in
87-
credentials.handleQrScan(code)
88-
}
89-
)
90-
}
9183
.sheet(isPresented: $credentials.showMultiFieldScanner) {
9284
MultiFieldScannerSheet(
9385
title: String(localized: "Scan All Credentials"),
@@ -291,8 +283,7 @@ struct ExchangeDetailView: View {
291283
label: String(localized: "Client ID"),
292284
text: $credentials.clientId,
293285
placeholder: String(localized: "Enter your client ID"),
294-
isSecure: false,
295-
scanTarget: .clientId
286+
isSecure: false
296287
)
297288
}
298289

@@ -305,8 +296,7 @@ struct ExchangeDetailView: View {
305296
? String(localized: "Enter your public key")
306297
: String(localized: "Enter your API key"),
307298
isSecure: false,
308-
showContent: .constant(true),
309-
scanTarget: .apiKey
299+
showContent: .constant(true)
310300
)
311301

312302
credentialField(
@@ -318,8 +308,7 @@ struct ExchangeDetailView: View {
318308
? String(localized: "Enter your private key")
319309
: String(localized: "Enter your API secret"),
320310
isSecure: true,
321-
showContent: $showSecret,
322-
scanTarget: .apiSecret
311+
showContent: $showSecret
323312
)
324313

325314
if exchange.requiresPassphrase {
@@ -328,8 +317,7 @@ struct ExchangeDetailView: View {
328317
text: $credentials.passphrase,
329318
placeholder: String(localized: "Enter your passphrase"),
330319
isSecure: true,
331-
showContent: $showPassphrase,
332-
scanTarget: .passphrase
320+
showContent: $showPassphrase
333321
)
334322
}
335323

@@ -504,87 +492,69 @@ struct ExchangeDetailView: View {
504492
text: Binding<String>,
505493
placeholder: String,
506494
isSecure: Bool,
507-
showContent: Binding<Bool> = .constant(true),
508-
scanTarget: CredentialScanTarget? = nil
495+
showContent: Binding<Bool> = .constant(true)
509496
) -> some View {
510497
VStack(alignment: .leading, spacing: Spacing.xs) {
511498
Text(label)
512499
.font(AccBotFonts.caption)
513500
.foregroundStyle(colors.onSurfaceVariant)
514501

515-
HStack(spacing: Spacing.sm) {
516-
HStack(spacing: 0) {
517-
Group {
518-
if isSecure && !showContent.wrappedValue {
519-
SecureField(placeholder, text: text)
520-
} else {
521-
TextField(placeholder, text: text)
522-
}
523-
}
524-
.font(AccBotFonts.mono)
525-
.foregroundStyle(colors.onSurface)
526-
.autocorrectionDisabled()
527-
.textInputAutocapitalization(.never)
528-
529-
// Paste (empty) or Clear (non-empty) button
530-
if text.wrappedValue.isEmpty {
531-
Button {
532-
if let clipboard = UIPasteboard.general.string {
533-
text.wrappedValue = clipboard.trimmingCharacters(in: .whitespacesAndNewlines)
534-
}
535-
} label: {
536-
Image(systemName: "doc.on.clipboard")
537-
.font(AccBotFonts.body)
538-
.foregroundStyle(colors.primary)
539-
}
540-
.buttonStyle(.plain)
541-
.padding(.leading, Spacing.sm)
542-
.accessibilityLabel(String(localized: "Paste"))
502+
HStack(spacing: 0) {
503+
Group {
504+
if isSecure && !showContent.wrappedValue {
505+
SecureField(placeholder, text: text)
543506
} else {
544-
Button {
545-
text.wrappedValue = ""
546-
} label: {
547-
Image(systemName: "xmark.circle.fill")
548-
.font(AccBotFonts.body)
549-
.foregroundStyle(colors.onSurfaceVariant)
550-
}
551-
.buttonStyle(.plain)
552-
.padding(.leading, Spacing.sm)
553-
.accessibilityLabel(String(localized: "Clear"))
507+
TextField(placeholder, text: text)
554508
}
509+
}
510+
.font(AccBotFonts.mono)
511+
.foregroundStyle(colors.onSurface)
512+
.autocorrectionDisabled()
513+
.textInputAutocapitalization(.never)
555514

556-
if isSecure {
557-
Button {
558-
showContent.wrappedValue.toggle()
559-
} label: {
560-
Image(systemName: showContent.wrappedValue ? "eye.slash" : "eye")
561-
.font(AccBotFonts.body)
562-
.foregroundStyle(colors.onSurfaceVariant)
515+
// Paste (empty) or Clear (non-empty) button
516+
if text.wrappedValue.isEmpty {
517+
Button {
518+
if let clipboard = UIPasteboard.general.string {
519+
text.wrappedValue = clipboard.trimmingCharacters(in: .whitespacesAndNewlines)
563520
}
564-
.buttonStyle(.plain)
565-
.padding(.leading, Spacing.sm)
566-
.accessibilityLabel(String(localized: "Toggle secret visibility"))
521+
} label: {
522+
Image(systemName: "doc.on.clipboard")
523+
.font(AccBotFonts.body)
524+
.foregroundStyle(colors.primary)
567525
}
526+
.buttonStyle(.plain)
527+
.padding(.leading, Spacing.sm)
528+
.accessibilityLabel(String(localized: "Paste"))
529+
} else {
530+
Button {
531+
text.wrappedValue = ""
532+
} label: {
533+
Image(systemName: "xmark.circle.fill")
534+
.font(AccBotFonts.body)
535+
.foregroundStyle(colors.onSurfaceVariant)
536+
}
537+
.buttonStyle(.plain)
538+
.padding(.leading, Spacing.sm)
539+
.accessibilityLabel(String(localized: "Clear"))
568540
}
569-
.padding(Spacing.md)
570-
.background(colors.surfaceVariant.opacity(0.3))
571-
.clipShape(RoundedRectangle(cornerRadius: CornerRadius.sm))
572541

573-
if let target = scanTarget {
542+
if isSecure {
574543
Button {
575-
credentials.qrScanTarget = target
576-
credentials.showQrScanner = true
544+
showContent.wrappedValue.toggle()
577545
} label: {
578-
Image(systemName: "qrcode.viewfinder")
579-
.font(AccBotFonts.iconSmall)
580-
.foregroundStyle(colors.primary)
581-
.frame(minWidth: 44, minHeight: 44)
582-
.contentShape(Rectangle())
546+
Image(systemName: showContent.wrappedValue ? "eye.slash" : "eye")
547+
.font(AccBotFonts.body)
548+
.foregroundStyle(colors.onSurfaceVariant)
583549
}
584550
.buttonStyle(.plain)
585-
.accessibilityLabel(String(localized: "Scan QR code for \(label)"))
551+
.padding(.leading, Spacing.sm)
552+
.accessibilityLabel(String(localized: "Toggle secret visibility"))
586553
}
587554
}
555+
.padding(Spacing.md)
556+
.background(colors.surfaceVariant.opacity(0.3))
557+
.clipShape(RoundedRectangle(cornerRadius: CornerRadius.sm))
588558
}
589559
}
590560

accbot-ios/AccBot/cs.lproj/Localizable.strings

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -811,3 +811,39 @@
811811

812812
/* Authentication */
813813
"Authentication is not available on this device. Please set up a device passcode in Settings." = "Ověření není na tomto zařízení k dispozici. Prosím nastavte kód zařízení v Nastavení.";
814+
815+
/* ===== Missing translations — Portfolio, Import, Dashboard ===== */
816+
817+
/* PortfolioView — chart insufficient data */
818+
"You need at least 2 transactions to view the portfolio chart" = "Pro zobrazení grafu portfolia potřebujete alespoň 2 transakce";
819+
"Swipe left or right to scrub through chart data points" = "Přejeďte doleva nebo doprava pro procházení datových bodů grafu";
820+
"Portfolio chart. Value: %@, ROI: %@, %lld transactions. Use legend to toggle series." = "Graf portfolia. Hodnota: %1$@, ROI: %2$@, %3$lld transakcí. Legendou přepínáte série.";
821+
822+
/* DashboardView — execution complete */
823+
"Execution Complete" = "Provedení dokončeno";
824+
825+
/* ImportCsvView — error messages */
826+
"Failed to read the selected file." = "Nepodařilo se přečíst vybraný soubor.";
827+
"Import failed: %@. No transactions were imported." = "Import selhal: %@. Žádné transakce nebyly importovány.";
828+
"No credentials found for %@" = "Přihlašovací údaje pro %@ nenalezeny";
829+
830+
/* ===== Credential form — new per-field & QR buttons ===== */
831+
"Paste" = "Vložit";
832+
"Paste All" = "Vložit vše";
833+
"Scan All" = "Skenovat vše";
834+
"Scan QR" = "Skenovat QR";
835+
"Scan Binance QR" = "Skenovat Binance QR";
836+
"Toggle secret visibility" = "Přepnout viditelnost";
837+
838+
/* ===== Experimental exchanges ===== */
839+
"Experimental Exchanges" = "Experimentální burzy";
840+
"Show additional exchanges that haven't been fully tested" = "Zobrazit další burzy, které nebyly plně otestovány";
841+
"Enable Experimental Exchanges?" = "Povolit experimentální burzy?";
842+
"These exchanges haven't been fully tested with AccBot. Use at your own risk. Please report any issues on GitHub." = "Tyto burzy nebyly plně otestovány s AccBot. Používáte na vlastní riziko. Prosím nahlaste problémy na GitHubu.";
843+
"Enable" = "Povolit";
844+
"EXPERIMENTAL" = "EXPERIMENTÁLNÍ";
845+
846+
/* ===== Onboarding — Exchange Setup ===== */
847+
"Skip Exchange Setup?" = "Přeskočit nastavení burzy?";
848+
"You can add exchanges later in Settings." = "Burzy můžete přidat později v Nastavení.";
849+
"Validate & Connect" = "Ověřit a připojit";

0 commit comments

Comments
 (0)