dioxus_cameras/streams.rs
1use dioxus::prelude::*;
2
3/// Handle returned by [`use_streams`].
4#[derive(Copy, Clone, PartialEq)]
5pub struct UseStreams {
6 /// The current list of active stream ids, in insertion order.
7 ///
8 /// Because `ids` is a field (not a method), call `let ids = streams.ids;`
9 /// before reading so `rsx!` can use `ids()` as a Signal call, Rust's
10 /// method-call syntax would otherwise treat `streams.ids()` as a method.
11 pub ids: Signal<Vec<u32>>,
12 /// Callback that appends a fresh id and returns it.
13 ///
14 /// Ids are allocated monotonically from 0 and never reused within one
15 /// hook instance, so the returned id is safe to use as a Dioxus key.
16 pub add: Callback<(), u32>,
17 /// Callback that removes the given id from the list. No-op if absent.
18 ///
19 /// The stream's [`Registry`](crate::Registry) entry and camera pump are
20 /// torn down automatically via the
21 /// [`use_camera_stream`](crate::use_camera_stream) drop guard when the
22 /// corresponding component unmounts, you do not need to touch the
23 /// registry here.
24 pub remove: Callback<u32>,
25}
26
27/// Hook that manages a dynamic list of stream ids for multi-stream apps.
28///
29/// Typical usage:
30///
31/// ```no_run
32/// use dioxus::prelude::*;
33/// use dioxus_cameras::{StreamPreview, use_streams};
34///
35/// fn app() -> Element {
36/// let streams = use_streams();
37/// let ids = streams.ids;
38/// rsx! {
39/// button { onclick: move |_| { streams.add.call(()); }, "Add stream" }
40/// for id in ids() {
41/// StreamPreview { key: "{id}", id }
42/// }
43/// }
44/// }
45/// ```
46pub fn use_streams() -> UseStreams {
47 let mut next_id = use_signal(|| 0u32);
48 let mut ids = use_signal(Vec::<u32>::new);
49
50 let add = use_callback(move |()| {
51 let id = *next_id.peek();
52 next_id.set(id + 1);
53 ids.write().push(id);
54 id
55 });
56
57 let remove = use_callback(move |id: u32| {
58 ids.write().retain(|other| *other != id);
59 });
60
61 UseStreams { ids, add, remove }
62}