import AppIntents /// What a widget or control button asks the player to do. [MixRemote] carries it out: the app's version drives /// the player, the widget extension's does nothing, since audio intents run in the app's process. enum MixAction: Sendable { case cycle case nudge(String, Int) case mute(String) case playPause } struct CycleMixIntent: AudioPlaybackIntent { static let title: LocalizedStringResource = "Change Mix" static let description = IntentDescription("Moves to the next stem mix, in the order set in the Stem Editor.") init() {} func perform() async throws -> some IntentResult { await MixRemote.run(.cycle) return .result() } } struct NudgeStemIntent: AudioPlaybackIntent { static let title: LocalizedStringResource = "Turn a Stem Up or Down" static let isDiscoverable = false @Parameter(title: "Stem") var stem: String @Parameter(title: "Steps") var steps: Int init() {} init(stem: String, steps: Int) { self.stem = stem self.steps = steps } func perform() async throws -> some IntentResult { await MixRemote.run(.nudge(stem, steps)) return .result() } } struct MuteStemIntent: AudioPlaybackIntent { static let title: LocalizedStringResource = "Mute or Unmute a Stem" static let isDiscoverable = false @Parameter(title: "Stem") var stem: String init() {} init(stem: String) { self.stem = stem } func perform() async throws -> some IntentResult { await MixRemote.run(.mute(stem)) return .result() } } struct PlayPauseIntent: AudioPlaybackIntent { static let title: LocalizedStringResource = "Play or Pause" static let isDiscoverable = false init() {} func perform() async throws -> some IntentResult { await MixRemote.run(.playPause) return .result() } }