From 8944002b9af28d18b8b841da62e99c782dfa6f24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ail=C3=A9n=20Grimaldi?= <63558201+ail3ngrimaldi@users.noreply.github.com> Date: Thu, 10 Oct 2024 11:09:21 -0300 Subject: [PATCH] Add hook to determine location (#101) * Add hook to determine location * feat: create action transfer as community (#112) * feat: deposit from Kusama to Kreivo (#114) --------- Co-authored-by: Brayan Vargas <86427419+b-avb@users.noreply.github.com> --- src/hooks/use_location.rs | 78 +++++++++++++++++++++++++++++++++++++++ src/lib.rs | 1 + 2 files changed, 79 insertions(+) create mode 100644 src/hooks/use_location.rs diff --git a/src/hooks/use_location.rs b/src/hooks/use_location.rs new file mode 100644 index 0000000..5884dbe --- /dev/null +++ b/src/hooks/use_location.rs @@ -0,0 +1,78 @@ +use dioxus::prelude::*; +use serde::{Deserialize, Serialize}; +use gloo::storage::{LocalStorage, Storage}; +use wasm_bindgen_futures::spawn_local; + +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct Location { + pub city: String, + pub country: String, +} + +#[derive(Clone, Debug)] +pub enum LocationError { + FetchError, + StorageError, +} + +pub fn use_location() -> UseLocationState { + let mut location = use_signal(|| None); + let mut error = use_signal(|| None); + + use_coroutine(move |_:UnboundedReceiver<()>| async move { + if let Some(stored_location) = LocalStorage::get("user_location").ok() { + location.set(Some(stored_location)); + log::info!("{}", "Location loaded from storage"); + } else { + match fetch_and_store_location().await { + Ok(loc) => { + location.set(Some(loc.clone())); + error.set(None); + log::info!("{}", &format!("Location fetched: {}, {}", loc.city, loc.country)); + } + Err(err) => { + location.set(None); + error.set(Some(err.clone())); + log::error!("{}", &format!("Error fetching location: {:?}", err)); + } + } + } + }); + + UseLocationState { location, error } +} + +#[derive(Clone, Copy)] +pub struct UseLocationState { + location: Signal>, + error: Signal>, +} + +impl UseLocationState { + pub fn get_location(&self) -> Option { + self.location.read().clone() + } + + pub fn get_error(&self) -> Option { + self.error.read().clone() + } + + pub fn is_loading(&self) -> bool { + self.location.read().is_none() && self.error.read().is_none() + } +} + +async fn fetch_and_store_location() -> Result { + let client = reqwest::Client::new(); + let res = client + .get("https://ipapi.co/json/") + .send() + .await + .map_err(|_| LocationError::FetchError)?; + + let location: Location = res.json().await.map_err(|_| LocationError::FetchError)?; + + LocalStorage::set("user_location", &location).map_err(|_| LocationError::StorageError)?; + + Ok(location) +} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 9819081..6b910e7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -29,6 +29,7 @@ pub mod hooks { pub mod use_deposit; pub mod use_initiative; pub mod use_language; + pub mod use_location; pub mod use_market_client; pub mod use_notification; pub mod use_onboard;