dioxus_audio/components/
recorder.rs1use dioxus::prelude::*;
2use dioxus_icons::lucide::{Mic, Pause, Play, Square, X};
3
4use crate::recorder::{AudioRecorder, RecorderStatus};
5
6#[component]
7pub fn RecorderControls(
8 recorder: AudioRecorder,
9 #[props(default)] on_cancelled: Option<EventHandler<()>>,
10) -> Element {
11 let status = recorder.status()();
12 let state_name = recorder_state_name(&status);
13 let paused = matches!(status, RecorderStatus::Paused);
14 let has_completed = recorder.completed().read().is_some();
15
16 rsx! {
17 div {
18 class: "dioxus-audio dioxus-audio__recorder-controls",
19 "data-state": state_name,
20 match status {
21 RecorderStatus::Idle | RecorderStatus::Failed(_) => rsx! {
22 button {
23 class: "dioxus-audio__record-action dioxus-audio__record-action--record",
24 r#type: "button",
25 aria_label: if has_completed { "Clear completed recording before starting" } else { "Start recording" },
26 disabled: has_completed,
27 onclick: move |_| { let _ = recorder.start(); },
28 Mic { size: 24 }
29 }
30 },
31 RecorderStatus::RequestingPermission => rsx! {
32 button {
33 class: "dioxus-audio__record-action",
34 r#type: "button",
35 aria_label: "Cancel microphone request",
36 onclick: move |_| {
37 if recorder.cancel().is_ok()
38 && let Some(on_cancelled) = on_cancelled
39 {
40 on_cancelled.call(());
41 }
42 },
43 X { size: 20 }
44 }
45 },
46 RecorderStatus::Recording | RecorderStatus::Paused => rsx! {
47 button {
48 class: "dioxus-audio__record-action",
49 r#type: "button",
50 aria_label: "Cancel recording",
51 onclick: move |_| {
52 if recorder.cancel().is_ok()
53 && let Some(on_cancelled) = on_cancelled
54 {
55 on_cancelled.call(());
56 }
57 },
58 X { size: 20 }
59 }
60 button {
61 class: "dioxus-audio__record-action",
62 r#type: "button",
63 aria_label: if paused { "Resume" } else { "Pause" },
64 onclick: move |_| {
65 if paused {
66 let _ = recorder.resume();
67 } else {
68 let _ = recorder.pause();
69 }
70 },
71 if paused {
72 Play { size: 20 }
73 } else {
74 Pause { size: 20 }
75 }
76 }
77 button {
78 class: "dioxus-audio__record-action dioxus-audio__record-action--stop",
79 r#type: "button",
80 aria_label: "Stop recording",
81 onclick: move |_| { let _ = recorder.stop(); },
82 Square { size: 22 }
83 }
84 },
85 RecorderStatus::Stopping => rsx! {
86 button {
87 class: "dioxus-audio__record-action dioxus-audio__record-action--stop",
88 r#type: "button",
89 aria_label: "Finishing recording",
90 disabled: true,
91 Square { size: 22 }
92 }
93 },
94 }
95 }
96 }
97}
98
99fn recorder_state_name(status: &RecorderStatus) -> &'static str {
100 match status {
101 RecorderStatus::Idle => "idle",
102 RecorderStatus::RequestingPermission => "requesting",
103 RecorderStatus::Recording => "recording",
104 RecorderStatus::Paused => "paused",
105 RecorderStatus::Stopping => "stopping",
106 RecorderStatus::Failed(_) => "error",
107 }
108}