mirror of
https://github.com/adoyle0/leptos-use.git
synced 2025-01-23 09:09:21 -05:00
parent
93b827dfc3
commit
1e9e03feb8
2 changed files with 83 additions and 61 deletions
|
@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
- `use_device_pixel_ratio` (thanks to @mondeja)
|
- `use_device_pixel_ratio` (thanks to @mondeja)
|
||||||
- `use_element_bounding`
|
- `use_element_bounding`
|
||||||
|
|
||||||
|
### Fixes 🍕
|
||||||
|
|
||||||
|
- Fixed `use_geolocation` SSR compile issue
|
||||||
|
|
||||||
### Changes 🔥
|
### Changes 🔥
|
||||||
|
|
||||||
- The `UseMouseReturn` signals `x`, `y`, and `source_type` are now of type `Signal<f64>` instead of `ReadSignal<f64>`.
|
- The `UseMouseReturn` signals `x`, `y`, and `source_type` are now of type `Signal<f64>` instead of `ReadSignal<f64>`.
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
use crate::use_window;
|
use cfg_if::cfg_if;
|
||||||
use default_struct_builder::DefaultBuilder;
|
use default_struct_builder::DefaultBuilder;
|
||||||
use leptos::*;
|
use leptos::*;
|
||||||
use std::cell::Cell;
|
|
||||||
use std::rc::Rc;
|
|
||||||
use wasm_bindgen::prelude::*;
|
|
||||||
|
|
||||||
/// Reactive [Geolocation API](https://developer.mozilla.org/en-US/docs/Web/API/Geolocation_API).
|
/// Reactive [Geolocation API](https://developer.mozilla.org/en-US/docs/Web/API/Geolocation_API).
|
||||||
/// It allows the user to provide their location to web applications if they so desire. For privacy reasons,
|
/// It allows the user to provide their location to web applications if they so desire. For privacy reasons,
|
||||||
|
@ -32,6 +29,10 @@ use wasm_bindgen::prelude::*;
|
||||||
/// # view! { }
|
/// # view! { }
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
|
///
|
||||||
|
/// ## Server-Side Rendering
|
||||||
|
///
|
||||||
|
/// On the server all signals returns will always contain `None` and the functions do nothing.
|
||||||
pub fn use_geolocation() -> UseGeolocationReturn<impl Fn() + Clone, impl Fn() + Clone> {
|
pub fn use_geolocation() -> UseGeolocationReturn<impl Fn() + Clone, impl Fn() + Clone> {
|
||||||
use_geolocation_with_options(UseGeolocationOptions::default())
|
use_geolocation_with_options(UseGeolocationOptions::default())
|
||||||
}
|
}
|
||||||
|
@ -44,74 +45,89 @@ pub fn use_geolocation_with_options(
|
||||||
let (error, set_error) = create_signal(None::<web_sys::PositionError>);
|
let (error, set_error) = create_signal(None::<web_sys::PositionError>);
|
||||||
let (coords, set_coords) = create_signal(None::<web_sys::Coordinates>);
|
let (coords, set_coords) = create_signal(None::<web_sys::Coordinates>);
|
||||||
|
|
||||||
let update_position = move |position: web_sys::Position| {
|
cfg_if! { if #[cfg(feature = "ssr")] {
|
||||||
set_located_at.set(Some(position.timestamp()));
|
let resume = || ();
|
||||||
set_coords.set(Some(position.coords()));
|
let pause = || ();
|
||||||
set_error.set(None);
|
|
||||||
};
|
|
||||||
|
|
||||||
let on_error = move |err: web_sys::PositionError| {
|
let _ = options;
|
||||||
set_error.set(Some(err));
|
let _ = set_located_at;
|
||||||
};
|
let _ = set_error;
|
||||||
|
let _ = set_coords;
|
||||||
|
} else {
|
||||||
|
use crate::use_window;
|
||||||
|
use std::cell::Cell;
|
||||||
|
use std::rc::Rc;
|
||||||
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
let watch_handle = Rc::new(Cell::new(None::<i32>));
|
let update_position = move |position: web_sys::Position| {
|
||||||
|
set_located_at.set(Some(position.timestamp()));
|
||||||
|
set_coords.set(Some(position.coords()));
|
||||||
|
set_error.set(None);
|
||||||
|
};
|
||||||
|
|
||||||
let resume = {
|
let on_error = move |err: web_sys::PositionError| {
|
||||||
let watch_handle = Rc::clone(&watch_handle);
|
set_error.set(Some(err));
|
||||||
let position_options = options.as_position_options();
|
};
|
||||||
|
|
||||||
move || {
|
let watch_handle = Rc::new(Cell::new(None::<i32>));
|
||||||
let navigator = use_window().navigator();
|
|
||||||
if let Some(navigator) = navigator {
|
|
||||||
if let Ok(geolocation) = navigator.geolocation() {
|
|
||||||
let update_position =
|
|
||||||
Closure::wrap(Box::new(update_position) as Box<dyn Fn(web_sys::Position)>);
|
|
||||||
let on_error =
|
|
||||||
Closure::wrap(Box::new(on_error) as Box<dyn Fn(web_sys::PositionError)>);
|
|
||||||
|
|
||||||
watch_handle.replace(
|
let resume = {
|
||||||
geolocation
|
let watch_handle = Rc::clone(&watch_handle);
|
||||||
.watch_position_with_error_callback_and_options(
|
let position_options = options.as_position_options();
|
||||||
update_position.as_ref().unchecked_ref(),
|
|
||||||
Some(on_error.as_ref().unchecked_ref()),
|
|
||||||
&position_options,
|
|
||||||
)
|
|
||||||
.ok(),
|
|
||||||
);
|
|
||||||
|
|
||||||
update_position.forget();
|
move || {
|
||||||
on_error.forget();
|
let navigator = use_window().navigator();
|
||||||
}
|
if let Some(navigator) = navigator {
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if options.immediate {
|
|
||||||
resume();
|
|
||||||
}
|
|
||||||
|
|
||||||
let pause = {
|
|
||||||
let watch_handle = Rc::clone(&watch_handle);
|
|
||||||
|
|
||||||
move || {
|
|
||||||
let navigator = use_window().navigator();
|
|
||||||
if let Some(navigator) = navigator {
|
|
||||||
if let Some(handle) = watch_handle.take() {
|
|
||||||
if let Ok(geolocation) = navigator.geolocation() {
|
if let Ok(geolocation) = navigator.geolocation() {
|
||||||
geolocation.clear_watch(handle);
|
let update_position =
|
||||||
|
Closure::wrap(Box::new(update_position) as Box<dyn Fn(web_sys::Position)>);
|
||||||
|
let on_error =
|
||||||
|
Closure::wrap(Box::new(on_error) as Box<dyn Fn(web_sys::PositionError)>);
|
||||||
|
|
||||||
|
watch_handle.replace(
|
||||||
|
geolocation
|
||||||
|
.watch_position_with_error_callback_and_options(
|
||||||
|
update_position.as_ref().unchecked_ref(),
|
||||||
|
Some(on_error.as_ref().unchecked_ref()),
|
||||||
|
&position_options,
|
||||||
|
)
|
||||||
|
.ok(),
|
||||||
|
);
|
||||||
|
|
||||||
|
update_position.forget();
|
||||||
|
on_error.forget();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
};
|
|
||||||
|
|
||||||
on_cleanup({
|
if options.immediate {
|
||||||
let pause = pause.clone();
|
resume();
|
||||||
|
|
||||||
move || {
|
|
||||||
pause();
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
let pause = {
|
||||||
|
let watch_handle = Rc::clone(&watch_handle);
|
||||||
|
|
||||||
|
move || {
|
||||||
|
let navigator = use_window().navigator();
|
||||||
|
if let Some(navigator) = navigator {
|
||||||
|
if let Some(handle) = watch_handle.take() {
|
||||||
|
if let Ok(geolocation) = navigator.geolocation() {
|
||||||
|
geolocation.clear_watch(handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
on_cleanup({
|
||||||
|
let pause = pause.clone();
|
||||||
|
|
||||||
|
move || {
|
||||||
|
pause();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
|
||||||
UseGeolocationReturn {
|
UseGeolocationReturn {
|
||||||
coords: coords.into(),
|
coords: coords.into(),
|
||||||
|
@ -123,7 +139,8 @@ pub fn use_geolocation_with_options(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Options for [`use_geolocation_with_options`].
|
/// Options for [`use_geolocation_with_options`].
|
||||||
#[derive(DefaultBuilder)]
|
#[derive(DefaultBuilder, Clone)]
|
||||||
|
#[allow(dead_code)]
|
||||||
pub struct UseGeolocationOptions {
|
pub struct UseGeolocationOptions {
|
||||||
/// If `true` the geolocation watch is started when this function is called.
|
/// If `true` the geolocation watch is started when this function is called.
|
||||||
/// If `false` you have to call `resume` manually to start it. Defaults to `true`.
|
/// If `false` you have to call `resume` manually to start it. Defaults to `true`.
|
||||||
|
@ -159,6 +176,7 @@ impl Default for UseGeolocationOptions {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "ssr"))]
|
||||||
impl UseGeolocationOptions {
|
impl UseGeolocationOptions {
|
||||||
fn as_position_options(&self) -> web_sys::PositionOptions {
|
fn as_position_options(&self) -> web_sys::PositionOptions {
|
||||||
let UseGeolocationOptions {
|
let UseGeolocationOptions {
|
||||||
|
|
Loading…
Add table
Reference in a new issue