Forráskód Böngészése

add use_router hook

Adrian Wannenmacher 2 éve
szülő
commit
3b088be9a6

+ 5 - 0
packages/router/Cargo.toml

@@ -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
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
 
 [dependencies]
 [dependencies]
+async-rwlock = "1.3.0"
 dioxus = { path="../dioxus" }
 dioxus = { path="../dioxus" }
 dioxus-router-core = { path = "../router-core"}
 dioxus-router-core = { path = "../router-core"}
+futures-channel = "0.3.25"
+futures-util = "0.3.25"
 
 
 # for wasm
 # for wasm
 
 
 [features]
 [features]
+regex = ["dioxus-router-core/regex"]
+serde = ["dioxus-router-core/serde"]

+ 12 - 0
packages/router/src/contexts/router.rs

@@ -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 - 0
packages/router/src/hooks/use_router.rs

@@ -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 - 0
packages/router/src/lib.rs

@@ -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 mod prelude {
     pub use dioxus_router_core::prelude::*;
     pub use dioxus_router_core::prelude::*;
 }
 }