Skip to content

Commit

Permalink
Support actions for the standard settings menu (#1160)
Browse files Browse the repository at this point in the history
  • Loading branch information
defagos authored Mar 7, 2025
1 parent e39b5b9 commit 70e9697
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 6 deletions.
16 changes: 16 additions & 0 deletions Sources/Player/Types/SettingsUpdate.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//
// Copyright (c) SRG SSR. All rights reserved.
//
// License information is available from the LICENSE file.
//

import AVFoundation

/// A settings update.
public enum SettingsUpdate {
/// Playback speed.
case playbackSpeed(Float)

/// Media selection.
case mediaSelection(characteristic: AVMediaCharacteristic, option: MediaSelectionOption)
}
29 changes: 23 additions & 6 deletions Sources/Player/UserInterface/SettingsMenu.swift
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ private struct MediaSelectionMenuContent: View {
@available(iOS 16.0, tvOS 17.0, *)
private struct SettingsMenuContent: View {
let player: Player
let speeds: Set<Float>
let action: (SettingsUpdate) -> Void

var body: some View {
playbackSpeedMenu()
Expand All @@ -93,7 +95,9 @@ private struct SettingsMenuContent: View {

private func playbackSpeedMenu() -> some View {
Menu {
player.playbackSpeedMenu()
player.playbackSpeedMenu(speeds: speeds) { speed in
action(.playbackSpeed(speed))
}
} label: {
Label {
Text("Playback Speed", bundle: .module, comment: "Playback setting menu title")
Expand All @@ -105,7 +109,7 @@ private struct SettingsMenuContent: View {

private func audibleMediaSelectionMenu() -> some View {
Menu {
player.mediaSelectionMenu(characteristic: .audible)
mediaSelectionMenuContent(characteristic: .audible)
} label: {
Label {
Text("Languages", bundle: .module, comment: "Playback setting menu title")
Expand All @@ -117,7 +121,7 @@ private struct SettingsMenuContent: View {

private func legibleMediaSelectionMenu() -> some View {
Menu {
player.mediaSelectionMenu(characteristic: .legible)
mediaSelectionMenuContent(characteristic: .legible)
} label: {
Label {
Text("Subtitles", bundle: .module, comment: "Playback setting menu title")
Expand All @@ -126,23 +130,36 @@ private struct SettingsMenuContent: View {
}
}
}

private func mediaSelectionMenuContent(characteristic: AVMediaCharacteristic) -> some View {
player.mediaSelectionMenu(characteristic: characteristic) { option in
action(.mediaSelection(characteristic: characteristic, option: option))
}
}
}

@available(iOS 16.0, tvOS 17.0, *)
public extension Player {
/// Returns content for a standard player settings menu.
///
/// - Parameters:
/// - speeds: The offered playback speeds.
/// - action: The action to perform when the user interacts with an item from the menu.
///
/// The returned view is meant to be used as content of a `Menu`. Using it for any other purpose has undefined
/// behavior.
///
func standardSettingsMenu() -> some View {
SettingsMenuContent(player: self)
func standardSettingsMenu(
speeds: Set<Float> = [0.5, 1, 1.25, 1.5, 2],
action: @escaping (_ update: SettingsUpdate) -> Void = { _ in }
) -> some View {
SettingsMenuContent(player: self, speeds: speeds, action: action)
}

/// Returns content for a playback speed menu.
///
/// - Parameters:
/// - speeds: The offered speeds.
/// - speeds: The offered playback speeds.
/// - action: The action to perform when the user interacts with an item from the menu.
///
/// The returned view is meant to be used as content of a `Menu`. Using it for any other purpose has undefined
Expand Down

0 comments on commit 70e9697

Please sign in to comment.