mirror of
https://github.com/yattee/yattee.git
synced 2025-01-08 22:07:10 +00:00
Setting for player sidebar
This commit is contained in:
parent
f8e6560698
commit
c69d60f3ee
@ -82,6 +82,7 @@
|
|||||||
372915E72687E3B900F5A35B /* Defaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 372915E52687E3B900F5A35B /* Defaults.swift */; };
|
372915E72687E3B900F5A35B /* Defaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 372915E52687E3B900F5A35B /* Defaults.swift */; };
|
||||||
372915E82687E3B900F5A35B /* Defaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 372915E52687E3B900F5A35B /* Defaults.swift */; };
|
372915E82687E3B900F5A35B /* Defaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 372915E52687E3B900F5A35B /* Defaults.swift */; };
|
||||||
3730D8A02712E2B70020ED53 /* NowPlayingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3730D89F2712E2B70020ED53 /* NowPlayingView.swift */; };
|
3730D8A02712E2B70020ED53 /* NowPlayingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3730D89F2712E2B70020ED53 /* NowPlayingView.swift */; };
|
||||||
|
3730F75A2733481E00F385FC /* RelatedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 373197D82732015300EF734F /* RelatedView.swift */; };
|
||||||
373197D92732015300EF734F /* RelatedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 373197D82732015300EF734F /* RelatedView.swift */; };
|
373197D92732015300EF734F /* RelatedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 373197D82732015300EF734F /* RelatedView.swift */; };
|
||||||
373197DA2732060100EF734F /* RelatedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 373197D82732015300EF734F /* RelatedView.swift */; };
|
373197DA2732060100EF734F /* RelatedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 373197D82732015300EF734F /* RelatedView.swift */; };
|
||||||
37319F0527103F94004ECCD0 /* PlayerQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37319F0427103F94004ECCD0 /* PlayerQueue.swift */; };
|
37319F0527103F94004ECCD0 /* PlayerQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37319F0427103F94004ECCD0 /* PlayerQueue.swift */; };
|
||||||
@ -1876,6 +1877,7 @@
|
|||||||
3700155C271B0D4D0049C794 /* PipedAPI.swift in Sources */,
|
3700155C271B0D4D0049C794 /* PipedAPI.swift in Sources */,
|
||||||
37D4B19826717E1500C925CA /* Video.swift in Sources */,
|
37D4B19826717E1500C925CA /* Video.swift in Sources */,
|
||||||
37599F31272B42810087F250 /* FavoriteItem.swift in Sources */,
|
37599F31272B42810087F250 /* FavoriteItem.swift in Sources */,
|
||||||
|
3730F75A2733481E00F385FC /* RelatedView.swift in Sources */,
|
||||||
375168D72700FDB8008F96A6 /* Debounce.swift in Sources */,
|
375168D72700FDB8008F96A6 /* Debounce.swift in Sources */,
|
||||||
37D526DF2720AC4400ED2F5E /* VideosAPI.swift in Sources */,
|
37D526DF2720AC4400ED2F5E /* VideosAPI.swift in Sources */,
|
||||||
37D4B0E52671614900C925CA /* PearvidiousApp.swift in Sources */,
|
37D4B0E52671614900C925CA /* PearvidiousApp.swift in Sources */,
|
||||||
|
@ -1,6 +1,18 @@
|
|||||||
import Defaults
|
import Defaults
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
enum PlayerSidebarSetting: String, CaseIterable, Defaults.Serializable {
|
||||||
|
case always, whenFits, never
|
||||||
|
|
||||||
|
static var defaultValue: Self {
|
||||||
|
#if os(macOS)
|
||||||
|
.always
|
||||||
|
#else
|
||||||
|
.whenFits
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extension Defaults.Keys {
|
extension Defaults.Keys {
|
||||||
static let invidiousInstanceID = "default-invidious-instance"
|
static let invidiousInstanceID = "default-invidious-instance"
|
||||||
static let pipedInstanceID = "default-piped-instance"
|
static let pipedInstanceID = "default-piped-instance"
|
||||||
@ -40,6 +52,7 @@ extension Defaults.Keys {
|
|||||||
])
|
])
|
||||||
|
|
||||||
static let quality = Key<Stream.ResolutionSetting>("quality", default: .hd720pFirstThenBest)
|
static let quality = Key<Stream.ResolutionSetting>("quality", default: .hd720pFirstThenBest)
|
||||||
|
static let playerSidebar = Key<PlayerSidebarSetting>("playerSidebar", default: PlayerSidebarSetting.defaultValue)
|
||||||
|
|
||||||
static let recentlyOpened = Key<[RecentItem]>("recentlyOpened", default: [])
|
static let recentlyOpened = Key<[RecentItem]>("recentlyOpened", default: [])
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ import Foundation
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
struct PlayerQueueView: View {
|
struct PlayerQueueView: View {
|
||||||
|
@Binding var sidebarQueue: Bool
|
||||||
@Binding var fullScreen: Bool
|
@Binding var fullScreen: Bool
|
||||||
|
|
||||||
@EnvironmentObject<PlayerModel> private var player
|
@EnvironmentObject<PlayerModel> private var player
|
||||||
@ -10,7 +11,9 @@ struct PlayerQueueView: View {
|
|||||||
List {
|
List {
|
||||||
Group {
|
Group {
|
||||||
playingNext
|
playingNext
|
||||||
|
if sidebarQueue {
|
||||||
related
|
related
|
||||||
|
}
|
||||||
playedPreviously
|
playedPreviously
|
||||||
}
|
}
|
||||||
#if !os(iOS)
|
#if !os(iOS)
|
||||||
@ -119,7 +122,7 @@ struct PlayerQueueView: View {
|
|||||||
struct PlayerQueueView_Previews: PreviewProvider {
|
struct PlayerQueueView_Previews: PreviewProvider {
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
VStack {
|
VStack {
|
||||||
PlayerQueueView(fullScreen: .constant(true))
|
PlayerQueueView(sidebarQueue: .constant(true), fullScreen: .constant(true))
|
||||||
}
|
}
|
||||||
.injectFixtureEnvironmentObjects()
|
.injectFixtureEnvironmentObjects()
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,7 @@ struct VideoDetails: View {
|
|||||||
}
|
}
|
||||||
.padding(.horizontal)
|
.padding(.horizontal)
|
||||||
|
|
||||||
if !video.isNil, !sidebarQueue {
|
if !sidebarQueue {
|
||||||
pagePicker
|
pagePicker
|
||||||
.padding(.horizontal)
|
.padding(.horizontal)
|
||||||
}
|
}
|
||||||
@ -87,25 +87,19 @@ struct VideoDetails: View {
|
|||||||
detailsPage
|
detailsPage
|
||||||
}
|
}
|
||||||
case .queue:
|
case .queue:
|
||||||
PlayerQueueView(fullScreen: $fullScreen)
|
PlayerQueueView(sidebarQueue: $sidebarQueue, fullScreen: $fullScreen)
|
||||||
.edgesIgnoringSafeArea(.horizontal)
|
.edgesIgnoringSafeArea(.horizontal)
|
||||||
|
|
||||||
case .related:
|
case .related:
|
||||||
#if os(macOS)
|
|
||||||
EmptyView()
|
|
||||||
#else
|
|
||||||
RelatedView()
|
RelatedView()
|
||||||
.edgesIgnoringSafeArea(.horizontal)
|
.edgesIgnoringSafeArea(.horizontal)
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.padding(.top, inNavigationView && fullScreen ? 10 : 0)
|
.padding(.top, inNavigationView && fullScreen ? 10 : 0)
|
||||||
.onAppear {
|
.onAppear {
|
||||||
#if !os(macOS)
|
|
||||||
if video.isNil {
|
if video.isNil {
|
||||||
currentPage = .queue
|
currentPage = .queue
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
guard video != nil, accounts.app.supportsSubscriptions else {
|
guard video != nil, accounts.app.supportsSubscriptions else {
|
||||||
subscribed = false
|
subscribed = false
|
||||||
@ -115,15 +109,13 @@ struct VideoDetails: View {
|
|||||||
subscribed = subscriptions.isSubscribing(video!.channel.id)
|
subscribed = subscriptions.isSubscribing(video!.channel.id)
|
||||||
}
|
}
|
||||||
.onChange(of: sidebarQueue) { queue in
|
.onChange(of: sidebarQueue) { queue in
|
||||||
#if !os(macOS)
|
|
||||||
if queue {
|
if queue {
|
||||||
if currentPage == .queue {
|
if currentPage == .queue {
|
||||||
currentPage = .details
|
currentPage = .details
|
||||||
}
|
}
|
||||||
} else {
|
} else if video.isNil {
|
||||||
currentPage = .queue
|
currentPage = .queue
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
.edgesIgnoringSafeArea(.horizontal)
|
.edgesIgnoringSafeArea(.horizontal)
|
||||||
.frame(minWidth: 0, maxWidth: .infinity, alignment: .leading)
|
.frame(minWidth: 0, maxWidth: .infinity, alignment: .leading)
|
||||||
@ -134,9 +126,7 @@ struct VideoDetails: View {
|
|||||||
if video != nil {
|
if video != nil {
|
||||||
Text(video!.title)
|
Text(video!.title)
|
||||||
.onAppear {
|
.onAppear {
|
||||||
#if !os(macOS)
|
|
||||||
currentPage = .details
|
currentPage = .details
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.font(.title2.bold())
|
.font(.title2.bold())
|
||||||
@ -225,11 +215,13 @@ struct VideoDetails: View {
|
|||||||
|
|
||||||
var pagePicker: some View {
|
var pagePicker: some View {
|
||||||
Picker("Page", selection: $currentPage) {
|
Picker("Page", selection: $currentPage) {
|
||||||
|
if !video.isNil {
|
||||||
Text("Details").tag(Page.details)
|
Text("Details").tag(Page.details)
|
||||||
Text("Related").tag(Page.related)
|
Text("Related").tag(Page.related)
|
||||||
|
}
|
||||||
Text("Queue").tag(Page.queue)
|
Text("Queue").tag(Page.queue)
|
||||||
}
|
}
|
||||||
|
.labelsHidden()
|
||||||
.pickerStyle(.segmented)
|
.pickerStyle(.segmented)
|
||||||
.onDisappear {
|
.onDisappear {
|
||||||
currentPage = .details
|
currentPage = .details
|
||||||
|
@ -13,21 +13,19 @@ struct VideoPlayerView: View {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@State private var playerSize: CGSize = .zero
|
||||||
@State private var fullScreen = false
|
@State private var fullScreen = false
|
||||||
|
|
||||||
#if os(iOS)
|
#if os(iOS)
|
||||||
@Environment(\.dismiss) private var dismiss
|
@Environment(\.dismiss) private var dismiss
|
||||||
@Environment(\.horizontalSizeClass) private var horizontalSizeClass
|
@Environment(\.horizontalSizeClass) private var horizontalSizeClass
|
||||||
@Environment(\.verticalSizeClass) private var verticalSizeClass
|
@Environment(\.verticalSizeClass) private var verticalSizeClass
|
||||||
|
|
||||||
private var idiom: UIUserInterfaceIdiom {
|
|
||||||
UIDevice.current.userInterfaceIdiom
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@EnvironmentObject<PlayerModel> private var player
|
@EnvironmentObject<PlayerModel> private var player
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
|
GeometryReader { geometry in
|
||||||
#if os(macOS)
|
#if os(macOS)
|
||||||
HSplitView {
|
HSplitView {
|
||||||
content
|
content
|
||||||
@ -37,10 +35,15 @@ struct VideoPlayerView: View {
|
|||||||
HStack(spacing: 0) {
|
HStack(spacing: 0) {
|
||||||
content
|
content
|
||||||
}
|
}
|
||||||
#if os(iOS)
|
.onAppear {
|
||||||
|
self.playerSize = geometry.size
|
||||||
|
}
|
||||||
|
.onChange(of: geometry.size) { size in
|
||||||
|
self.playerSize = size
|
||||||
|
}
|
||||||
.navigationBarHidden(true)
|
.navigationBarHidden(true)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var content: some View {
|
var content: some View {
|
||||||
@ -92,7 +95,7 @@ struct VideoPlayerView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
VideoDetails(fullScreen: $fullScreen)
|
VideoDetails(sidebarQueue: sidebarQueueBinding, fullScreen: $fullScreen)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
.background()
|
.background()
|
||||||
@ -105,12 +108,14 @@ struct VideoPlayerView: View {
|
|||||||
#endif
|
#endif
|
||||||
#if os(iOS)
|
#if os(iOS)
|
||||||
if sidebarQueue {
|
if sidebarQueue {
|
||||||
PlayerQueueView(fullScreen: $fullScreen)
|
PlayerQueueView(sidebarQueue: .constant(true), fullScreen: $fullScreen)
|
||||||
.frame(maxWidth: 350)
|
.frame(maxWidth: 350)
|
||||||
}
|
}
|
||||||
#elseif os(macOS)
|
#elseif os(macOS)
|
||||||
PlayerQueueView(fullScreen: $fullScreen)
|
if Defaults[.playerSidebar] != .never {
|
||||||
|
PlayerQueueView(sidebarQueue: sidebarQueueBinding, fullScreen: $fullScreen)
|
||||||
.frame(minWidth: 250)
|
.frame(minWidth: 250)
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
.onDisappear {
|
.onDisappear {
|
||||||
@ -140,18 +145,23 @@ struct VideoPlayerView: View {
|
|||||||
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: geometry.size.width / VideoPlayerView.defaultAspectRatio)
|
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: geometry.size.width / VideoPlayerView.defaultAspectRatio)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if os(iOS)
|
|
||||||
var sidebarQueue: Bool {
|
var sidebarQueue: Bool {
|
||||||
horizontalSizeClass == .regular && idiom == .pad
|
switch Defaults[.playerSidebar] {
|
||||||
|
case .never:
|
||||||
|
return false
|
||||||
|
case .always:
|
||||||
|
return true
|
||||||
|
case .whenFits:
|
||||||
|
return playerSize.width > 900
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var sidebarQueueBinding: Binding<Bool> {
|
var sidebarQueueBinding: Binding<Bool> {
|
||||||
Binding(
|
Binding(
|
||||||
get: { self.sidebarQueue },
|
get: { sidebarQueue },
|
||||||
set: { _ in }
|
set: { _ in }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct VideoPlayerView_Previews: PreviewProvider {
|
struct VideoPlayerView_Previews: PreviewProvider {
|
||||||
|
@ -3,6 +3,13 @@ import SwiftUI
|
|||||||
|
|
||||||
struct PlaybackSettings: View {
|
struct PlaybackSettings: View {
|
||||||
@Default(.quality) private var quality
|
@Default(.quality) private var quality
|
||||||
|
@Default(.playerSidebar) private var playerSidebar
|
||||||
|
|
||||||
|
#if os(iOS)
|
||||||
|
private var idiom: UIUserInterfaceIdiom {
|
||||||
|
UIDevice.current.userInterfaceIdiom
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
Section(header: Text("Quality")) {
|
Section(header: Text("Quality")) {
|
||||||
@ -18,10 +25,41 @@ struct PlaybackSettings: View {
|
|||||||
#elseif os(tvOS)
|
#elseif os(tvOS)
|
||||||
.pickerStyle(.inline)
|
.pickerStyle(.inline)
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if os(iOS)
|
||||||
|
if idiom == .pad {
|
||||||
|
playerSidebarSection
|
||||||
|
}
|
||||||
|
#elseif os(macOS)
|
||||||
|
playerSidebarSection
|
||||||
|
#endif
|
||||||
|
|
||||||
#if os(macOS)
|
#if os(macOS)
|
||||||
Spacer()
|
Spacer()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var playerSidebarSection: some View {
|
||||||
|
Section(header: Text("Player Sidebar")) {
|
||||||
|
Picker("Player Sidebar", selection: $playerSidebar) {
|
||||||
|
#if os(macOS)
|
||||||
|
Text("Show").tag(PlayerSidebarSetting.always)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if os(iOS)
|
||||||
|
Text("Show when space permits").tag(PlayerSidebarSetting.whenFits)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Text("Hide").tag(PlayerSidebarSetting.never)
|
||||||
|
}
|
||||||
|
.labelsHidden()
|
||||||
|
|
||||||
|
#if os(iOS)
|
||||||
|
.pickerStyle(.automatic)
|
||||||
|
#elseif os(tvOS)
|
||||||
|
.pickerStyle(.inline)
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ import SwiftUI
|
|||||||
struct SettingsView: View {
|
struct SettingsView: View {
|
||||||
#if os(macOS)
|
#if os(macOS)
|
||||||
private enum Tabs: Hashable {
|
private enum Tabs: Hashable {
|
||||||
case playback, services, instances
|
case instances, playback, services
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -24,14 +24,6 @@ struct SettingsView: View {
|
|||||||
}
|
}
|
||||||
.tag(Tabs.instances)
|
.tag(Tabs.instances)
|
||||||
|
|
||||||
Form {
|
|
||||||
ServicesSettings()
|
|
||||||
}
|
|
||||||
.tabItem {
|
|
||||||
Label("Services", systemImage: "puzzlepiece.extension")
|
|
||||||
}
|
|
||||||
.tag(Tabs.services)
|
|
||||||
|
|
||||||
Form {
|
Form {
|
||||||
PlaybackSettings()
|
PlaybackSettings()
|
||||||
}
|
}
|
||||||
@ -39,6 +31,14 @@ struct SettingsView: View {
|
|||||||
Label("Playback", systemImage: "play.rectangle.on.rectangle.fill")
|
Label("Playback", systemImage: "play.rectangle.on.rectangle.fill")
|
||||||
}
|
}
|
||||||
.tag(Tabs.playback)
|
.tag(Tabs.playback)
|
||||||
|
|
||||||
|
Form {
|
||||||
|
ServicesSettings()
|
||||||
|
}
|
||||||
|
.tabItem {
|
||||||
|
Label("Services", systemImage: "puzzlepiece.extension")
|
||||||
|
}
|
||||||
|
.tag(Tabs.services)
|
||||||
}
|
}
|
||||||
.padding(20)
|
.padding(20)
|
||||||
.frame(width: 400, height: 310)
|
.frame(width: 400, height: 310)
|
||||||
@ -49,8 +49,8 @@ struct SettingsView: View {
|
|||||||
AccountSelectionView()
|
AccountSelectionView()
|
||||||
#endif
|
#endif
|
||||||
InstancesSettings()
|
InstancesSettings()
|
||||||
ServicesSettings()
|
|
||||||
PlaybackSettings()
|
PlaybackSettings()
|
||||||
|
ServicesSettings()
|
||||||
}
|
}
|
||||||
.navigationTitle("Settings")
|
.navigationTitle("Settings")
|
||||||
.toolbar {
|
.toolbar {
|
||||||
|
Loading…
Reference in New Issue
Block a user