mirror of
				https://github.com/yattee/yattee.git
				synced 2025-11-03 22:22:02 +00:00 
			
		
		
		
	Regular TV layout
This commit is contained in:
		@@ -45,7 +45,7 @@ struct FixtureEnvironmentObjectsModifier: ViewModifier {
 | 
			
		||||
        player.currentItem = PlayerQueueItem(
 | 
			
		||||
            Video(
 | 
			
		||||
                videoID: "",
 | 
			
		||||
                title: "",
 | 
			
		||||
                title: "Video Name",
 | 
			
		||||
                author: "",
 | 
			
		||||
                length: 0,
 | 
			
		||||
                published: "2 days ago",
 | 
			
		||||
 
 | 
			
		||||
@@ -102,8 +102,8 @@ extension Defaults.Keys {
 | 
			
		||||
        static let playerControlsLayoutDefault = UIDevice.current.userInterfaceIdiom == .pad ? PlayerControlsLayout.medium : .small
 | 
			
		||||
        static let fullScreenPlayerControlsLayoutDefault = UIDevice.current.userInterfaceIdiom == .pad ? PlayerControlsLayout.medium : .small
 | 
			
		||||
    #elseif os(tvOS)
 | 
			
		||||
        static let playerControlsLayoutDefault = PlayerControlsLayout.veryLarge
 | 
			
		||||
        static let fullScreenPlayerControlsLayoutDefault = PlayerControlsLayout.veryLarge
 | 
			
		||||
        static let playerControlsLayoutDefault = PlayerControlsLayout.tvRegular
 | 
			
		||||
        static let fullScreenPlayerControlsLayoutDefault = PlayerControlsLayout.tvRegular
 | 
			
		||||
    #else
 | 
			
		||||
        static let playerControlsLayoutDefault = PlayerControlsLayout.medium
 | 
			
		||||
        static let fullScreenPlayerControlsLayoutDefault = PlayerControlsLayout.medium
 | 
			
		||||
@@ -129,7 +129,12 @@ extension Defaults.Keys {
 | 
			
		||||
    #if !os(macOS)
 | 
			
		||||
        static let pauseOnEnteringBackground = Key<Bool>("pauseOnEnteringBackground", default: true)
 | 
			
		||||
    #endif
 | 
			
		||||
    static let closeLastItemOnPlaybackEnd = Key<Bool>("closeLastItemOnPlaybackEnd", default: false)
 | 
			
		||||
    #if os(tvOS)
 | 
			
		||||
        static let closeLastItemOnPlaybackEndDefault = true
 | 
			
		||||
    #else
 | 
			
		||||
        static let closeLastItemOnPlaybackEndDefault = false
 | 
			
		||||
    #endif
 | 
			
		||||
    static let closeLastItemOnPlaybackEnd = Key<Bool>("closeLastItemOnPlaybackEnd", default: closeLastItemOnPlaybackEndDefault)
 | 
			
		||||
 | 
			
		||||
    #if os(tvOS)
 | 
			
		||||
        static let closePlayerOnItemCloseDefault = true
 | 
			
		||||
 
 | 
			
		||||
@@ -19,9 +19,9 @@ struct Seek: View {
 | 
			
		||||
 | 
			
		||||
    var body: some View {
 | 
			
		||||
        Button(action: model.restoreTime) {
 | 
			
		||||
            VStack(spacing: 2) {
 | 
			
		||||
            VStack(spacing: playerControlsLayout.osdSpacing) {
 | 
			
		||||
                ProgressBar(value: progress)
 | 
			
		||||
                    .frame(maxHeight: 5)
 | 
			
		||||
                    .frame(maxHeight: playerControlsLayout.osdProgressBarHeight)
 | 
			
		||||
 | 
			
		||||
                timeline
 | 
			
		||||
 | 
			
		||||
@@ -37,6 +37,7 @@ struct Seek: View {
 | 
			
		||||
                        Text(chapter.title)
 | 
			
		||||
                            .multilineTextAlignment(.center)
 | 
			
		||||
                            .font(.system(size: playerControlsLayout.chapterFontSize))
 | 
			
		||||
                            .fixedSize(horizontal: false, vertical: true)
 | 
			
		||||
                    }
 | 
			
		||||
                    if let segment = projectedSegment {
 | 
			
		||||
                        Text(SponsorBlockAPI.categoryDescription(segment.category) ?? "Sponsor")
 | 
			
		||||
@@ -44,14 +45,15 @@ struct Seek: View {
 | 
			
		||||
                            .foregroundColor(Color("AppRedColor"))
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
                    if !model.restoreSeekTime.isNil {
 | 
			
		||||
                        Divider()
 | 
			
		||||
                        Label(model.restoreSeekPlaybackTime, systemImage: "arrow.counterclockwise")
 | 
			
		||||
                            .foregroundColor(.secondary)
 | 
			
		||||
                            .font(.system(size: playerControlsLayout.chapterFontSize).monospacedDigit())
 | 
			
		||||
                            .frame(height: playerControlsLayout.chapterFontSize + 5)
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    #if !os(tvOS)
 | 
			
		||||
                        if !model.restoreSeekTime.isNil {
 | 
			
		||||
                            Divider()
 | 
			
		||||
                            Label(model.restoreSeekPlaybackTime, systemImage: "arrow.counterclockwise")
 | 
			
		||||
                                .foregroundColor(.secondary)
 | 
			
		||||
                                .font(.system(size: playerControlsLayout.chapterFontSize).monospacedDigit())
 | 
			
		||||
                                .frame(height: playerControlsLayout.chapterFontSize + 5)
 | 
			
		||||
                        }
 | 
			
		||||
                    #endif
 | 
			
		||||
                    Group {
 | 
			
		||||
                        switch model.lastSeekType {
 | 
			
		||||
                        case let .segmentSkip(category):
 | 
			
		||||
@@ -67,7 +69,7 @@ struct Seek: View {
 | 
			
		||||
            }
 | 
			
		||||
            #if os(tvOS)
 | 
			
		||||
            .frame(minWidth: 250, minHeight: 100)
 | 
			
		||||
            .padding(10)
 | 
			
		||||
            .padding(30)
 | 
			
		||||
            #endif
 | 
			
		||||
            .frame(maxWidth: playerControlsLayout.seekOSDWidth)
 | 
			
		||||
            .padding(2)
 | 
			
		||||
 
 | 
			
		||||
@@ -49,7 +49,7 @@ struct PlayerControls: View {
 | 
			
		||||
                .transition(.opacity)
 | 
			
		||||
                .frame(maxWidth: .infinity, alignment: .topLeading)
 | 
			
		||||
            #if os(tvOS)
 | 
			
		||||
                .offset(x: 10, y: 5)
 | 
			
		||||
                .offset(x: 10, y: 10)
 | 
			
		||||
                .focused($focusedField, equals: .seekOSD)
 | 
			
		||||
                .onChange(of: player.playerTime.lastSeekTime) { _ in
 | 
			
		||||
                    if !model.presentingControls {
 | 
			
		||||
@@ -108,8 +108,26 @@ struct PlayerControls: View {
 | 
			
		||||
 | 
			
		||||
                                Spacer()
 | 
			
		||||
 | 
			
		||||
                                if playerControlsLayout.displaysTitleLine {
 | 
			
		||||
                                    VStack(alignment: .leading) {
 | 
			
		||||
                                        Text(player.currentVideo?.title ?? "Not Playing")
 | 
			
		||||
                                            .shadow(radius: 10)
 | 
			
		||||
                                            .font(.system(size: playerControlsLayout.titleLineFontSize).bold())
 | 
			
		||||
                                            .lineLimit(1)
 | 
			
		||||
 | 
			
		||||
                                        Text(player.currentVideo?.channel.name ?? "")
 | 
			
		||||
                                            .fontWeight(.semibold)
 | 
			
		||||
                                            .shadow(radius: 10)
 | 
			
		||||
                                            .foregroundColor(.secondary)
 | 
			
		||||
                                            .font(.system(size: playerControlsLayout.authorLineFontSize))
 | 
			
		||||
                                            .lineLimit(1)
 | 
			
		||||
                                    }
 | 
			
		||||
 | 
			
		||||
                                    .frame(maxWidth: .infinity, alignment: .leading)
 | 
			
		||||
                                    .offset(y: -40)
 | 
			
		||||
                                }
 | 
			
		||||
 | 
			
		||||
                                timeline
 | 
			
		||||
                                    .frame(maxWidth: 1000)
 | 
			
		||||
                                    .padding(.bottom, 2)
 | 
			
		||||
                            }
 | 
			
		||||
                            .zIndex(1)
 | 
			
		||||
@@ -135,9 +153,6 @@ struct PlayerControls: View {
 | 
			
		||||
                                    musicModeButton
 | 
			
		||||
                                #endif
 | 
			
		||||
                            }
 | 
			
		||||
                            #if os(tvOS)
 | 
			
		||||
                            .frame(width: 1200)
 | 
			
		||||
                            #endif
 | 
			
		||||
                            .zIndex(0)
 | 
			
		||||
                            #if os(tvOS)
 | 
			
		||||
                                .offset(y: -playerControlsLayout.timelineHeight - 30)
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,7 @@ import Defaults
 | 
			
		||||
import Foundation
 | 
			
		||||
 | 
			
		||||
enum PlayerControlsLayout: String, CaseIterable, Defaults.Serializable {
 | 
			
		||||
    case tvRegular
 | 
			
		||||
    case veryLarge
 | 
			
		||||
    case large
 | 
			
		||||
    case medium
 | 
			
		||||
@@ -10,6 +11,8 @@ enum PlayerControlsLayout: String, CaseIterable, Defaults.Serializable {
 | 
			
		||||
 | 
			
		||||
    var description: String {
 | 
			
		||||
        switch self {
 | 
			
		||||
        case .tvRegular:
 | 
			
		||||
            return "TV"
 | 
			
		||||
        case .veryLarge:
 | 
			
		||||
            return "Very Large"
 | 
			
		||||
        default:
 | 
			
		||||
@@ -19,6 +22,8 @@ enum PlayerControlsLayout: String, CaseIterable, Defaults.Serializable {
 | 
			
		||||
 | 
			
		||||
    var buttonsSpacing: Double {
 | 
			
		||||
        switch self {
 | 
			
		||||
        case .tvRegular:
 | 
			
		||||
            return 80
 | 
			
		||||
        case .veryLarge:
 | 
			
		||||
            return 40
 | 
			
		||||
        case .large:
 | 
			
		||||
@@ -34,6 +39,8 @@ enum PlayerControlsLayout: String, CaseIterable, Defaults.Serializable {
 | 
			
		||||
 | 
			
		||||
    var buttonFontSize: Double {
 | 
			
		||||
        switch self {
 | 
			
		||||
        case .tvRegular:
 | 
			
		||||
            return 48
 | 
			
		||||
        case .veryLarge:
 | 
			
		||||
            return 35
 | 
			
		||||
        case .large:
 | 
			
		||||
@@ -49,6 +56,8 @@ enum PlayerControlsLayout: String, CaseIterable, Defaults.Serializable {
 | 
			
		||||
 | 
			
		||||
    var bigButtonFontSize: Double {
 | 
			
		||||
        switch self {
 | 
			
		||||
        case .tvRegular:
 | 
			
		||||
            return 65
 | 
			
		||||
        case .veryLarge:
 | 
			
		||||
            return 55
 | 
			
		||||
        case .large:
 | 
			
		||||
@@ -64,6 +73,8 @@ enum PlayerControlsLayout: String, CaseIterable, Defaults.Serializable {
 | 
			
		||||
 | 
			
		||||
    var buttonSize: Double {
 | 
			
		||||
        switch self {
 | 
			
		||||
        case .tvRegular:
 | 
			
		||||
            return 90
 | 
			
		||||
        case .veryLarge:
 | 
			
		||||
            return 60
 | 
			
		||||
        case .large:
 | 
			
		||||
@@ -79,6 +90,8 @@ enum PlayerControlsLayout: String, CaseIterable, Defaults.Serializable {
 | 
			
		||||
 | 
			
		||||
    var bigButtonSize: Double {
 | 
			
		||||
        switch self {
 | 
			
		||||
        case .tvRegular:
 | 
			
		||||
            return 100
 | 
			
		||||
        case .veryLarge:
 | 
			
		||||
            return 85
 | 
			
		||||
        case .large:
 | 
			
		||||
@@ -94,6 +107,8 @@ enum PlayerControlsLayout: String, CaseIterable, Defaults.Serializable {
 | 
			
		||||
 | 
			
		||||
    var segmentFontSize: Double {
 | 
			
		||||
        switch self {
 | 
			
		||||
        case .tvRegular:
 | 
			
		||||
            return 20
 | 
			
		||||
        case .veryLarge:
 | 
			
		||||
            return 16
 | 
			
		||||
        case .large:
 | 
			
		||||
@@ -109,6 +124,8 @@ enum PlayerControlsLayout: String, CaseIterable, Defaults.Serializable {
 | 
			
		||||
 | 
			
		||||
    var chapterFontSize: Double {
 | 
			
		||||
        switch self {
 | 
			
		||||
        case .tvRegular:
 | 
			
		||||
            return 24
 | 
			
		||||
        case .veryLarge:
 | 
			
		||||
            return 20
 | 
			
		||||
        case .large:
 | 
			
		||||
@@ -124,6 +141,8 @@ enum PlayerControlsLayout: String, CaseIterable, Defaults.Serializable {
 | 
			
		||||
 | 
			
		||||
    var projectedTimeFontSize: Double {
 | 
			
		||||
        switch self {
 | 
			
		||||
        case .tvRegular:
 | 
			
		||||
            return 30
 | 
			
		||||
        case .veryLarge:
 | 
			
		||||
            return 25
 | 
			
		||||
        case .large:
 | 
			
		||||
@@ -139,6 +158,8 @@ enum PlayerControlsLayout: String, CaseIterable, Defaults.Serializable {
 | 
			
		||||
 | 
			
		||||
    var thumbSize: Double {
 | 
			
		||||
        switch self {
 | 
			
		||||
        case .tvRegular:
 | 
			
		||||
            return 45
 | 
			
		||||
        case .veryLarge:
 | 
			
		||||
            return 35
 | 
			
		||||
        case .large:
 | 
			
		||||
@@ -154,6 +175,8 @@ enum PlayerControlsLayout: String, CaseIterable, Defaults.Serializable {
 | 
			
		||||
 | 
			
		||||
    var timeFontSize: Double {
 | 
			
		||||
        switch self {
 | 
			
		||||
        case .tvRegular:
 | 
			
		||||
            return 45
 | 
			
		||||
        case .veryLarge:
 | 
			
		||||
            return 35
 | 
			
		||||
        case .large:
 | 
			
		||||
@@ -169,6 +192,8 @@ enum PlayerControlsLayout: String, CaseIterable, Defaults.Serializable {
 | 
			
		||||
 | 
			
		||||
    var bufferingStateFontSize: Double {
 | 
			
		||||
        switch self {
 | 
			
		||||
        case .tvRegular:
 | 
			
		||||
            return 45
 | 
			
		||||
        case .veryLarge:
 | 
			
		||||
            return 30
 | 
			
		||||
        case .large:
 | 
			
		||||
@@ -184,6 +209,8 @@ enum PlayerControlsLayout: String, CaseIterable, Defaults.Serializable {
 | 
			
		||||
 | 
			
		||||
    var timeLeadingEdgePadding: Double {
 | 
			
		||||
        switch self {
 | 
			
		||||
        case .tvRegular:
 | 
			
		||||
            return 20
 | 
			
		||||
        case .veryLarge:
 | 
			
		||||
            return 5
 | 
			
		||||
        case .large:
 | 
			
		||||
@@ -199,6 +226,8 @@ enum PlayerControlsLayout: String, CaseIterable, Defaults.Serializable {
 | 
			
		||||
 | 
			
		||||
    var timeTrailingEdgePadding: Double {
 | 
			
		||||
        switch self {
 | 
			
		||||
        case .tvRegular:
 | 
			
		||||
            return 20
 | 
			
		||||
        case .veryLarge:
 | 
			
		||||
            return 16
 | 
			
		||||
        case .large:
 | 
			
		||||
@@ -214,6 +243,8 @@ enum PlayerControlsLayout: String, CaseIterable, Defaults.Serializable {
 | 
			
		||||
 | 
			
		||||
    var timelineHeight: Double {
 | 
			
		||||
        switch self {
 | 
			
		||||
        case .tvRegular:
 | 
			
		||||
            return 80
 | 
			
		||||
        case .veryLarge:
 | 
			
		||||
            return 40
 | 
			
		||||
        case .large:
 | 
			
		||||
@@ -229,6 +260,8 @@ enum PlayerControlsLayout: String, CaseIterable, Defaults.Serializable {
 | 
			
		||||
 | 
			
		||||
    var seekOSDWidth: Double {
 | 
			
		||||
        switch self {
 | 
			
		||||
        case .tvRegular:
 | 
			
		||||
            return 240
 | 
			
		||||
        case .veryLarge:
 | 
			
		||||
            return 240
 | 
			
		||||
        case .large:
 | 
			
		||||
@@ -245,4 +278,50 @@ enum PlayerControlsLayout: String, CaseIterable, Defaults.Serializable {
 | 
			
		||||
    var osdVerticalOffset: Double {
 | 
			
		||||
        buttonSize
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    var osdProgressBarHeight: Double {
 | 
			
		||||
        switch self {
 | 
			
		||||
        case .tvRegular:
 | 
			
		||||
            return 20
 | 
			
		||||
        case .veryLarge:
 | 
			
		||||
            return 10
 | 
			
		||||
        case .large:
 | 
			
		||||
            return 8
 | 
			
		||||
        case .medium:
 | 
			
		||||
            return 5
 | 
			
		||||
        case .small:
 | 
			
		||||
            return 5
 | 
			
		||||
        case .smaller:
 | 
			
		||||
            return 2
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    var osdSpacing: Double {
 | 
			
		||||
        switch self {
 | 
			
		||||
        case .tvRegular:
 | 
			
		||||
            return 8
 | 
			
		||||
        case .veryLarge:
 | 
			
		||||
            return 8
 | 
			
		||||
        case .large:
 | 
			
		||||
            return 6
 | 
			
		||||
        case .medium:
 | 
			
		||||
            return 4
 | 
			
		||||
        case .small:
 | 
			
		||||
            return 2
 | 
			
		||||
        case .smaller:
 | 
			
		||||
            return 2
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    var displaysTitleLine: Bool {
 | 
			
		||||
        self == .tvRegular
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    var titleLineFontSize: Double {
 | 
			
		||||
        60
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    var authorLineFontSize: Double {
 | 
			
		||||
        30
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -60,7 +60,9 @@ struct VideoPlayerView: View {
 | 
			
		||||
    @EnvironmentObject<PlayerModel> internal var player
 | 
			
		||||
    @EnvironmentObject<PlayerControlsModel> internal var playerControls
 | 
			
		||||
    @EnvironmentObject<RecentsModel> internal var recents
 | 
			
		||||
    @EnvironmentObject<SearchModel> internal var search
 | 
			
		||||
    #if os(macOS)
 | 
			
		||||
        @EnvironmentObject<SearchModel> internal var search
 | 
			
		||||
    #endif
 | 
			
		||||
    @EnvironmentObject<ThumbnailsModel> internal var thumbnails
 | 
			
		||||
 | 
			
		||||
    @Default(.horizontalPlayerGestureEnabled) var horizontalPlayerGestureEnabled
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user