add use_router hook

This commit is contained in:
Adrian Wannenmacher committed 2022-12-06 11:03:01 +01:00
1 parent 998f9b9ec9
commit 3b088be9a6
4 files changed
+107

No files matched your search

+5
View File
@@ -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"]
+12
View File
@@ -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>>,
}
+81
View File
@@ -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,
}
}
}
+9
View File
@@ -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::*;
}