Files
yattee/Yattee/Views/Player/ExpandedPlayerSheet+VideoInfo.swift
Arkadiusz Fal 4770bbe3b9 Remove dead code found by Periphery on all platforms
Delete declarations that Periphery reports unused on every platform that
compiles them (iOS, macOS, tvOS), including nine views used only by their
own previews. Platform-gated code still used on another platform, device-
only MPV render paths, migration models, CloudKit record names, App
Intents metadata and unused parameters are kept.
2026-10-08 23:57:56 +02:00

99 lines
3.2 KiB
Swift

//
// ExpandedPlayerSheet+VideoInfo.swift
// Yattee
//
// Video info, description, and comments functionality for the expanded player sheet.
//
import SwiftUI
#if os(iOS) || os(macOS) || os(tvOS)
extension ExpandedPlayerSheet {
// MARK: - Scroll & Comments
/// Collapses the comments overlay.
func collapseComments() {
navigationCoordinator?.commentsFrame = .zero
// Use same animation as player sheet dismiss (0.3s, no bounce)
withAnimation(.smooth(duration: 0.3)) {
isCommentsExpanded = false
commentsDismissOffset = 0
}
}
/// Starts preloading comments, cancelling any in-flight task.
func startPreloadingComments() {
commentsPreloadTask?.cancel()
commentsPreloadTask = Task { await preloadComments() }
}
/// Cancels any in-flight comments preload task.
func cancelCommentsPreload() {
commentsPreloadTask?.cancel()
commentsPreloadTask = nil
}
/// Handles comments dismiss offset during drag.
func handleCommentsDismissOffset(_ offset: CGFloat) {
// Don't apply real-time offset during drag - it causes feedback loop
// with scroll geometry. The scroll view bounces naturally with iOS rubber-banding.
}
/// Handles the end of comments dismiss gesture.
func handleCommentsDismissGestureEnded(_ finalOffset: CGFloat) {
let dismissThreshold: CGFloat = 30
if finalOffset >= dismissThreshold {
collapseComments()
}
// Below threshold - scroll view will rubber-band back naturally
}
/// Preloads comments for the current video.
func preloadComments() async {
guard let playerState, playerState.commentsState == .idle else { return }
// Skip when nothing displays comments (page disabled and pill disabled)
guard playerControlsLayout.effectivePanelSettings.shouldLoadComments else {
playerState.commentsState = .disabled
return
}
guard let contentService = appEnvironment?.contentService,
let instancesManager = appEnvironment?.instancesManager else { return }
await playerState.loadComments(contentService: contentService, instancesManager: instancesManager)
}
// MARK: - Actions
/// Closes the current video and dismisses the player.
func closeVideo() {
// Mark as closing to hide tab accessory before dismissal
playerState?.isClosingVideo = true
// Clear the queue when closing video
appEnvironment?.queueManager.clearQueue()
// Reset panel visibility when closing player
appEnvironment?.settingsManager.landscapeDetailsPanelVisible = false
// Stop player FIRST before dismissing window
// This ensures MPVRenderView and backend are properly cleaned up
// before the window's content view hierarchy is destroyed
playerService?.stop()
// Then dismiss player window (after backend is stopped)
navigationCoordinator?.isPlayerExpanded = false
}
/// Switches to a different stream.
func switchToStream(_ stream: Stream, audioStream: Stream? = nil) {
Task {
await playerService?.selectStreamManually(stream, audioStream: audioStream)
}
}
}
#endif