add use_router hook
This commit is contained in:
4 files changed
+107
No files matched your search
@@ -11,9 +11,14 @@ keywords = ["dom", "ui", "gui", "react", "wasm"]
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
async-rwlock = "1.3.0"
|
||||
dioxus = { path="../dioxus" }
|
||||
dioxus-router-core = { path = "../router-core"}
|
||||
futures-channel = "0.3.25"
|
||||
futures-util = "0.3.25"
|
||||
|
||||
# for wasm
|
||||
|
||||
[features]
|
||||
regex = ["dioxus-router-core/regex"]
|
||||
serde = ["dioxus-router-core/serde"]
|
||||
@@ -0,0 +1,12 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use async_rwlock::RwLock;
|
||||
use dioxus::prelude::{Component, ScopeId};
|
||||
use dioxus_router_core::{RouterMessage, RouterState};
|
||||
use futures_channel::mpsc::UnboundedSender;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct RouterContext {
|
||||
pub(crate) state: Arc<RwLock<RouterState<Component>>>,
|
||||
pub(crate) sender: UnboundedSender<RouterMessage<ScopeId>>,
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
use async_rwlock::RwLockReadGuard;
|
||||
use dioxus::prelude::*;
|
||||
use dioxus_router_core::{
|
||||
history::{HistoryProvider, MemoryHistory},
|
||||
routes::{ContentAtom, Segment},
|
||||
RouterService, RouterState, RoutingCallback,
|
||||
};
|
||||
|
||||
use crate::contexts::router::RouterContext;
|
||||
|
||||
pub fn use_router<'a>(
|
||||
cx: &'a ScopeState,
|
||||
cfg: &dyn Fn() -> RouterConfiguration,
|
||||
content: &dyn Fn() -> Segment<Component>,
|
||||
) -> (RwLockReadGuard<'a, RouterState<Component>>, ()) {
|
||||
let (service, state, sender) = cx.use_hook(|| {
|
||||
let cfg = cfg();
|
||||
let content = content();
|
||||
|
||||
let (mut service, sender, state) = RouterService::new(
|
||||
content,
|
||||
cfg.history,
|
||||
cx.schedule_update_any(),
|
||||
cfg.on_update,
|
||||
cfg.failure_external_navigation,
|
||||
cfg.failure_named_navigation,
|
||||
cfg.failure_redirection_limit,
|
||||
);
|
||||
|
||||
cx.provide_context(RouterContext {
|
||||
state: state.clone(),
|
||||
sender: sender.clone(),
|
||||
});
|
||||
|
||||
(
|
||||
if cfg.synchronous {
|
||||
Some(service)
|
||||
} else {
|
||||
cx.spawn(async move { service.run().await });
|
||||
None
|
||||
},
|
||||
state,
|
||||
sender,
|
||||
)
|
||||
});
|
||||
|
||||
if let Some(service) = service {
|
||||
service.run_current();
|
||||
}
|
||||
|
||||
(
|
||||
loop {
|
||||
if let Some(state) = state.try_read() {
|
||||
break state;
|
||||
}
|
||||
},
|
||||
(),
|
||||
)
|
||||
}
|
||||
|
||||
pub struct RouterConfiguration {
|
||||
pub failure_external_navigation: ContentAtom<Component>,
|
||||
pub failure_named_navigation: ContentAtom<Component>,
|
||||
pub failure_redirection_limit: ContentAtom<Component>,
|
||||
pub history: Box<dyn HistoryProvider>,
|
||||
pub on_update: Option<RoutingCallback<Component>>,
|
||||
pub synchronous: bool,
|
||||
}
|
||||
|
||||
impl Default for RouterConfiguration {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
failure_external_navigation: todo!("provide default component for external navigation"),
|
||||
failure_named_navigation: todo!("provide default component for named navigation"),
|
||||
failure_redirection_limit: todo!("provide default component for redirection limit"),
|
||||
history: Box::new(MemoryHistory::default()),
|
||||
on_update: None,
|
||||
synchronous: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,12 @@
|
||||
pub(crate) mod contexts {
|
||||
pub(crate) mod router;
|
||||
}
|
||||
|
||||
pub mod hooks {
|
||||
mod use_router;
|
||||
pub use use_router::*;
|
||||
}
|
||||
|
||||
pub mod prelude {
|
||||
pub use dioxus_router_core::prelude::*;
|
||||
}
|
||||
Reference in new issue
Block a user