Files
yattee/Yattee/Views/Settings/YouTubeEnhancementsSettingsView.swift
Arkadiusz Fal 5a839da1bd Resolve URL shorteners and prompt for ambiguous description links
Tapping bit.ly/tinyurl/t.co/etc. in a description or comment previously
opened Safari even when the destination was a playable YouTube URL.
Added an opt-in "Resolve Short Links" toggle under YouTube Enhancements
(off by default) that follows the redirect on tap: if the target is a
YouTube/PeerTube/direct-media URL, open it in-app; otherwise prompt the
user before falling back to yt-dlp extraction or the browser.

Also added a confirmation dialog for non-shortener links that only
matched the loose .externalVideo yt-dlp fallback, so arbitrary web
pages in descriptions no longer silently kick off extraction.

Prompts live on NavigationCoordinator and are dual-hosted by YatteeApp
and ExpandedPlayerSheet so they remain visible whether or not the
expanded player is covering the main view.
2026-04-23 07:29:57 +02:00

118 lines
3.4 KiB
Swift

//
// YouTubeEnhancementsSettingsView.swift
// Yattee
//
// Settings view for YouTube-specific enhancements.
//
import SwiftUI
struct YouTubeEnhancementsSettingsView: View {
@Environment(\.appEnvironment) private var appEnvironment
var body: some View {
SettingsFormContainer {
if let settings = appEnvironment?.settingsManager {
SponsorBlockSection(settings: settings)
ReturnYouTubeDislikeSection(settings: settings)
DeArrowSection(settings: settings)
ResolveShortLinksSection(settings: settings)
}
}
#if !os(tvOS)
.navigationTitle(String(localized: "settings.youtubeEnhancements.title"))
#endif
#if os(iOS)
.navigationBarTitleDisplayMode(.inline)
#endif
}
}
// MARK: - SponsorBlock Section
private struct SponsorBlockSection: View {
@Bindable var settings: SettingsManager
var body: some View {
SettingsFormSection(footer: "settings.youtubeEnhancements.sponsorBlock.footer") {
SettingsNavigationRow(
"settings.sponsorBlock.sectionTitle",
systemImage: "forward",
trailing: {
Text(settings.sponsorBlockEnabled
? String(localized: "common.enabled")
: String(localized: "common.disabled"))
}
) {
SponsorBlockSettingsView()
}
}
}
}
// MARK: - Return YouTube Dislike Section
private struct ReturnYouTubeDislikeSection: View {
@Bindable var settings: SettingsManager
var body: some View {
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"))
}
) {
ReturnYouTubeDislikeSettingsView()
}
}
}
}
// MARK: - DeArrow Section
private struct DeArrowSection: View {
@Bindable var settings: SettingsManager
var body: some View {
SettingsFormSection(footer: "settings.youtubeEnhancements.deArrow.footer") {
SettingsNavigationRow(
"settings.deArrow.sectionTitle",
systemImage: "textformat",
trailing: {
Text(settings.deArrowEnabled
? String(localized: "common.enabled")
: String(localized: "common.disabled"))
}
) {
DeArrowSettingsView()
}
}
}
}
// MARK: - Resolve Short Links Section
private struct ResolveShortLinksSection: View {
@Bindable var settings: SettingsManager
var body: some View {
SettingsFormSection(footer: "settings.youtubeEnhancements.resolveShortLinks.footer") {
Toggle(
String(localized: "settings.resolveShortLinks.title"),
isOn: $settings.resolveShortLinksEnabled
)
}
}
}
#Preview {
NavigationStack {
YouTubeEnhancementsSettingsView()
}
.appEnvironment(.preview)
}