mirror of
https://github.com/yattee/yattee.git
synced 2026-05-13 02:45:03 +00:00
Focus first video by default in Continue Watching on tvOS
Use @FocusState with programmatic assignment on appear instead of prefersDefaultFocus, which is broken when the target sits inside a ScrollView/LazyVGrid on tvOS. A 0.15s delay gives the grid time to materialize cells before the focus write.
This commit is contained in:
@@ -10,6 +10,9 @@ import SwiftUI
|
|||||||
struct ContinueWatchingView: View {
|
struct ContinueWatchingView: View {
|
||||||
@Environment(\.appEnvironment) private var appEnvironment
|
@Environment(\.appEnvironment) private var appEnvironment
|
||||||
@Namespace private var sheetTransition
|
@Namespace private var sheetTransition
|
||||||
|
#if os(tvOS)
|
||||||
|
@FocusState private var focusedVideoID: String?
|
||||||
|
#endif
|
||||||
@State private var watchHistory: [WatchEntry] = []
|
@State private var watchHistory: [WatchEntry] = []
|
||||||
|
|
||||||
// View options (persisted)
|
// View options (persisted)
|
||||||
@@ -149,6 +152,16 @@ struct ContinueWatchingView: View {
|
|||||||
.onReceive(NotificationCenter.default.publisher(for: .watchHistoryDidChange)) { _ in
|
.onReceive(NotificationCenter.default.publisher(for: .watchHistoryDidChange)) { _ in
|
||||||
loadHistory()
|
loadHistory()
|
||||||
}
|
}
|
||||||
|
#if os(tvOS)
|
||||||
|
.onChange(of: inProgressEntries.first?.videoID, initial: true) { _, newValue in
|
||||||
|
// Work around tvOS ScrollView + prefersDefaultFocus bug: set initial focus
|
||||||
|
// to the first video after LazyVGrid has time to materialize cells.
|
||||||
|
guard let newValue else { return }
|
||||||
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.15) {
|
||||||
|
focusedVideoID = newValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Content
|
// MARK: - Content
|
||||||
@@ -176,7 +189,9 @@ struct ContinueWatchingView: View {
|
|||||||
) {
|
) {
|
||||||
entryRowView(entry: entry, index: index)
|
entryRowView(entry: entry, index: index)
|
||||||
}
|
}
|
||||||
#if !os(tvOS)
|
#if os(tvOS)
|
||||||
|
.focused($focusedVideoID, equals: entry.videoID)
|
||||||
|
#else
|
||||||
.videoSwipeActions(
|
.videoSwipeActions(
|
||||||
video: entry.toVideo(),
|
video: entry.toVideo(),
|
||||||
fixedActions: [
|
fixedActions: [
|
||||||
@@ -235,6 +250,9 @@ struct ContinueWatchingView: View {
|
|||||||
TappableContinueWatchingGridCard(entry: entry, onRemove: {
|
TappableContinueWatchingGridCard(entry: entry, onRemove: {
|
||||||
removeEntry(entry)
|
removeEntry(entry)
|
||||||
})
|
})
|
||||||
|
#if os(tvOS)
|
||||||
|
.focused($focusedVideoID, equals: entry.videoID)
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user