mirror of
https://github.com/yattee/yattee.git
synced 2024-12-22 21:43:41 +00:00
Add buttons to next video and restart video (fix #106)
Previous video requires rebuilding queue a little, maybe in the future
This commit is contained in:
parent
d07b82a21b
commit
c5af865ffe
@ -281,8 +281,12 @@ final class PlayerModel: ObservableObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func upgradeToStream(_ stream: Stream, force: Bool = false) {
|
func upgradeToStream(_ stream: Stream, force: Bool = false) {
|
||||||
|
guard let video = currentVideo else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if !self.stream.isNil, force || self.stream != stream {
|
if !self.stream.isNil, force || self.stream != stream {
|
||||||
playStream(stream, of: currentVideo!, preservingTime: true, upgrading: true)
|
playStream(stream, of: video, preservingTime: true, upgrading: true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
import CoreData
|
import CoreData
|
||||||
|
import CoreMedia
|
||||||
import Defaults
|
import Defaults
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
@objc(Watch)
|
@objc(Watch)
|
||||||
final class Watch: NSManagedObject, Identifiable {
|
final class Watch: NSManagedObject, Identifiable {
|
||||||
@Default(.watchedThreshold) private var watchedThreshold
|
@Default(.watchedThreshold) private var watchedThreshold
|
||||||
|
@Default(.saveHistory) private var saveHistory
|
||||||
}
|
}
|
||||||
|
|
||||||
extension Watch {
|
extension Watch {
|
||||||
@ -45,4 +47,15 @@ extension Watch {
|
|||||||
formatter.unitsStyle = .full
|
formatter.unitsStyle = .full
|
||||||
return formatter.localizedString(for: watchedAt, relativeTo: Date())
|
return formatter.localizedString(for: watchedAt, relativeTo: Date())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var timeToRestart: CMTime? {
|
||||||
|
finished ? nil : saveHistory ? .secondsInDefaultTimescale(stoppedAt) : nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var video: Video {
|
||||||
|
Video(
|
||||||
|
videoID: videoID, title: "", author: "",
|
||||||
|
length: 0, published: "", views: -1, channel: Channel(id: "", name: "")
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -272,6 +272,9 @@ struct PlayerControls: View {
|
|||||||
var mediumButtonsBar: some View {
|
var mediumButtonsBar: some View {
|
||||||
HStack {
|
HStack {
|
||||||
#if !os(tvOS)
|
#if !os(tvOS)
|
||||||
|
restartVideoButton
|
||||||
|
.padding(.trailing, 15)
|
||||||
|
|
||||||
button("Seek Backward", systemImage: "gobackward.10", size: 30, cornerRadius: 5) {
|
button("Seek Backward", systemImage: "gobackward.10", size: 30, cornerRadius: 5) {
|
||||||
player.backend.seek(relative: .secondsInDefaultTimescale(-10))
|
player.backend.seek(relative: .secondsInDefaultTimescale(-10))
|
||||||
}
|
}
|
||||||
@ -314,12 +317,28 @@ struct PlayerControls: View {
|
|||||||
.keyboardShortcut("l", modifiers: [])
|
.keyboardShortcut("l", modifiers: [])
|
||||||
.keyboardShortcut(KeyEquivalent.rightArrow, modifiers: [])
|
.keyboardShortcut(KeyEquivalent.rightArrow, modifiers: [])
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
advanceToNextItemButton
|
||||||
|
.padding(.leading, 15)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
.font(.system(size: 20))
|
.font(.system(size: 20))
|
||||||
.padding(.horizontal, 4)
|
.padding(.horizontal, 4)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var restartVideoButton: some View {
|
||||||
|
button("Restart video", systemImage: "backward.end.fill", size: 30, cornerRadius: 5) {
|
||||||
|
player.backend.seek(to: 0.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var advanceToNextItemButton: some View {
|
||||||
|
button("Next", systemImage: "forward.fill", size: 30, cornerRadius: 5) {
|
||||||
|
player.advanceToNextItem()
|
||||||
|
}
|
||||||
|
.disabled(player.queue.isEmpty)
|
||||||
|
}
|
||||||
|
|
||||||
var bottomBar: some View {
|
var bottomBar: some View {
|
||||||
HStack {
|
HStack {
|
||||||
Text(model.playbackTime)
|
Text(model.playbackTime)
|
||||||
|
@ -141,16 +141,8 @@ struct VideoContextMenuView: View {
|
|||||||
Button {
|
Button {
|
||||||
player.controls.startPiP(startImmediately: false)
|
player.controls.startPiP(startImmediately: false)
|
||||||
|
|
||||||
var time: CMTime?
|
|
||||||
if saveHistory,
|
|
||||||
let stoppedAt = watch?.stoppedAt,
|
|
||||||
!watch!.finished
|
|
||||||
{
|
|
||||||
time = .secondsInDefaultTimescale(stoppedAt)
|
|
||||||
}
|
|
||||||
|
|
||||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
||||||
player.play(video, at: time, showingPlayer: false)
|
player.play(video, at: watch?.timeToRestart, showingPlayer: false)
|
||||||
}
|
}
|
||||||
} label: {
|
} label: {
|
||||||
Label("Play in PiP", systemImage: "pip")
|
Label("Play in PiP", systemImage: "pip")
|
||||||
|
Loading…
Reference in New Issue
Block a user