mirror of
https://github.com/yattee/yattee.git
synced 2026-10-23 05:02:53 +00:00
Tell the views when a credential is replaced
Signing in again as a different person on the same server changes neither the account ID, the context, nor usually the status — so nothing the views observe moved, and the previous user's subscriptions and feed stayed on screen while actions went out under the new credential. There is now a notification for exactly that, and the subscriptions view and the instance browser discard and reload on it. An account deleted after its instance disappeared retires its legacy Keychain item too. Identifying that item needs the instance, but checking it does not: the adoption marker is specific to service, account, scope and the exact secret, so asking both managers retires it if either owns it and does nothing otherwise.
This commit is contained in:
@@ -892,5 +892,9 @@ extension Notification.Name {
|
||||
static let accountsDidChange = Notification.Name("stream.yattee.accountsDidChange")
|
||||
/// An account's usability changed — not the list of accounts.
|
||||
static let accountStatusesDidChange = Notification.Name("stream.yattee.accountStatusesDidChange")
|
||||
/// An account's stored credential was replaced. The account itself is
|
||||
/// unchanged, so anything holding data fetched with the old one has to be
|
||||
/// told: it may belong to an entirely different person on that server.
|
||||
static let accountCredentialDidChange = Notification.Name("stream.yattee.accountCredentialDidChange")
|
||||
static let dataContextDidChange = Notification.Name("stream.yattee.dataContextDidChange")
|
||||
}
|
||||
|
||||
@@ -441,6 +441,17 @@ final class AppEnvironment {
|
||||
guard let account, let credentials = self.accountCredentialsManager(for: account) else {
|
||||
self.invidiousCredentialsManager.deleteCredential(forAccountID: accountID)
|
||||
self.pipedCredentialsManager.deleteCredential(forAccountID: accountID)
|
||||
|
||||
// The unscoped legacy item needs the instance to be identified,
|
||||
// but not to be *checked*: the adoption marker is specific to
|
||||
// service, account, scope and the exact secret, so asking both
|
||||
// managers retires it if either owns it and does nothing
|
||||
// otherwise. Worth asking — this account was explicitly deleted,
|
||||
// and the instance may simply have gone first.
|
||||
if let account {
|
||||
self.invidiousCredentialsManager.deleteLegacyCredentialIfOwned(for: account)
|
||||
self.pipedCredentialsManager.deleteLegacyCredentialIfOwned(for: account)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -696,6 +707,12 @@ final class AppEnvironment {
|
||||
if accountsManager.currentContext == .account(account.id) {
|
||||
SubscriptionFeedCache.shared.handleAccountChange()
|
||||
}
|
||||
|
||||
// Views hold their own copies of this account's data, and signing in
|
||||
// again as somebody else changes neither the account ID, the context,
|
||||
// nor usually the status — so nothing they observe would move. Told
|
||||
// explicitly instead.
|
||||
NotificationCenter.default.post(name: .accountCredentialDidChange, object: nil)
|
||||
}
|
||||
|
||||
/// Drops everything cached for whichever account was being shown.
|
||||
|
||||
@@ -455,6 +455,13 @@ struct InstanceBrowseView: View {
|
||||
refreshLoginState()
|
||||
Task { await startContentLoad() }
|
||||
}
|
||||
// Same reason, without the context moving: the credential behind this
|
||||
// instance's account was replaced.
|
||||
.onReceive(NotificationCenter.default.publisher(for: .accountCredentialDidChange)) { _ in
|
||||
discardAccountScopedContent()
|
||||
refreshLoginState()
|
||||
Task { await startContentLoad() }
|
||||
}
|
||||
.onChange(of: selectedTab) { _, _ in
|
||||
isLoading = true
|
||||
errorMessage = nil
|
||||
|
||||
@@ -527,6 +527,12 @@ struct SubscriptionsView: View {
|
||||
.onReceive(NotificationCenter.default.publisher(for: .instancesDidChange)) { _ in
|
||||
reloadIfEffectiveContextMoved()
|
||||
}
|
||||
// Signing in again keeps the same account and context, so
|
||||
// nothing above would fire — but the data on screen may now
|
||||
// belong to a different person on that server.
|
||||
.onReceive(NotificationCenter.default.publisher(for: .accountCredentialDidChange)) { _ in
|
||||
reloadForContextChange()
|
||||
}
|
||||
.task(id: instanceConfigurationID) {
|
||||
LoggingService.shared.debug("SubscriptionsView task triggered, instanceConfigurationID: \(instanceConfigurationID)", category: .general)
|
||||
await loadSubscriptionsAsync()
|
||||
|
||||
Reference in New Issue
Block a user