jellyflood/Swiftfin tvOS/Views/VideoPlayerContainerState/PlaybackControls/Components/ActionButtons/ActionButtons.swift

127 lines
3.9 KiB
Swift

//
// 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 (c) 2025 Jellyfin & Jellyfin Contributors
//
import Defaults
import SwiftUI
extension VideoPlayer.PlaybackControls.NavigationBar {
struct ActionButtons: View {
@Default(.VideoPlayer.barActionButtons)
private var rawBarActionButtons
@Default(.VideoPlayer.menuActionButtons)
private var rawMenuActionButtons
@EnvironmentObject
private var containerState: VideoPlayerContainerState
@EnvironmentObject
private var manager: MediaPlayerManager
private func filteredActionButtons(_ rawButtons: [VideoPlayerActionButton]) -> [VideoPlayerActionButton] {
var filteredButtons = rawButtons
if manager.playbackItem?.audioStreams.isEmpty == true {
filteredButtons.removeAll { $0 == .audio }
}
if manager.playbackItem?.subtitleStreams.isEmpty == true {
filteredButtons.removeAll { $0 == .subtitles }
}
if manager.queue == nil {
filteredButtons.removeAll { $0 == .autoPlay }
filteredButtons.removeAll { $0 == .playNextItem }
filteredButtons.removeAll { $0 == .playPreviousItem }
}
if manager.item.isLiveStream {
filteredButtons.removeAll { $0 == .audio }
filteredButtons.removeAll { $0 == .autoPlay }
filteredButtons.removeAll { $0 == .playbackSpeed }
// filteredButtons.removeAll { $0 == .playbackQuality }
filteredButtons.removeAll { $0 == .subtitles }
}
return filteredButtons
}
private var barActionButtons: [VideoPlayerActionButton] {
filteredActionButtons(rawBarActionButtons)
}
private var menuActionButtons: [VideoPlayerActionButton] {
filteredActionButtons(rawMenuActionButtons)
}
@ViewBuilder
private func view(for button: VideoPlayerActionButton) -> some View {
switch button {
case .aspectFill:
AspectFill()
case .audio:
Audio()
case .autoPlay:
AutoPlay()
case .gestureLock:
EmptyView()
// GestureLock()
case .playbackSpeed:
EmptyView()
// PlaybackRateMenu()
// case .playbackQuality:
// PlaybackQuality()
case .playNextItem:
PlayNextItem()
case .playPreviousItem:
PlayPreviousItem()
case .subtitles:
Subtitles()
}
}
@ViewBuilder
private var menuButtons: some View {
Menu(
"Menu",
systemImage: "ellipsis.circle"
) {
ForEach(menuActionButtons) { actionButton in
view(for: actionButton)
}
}
}
var body: some View {
HStack(spacing: 10) {
ForEach(
barActionButtons,
content: view(for:)
)
if menuActionButtons.isNotEmpty {
Menu(
L10n.menu,
systemImage: "ellipsis.circle"
) {
ForEach(
menuActionButtons,
content: view(for:)
)
.environment(\.isInMenu, true)
}
}
}
.menuStyle(.button)
.labelStyle(.iconOnly)
.buttonBorderShape(.circle)
.buttonStyle(.plain)
}
}
}