feat: apply local router changes
This commit is contained in:
1 parent
3928856a9b
commit
f2979cb12a
28 files changed
+672
-516
No files matched your search
@@ -0,0 +1,5 @@
|
||||
use dioxus_core::prelude::*;
|
||||
|
||||
pub fn use_param<T>(cx: &ScopeState) -> Option<T> {
|
||||
todo!()
|
||||
}
|
||||
Whitespace-only changes.
@@ -1,94 +1,27 @@
|
||||
use dioxus_core::{ScopeId, ScopeState};
|
||||
use gloo::history::{HistoryResult, Location};
|
||||
use serde::de::DeserializeOwned;
|
||||
use std::{rc::Rc, str::FromStr};
|
||||
use std::{rc::Rc, str::FromStr, sync::Arc};
|
||||
|
||||
use crate::RouterService;
|
||||
|
||||
/// This struct provides is a wrapper around the internal router
|
||||
/// implementation, with methods for getting information about the current
|
||||
/// route.
|
||||
#[derive(Clone)]
|
||||
pub struct UseRoute {
|
||||
router: Rc<RouterService>,
|
||||
}
|
||||
|
||||
impl UseRoute {
|
||||
/// This method simply calls the [`Location::query`] method.
|
||||
pub fn query<T>(&self) -> HistoryResult<T>
|
||||
where
|
||||
T: DeserializeOwned,
|
||||
{
|
||||
self.current_location().query::<T>()
|
||||
}
|
||||
|
||||
/// Returns the nth segment in the path. Paths that end with a slash have
|
||||
/// the slash removed before determining the segments. If the path has
|
||||
/// fewer segments than `n` then this method returns `None`.
|
||||
pub fn nth_segment(&self, n: usize) -> Option<String> {
|
||||
let mut segments = self.path_segments();
|
||||
let len = segments.len();
|
||||
if len - 1 < n {
|
||||
return None;
|
||||
}
|
||||
Some(segments.remove(n))
|
||||
}
|
||||
|
||||
/// Returns the last segment in the path. Paths that end with a slash have
|
||||
/// the slash removed before determining the segments. The root path, `/`,
|
||||
/// will return an empty string.
|
||||
pub fn last_segment(&self) -> String {
|
||||
let mut segments = self.path_segments();
|
||||
segments.remove(segments.len() - 1)
|
||||
}
|
||||
|
||||
/// Get the named parameter from the path, as defined in your router. The
|
||||
/// value will be parsed into the type specified by `T` by calling
|
||||
/// `value.parse::<T>()`. This method returns `None` if the named
|
||||
/// parameter does not exist in the current path.
|
||||
pub fn segment<T>(&self, name: &str) -> Option<Result<T, T::Err>>
|
||||
where
|
||||
T: FromStr,
|
||||
{
|
||||
self.router
|
||||
.current_path_params()
|
||||
.get(name)
|
||||
.and_then(|v| Some(v.parse::<T>()))
|
||||
}
|
||||
|
||||
/// Returns the [Location] for the current route.
|
||||
pub fn current_location(&self) -> Location {
|
||||
self.router.current_location()
|
||||
}
|
||||
|
||||
fn path_segments(&self) -> Vec<String> {
|
||||
let location = self.router.current_location();
|
||||
let path = location.path();
|
||||
if path == "/" {
|
||||
return vec![String::new()];
|
||||
}
|
||||
let stripped = &location.path()[1..];
|
||||
stripped.split('/').map(str::to_string).collect::<Vec<_>>()
|
||||
}
|
||||
}
|
||||
use crate::{location::ParsedRoute, RouterCore, RouterService};
|
||||
|
||||
/// This hook provides access to information about the current location in the
|
||||
/// context of a [`Router`]. If this function is called outside of a `Router`
|
||||
/// component it will panic.
|
||||
pub fn use_route(cx: &ScopeState) -> &UseRoute {
|
||||
&cx.use_hook(|_| {
|
||||
pub fn use_route(cx: &ScopeState) -> &ParsedRoute {
|
||||
let handle = cx.use_hook(|_| {
|
||||
let router = cx
|
||||
.consume_context::<RouterService>()
|
||||
.consume_context::<Arc<RouterCore>>()
|
||||
.expect("Cannot call use_route outside the scope of a Router component");
|
||||
|
||||
router.subscribe_onchange(cx.scope_id());
|
||||
|
||||
UseRouteListener {
|
||||
router: UseRoute { router },
|
||||
route: router.current_location(),
|
||||
router,
|
||||
scope: cx.scope_id(),
|
||||
}
|
||||
})
|
||||
.router
|
||||
});
|
||||
|
||||
&handle.route
|
||||
}
|
||||
|
||||
// The entire purpose of this struct is to unubscribe this component when it is unmounted.
|
||||
@@ -96,19 +29,13 @@ pub fn use_route(cx: &ScopeState) -> &UseRoute {
|
||||
// Instead, we hide the drop implementation on this private type exclusive to the hook,
|
||||
// and reveal our cached version of UseRoute to the component.
|
||||
struct UseRouteListener {
|
||||
router: UseRoute,
|
||||
route: Arc<ParsedRoute>,
|
||||
router: Arc<RouterCore>,
|
||||
scope: ScopeId,
|
||||
}
|
||||
|
||||
impl Drop for UseRouteListener {
|
||||
fn drop(&mut self) {
|
||||
self.router.router.unsubscribe_onchange(self.scope)
|
||||
self.router.unsubscribe_onchange(self.scope)
|
||||
}
|
||||
}
|
||||
|
||||
/// This hook provides access to the `RouterService` for the app.
|
||||
pub fn use_router(cx: &ScopeState) -> &Rc<RouterService> {
|
||||
cx.use_hook(|_| {
|
||||
cx.consume_context::<RouterService>()
|
||||
.expect("Cannot call use_route outside the scope of a Router component")
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
use crate::RouterService;
|
||||
use dioxus_core::ScopeState;
|
||||
|
||||
/// This hook provides access to the `RouterService` for the app.
|
||||
pub fn use_router(cx: &ScopeState) -> &RouterService {
|
||||
cx.use_hook(|_| {
|
||||
cx.consume_context::<RouterService>()
|
||||
.expect("Cannot call use_route outside the scope of a Router component")
|
||||
})
|
||||
}
|
||||
Reference in new issue
Block a user