resume offset and live tv moved to experimental
This commit is contained in:
parent
c310b71963
commit
6a7c4c0a5b
|
@ -23,7 +23,7 @@ struct MediaPlayButtonRowView: View {
|
|||
MediaViewActionButton(icon: "play.fill", scrollView: $wrappedScrollView)
|
||||
}
|
||||
|
||||
Text(viewModel.item.getItemProgressString() != "" ? "\(viewModel.item.getItemProgressString()) left" : L10n.play)
|
||||
Text(viewModel.item.getItemProgressString() != "" ? "\(viewModel.item.getItemProgressString() ?? "") left" : L10n.play)
|
||||
.font(.caption)
|
||||
}
|
||||
VStack {
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
* Copyright 2021 Aiden Vigue & Jellyfin Contributors
|
||||
*/
|
||||
|
||||
import Defaults
|
||||
import Foundation
|
||||
import SwiftUI
|
||||
|
||||
|
@ -15,6 +16,8 @@ struct LibraryListView: View {
|
|||
@EnvironmentObject var libraryListRouter: LibraryListCoordinator.Router
|
||||
@StateObject var viewModel = LibraryListViewModel()
|
||||
|
||||
@Default(.Experimental.liveTVAlphaEnabled) var liveTVAlphaEnabled
|
||||
|
||||
var body: some View {
|
||||
ScrollView {
|
||||
LazyVStack {
|
||||
|
@ -23,32 +26,55 @@ struct LibraryListView: View {
|
|||
if library.collectionType ?? "" == "movies" || library.collectionType ?? "" == "tvshows" || library.collectionType ?? "" == "music" {
|
||||
EmptyView()
|
||||
} else {
|
||||
Button() {
|
||||
if library.collectionType == "livetv" {
|
||||
self.mainCoordinator.root(\.liveTV)
|
||||
} else {
|
||||
if library.collectionType == "livetv" {
|
||||
if liveTVAlphaEnabled {
|
||||
Button() {
|
||||
self.mainCoordinator.root(\.liveTV)
|
||||
}
|
||||
label: {
|
||||
ZStack {
|
||||
HStack {
|
||||
Spacer()
|
||||
VStack {
|
||||
Text(library.name ?? "")
|
||||
.foregroundColor(.white)
|
||||
.font(.title2)
|
||||
.fontWeight(.semibold)
|
||||
}
|
||||
Spacer()
|
||||
}.padding(32)
|
||||
}
|
||||
.frame(minWidth: 100, maxWidth: .infinity)
|
||||
.frame(height: 100)
|
||||
}
|
||||
.cornerRadius(10)
|
||||
.shadow(radius: 5)
|
||||
.padding(.bottom, 5)
|
||||
}
|
||||
} else {
|
||||
Button() {
|
||||
self.libraryListRouter.route(to: \.library, (viewModel: LibraryViewModel(), title: library.name ?? ""))
|
||||
}
|
||||
}
|
||||
label: {
|
||||
ZStack {
|
||||
HStack {
|
||||
Spacer()
|
||||
VStack {
|
||||
Text(library.name ?? "")
|
||||
.foregroundColor(.white)
|
||||
.font(.title2)
|
||||
.fontWeight(.semibold)
|
||||
}
|
||||
Spacer()
|
||||
}.padding(32)
|
||||
label: {
|
||||
ZStack {
|
||||
HStack {
|
||||
Spacer()
|
||||
VStack {
|
||||
Text(library.name ?? "")
|
||||
.foregroundColor(.white)
|
||||
.font(.title2)
|
||||
.fontWeight(.semibold)
|
||||
}
|
||||
Spacer()
|
||||
}.padding(32)
|
||||
}
|
||||
.frame(minWidth: 100, maxWidth: .infinity)
|
||||
.frame(height: 100)
|
||||
}
|
||||
.frame(minWidth: 100, maxWidth: .infinity)
|
||||
.frame(height: 100)
|
||||
.cornerRadius(10)
|
||||
.shadow(radius: 5)
|
||||
.padding(.bottom, 5)
|
||||
}
|
||||
.cornerRadius(10)
|
||||
.shadow(radius: 5)
|
||||
.padding(.bottom, 5)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -13,6 +13,7 @@ import SwiftUI
|
|||
struct ExperimentalSettingsView: View {
|
||||
|
||||
@Default(.Experimental.syncSubtitleStateWithAdjacent) var syncSubtitleStateWithAdjacent
|
||||
@Default(.Experimental.liveTVAlphaEnabled) var liveTVAlphaEnabled
|
||||
|
||||
var body: some View {
|
||||
Form {
|
||||
|
@ -20,6 +21,8 @@ struct ExperimentalSettingsView: View {
|
|||
|
||||
Toggle("Sync Subtitles with Adjacent Episodes", isOn: $syncSubtitleStateWithAdjacent)
|
||||
|
||||
Toggle("Live TV (Alpha)", isOn: $liveTVAlphaEnabled)
|
||||
|
||||
} header: {
|
||||
Text("Experimental")
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ struct SettingsView: View {
|
|||
@Default(.tvOSEpisodeItemCinematicView) var tvOSEpisodeItemCinematicView
|
||||
@Default(.tvOSMovieItemCinematicView) var tvOSMovieItemCinematicView
|
||||
@Default(.showPosterLabels) var showPosterLabels
|
||||
@Default(.resumeOffset) var resumeOffset
|
||||
|
||||
var body: some View {
|
||||
GeometryReader { reader in
|
||||
|
@ -80,6 +81,8 @@ struct SettingsView: View {
|
|||
}
|
||||
}
|
||||
|
||||
Toggle("Resume 5 Second Offset", isOn: $resumeOffset)
|
||||
|
||||
Toggle("Press Down for Menu", isOn: $downActionShowsMenu)
|
||||
|
||||
Toggle("Confirm Close", isOn: $confirmClose)
|
||||
|
|
|
@ -418,7 +418,15 @@ extension VLCPlayerViewController {
|
|||
let startPercentage = newViewModel.item.userData?.playedPercentage ?? 0
|
||||
|
||||
if startPercentage > 0 {
|
||||
newViewModel.sliderPercentage = startPercentage / 100
|
||||
if viewModel.resumeOffset {
|
||||
let videoDurationSeconds = Double(viewModel.item.runTimeTicks! / 10_000_000)
|
||||
var startSeconds = round((startPercentage / 100) * videoDurationSeconds)
|
||||
startSeconds = startSeconds.subtract(5, floor: 0)
|
||||
let newStartPercentage = startSeconds / videoDurationSeconds
|
||||
newViewModel.sliderPercentage = newStartPercentage
|
||||
} else {
|
||||
newViewModel.sliderPercentage = startPercentage / 100
|
||||
}
|
||||
}
|
||||
|
||||
viewModel = newViewModel
|
||||
|
|
|
@ -395,6 +395,9 @@
|
|||
E1D4BF8C2719F39F00A11E64 /* AppAppearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1D4BF802719D22800A11E64 /* AppAppearance.swift */; };
|
||||
E1D4BF8D2719F3A300A11E64 /* VideoPlayerJumpLength.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1F0204D26CCCA74001C1C3B /* VideoPlayerJumpLength.swift */; };
|
||||
E1D4BF8F271A079A00A11E64 /* BasicAppSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1D4BF8E271A079A00A11E64 /* BasicAppSettingsView.swift */; };
|
||||
E1E00A35278628A40022235B /* DoubleExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1E00A34278628A40022235B /* DoubleExtensions.swift */; };
|
||||
E1E00A36278628A40022235B /* DoubleExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1E00A34278628A40022235B /* DoubleExtensions.swift */; };
|
||||
E1E00A37278628A40022235B /* DoubleExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1E00A34278628A40022235B /* DoubleExtensions.swift */; };
|
||||
E1E48CC9271E6D410021A2F9 /* RefreshHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1E48CC8271E6D410021A2F9 /* RefreshHelper.swift */; };
|
||||
E1E5D5372783A52C00692DFE /* CinematicEpisodeItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1E5D5362783A52C00692DFE /* CinematicEpisodeItemView.swift */; };
|
||||
E1E5D5392783A56B00692DFE /* EpisodesRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1E5D5382783A56B00692DFE /* EpisodesRowView.swift */; };
|
||||
|
@ -695,6 +698,7 @@
|
|||
E1D4BF862719D27100A11E64 /* Bitrates.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Bitrates.swift; sourceTree = "<group>"; };
|
||||
E1D4BF892719D3D000A11E64 /* BasicAppSettingsCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BasicAppSettingsCoordinator.swift; sourceTree = "<group>"; };
|
||||
E1D4BF8E271A079A00A11E64 /* BasicAppSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BasicAppSettingsView.swift; sourceTree = "<group>"; };
|
||||
E1E00A34278628A40022235B /* DoubleExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DoubleExtensions.swift; sourceTree = "<group>"; };
|
||||
E1E48CC8271E6D410021A2F9 /* RefreshHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RefreshHelper.swift; sourceTree = "<group>"; };
|
||||
E1E5D5362783A52C00692DFE /* CinematicEpisodeItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CinematicEpisodeItemView.swift; sourceTree = "<group>"; };
|
||||
E1E5D5382783A56B00692DFE /* EpisodesRowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EpisodesRowView.swift; sourceTree = "<group>"; };
|
||||
|
@ -1179,6 +1183,7 @@
|
|||
E10EAA4E277BBCC4000269ED /* CGSizeExtensions.swift */,
|
||||
6267B3D526710B8900A7371D /* CollectionExtensions.swift */,
|
||||
E173DA5126D04AAF00CC4EB7 /* ColorExtension.swift */,
|
||||
E1E00A34278628A40022235B /* DoubleExtensions.swift */,
|
||||
6267B3D92671138200A7371D /* ImageExtensions.swift */,
|
||||
E1AD105226D96D5F003E4A08 /* JellyfinAPIExtensions */,
|
||||
621338922660107500A81A2A /* StringExtensions.swift */,
|
||||
|
@ -2060,6 +2065,7 @@
|
|||
53272537268C1DBB0035FBF1 /* SeasonItemView.swift in Sources */,
|
||||
09389CC526814E4500AE350E /* DeviceProfileBuilder.swift in Sources */,
|
||||
E1C812D2277AE50A00918266 /* URLComponentsExtensions.swift in Sources */,
|
||||
E1E00A36278628A40022235B /* DoubleExtensions.swift in Sources */,
|
||||
E1FA2F7427818A8800B4C270 /* SmallMenuOverlay.swift in Sources */,
|
||||
E193D53C27193F9500900D82 /* UserListCoordinator.swift in Sources */,
|
||||
E13DD3C927164B1E009D4DAF /* UIDeviceExtensions.swift in Sources */,
|
||||
|
@ -2231,6 +2237,7 @@
|
|||
6220D0BA26D6092100B8E046 /* FilterCoordinator.swift in Sources */,
|
||||
E1E5D54C2783E27200692DFE /* ExperimentalSettingsView.swift in Sources */,
|
||||
6267B3DA2671138200A7371D /* ImageExtensions.swift in Sources */,
|
||||
E1E00A35278628A40022235B /* DoubleExtensions.swift in Sources */,
|
||||
62EC353426766B03000E9F2D /* DeviceRotationViewModifier.swift in Sources */,
|
||||
5389277C263CC3DB0035E14B /* BlurHashDecode.swift in Sources */,
|
||||
E1D4BF8A2719D3D000A11E64 /* BasicAppSettingsCoordinator.swift in Sources */,
|
||||
|
@ -2259,6 +2266,7 @@
|
|||
E13DD3CB27164BA8009D4DAF /* UIDeviceExtensions.swift in Sources */,
|
||||
6264E88A27384A6F0081A12A /* NetworkError.swift in Sources */,
|
||||
E19169D0272514760085832A /* HTTPScheme.swift in Sources */,
|
||||
E1E00A37278628A40022235B /* DoubleExtensions.swift in Sources */,
|
||||
6267B3D726710B9700A7371D /* CollectionExtensions.swift in Sources */,
|
||||
628B953C2670D2430091AF3B /* StringExtensions.swift in Sources */,
|
||||
6267B3DB2671139400A7371D /* ImageExtensions.swift in Sources */,
|
||||
|
|
|
@ -27,6 +27,7 @@ struct SettingsView: View {
|
|||
@Default(.jumpGesturesEnabled) var jumpGesturesEnabled
|
||||
@Default(.showPosterLabels) var showPosterLabels
|
||||
@Default(.showCastAndCrew) var showCastAndCrew
|
||||
@Default(.resumeOffset) var resumeOffset
|
||||
|
||||
var body: some View {
|
||||
Form {
|
||||
|
@ -91,6 +92,8 @@ struct SettingsView: View {
|
|||
|
||||
Toggle("Jump Gestures Enabled", isOn: $jumpGesturesEnabled)
|
||||
|
||||
Toggle("Resume 5 Second Offset", isOn: $resumeOffset)
|
||||
|
||||
Button {
|
||||
settingsRouter.route(to: \.overlaySettings)
|
||||
} label: {
|
||||
|
|
|
@ -316,7 +316,15 @@ extension VLCPlayerViewController {
|
|||
let startPercentage = newViewModel.item.userData?.playedPercentage ?? 0
|
||||
|
||||
if startPercentage > 0 {
|
||||
newViewModel.sliderPercentage = startPercentage / 100
|
||||
if viewModel.resumeOffset {
|
||||
let videoDurationSeconds = Double(viewModel.item.runTimeTicks! / 10_000_000)
|
||||
var startSeconds = round((startPercentage / 100) * videoDurationSeconds)
|
||||
startSeconds = startSeconds.subtract(5, floor: 0)
|
||||
let newStartPercentage = startSeconds / videoDurationSeconds
|
||||
newViewModel.sliderPercentage = newStartPercentage
|
||||
} else {
|
||||
newViewModel.sliderPercentage = startPercentage / 100
|
||||
}
|
||||
}
|
||||
|
||||
viewModel = newViewModel
|
||||
|
@ -522,6 +530,7 @@ extension VLCPlayerViewController: VLCMediaPlayerDelegate {
|
|||
didSelectSubtitleStream(index: viewModel.selectedSubtitleStreamIndex)
|
||||
}
|
||||
|
||||
// If needing to fix audio stream during playback
|
||||
if vlcMediaPlayer.currentAudioTrackIndex != viewModel.selectedAudioStreamIndex {
|
||||
didSelectAudioStream(index: viewModel.selectedAudioStreamIndex)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
//
|
||||
/*
|
||||
* SwiftFin is subject to the terms of the Mozilla Public
|
||||
* License, v2.0. If a copy of the MPL was not distributed with this
|
||||
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* Copyright 2021 Aiden Vigue & Jellyfin Contributors
|
||||
*/
|
||||
|
||||
import Foundation
|
||||
|
||||
extension Double {
|
||||
|
||||
func subtract(_ other: Double, floor: Double) -> Double {
|
||||
var v = self - other
|
||||
|
||||
if v < floor {
|
||||
v += abs(floor - v)
|
||||
}
|
||||
|
||||
return v
|
||||
}
|
||||
}
|
|
@ -48,6 +48,7 @@ extension Defaults.Keys {
|
|||
static let videoPlayerJumpForward = Key<VideoPlayerJumpLength>("videoPlayerJumpForward", default: .fifteen, suite: SwiftfinStore.Defaults.generalSuite)
|
||||
static let videoPlayerJumpBackward = Key<VideoPlayerJumpLength>("videoPlayerJumpBackward", default: .fifteen, suite: SwiftfinStore.Defaults.generalSuite)
|
||||
static let autoplayEnabled = Key<Bool>("autoPlayNextItem", default: true, suite: SwiftfinStore.Defaults.generalSuite)
|
||||
static let resumeOffset = Key<Bool>("resumeOffset", default: false, suite: SwiftfinStore.Defaults.generalSuite)
|
||||
|
||||
// Should show video player items
|
||||
static let shouldShowPlayPreviousItem = Key<Bool>("shouldShowPreviousItem", default: true, suite: SwiftfinStore.Defaults.generalSuite)
|
||||
|
@ -60,6 +61,7 @@ extension Defaults.Keys {
|
|||
// Experimental settings
|
||||
struct Experimental {
|
||||
static let syncSubtitleStateWithAdjacent = Key<Bool>("experimental.syncSubtitleState", default: false, suite: SwiftfinStore.Defaults.generalSuite)
|
||||
static let liveTVAlphaEnabled = Key<Bool>("liveTVAlphaEnabled", default: false, suite: SwiftfinStore.Defaults.generalSuite)
|
||||
}
|
||||
|
||||
// tvos specific
|
||||
|
|
|
@ -88,6 +88,7 @@ final class VideoPlayerViewModel: ViewModel {
|
|||
let subtitleStreams: [MediaStream]
|
||||
let overlayType: OverlayType
|
||||
let jumpGesturesEnabled: Bool
|
||||
let resumeOffset: Bool
|
||||
|
||||
// MARK: Experimental
|
||||
let syncSubtitleStateWithAdjacent: Bool
|
||||
|
@ -162,6 +163,8 @@ final class VideoPlayerViewModel: ViewModel {
|
|||
self.jumpGesturesEnabled = Defaults[.jumpGesturesEnabled]
|
||||
self.shouldShowJumpButtonsInOverlayMenu = Defaults[.shouldShowJumpButtonsInOverlayMenu]
|
||||
|
||||
self.resumeOffset = Defaults[.resumeOffset]
|
||||
|
||||
self.syncSubtitleStateWithAdjacent = Defaults[.Experimental.syncSubtitleStateWithAdjacent]
|
||||
|
||||
self.confirmClose = Defaults[.confirmClose]
|
||||
|
|
Loading…
Reference in New Issue