mirror of
https://github.com/yattee/yattee.git
synced 2026-07-20 14:22:02 +00:00
The NavigationStack-level background wasn't enough: macOS draws its own translucent material behind pushed navigation pages, and Form/List containers draw a translucent scroll background on top of anything placed behind them, so several pages kept the wallpaper-tinted look. Bake the opaque background into SettingsFormContainer (covers all pages built on it, pushed or not) and add opaqueSettingsFormBackground(), which hides the container's scroll background before applying the opaque one, to every macOS-reachable Form/List settings page: player controls and its sub-editors, sidebar settings, edit source, legacy data import, subscription/playlist import, customize home and its shortcut style page, and the log viewer. Contributors, translators and the remote control device page get the plain opaque background. Claude-Session: https://claude.ai/code/session_0154KH8RAVAvm6iVanhmoW8o
200 lines
6.3 KiB
Swift
200 lines
6.3 KiB
Swift
//
|
|
// ProgressBarSettingsView.swift
|
|
// Yattee
|
|
//
|
|
// View for configuring progress bar appearance settings.
|
|
//
|
|
|
|
import SwiftUI
|
|
|
|
/// View for configuring progress bar settings.
|
|
struct ProgressBarSettingsView: View {
|
|
@Bindable var viewModel: PlayerControlsSettingsViewModel
|
|
|
|
@State private var playedColor: Color = .red
|
|
@State private var showChapters: Bool = true
|
|
@State private var showSponsorSegments: Bool = true
|
|
@State private var categorySettings: [String: SponsorBlockCategorySettings] = [:]
|
|
|
|
var body: some View {
|
|
Form {
|
|
appearanceSection
|
|
chaptersSection
|
|
sponsorSegmentsSection
|
|
|
|
if showSponsorSegments {
|
|
segmentColorsSection
|
|
}
|
|
}
|
|
.navigationTitle(String(localized: "settings.playerControls.progressBar"))
|
|
#if os(iOS)
|
|
.navigationBarTitleDisplayMode(.inline)
|
|
#elseif os(macOS)
|
|
.formStyle(.grouped)
|
|
#endif
|
|
.opaqueSettingsFormBackground()
|
|
.onAppear {
|
|
loadSettings()
|
|
}
|
|
}
|
|
|
|
// MARK: - Appearance Section
|
|
|
|
private var appearanceSection: some View {
|
|
Section {
|
|
#if !os(tvOS)
|
|
ColorPicker(
|
|
String(localized: "settings.playerControls.progressBar.playedColor"),
|
|
selection: $playedColor,
|
|
supportsOpacity: false
|
|
)
|
|
.onChange(of: playedColor) { _, newValue in
|
|
viewModel.updateProgressBarSettingsSync { $0.playedColor = CodableColor(newValue) }
|
|
}
|
|
.disabled(!viewModel.canEditActivePreset)
|
|
#else
|
|
HStack {
|
|
Text(String(localized: "settings.playerControls.progressBar.playedColor"))
|
|
Spacer()
|
|
Circle()
|
|
.fill(playedColor)
|
|
.frame(width: 24, height: 24)
|
|
}
|
|
#endif
|
|
} header: {
|
|
Text(String(localized: "settings.playerControls.progressBar.appearance"))
|
|
}
|
|
}
|
|
|
|
// MARK: - Chapters Section
|
|
|
|
private var chaptersSection: some View {
|
|
Section {
|
|
Toggle(
|
|
String(localized: "settings.playerControls.progressBar.showChapters"),
|
|
isOn: $showChapters
|
|
)
|
|
.onChange(of: showChapters) { _, newValue in
|
|
viewModel.updateProgressBarSettingsSync { $0.showChapters = newValue }
|
|
}
|
|
.disabled(!viewModel.canEditActivePreset)
|
|
} header: {
|
|
Text(String(localized: "settings.playerControls.progressBar.chapters"))
|
|
} footer: {
|
|
Text(String(localized: "settings.playerControls.progressBar.chaptersFooter"))
|
|
}
|
|
}
|
|
|
|
// MARK: - Sponsor Segments Section
|
|
|
|
private var sponsorSegmentsSection: some View {
|
|
Section {
|
|
Toggle(
|
|
String(localized: "settings.playerControls.progressBar.showSponsorSegments"),
|
|
isOn: $showSponsorSegments
|
|
)
|
|
.onChange(of: showSponsorSegments) { _, newValue in
|
|
viewModel.updateProgressBarSettingsSync {
|
|
$0.sponsorBlockSettings.showSegments = newValue
|
|
}
|
|
}
|
|
.disabled(!viewModel.canEditActivePreset)
|
|
} header: {
|
|
Text(String(localized: "settings.playerControls.progressBar.sponsorSegments"))
|
|
}
|
|
}
|
|
|
|
// MARK: - Segment Colors Section
|
|
|
|
private var segmentColorsSection: some View {
|
|
Section {
|
|
ForEach(SponsorBlockCategory.allCases, id: \.rawValue) { category in
|
|
categoryRow(for: category)
|
|
}
|
|
} header: {
|
|
Text(String(localized: "settings.playerControls.progressBar.segmentColors"))
|
|
}
|
|
}
|
|
|
|
@ViewBuilder
|
|
private func categoryRow(for category: SponsorBlockCategory) -> some View {
|
|
let settings = categorySettings[category.rawValue]
|
|
?? SponsorBlockSegmentSettings.defaultCategorySettings[category.rawValue]
|
|
?? SponsorBlockCategorySettings()
|
|
|
|
let isVisible = Binding<Bool>(
|
|
get: { settings.isVisible },
|
|
set: { newValue in
|
|
updateCategorySettings(for: category) { $0.isVisible = newValue }
|
|
}
|
|
)
|
|
|
|
let color = Binding<Color>(
|
|
get: { settings.color.color },
|
|
set: { newValue in
|
|
updateCategorySettings(for: category) { $0.color = CodableColor(newValue) }
|
|
}
|
|
)
|
|
|
|
HStack {
|
|
Toggle(category.displayName, isOn: isVisible)
|
|
.disabled(!viewModel.canEditActivePreset)
|
|
|
|
Spacer()
|
|
|
|
#if !os(tvOS)
|
|
ColorPicker("", selection: color, supportsOpacity: false)
|
|
.labelsHidden()
|
|
.disabled(!viewModel.canEditActivePreset || !settings.isVisible)
|
|
#else
|
|
Circle()
|
|
.fill(color.wrappedValue)
|
|
.frame(width: 24, height: 24)
|
|
.opacity(settings.isVisible ? 1 : 0.4)
|
|
#endif
|
|
}
|
|
}
|
|
|
|
// MARK: - Helpers
|
|
|
|
private func loadSettings() {
|
|
let progressBarSettings = viewModel.progressBarSettings
|
|
playedColor = progressBarSettings.playedColor.color
|
|
showChapters = progressBarSettings.showChapters
|
|
showSponsorSegments = progressBarSettings.sponsorBlockSettings.showSegments
|
|
categorySettings = progressBarSettings.sponsorBlockSettings.categorySettings
|
|
}
|
|
|
|
private func updateCategorySettings(
|
|
for category: SponsorBlockCategory,
|
|
mutation: (inout SponsorBlockCategorySettings) -> Void
|
|
) {
|
|
var settings = categorySettings[category.rawValue]
|
|
?? SponsorBlockSegmentSettings.defaultCategorySettings[category.rawValue]
|
|
?? SponsorBlockCategorySettings()
|
|
|
|
mutation(&settings)
|
|
categorySettings[category.rawValue] = settings
|
|
|
|
viewModel.updateProgressBarSettingsSync {
|
|
$0.sponsorBlockSettings = $0.sponsorBlockSettings.withUpdatedSettings(
|
|
forKey: category.rawValue,
|
|
settings
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: - Preview
|
|
|
|
#Preview {
|
|
NavigationStack {
|
|
ProgressBarSettingsView(
|
|
viewModel: PlayerControlsSettingsViewModel(
|
|
layoutService: PlayerControlsLayoutService(),
|
|
settingsManager: SettingsManager()
|
|
)
|
|
)
|
|
}
|
|
}
|