Give Monero sync its own section and consolidate the wallet buttons
This commit is contained in:
@@ -259,3 +259,52 @@ struct ScreenHeader: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
/// Monero's chain sync as its own section, rather than buried in the wallet card.
|
||||
struct SyncCard: View {
|
||||
@EnvironmentObject private var model: AppModel
|
||||
|
||||
var body: some View {
|
||||
Card {
|
||||
VStack(alignment: .leading, spacing: 12) {
|
||||
HStack {
|
||||
Text("Sync")
|
||||
.font(.system(size: 13, weight: .semibold))
|
||||
.foregroundStyle(Theme.muted)
|
||||
Spacer()
|
||||
if let status = model.syncStatus { SyncBadge(status: status) }
|
||||
}
|
||||
|
||||
if let status = model.syncStatus {
|
||||
SyncProgress(status: status, eta: model.syncEta)
|
||||
} else {
|
||||
Text("Sync status is not available yet.")
|
||||
.font(.system(size: 11))
|
||||
.foregroundStyle(Theme.muted)
|
||||
}
|
||||
|
||||
SecondaryButton(title: model.syncStatus?.syncing == true ? "Syncing…" : "Sync now") {
|
||||
Task { await model.startMoneroSync() }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A small circular icon button for utility actions (refresh, delete, …).
|
||||
struct IconButton: View {
|
||||
var systemName: String
|
||||
var destructive = false
|
||||
var action: () -> Void
|
||||
|
||||
var body: some View {
|
||||
Button(action: action) {
|
||||
Image(systemName: systemName)
|
||||
.font(.system(size: 14, weight: .semibold))
|
||||
.foregroundStyle(destructive ? Theme.danger : Theme.muted)
|
||||
.frame(width: 42, height: 42)
|
||||
.background(Theme.surface)
|
||||
.overlay(Circle().stroke(Theme.border))
|
||||
.clipShape(Circle())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,7 +91,6 @@ struct RootView: View {
|
||||
struct HomeView: View {
|
||||
@EnvironmentObject private var model: AppModel
|
||||
@Binding var route: Route
|
||||
@State private var showDeleteConfirm = false
|
||||
@State private var selectedTransaction: TransactionRecord?
|
||||
@State private var showSettings = false
|
||||
@State private var qrAddress: AddressQR?
|
||||
@@ -137,19 +136,6 @@ struct HomeView: View {
|
||||
SettingsView()
|
||||
.environmentObject(model)
|
||||
}
|
||||
.confirmationDialog("Delete this wallet?",
|
||||
isPresented: $showDeleteConfirm,
|
||||
titleVisibility: .visible) {
|
||||
Button("Delete wallet", role: .destructive) {
|
||||
Task {
|
||||
await model.deleteWallet()
|
||||
route = .home
|
||||
}
|
||||
}
|
||||
Button("Cancel", role: .cancel) {}
|
||||
} message: {
|
||||
Text("The keys stored on this device are removed. Make sure your recovery seed is backed up.")
|
||||
}
|
||||
}
|
||||
|
||||
private var header: some View {
|
||||
@@ -189,9 +175,6 @@ struct HomeView: View {
|
||||
.font(.system(size: 16, weight: .semibold))
|
||||
.foregroundStyle(Theme.text)
|
||||
Spacer()
|
||||
if model.chain == .xmr, let status = model.syncStatus {
|
||||
SyncBadge(status: status)
|
||||
}
|
||||
}
|
||||
|
||||
if model.chain == .xmr, !model.moneroAccounts.isEmpty {
|
||||
@@ -223,25 +206,25 @@ struct HomeView: View {
|
||||
AddressRow(address: model.displayAddress)
|
||||
}
|
||||
|
||||
if model.chain == .xmr, let status = model.syncStatus {
|
||||
SyncProgress(status: status, eta: model.syncEta)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if model.chain == .xmr {
|
||||
SyncCard()
|
||||
}
|
||||
|
||||
HStack(spacing: 10) {
|
||||
PrimaryButton(title: "Send") { route = .send }
|
||||
SecondaryButton(title: "Receive") { route = .receive }
|
||||
SecondaryButton(title: "Swap") { route = .swap }
|
||||
}
|
||||
|
||||
if model.chain == .xmr {
|
||||
HStack(spacing: 10) {
|
||||
SecondaryButton(title: model.syncStatus?.syncing == true ? "Syncing…" : "Sync now") {
|
||||
Task { await model.startMoneroSync() }
|
||||
}
|
||||
SecondaryButton(title: "Addresses") { route = .accounts }
|
||||
HStack(spacing: 12) {
|
||||
IconButton(systemName: "arrow.clockwise") { Task { await model.refresh(force: true) } }
|
||||
if model.chain == .xmr {
|
||||
IconButton(systemName: "person.2.fill") { route = .accounts }
|
||||
}
|
||||
Spacer()
|
||||
}
|
||||
|
||||
if model.chain == .xrp, model.moneroReady, let status = model.syncStatus, status.syncing {
|
||||
@@ -264,10 +247,6 @@ struct HomeView: View {
|
||||
}
|
||||
}
|
||||
|
||||
HStack(spacing: 10) {
|
||||
SecondaryButton(title: "Refresh") { Task { await model.refresh(force: true) } }
|
||||
SecondaryButton(title: "Delete") { showDeleteConfirm = true }
|
||||
}
|
||||
|
||||
if !model.transactions.isEmpty {
|
||||
Card {
|
||||
|
||||
@@ -3,6 +3,7 @@ import SwiftUI
|
||||
struct SettingsView: View {
|
||||
@EnvironmentObject private var model: AppModel
|
||||
@Environment(\.dismiss) private var dismiss
|
||||
@State private var showDeleteConfirm = false
|
||||
|
||||
private let currencies = ["USD", "MYR", "JPY"]
|
||||
|
||||
@@ -63,11 +64,46 @@ struct SettingsView: View {
|
||||
}
|
||||
}
|
||||
|
||||
Card {
|
||||
VStack(alignment: .leading, spacing: 10) {
|
||||
Text("Danger zone")
|
||||
.font(.system(size: 13, weight: .semibold))
|
||||
.foregroundStyle(Theme.muted)
|
||||
Button {
|
||||
showDeleteConfirm = true
|
||||
} label: {
|
||||
Text("Delete this wallet")
|
||||
.font(.system(size: 15, weight: .semibold))
|
||||
.foregroundStyle(Theme.danger)
|
||||
.frame(maxWidth: .infinity)
|
||||
.padding(.vertical, 14)
|
||||
.background(Theme.danger.opacity(0.12))
|
||||
.clipShape(RoundedRectangle(cornerRadius: 14, style: .continuous))
|
||||
}
|
||||
Text("Removes the wallet from this device. Your recovery phrase is the only way to get it back.")
|
||||
.font(.system(size: 11))
|
||||
.foregroundStyle(Theme.muted)
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(minLength: 0)
|
||||
}
|
||||
.padding(.horizontal, 20)
|
||||
.padding(.top, 12)
|
||||
}
|
||||
.preferredColorScheme(.dark)
|
||||
.confirmationDialog("Delete this wallet?",
|
||||
isPresented: $showDeleteConfirm,
|
||||
titleVisibility: .visible) {
|
||||
Button("Delete wallet", role: .destructive) {
|
||||
Task {
|
||||
await model.deleteWallet()
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
Button("Cancel", role: .cancel) {}
|
||||
} message: {
|
||||
Text("The keys stored on this device are removed. Make sure your recovery phrase is backed up.")
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user