use crate::{context::use_page_data, web::QueryParamsError};
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use std::ops::Deref;
use yew::hook;
#[derive(Debug, Serialize, Deserialize)]
pub struct QueryParamsHandle<Q> {
query: Q,
}
impl<Q> QueryParamsHandle<Q>
where
Q: Serialize + DeserializeOwned,
{
pub fn new(query: Q) -> Self {
QueryParamsHandle { query }
}
pub fn set(&mut self, query_params: Q) {
self.query = query_params;
let window = web_sys::window().unwrap();
let location = window.location();
location
.set_search(&serde_qs::to_string(&self.query).unwrap())
.unwrap();
}
pub fn set_without_refresh(&mut self, query_params: Q) {
self.query = query_params;
let window = web_sys::window().unwrap();
let location = window.location();
let history = window.history().unwrap();
history
.push_state_with_url(
&location,
"",
Some(&serde_qs::to_string(&self.query).unwrap()),
)
.unwrap();
}
}
impl<Q> Deref for QueryParamsHandle<Q> {
type Target = Q;
fn deref(&self) -> &Self::Target {
&self.query
}
}
#[hook]
pub fn use_query_params<Q>() -> Result<QueryParamsHandle<Q>, QueryParamsError>
where
Q: Serialize + DeserializeOwned + 'static,
{
let page_data = use_page_data();
let query = page_data.uri.query().ok_or(QueryParamsError::NotFound)?;
if query.is_empty() {
return Err(QueryParamsError::NotFound);
}
serde_qs::from_str(query).map_err(QueryParamsError::Parse)
}