krz/hutch
an ios client for sourcehut
clone: git clone https://gitbay.org/krz/hutch.git
v2.15.1: Hutch/Views/More/AccountSwitcherView.swift · raw
1import SwiftUI
2
3struct AccountSwitcherView: View {
4 @Environment(AppState.self) private var appState
5 @Environment(\.dismiss) private var dismiss
6
7 @State private var showAddAccount = false
8 @State private var isSwitching = false
9 @State private var switchError: String?
10
11 var body: some View {
12 NavigationStack {
13 List {
14 Section {
15 ForEach(appState.accounts) { account in
16 Button {
17 guard account.id != appState.activeAccountID else { return }
18 switchTo(account)
19 } label: {
20 HStack {
21 Text("~\(account.username)")
22 .foregroundStyle(.primary)
23 Spacer()
24 if account.id == appState.activeAccountID {
25 Image(systemName: "checkmark")
26 .foregroundStyle(.tint)
27 }
28 }
29 }
30 .disabled(isSwitching)
31 }
32 .onDelete { indexSet in
33 for index in indexSet {
34 let account = appState.accounts[index]
35 Task { await appState.removeAccount(id: account.id) }
36 }
37 }
38 }
39
40 Section {
41 Button {
42 showAddAccount = true
43 } label: {
44 Label("Add Account", systemImage: "plus.circle")
45 }
46 .disabled(isSwitching)
47 }
48 }
49 .navigationTitle("Accounts")
50 .navigationBarTitleDisplayMode(.inline)
51 .toolbar {
52 ToolbarItem(placement: .confirmationAction) {
53 Button("Done") { dismiss() }
54 }
55 }
56 .overlay {
57 if isSwitching {
58 ZStack {
59 Color.black.opacity(0.25).ignoresSafeArea()
60 ProgressView("Switching…")
61 .padding()
62 .background(.regularMaterial, in: RoundedRectangle(cornerRadius: 12))
63 }
64 }
65 }
66 .alert("Switch Failed", isPresented: Binding(
67 get: { switchError != nil },
68 set: { if !$0 { switchError = nil } }
69 )) {
70 Button("OK") { switchError = nil }
71 } message: {
72 Text(switchError ?? "")
73 }
74 .sheet(isPresented: $showAddAccount) {
75 AddAccountView()
76 }
77 }
78 }
79
80 private func switchTo(_ account: AccountEntry) {
81 isSwitching = true
82 Task {
83 do {
84 try await appState.switchAccount(to: account.id)
85 dismiss()
86 } catch {
87 switchError = error.localizedDescription
88 }
89 isSwitching = false
90 }
91 }
92}