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.
This commit is contained in:
Arkadiusz Fal
2026-04-23 07:29:57 +02:00
parent d38b781858
commit 5a839da1bd
13 changed files with 511 additions and 2 deletions

View File

@@ -51,6 +51,9 @@ struct YatteeApp: App {
#endif
@State private var showingOpenLinkSheet = false
// Ambiguous-link prompts are stored on NavigationCoordinator so they can
// be dual-hosted by the root app view (here) and the expanded player sheet.
init() {
// Configure Nuke image loading pipeline
ImageLoadingService.shared.configure()
@@ -192,6 +195,23 @@ struct YatteeApp: App {
handleDescriptionLink(url)
}
}
.onReceive(NotificationCenter.default.publisher(for: .promptResolvedShortLink)) { notification in
if let url = notification.object as? URL {
appEnvironment.navigationCoordinator.resolvedShortLinkPrompt = url
}
}
.onReceive(NotificationCenter.default.publisher(for: .promptAmbiguousExternalLink)) { notification in
if let url = notification.object as? URL {
appEnvironment.navigationCoordinator.ambiguousExternalLinkPrompt = url
}
}
// Present confirmation dialogs at root level only when the expanded
// player isn't covering it. ExpandedPlayerSheet hosts the same
// dialogs when it *is* expanded, so they always sit on top.
.resolvedLinkPrompts(
shouldHost: !appEnvironment.navigationCoordinator.isPlayerExpanded,
appEnvironment: appEnvironment
)
}
#if os(macOS)
.windowStyle(.hiddenTitleBar)