dioxus_std/geolocation/
use_geolocation.rs1use super::core::{Error, Event, Geocoordinates, Geolocator, PowerMode, Status};
4use dioxus::{
5 prelude::{
6 provide_context, try_consume_context, use_coroutine, use_hook, use_signal, Signal,
7 UnboundedReceiver,
8 },
9 signals::{Readable, Writable},
10};
11use futures_util::stream::StreamExt;
12use std::sync::Once;
13
14static INIT: Once = Once::new();
15
16pub fn use_geolocation() -> Result<Geocoordinates, Error> {
18 let mut coords: Signal<Result<Geocoordinates, Error>> =
20 use_signal(|| Err(Error::NotInitialized));
21 let Some(geolocator) = try_consume_context::<Signal<Result<Geolocator, Error>>>() else {
22 return Err(Error::NotInitialized);
23 };
24 let geolocator = geolocator.read();
25
26 let Ok(geolocator) = geolocator.as_ref() else {
28 return Err(Error::NotInitialized);
29 };
30
31 let listener = use_coroutine(|mut rx: UnboundedReceiver<Event>| async move {
33 while let Some(event) = rx.next().await {
34 match event {
35 Event::NewGeocoordinates(new_coords) => {
36 *coords.write() = Ok(new_coords);
37 }
38 Event::StatusChanged(Status::Disabled) => {
39 *coords.write() = Err(Error::AccessDenied);
40 }
41 _ => {}
42 }
43 }
44 });
45
46 INIT.call_once(|| {
48 geolocator.listen(listener).ok();
49 });
50
51 coords.read_unchecked().clone()
53}
54
55pub fn init_geolocator(power_mode: PowerMode) -> Signal<Result<Geolocator, Error>> {
57 use_hook(|| {
58 let geolocator = Signal::new(Geolocator::new(power_mode));
59 provide_context(geolocator)
60 })
61}