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

199 lines
6.1 KiB
Swift

//
// DeArrowSettingsView.swift
// Yattee
//
// DeArrow settings.
//
import SwiftUI
struct DeArrowSettingsView: View {
@Environment(\.appEnvironment) private var appEnvironment
var body: some View {
Form {
if let settings = appEnvironment?.settingsManager {
// Enable/Disable toggle
EnableSection(settings: settings)
// Options section (only shown when enabled)
if settings.deArrowEnabled {
OptionsSection(settings: settings)
}
// Advanced section
AdvancedSection(settings: settings)
// About section
AboutSection()
}
}
#if os(iOS)
.scrollDismissesKeyboard(.interactively)
#endif
.navigationTitle(String(localized: "settings.deArrow.title"))
#if os(iOS)
.navigationBarTitleDisplayMode(.inline)
#endif
}
}
// MARK: - Enable Section
private struct EnableSection: View {
@Bindable var settings: SettingsManager
var body: some View {
Section {
Toggle(
String(localized: "settings.deArrow.enabled"),
isOn: $settings.deArrowEnabled
)
} footer: {
Text(String(localized: "settings.deArrow.footer"))
}
}
}
// MARK: - Options Section
private struct OptionsSection: View {
@Bindable var settings: SettingsManager
var body: some View {
Section(String(localized: "settings.deArrow.options.header")) {
Toggle(
String(localized: "settings.deArrow.replaceTitles"),
isOn: $settings.deArrowReplaceTitles
)
Toggle(
String(localized: "settings.deArrow.replaceThumbnails"),
isOn: $settings.deArrowReplaceThumbnails
)
}
}
}
// MARK: - Advanced Section
private struct AdvancedSection: View {
@Environment(\.appEnvironment) private var appEnvironment
@Bindable var settings: SettingsManager
@State private var apiURLText: String = ""
@State private var thumbnailAPIURLText: String = ""
var body: some View {
Section {
TextField(
String(localized: "settings.deArrow.apiURL"),
text: $apiURLText,
prompt: Text(SettingsManager.defaultDeArrowAPIURL)
)
#if os(iOS)
.textInputAutocapitalization(.never)
.keyboardType(.URL)
#endif
.autocorrectionDisabled()
.onChange(of: apiURLText) { _, newValue in
let trimmed = newValue.trimmingCharacters(in: .whitespacesAndNewlines)
if trimmed.isEmpty {
settings.deArrowAPIURL = SettingsManager.defaultDeArrowAPIURL
} else {
settings.deArrowAPIURL = trimmed
}
syncAPIURLs()
}
if settings.deArrowAPIURL != SettingsManager.defaultDeArrowAPIURL {
Button(String(localized: "settings.deArrow.apiURL.reset")) {
apiURLText = ""
settings.deArrowAPIURL = SettingsManager.defaultDeArrowAPIURL
syncAPIURLs()
}
}
TextField(
String(localized: "settings.deArrow.thumbnailAPIURL"),
text: $thumbnailAPIURLText,
prompt: Text(SettingsManager.defaultDeArrowThumbnailAPIURL)
)
#if os(iOS)
.textInputAutocapitalization(.never)
.keyboardType(.URL)
#endif
.autocorrectionDisabled()
.onChange(of: thumbnailAPIURLText) { _, newValue in
let trimmed = newValue.trimmingCharacters(in: .whitespacesAndNewlines)
if trimmed.isEmpty {
settings.deArrowThumbnailAPIURL = SettingsManager.defaultDeArrowThumbnailAPIURL
} else {
settings.deArrowThumbnailAPIURL = trimmed
}
syncAPIURLs()
}
if settings.deArrowThumbnailAPIURL != SettingsManager.defaultDeArrowThumbnailAPIURL {
Button(String(localized: "settings.deArrow.thumbnailAPIURL.reset")) {
thumbnailAPIURLText = ""
settings.deArrowThumbnailAPIURL = SettingsManager.defaultDeArrowThumbnailAPIURL
syncAPIURLs()
}
}
} header: {
Text(String(localized: "settings.deArrow.advanced.header"))
} footer: {
Text(String(localized: "settings.deArrow.apiURL.footer"))
}
.onAppear {
let currentAPIURL = settings.deArrowAPIURL
if currentAPIURL != SettingsManager.defaultDeArrowAPIURL {
apiURLText = currentAPIURL
}
let currentThumbnailAPIURL = settings.deArrowThumbnailAPIURL
if currentThumbnailAPIURL != SettingsManager.defaultDeArrowThumbnailAPIURL {
thumbnailAPIURLText = currentThumbnailAPIURL
}
}
}
private func syncAPIURLs() {
Task {
await appEnvironment?.deArrowBrandingProvider.syncAPIURLs()
}
}
}
// MARK: - About Section
private struct AboutSection: View {
var body: some View {
Section(String(localized: "settings.deArrow.about.header")) {
VStack(alignment: .leading, spacing: 8) {
Text(String(localized: "settings.deArrow.about.description"))
.font(.callout)
.foregroundStyle(.secondary)
Link(destination: URL(string: "https://dearrow.ajay.app")!) {
HStack {
Text(String(localized: "settings.deArrow.learnMore"))
Spacer()
Image(systemName: "arrow.up.right")
.font(.caption)
}
}
}
}
}
}
// MARK: - Preview
#Preview {
NavigationStack {
DeArrowSettingsView()
}
.appEnvironment(.preview)
}