import AppIntents import Commanding import Recording import SwiftUI import WidgetKit /// The buttons controlling the recording flow through the App Intents the app executes, matching the current state: a pause /// button while recording; discard, resume, and send buttons while paused; and only a discard button while the recorded input /// is being processed. struct RecordingControls: View { // MARK: Properties /// The dynamic content of the Live Activity to render. let state: RecordingActivityAttributes.ContentState // MARK: Body var body: some View { HStack( spacing: Constant.Spacing.stack ) { switch state.state { case .recording: Button(intent: ToggleRecordingIntent()) { Image.Symbol.pause .resizable() } .buttonStyle(.action( type: .default )) case .paused: Button(intent: DiscardRecordingIntent()) { Image.Symbol.discard .resizable() } .buttonStyle(.action( type: .destructive )) Button(intent: ToggleRecordingIntent()) { Image.Symbol.microphone .resizable() } .buttonStyle(.action( type: .default )) Button(intent: ProcessRecordingIntent()) { Image.Symbol.send .resizable() } .buttonStyle(.action( type: .confirmative )) case .processing: Button(intent: DiscardRecordingIntent()) { Image.Symbol.discard .resizable() } .buttonStyle(.action( type: .destructive )) } } .buttonStyle(.borderedProminent) } } // MARK: - Constants /// The constant values used across the recording Live Activity. private enum Constant { /// The spacing constants. enum Spacing { /// The spacing between the elements of a stack. static let stack: CGFloat = 16 } } // MARK: - Previews #Preview( "Recording Controls view", as: .content, using: RecordingActivityAttributes() ) { RecordingLiveActivity() } contentStates: { RecordingActivityAttributes.ContentState( state: .recording, anchor: .now, elapsed: 0 ) RecordingActivityAttributes.ContentState( state: .paused, anchor: nil, elapsed: 42 ) RecordingActivityAttributes.ContentState( state: .processing, anchor: nil, elapsed: 42 ) }