From ee9f2904aa319231b7047fca3cb069f0c07019cd Mon Sep 17 00:00:00 2001 From: Christian Cleberg Date: Sun, 12 Apr 2026 23:19:20 -0500 Subject: feat: add multi-account support Implements: https://todo.sr.ht/~ccleberg/hutch/49 Implements: https://todo.sr.ht/~ccleberg/hutch/50 Implements: https://todo.sr.ht/~ccleberg/hutch/51 --- Hutch/Views/More/AccountSwitcherView.swift | 49 +++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 7 deletions(-) (limited to 'Hutch/Views/More/AccountSwitcherView.swift') diff --git a/Hutch/Views/More/AccountSwitcherView.swift b/Hutch/Views/More/AccountSwitcherView.swift index aefcc82..5fde9c5 100644 --- a/Hutch/Views/More/AccountSwitcherView.swift +++ b/Hutch/Views/More/AccountSwitcherView.swift @@ -7,21 +7,35 @@ struct AccountSwitcherView: View { @State private var showAddAccount = false @State private var isSwitching = false @State private var switchError: String? + @State private var pendingRemoval: AccountEntry? var body: some View { NavigationStack { List { Section { ForEach(appState.accounts) { account in + let isActive = account.id == appState.activeAccountID Button { - guard account.id != appState.activeAccountID else { return } + guard !isActive else { return } switchTo(account) } label: { - HStack { - Text("~\(account.username)") - .foregroundStyle(.primary) + HStack(spacing: 12) { + if isActive { + Image(systemName: "person.crop.circle.fill") + .foregroundStyle(.tint) + } else { + Image(systemName: "person.crop.circle") + .foregroundStyle(.secondary) + } + VStack(alignment: .leading, spacing: 2) { + Text("~\(account.username)") + .foregroundStyle(.primary) + Text(isActive ? "Active Account" : "Tap to switch") + .font(.caption) + .foregroundStyle(.secondary) + } Spacer() - if account.id == appState.activeAccountID { + if isActive { Image(systemName: "checkmark") .foregroundStyle(.tint) } @@ -31,8 +45,7 @@ struct AccountSwitcherView: View { } .onDelete { indexSet in for index in indexSet { - let account = appState.accounts[index] - Task { await appState.removeAccount(id: account.id) } + pendingRemoval = appState.accounts[index] } } } @@ -71,6 +84,28 @@ struct AccountSwitcherView: View { } message: { Text(switchError ?? "") } + .alert( + "Remove Account?", + isPresented: Binding( + get: { pendingRemoval != nil }, + set: { isPresented in + if !isPresented { + pendingRemoval = nil + } + } + ) + ) { + Button("Cancel", role: .cancel) {} + Button("Remove", role: .destructive) { + guard let pendingRemoval else { return } + Task { await appState.removeAccount(id: pendingRemoval.id) } + self.pendingRemoval = nil + } + } message: { + if let pendingRemoval { + Text("~\(pendingRemoval.username) and its isolated local cache will be removed from this device.") + } + } .sheet(isPresented: $showAddAccount) { AddAccountView() } -- cgit v1.2.3