From b413648ab960147f031bac4773524436f2361848 Mon Sep 17 00:00:00 2001 From: Arkadiusz Fal Date: Wed, 16 Sep 2026 22:45:41 +0200 Subject: [PATCH] Hold the Accounts settings entry until a source can hold an account --- Yattee/Views/Settings/AccountsListView.swift | 14 +++++ Yattee/Views/Settings/SettingsView.swift | 54 ++++++++++++-------- 2 files changed, 47 insertions(+), 21 deletions(-) diff --git a/Yattee/Views/Settings/AccountsListView.swift b/Yattee/Views/Settings/AccountsListView.swift index dd6604c0..25bba578 100644 --- a/Yattee/Views/Settings/AccountsListView.swift +++ b/Yattee/Views/Settings/AccountsListView.swift @@ -466,6 +466,20 @@ struct AccountsListView: View { return parts.joined(separator: " · ") } + /// Whether Settings should offer the entry at all. + /// + /// With no Invidious/Piped source added there is nothing this screen can + /// do but explain itself, so the row waits for the first account-capable + /// source. Existing accounts keep it visible regardless — an orphan whose + /// source was deleted can only be cleaned up from here. + @MainActor + static func showsSettingsEntry(in appEnvironment: AppEnvironment?) -> Bool { + guard let appEnvironment else { return false } + + return appEnvironment.instancesManager.hasAccountCapableInstances + || !appEnvironment.accountsManager.accounts.isEmpty + } + /// Whether the settings entry should carry an attention badge. /// /// Both states the user can only clear from this screen: an orphan nothing diff --git a/Yattee/Views/Settings/SettingsView.swift b/Yattee/Views/Settings/SettingsView.swift index b370dafa..5e34a685 100644 --- a/Yattee/Views/Settings/SettingsView.swift +++ b/Yattee/Views/Settings/SettingsView.swift @@ -31,10 +31,18 @@ struct SettingsView: View { // MARK: - macOS Settings #if os(macOS) + /// Accounts stays out of the list until a source that can hold one exists + /// (or an account survives its source and needs cleaning up). + private var visibleSections: [SettingsSection] { + SettingsSection.allCases.filter { + $0 != .accounts || AccountsListView.showsSettingsEntry(in: appEnvironment) + } + } + private var macOSSettings: some View { NavigationSplitView { VStack(spacing: 0) { - List(SettingsSection.allCases, selection: $selectedSection) { section in + List(visibleSections, selection: $selectedSection) { section in HStack { Label(section.title, systemImage: section.icon) @@ -138,19 +146,21 @@ struct SettingsView: View { } .accessibilityIdentifier("settings.row.sources") - NavigationLink { - AccountsListView() - } label: { - HStack { - Label(String(localized: "accounts.title"), systemImage: "person.crop.circle") - Spacer() - if AccountsListView.needsAttention(in: appEnvironment) { - Image(systemName: "exclamationmark.circle.fill") - .foregroundStyle(.orange) + if AccountsListView.showsSettingsEntry(in: appEnvironment) { + NavigationLink { + AccountsListView() + } label: { + HStack { + Label(String(localized: "accounts.title"), systemImage: "person.crop.circle") + Spacer() + if AccountsListView.needsAttention(in: appEnvironment) { + Image(systemName: "exclamationmark.circle.fill") + .foregroundStyle(.orange) + } } } + .accessibilityIdentifier("settings.row.accounts") } - .accessibilityIdentifier("settings.row.accounts") NavigationLink { TVSidebarDetailContainer(systemImage: "icloud", title: String(localized: "settings.icloud.title")) { iCloudSettingsView() } @@ -254,19 +264,21 @@ struct SettingsView: View { } .accessibilityIdentifier("settings.row.sources") - NavigationLink { - AccountsListView() - } label: { - HStack { - Label(String(localized: "accounts.title"), systemImage: "person.crop.circle") - Spacer() - if AccountsListView.needsAttention(in: appEnvironment) { - Image(systemName: "exclamationmark.circle.fill") - .foregroundStyle(.orange) + if AccountsListView.showsSettingsEntry(in: appEnvironment) { + NavigationLink { + AccountsListView() + } label: { + HStack { + Label(String(localized: "accounts.title"), systemImage: "person.crop.circle") + Spacer() + if AccountsListView.needsAttention(in: appEnvironment) { + Image(systemName: "exclamationmark.circle.fill") + .foregroundStyle(.orange) + } } } + .accessibilityIdentifier("settings.row.accounts") } - .accessibilityIdentifier("settings.row.accounts") } Section {