Better UI for autoplay

This commit is contained in:
Arkadiusz Fal 2022-07-11 19:44:49 +02:00
parent fda4013907
commit 2de6df9899
3 changed files with 73 additions and 16 deletions

View File

@ -573,20 +573,36 @@ final class PlayerModel: ObservableObject {
}
func setRelatedAutoplayItem() {
guard let video = currentVideo?.related.randomElement() else { return }
guard let video = currentVideo else { return }
let related = video.related.filter { $0.videoID != autoplayItem?.video?.videoID }
let item = PlayerQueueItem(video)
autoplayItem = item
autoplayItemSource = video
let watchFetchRequest = Watch.fetchRequest()
watchFetchRequest.predicate = NSPredicate(format: "videoID IN %@", related.map(\.videoID) as [String])
DispatchQueue.main.asyncAfter(deadline: .now() + 3) { [weak self] in
guard let self = self else { return }
self.accounts.api.loadDetails(item, completionHandler: { newItem in
guard newItem.videoID == self.autoplayItem?.videoID else { return }
self.autoplayItem = newItem
self.updateRemoteCommandCenter()
self.controls.objectWillChange.send()
})
let results = try? context.fetch(watchFetchRequest)
context.perform { [weak self] in
guard let self = self,
let results = results else { return }
let resultsIds = results.map(\.videoID)
guard let autoplayVideo = related.filter({ !resultsIds.contains($0.videoID) }).randomElement() else {
return
}
let item = PlayerQueueItem(autoplayVideo)
self.autoplayItem = item
self.autoplayItemSource = video
DispatchQueue.main.asyncAfter(deadline: .now() + 3) { [weak self] in
guard let self = self else { return }
self.accounts.api.loadDetails(item, completionHandler: { newItem in
guard newItem.videoID == self.autoplayItem?.videoID else { return }
self.autoplayItem = newItem
self.updateRemoteCommandCenter()
self.controls.objectWillChange.send()
})
}
}
}

View File

@ -6,6 +6,7 @@ import SwiftUI
struct PlayerQueueRow: View {
let item: PlayerQueueItem
var history = false
var autoplay = false
@Binding var fullScreen: Bool
@EnvironmentObject<PlayerModel> private var player
@ -14,9 +15,10 @@ struct PlayerQueueRow: View {
@FetchRequest private var watchRequest: FetchedResults<Watch>
init(item: PlayerQueueItem, history: Bool = false, fullScreen: Binding<Bool> = .constant(false)) {
init(item: PlayerQueueItem, history: Bool = false, autoplay: Bool = false, fullScreen: Binding<Bool> = .constant(false)) {
self.item = item
self.history = history
self.autoplay = autoplay
_fullScreen = fullScreen
_watchRequest = FetchRequest<Watch>(
entity: Watch.entity(),
@ -48,6 +50,10 @@ struct PlayerQueueRow: View {
if closePiPOnNavigation, player.playingInPictureInPicture {
player.closePiP()
}
if autoplay {
player.resetAutoplay()
}
} label: {
VideoBanner(video: item.video, playbackTime: watchStoppedAt, videoDuration: watch?.videoDuration)
}

View File

@ -20,6 +20,9 @@ struct PlayerQueueView: View {
var body: some View {
List {
Group {
if player.playbackMode == .related {
autoplaying
}
playingNext
if sidebarQueue {
related
@ -46,10 +49,42 @@ struct PlayerQueueView: View {
#endif
}
@ViewBuilder var autoplaying: some View {
Section(header: autoplayingHeader) {
if let item = player.autoplayItem {
PlayerQueueRow(item: item, autoplay: true)
} else {
Group {
if player.currentItem.isNil {
Text("Not Playing")
} else {
Text("Finding something to play...")
}
}
.foregroundColor(.secondary)
}
}
}
var autoplayingHeader: some View {
HStack {
Text("Autoplaying Next")
Spacer()
Button {
player.setRelatedAutoplayItem()
} label: {
Label("Find Other", systemImage: "arrow.triangle.2.circlepath.circle")
.labelStyle(.iconOnly)
}
.disabled(player.currentItem.isNil)
.buttonStyle(.plain)
}
}
var playingNext: some View {
Section(header: Text("Playing Next")) {
Section(header: Text("Queue")) {
if player.queue.isEmpty {
Text("Playback queue is empty")
Text("Queue is empty")
.foregroundColor(.secondary)
}
@ -73,7 +108,7 @@ struct PlayerQueueView: View {
var playedPreviously: some View {
Group {
if !visibleWatches.isEmpty {
Section(header: Text("Played Previously")) {
Section(header: Text("History")) {
ForEach(visibleWatches, id: \.videoID) { watch in
PlayerQueueRow(
item: PlayerQueueItem.from(watch, video: player.historyVideo(watch.videoID)),