diff --git a/Yattee/Views/Settings/DeArrowSettingsView.swift b/Yattee/Views/Settings/DeArrowSettingsView.swift index a2aec869..4b2ee0ef 100644 --- a/Yattee/Views/Settings/DeArrowSettingsView.swift +++ b/Yattee/Views/Settings/DeArrowSettingsView.swift @@ -11,7 +11,7 @@ struct DeArrowSettingsView: View { @Environment(\.appEnvironment) private var appEnvironment var body: some View { - Form { + SettingsFormContainer { if let settings = appEnvironment?.settingsManager { // Enable/Disable toggle EnableSection(settings: settings) @@ -44,13 +44,11 @@ private struct EnableSection: View { @Bindable var settings: SettingsManager var body: some View { - Section { + SettingsFormSection(footer: "settings.deArrow.footer") { Toggle( String(localized: "settings.deArrow.enabled"), isOn: $settings.deArrowEnabled ) - } footer: { - Text(String(localized: "settings.deArrow.footer")) } } } @@ -61,7 +59,7 @@ private struct OptionsSection: View { @Bindable var settings: SettingsManager var body: some View { - Section(String(localized: "settings.deArrow.options.header")) { + SettingsFormSection("settings.deArrow.options.header") { Toggle( String(localized: "settings.deArrow.replaceTitles"), isOn: $settings.deArrowReplaceTitles @@ -84,7 +82,7 @@ private struct AdvancedSection: View { @State private var thumbnailAPIURLText: String = "" var body: some View { - Section { + SettingsFormSection("settings.deArrow.advanced.header", footer: "settings.deArrow.apiURL.footer") { TextField( String(localized: "settings.deArrow.apiURL"), text: $apiURLText, @@ -140,10 +138,6 @@ private struct AdvancedSection: View { syncAPIURLs() } } - } header: { - Text(String(localized: "settings.deArrow.advanced.header")) - } footer: { - Text(String(localized: "settings.deArrow.apiURL.footer")) } .onAppear { let currentAPIURL = settings.deArrowAPIURL @@ -169,7 +163,7 @@ private struct AdvancedSection: View { private struct AboutSection: View { var body: some View { - Section(String(localized: "settings.deArrow.about.header")) { + SettingsFormSection("settings.deArrow.about.header") { VStack(alignment: .leading, spacing: 8) { Text(String(localized: "settings.deArrow.about.description")) .font(.callout) diff --git a/Yattee/Views/Settings/MacOSSettings.swift b/Yattee/Views/Settings/MacOSSettings.swift index 31292b84..d3203093 100644 --- a/Yattee/Views/Settings/MacOSSettings.swift +++ b/Yattee/Views/Settings/MacOSSettings.swift @@ -139,18 +139,21 @@ struct SettingsFormSection: View { /// On macOS it renders as a plain full-width list row with a trailing /// chevron, matching the native macOS System Settings look. On iOS/tvOS /// it renders as a standard `NavigationLink` with a `Label`. -struct SettingsNavigationRow: View { +struct SettingsNavigationRow: View { let titleKey: LocalizedStringKey let systemImage: String + @ViewBuilder var trailing: () -> Trailing @ViewBuilder var destination: () -> Destination init( _ titleKey: LocalizedStringKey, systemImage: String, + @ViewBuilder trailing: @escaping () -> Trailing = { EmptyView() }, @ViewBuilder destination: @escaping () -> Destination ) { self.titleKey = titleKey self.systemImage = systemImage + self.trailing = trailing self.destination = destination } @@ -162,6 +165,8 @@ struct SettingsNavigationRow: View { HStack(spacing: 8) { Label(titleKey, systemImage: systemImage) Spacer() + trailing() + .foregroundStyle(.secondary) Image(systemName: "chevron.right") .font(.caption) .foregroundStyle(.tertiary) @@ -169,7 +174,12 @@ struct SettingsNavigationRow: View { .frame(maxWidth: .infinity, alignment: .leading) .contentShape(Rectangle()) #else - Label(titleKey, systemImage: systemImage) + HStack { + Label(titleKey, systemImage: systemImage) + Spacer() + trailing() + .foregroundStyle(.secondary) + } #endif } #if os(macOS) diff --git a/Yattee/Views/Settings/ReturnYouTubeDislikeSettingsView.swift b/Yattee/Views/Settings/ReturnYouTubeDislikeSettingsView.swift index bd371898..4c717839 100644 --- a/Yattee/Views/Settings/ReturnYouTubeDislikeSettingsView.swift +++ b/Yattee/Views/Settings/ReturnYouTubeDislikeSettingsView.swift @@ -11,20 +11,16 @@ struct ReturnYouTubeDislikeSettingsView: View { @Environment(\.appEnvironment) private var appEnvironment var body: some View { - Form { + SettingsFormContainer { if let settings = appEnvironment?.settingsManager { - // Enable/Disable toggle - Section { + SettingsFormSection(footer: "settings.returnYouTubeDislike.footer") { Toggle( String(localized: "settings.returnYouTubeDislike.enabled"), isOn: Bindable(settings).returnYouTubeDislikeEnabled ) - } footer: { - Text(String(localized: "settings.returnYouTubeDislike.footer")) } - // About section - Section(String(localized: "settings.returnYouTubeDislike.about.header")) { + SettingsFormSection("settings.returnYouTubeDislike.about.header") { VStack(alignment: .leading, spacing: 8) { Text(String(localized: "settings.returnYouTubeDislike.about.description")) .font(.callout) diff --git a/Yattee/Views/Settings/SponsorBlockSettingsView.swift b/Yattee/Views/Settings/SponsorBlockSettingsView.swift index 09fe0a17..2687047f 100644 --- a/Yattee/Views/Settings/SponsorBlockSettingsView.swift +++ b/Yattee/Views/Settings/SponsorBlockSettingsView.swift @@ -11,7 +11,7 @@ struct SponsorBlockSettingsView: View { @Environment(\.appEnvironment) private var appEnvironment var body: some View { - Form { + SettingsFormContainer { if let settings = appEnvironment?.settingsManager { // Enable/Disable toggle EnableSection(settings: settings) @@ -44,13 +44,11 @@ private struct EnableSection: View { @Bindable var settings: SettingsManager var body: some View { - Section { + SettingsFormSection(footer: "settings.sponsorBlock.footer") { Toggle( String(localized: "settings.sponsorBlock.enabled"), isOn: $settings.sponsorBlockEnabled ) - } footer: { - Text(String(localized: "settings.sponsorBlock.footer")) } } } @@ -61,7 +59,7 @@ private struct CategoriesSection: View { @Bindable var settings: SettingsManager var body: some View { - Section { + SettingsFormSection("settings.sponsorBlock.categories.header", footer: "settings.sponsorBlock.categories.footer") { ForEach(SponsorBlockCategory.allCases, id: \.self) { category in CategoryToggleRow( category: category, @@ -77,10 +75,6 @@ private struct CategoriesSection: View { } ) } - } header: { - Text(String(localized: "settings.sponsorBlock.categories.header")) - } footer: { - Text(String(localized: "settings.sponsorBlock.categories.footer")) } } } @@ -92,7 +86,7 @@ private struct AdvancedSection: View { @State private var apiURLText: String = "" var body: some View { - Section { + SettingsFormSection("settings.sponsorBlock.advanced.header", footer: "settings.sponsorBlock.apiURL.footer") { TextField( String(localized: "settings.sponsorBlock.apiURL"), text: $apiURLText, @@ -118,10 +112,6 @@ private struct AdvancedSection: View { settings.sponsorBlockAPIURL = SettingsManager.defaultSponsorBlockAPIURL } } - } header: { - Text(String(localized: "settings.sponsorBlock.advanced.header")) - } footer: { - Text(String(localized: "settings.sponsorBlock.apiURL.footer")) } .onAppear { let currentURL = settings.sponsorBlockAPIURL @@ -136,7 +126,7 @@ private struct AdvancedSection: View { private struct AboutSection: View { var body: some View { - Section(String(localized: "settings.sponsorBlock.about.header")) { + SettingsFormSection("settings.sponsorBlock.about.header") { VStack(alignment: .leading, spacing: 8) { Text(String(localized: "settings.sponsorBlock.about.description")) .font(.callout) diff --git a/Yattee/Views/Settings/YouTubeEnhancementsSettingsView.swift b/Yattee/Views/Settings/YouTubeEnhancementsSettingsView.swift index eaee14c8..b91ff0b1 100644 --- a/Yattee/Views/Settings/YouTubeEnhancementsSettingsView.swift +++ b/Yattee/Views/Settings/YouTubeEnhancementsSettingsView.swift @@ -11,7 +11,7 @@ struct YouTubeEnhancementsSettingsView: View { @Environment(\.appEnvironment) private var appEnvironment var body: some View { - Form { + SettingsFormContainer { if let settings = appEnvironment?.settingsManager { SponsorBlockSection(settings: settings) ReturnYouTubeDislikeSection(settings: settings) @@ -33,21 +33,18 @@ private struct SponsorBlockSection: View { @Bindable var settings: SettingsManager var body: some View { - Section { - NavigationLink { - SponsorBlockSettingsView() - } label: { - HStack { - Label(String(localized: "settings.sponsorBlock.sectionTitle"), systemImage: "forward") - Spacer() + SettingsFormSection(footer: "settings.youtubeEnhancements.sponsorBlock.footer") { + SettingsNavigationRow( + "settings.sponsorBlock.sectionTitle", + systemImage: "forward", + trailing: { Text(settings.sponsorBlockEnabled ? String(localized: "common.enabled") : String(localized: "common.disabled")) - .foregroundStyle(.secondary) } + ) { + SponsorBlockSettingsView() } - } footer: { - Text(String(localized: "settings.youtubeEnhancements.sponsorBlock.footer")) } } } @@ -58,21 +55,18 @@ private struct ReturnYouTubeDislikeSection: View { @Bindable var settings: SettingsManager var body: some View { - Section { - NavigationLink { - ReturnYouTubeDislikeSettingsView() - } label: { - HStack { - Label(String(localized: "settings.returnYouTubeDislike.sectionTitle"), systemImage: "hand.thumbsdown") - Spacer() + SettingsFormSection(footer: "settings.youtubeEnhancements.returnYouTubeDislike.footer") { + SettingsNavigationRow( + "settings.returnYouTubeDislike.sectionTitle", + systemImage: "hand.thumbsdown", + trailing: { Text(settings.returnYouTubeDislikeEnabled ? String(localized: "common.enabled") : String(localized: "common.disabled")) - .foregroundStyle(.secondary) } + ) { + ReturnYouTubeDislikeSettingsView() } - } footer: { - Text(String(localized: "settings.youtubeEnhancements.returnYouTubeDislike.footer")) } } } @@ -83,21 +77,18 @@ private struct DeArrowSection: View { @Bindable var settings: SettingsManager var body: some View { - Section { - NavigationLink { - DeArrowSettingsView() - } label: { - HStack { - Label(String(localized: "settings.deArrow.sectionTitle"), systemImage: "textformat") - Spacer() + SettingsFormSection(footer: "settings.youtubeEnhancements.deArrow.footer") { + SettingsNavigationRow( + "settings.deArrow.sectionTitle", + systemImage: "textformat", + trailing: { Text(settings.deArrowEnabled ? String(localized: "common.enabled") : String(localized: "common.disabled")) - .foregroundStyle(.secondary) } + ) { + DeArrowSettingsView() } - } footer: { - Text(String(localized: "settings.youtubeEnhancements.deArrow.footer")) } } }