1
0
mirror of https://github.com/yattee/yattee.git synced 2024-12-14 22:30:32 +05:30

Better UI for autoplay

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

View File

@ -573,20 +573,36 @@ final class PlayerModel: ObservableObject {
} }
func setRelatedAutoplayItem() { 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) let watchFetchRequest = Watch.fetchRequest()
autoplayItem = item watchFetchRequest.predicate = NSPredicate(format: "videoID IN %@", related.map(\.videoID) as [String])
autoplayItemSource = video
DispatchQueue.main.asyncAfter(deadline: .now() + 3) { [weak self] in let results = try? context.fetch(watchFetchRequest)
guard let self = self else { return }
self.accounts.api.loadDetails(item, completionHandler: { newItem in context.perform { [weak self] in
guard newItem.videoID == self.autoplayItem?.videoID else { return } guard let self = self,
self.autoplayItem = newItem let results = results else { return }
self.updateRemoteCommandCenter() let resultsIds = results.map(\.videoID)
self.controls.objectWillChange.send()
}) 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 { struct PlayerQueueRow: View {
let item: PlayerQueueItem let item: PlayerQueueItem
var history = false var history = false
var autoplay = false
@Binding var fullScreen: Bool @Binding var fullScreen: Bool
@EnvironmentObject<PlayerModel> private var player @EnvironmentObject<PlayerModel> private var player
@ -14,9 +15,10 @@ struct PlayerQueueRow: View {
@FetchRequest private var watchRequest: FetchedResults<Watch> @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.item = item
self.history = history self.history = history
self.autoplay = autoplay
_fullScreen = fullScreen _fullScreen = fullScreen
_watchRequest = FetchRequest<Watch>( _watchRequest = FetchRequest<Watch>(
entity: Watch.entity(), entity: Watch.entity(),
@ -48,6 +50,10 @@ struct PlayerQueueRow: View {
if closePiPOnNavigation, player.playingInPictureInPicture { if closePiPOnNavigation, player.playingInPictureInPicture {
player.closePiP() player.closePiP()
} }
if autoplay {
player.resetAutoplay()
}
} label: { } label: {
VideoBanner(video: item.video, playbackTime: watchStoppedAt, videoDuration: watch?.videoDuration) VideoBanner(video: item.video, playbackTime: watchStoppedAt, videoDuration: watch?.videoDuration)
} }

View File

@ -20,6 +20,9 @@ struct PlayerQueueView: View {
var body: some View { var body: some View {
List { List {
Group { Group {
if player.playbackMode == .related {
autoplaying
}
playingNext playingNext
if sidebarQueue { if sidebarQueue {
related related
@ -46,10 +49,42 @@ struct PlayerQueueView: View {
#endif #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 { var playingNext: some View {
Section(header: Text("Playing Next")) { Section(header: Text("Queue")) {
if player.queue.isEmpty { if player.queue.isEmpty {
Text("Playback queue is empty") Text("Queue is empty")
.foregroundColor(.secondary) .foregroundColor(.secondary)
} }
@ -73,7 +108,7 @@ struct PlayerQueueView: View {
var playedPreviously: some View { var playedPreviously: some View {
Group { Group {
if !visibleWatches.isEmpty { if !visibleWatches.isEmpty {
Section(header: Text("Played Previously")) { Section(header: Text("History")) {
ForEach(visibleWatches, id: \.videoID) { watch in ForEach(visibleWatches, id: \.videoID) { watch in
PlayerQueueRow( PlayerQueueRow(
item: PlayerQueueItem.from(watch, video: player.historyVideo(watch.videoID)), item: PlayerQueueItem.from(watch, video: player.historyVideo(watch.videoID)),