Files
yattee/Yattee/Views/Components/AccountStatusBadge.swift
Arkadiusz Fal 69179c9fe9 Give every login a screen, including the ones with nowhere to go
An account whose source is gone was listed nowhere: `orphanedAccounts` had
no readers, and the credential behind it could not be reached at all —
`AppEnvironment.accountCredentialsManager(for:)` resolves the store from
the account's instance, and an orphan has none. The new accounts screen
lists them and removes them by account ID, asking every account-keyed
store because the backend is no longer knowable. The pre-revamp
instance-keyed item is deliberately left behind: identifying it needs the
instance too.

Deleting a source has always signed out and removed the accounts on it.
Both confirmations now say so, and name them.

The sign-in that files a credential against an account is now one
implementation instead of a private method on the source editor, so the
accounts screen and the new optional sign-in step after adding a source
attach a login exactly as the editor does. Extracted verbatim — the
identity-scope guard, the account re-resolve, the write-then-read-back
and the rollback are what keep a half-written login from looking real.

Signing out from the per-instance section now asks first, and both
sign-out paths run one cascade rather than two copies of it.
2026-09-04 23:35:51 +02:00

48 lines
1.6 KiB
Swift

//
// AccountStatusBadge.swift
// Yattee
//
// How an account's status reads, wherever accounts are listed.
//
import SwiftUI
/// An account's status as one line of caption text.
///
/// Shared so a status says the same thing in every list it appears in — the
/// per-instance section, the accounts screen and the context switcher all name
/// the same states, and one added to `AccountStatus` is named once rather than
/// three times.
struct AccountStatusBadge: View {
let status: AccountStatus
var body: some View {
Text(Self.text(for: status))
.font(.caption)
.foregroundStyle(Self.color(for: status))
}
static func text(for status: AccountStatus) -> String {
switch status {
case .checking: String(localized: "accounts.status.checking")
case .signedIn: String(localized: "accounts.status.signedIn")
case .credentialMissing: String(localized: "accounts.status.credentialMissing")
case .credentialRejected: String(localized: "accounts.status.credentialRejected")
case .unreachable: String(localized: "accounts.status.unreachable")
}
}
/// Only the states the user has to act on are coloured. A credential that
/// never arrived on this device is ordinary — tvOS never receives them at
/// all — so it reads as secondary rather than as a fault.
static func color(for status: AccountStatus) -> Color {
switch status {
case .checking: .secondary
case .signedIn: .secondary
case .credentialMissing: .secondary
case .credentialRejected: .red
case .unreachable: .orange
}
}
}