mirror of
https://github.com/yattee/yattee.git
synced 2026-10-23 13:12:53 +00:00
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.
48 lines
1.6 KiB
Swift
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
|
|
}
|
|
}
|
|
}
|