Files
yattee/Yattee/Views/Settings/DownloadSettingsView.swift
2026-02-08 18:33:56 +01:00

158 lines
4.5 KiB
Swift

//
// DownloadSettingsView.swift
// Yattee
//
// Settings view for download configuration.
//
import SwiftUI
#if !os(tvOS)
struct DownloadSettingsView: View {
@Environment(\.appEnvironment) private var appEnvironment
var body: some View {
Form {
if let downloadSettings = appEnvironment?.downloadSettings,
let downloadManager = appEnvironment?.downloadManager {
StorageSection(downloadManager: downloadManager)
QualitySection(downloadSettings: downloadSettings)
ConcurrencySection(downloadSettings: downloadSettings)
#if os(iOS)
CellularSection(
downloadSettings: downloadSettings,
downloadManager: downloadManager
)
#endif
}
}
.navigationTitle(String(localized: "settings.downloads.title"))
#if os(iOS)
.navigationBarTitleDisplayMode(.inline)
#endif
}
}
// MARK: - Storage Section
private struct StorageSection: View {
let downloadManager: DownloadManager
private var storageUsed: Int64 {
downloadManager.storageUsed
}
private func formatBytes(_ bytes: Int64) -> String {
let formatter = ByteCountFormatter()
formatter.countStyle = .file
return formatter.string(fromByteCount: bytes)
}
var body: some View {
Section {
NavigationLink {
DownloadsStorageView()
} label: {
HStack {
Text(String(localized: "settings.downloads.usedStorage"))
Spacer()
Text(formatBytes(storageUsed))
.foregroundStyle(.secondary)
}
}
}
}
}
// MARK: - Quality Section
private struct QualitySection: View {
@Bindable var downloadSettings: DownloadSettings
var body: some View {
Section {
Picker(
String(localized: "settings.downloads.preferredQuality"),
selection: $downloadSettings.preferredDownloadQuality
) {
ForEach(DownloadQuality.allCases, id: \.self) { quality in
Text(quality.displayName).tag(quality)
}
}
if downloadSettings.preferredDownloadQuality != .ask {
Toggle(
String(localized: "settings.downloads.includeSubtitles"),
isOn: $downloadSettings.includeSubtitlesInAutoDownload
)
}
} header: {
Text(String(localized: "settings.downloads.quality.header"))
} footer: {
if downloadSettings.preferredDownloadQuality == .ask {
Text(String(localized: "settings.downloads.quality.ask.footer"))
} else {
Text(String(localized: "settings.downloads.quality.auto.footer"))
}
}
}
}
// MARK: - Concurrency Section
private struct ConcurrencySection: View {
@Bindable var downloadSettings: DownloadSettings
var body: some View {
Section {
#if os(iOS)
Stepper(value: $downloadSettings.maxConcurrentDownloads, in: 1...5) {
HStack {
Text(String(localized: "settings.downloads.maxConcurrent"))
Spacer()
Text("\(downloadSettings.maxConcurrentDownloads)")
.foregroundStyle(.secondary)
}
}
#else
Stepper(
"\(String(localized: "settings.downloads.maxConcurrent")): \(downloadSettings.maxConcurrentDownloads)",
value: $downloadSettings.maxConcurrentDownloads,
in: 1...5
)
#endif
}
}
}
// MARK: - Cellular Section
#if os(iOS)
private struct CellularSection: View {
@Bindable var downloadSettings: DownloadSettings
let downloadManager: DownloadManager?
var body: some View {
Section {
Toggle(
String(localized: "settings.downloads.allowCellular"),
isOn: $downloadSettings.allowCellularDownloads
)
.onChange(of: downloadSettings.allowCellularDownloads) {
downloadManager?.refreshCellularAccessSetting()
}
} footer: {
Text(String(localized: "settings.downloads.allowCellular.footer"))
}
}
}
#endif
#Preview {
NavigationStack {
DownloadSettingsView()
}
.appEnvironment(.preview)
}
#endif