Skip to content

Commit bc5f37d

Browse files
FrancisMurilloFrancis Murillo
andauthored
Add use_permission hook (#48)
Co-authored-by: Francis Murillo <oxidation_unbolted489@simplelogin.com>
1 parent ec4584a commit bc5f37d

4 files changed

Lines changed: 79 additions & 0 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ fn counter() -> Html {
136136
- `use_swipe` - detects swipe based on TouchEvent.
137137
- `use_visible` - checks if an element is visible.
138138
- `use_hovered` - checks if an element is hovered.
139+
- `use_permission` - tracks browser's permission changes using the `Permissions` API.
139140

140141
### UI
141142

crates/yew-hooks/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ features = [
4545
"IntersectionObserverEntry",
4646
"MessageEvent",
4747
"Navigator",
48+
"Permissions",
49+
"PermissionState",
50+
"PermissionStatus",
4851
"Position",
4952
"PositionError",
5053
"PositionOptions",

crates/yew-hooks/src/hooks/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ mod use_map;
2929
mod use_measure;
3030
mod use_media;
3131
mod use_mount;
32+
mod use_permission;
3233
mod use_previous;
3334
mod use_queue;
3435
mod use_raf;
@@ -86,6 +87,7 @@ pub use use_map::*;
8687
pub use use_measure::*;
8788
pub use use_media::*;
8889
pub use use_mount::*;
90+
pub use use_permission::*;
8991
pub use use_previous::*;
9092
pub use use_queue::*;
9193
pub use use_raf::*;
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
use gloo::utils::window;
2+
use js_sys::{Object, Reflect};
3+
use wasm_bindgen::{prelude::*, JsCast};
4+
use wasm_bindgen_futures::{spawn_local, JsFuture};
5+
use web_sys::{PermissionState, PermissionStatus};
6+
use yew::prelude::*;
7+
8+
use crate::use_effect_once;
9+
10+
/// A sensor hook that tracks browser's permission changes
11+
///
12+
/// # Example
13+
///
14+
/// ```rust
15+
/// # use yew::prelude::*;
16+
/// #
17+
/// use yew_hooks::prelude::*;
18+
///
19+
/// #[function_component(UsePermission)]
20+
/// fn permission() -> Html {
21+
/// let state = use_permission("notifications".to_owned());
22+
///
23+
/// html! {
24+
/// <>
25+
/// <b>{ " state: " }</b>
26+
/// { state.to_string() }
27+
/// </>
28+
/// }
29+
/// }
30+
/// ```
31+
#[hook]
32+
pub fn use_permission(name: String) -> UseStateHandle<Option<PermissionState>> {
33+
let state = use_state(Option::<PermissionState>::default);
34+
35+
{
36+
let state = state.clone();
37+
38+
use_effect_once(move || {
39+
let state = state.clone();
40+
41+
spawn_local(async move {
42+
let permissions = window().navigator().permissions().unwrap();
43+
44+
let obj = Object::new();
45+
Reflect::set(&obj, &"name".into(), &name.into()).unwrap();
46+
47+
let fut = JsFuture::from(permissions.query(&obj).unwrap());
48+
let stat = PermissionStatus::from(fut.await.unwrap());
49+
50+
let onchange = {
51+
let state = state.clone();
52+
53+
Closure::wrap(Box::new(move |event: Event| {
54+
if let Some(target) = event.target() {
55+
let stat: PermissionStatus = target.dyn_into().unwrap();
56+
57+
state.set(Some(stat.state()));
58+
}
59+
}) as Box<dyn FnMut(Event)>)
60+
};
61+
62+
stat.set_onchange(Some(onchange.as_ref().unchecked_ref()));
63+
onchange.forget();
64+
65+
state.set(Some(stat.state()));
66+
});
67+
68+
move || {}
69+
});
70+
}
71+
72+
state
73+
}

0 commit comments

Comments
 (0)