Merge pull request #1572 from DioxusLabs/jk/global-window-fun
Feat: add global context functions
This commit is contained in:
16 files changed
+78
-76
No files matched your search
@@ -1,18 +0,0 @@
|
|||||||
use dioxus::prelude::*;
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
dioxus_desktop::launch(app);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn app(cx: Scope) -> Element {
|
|
||||||
cx.render(rsx! {
|
|
||||||
button {
|
|
||||||
onclick: |_| async move {
|
|
||||||
println!("hello, desktop!");
|
|
||||||
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
|
|
||||||
println!("goodbye, desktop!");
|
|
||||||
},
|
|
||||||
"hello, desktop!"
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
+2
-7
@@ -1,7 +1,6 @@
|
|||||||
//! This example shows how to create a popup window and send data back to the parent window.
|
//! This example shows how to create a popup window and send data back to the parent window.
|
||||||
|
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
use dioxus_desktop::use_window;
|
|
||||||
use futures_util::StreamExt;
|
use futures_util::StreamExt;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
@@ -9,7 +8,6 @@ fn main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn app(cx: Scope) -> Element {
|
fn app(cx: Scope) -> Element {
|
||||||
let window = use_window(cx);
|
|
||||||
let emails_sent = use_ref(cx, Vec::new);
|
let emails_sent = use_ref(cx, Vec::new);
|
||||||
|
|
||||||
let tx = use_coroutine(cx, |mut rx: UnboundedReceiver<String>| {
|
let tx = use_coroutine(cx, |mut rx: UnboundedReceiver<String>| {
|
||||||
@@ -51,7 +49,6 @@ struct ComposeProps {
|
|||||||
|
|
||||||
fn compose(cx: Scope<ComposeProps>) -> Element {
|
fn compose(cx: Scope<ComposeProps>) -> Element {
|
||||||
let user_input = use_state(cx, String::new);
|
let user_input = use_state(cx, String::new);
|
||||||
let window = use_window(cx);
|
|
||||||
|
|
||||||
cx.render(rsx! {
|
cx.render(rsx! {
|
||||||
div {
|
div {
|
||||||
@@ -60,15 +57,13 @@ fn compose(cx: Scope<ComposeProps>) -> Element {
|
|||||||
button {
|
button {
|
||||||
onclick: move |_| {
|
onclick: move |_| {
|
||||||
cx.props.app_tx.send(user_input.get().clone());
|
cx.props.app_tx.send(user_input.get().clone());
|
||||||
window.close();
|
dioxus_desktop::window().close();
|
||||||
},
|
},
|
||||||
"Click to send"
|
"Click to send"
|
||||||
}
|
}
|
||||||
|
|
||||||
input {
|
input {
|
||||||
oninput: move |e| {
|
oninput: move |e| user_input.set(e.value.clone()),
|
||||||
user_input.set(e.value.clone());
|
|
||||||
},
|
|
||||||
value: "{user_input}"
|
value: "{user_input}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-3
@@ -87,8 +87,6 @@ fn ClientAdd(cx: Scope) -> Element {
|
|||||||
let last_name = use_state(cx, String::new);
|
let last_name = use_state(cx, String::new);
|
||||||
let description = use_state(cx, String::new);
|
let description = use_state(cx, String::new);
|
||||||
|
|
||||||
let navigator = use_navigator(cx);
|
|
||||||
|
|
||||||
cx.render(rsx! {
|
cx.render(rsx! {
|
||||||
h2 { "Add new Client" }
|
h2 { "Add new Client" }
|
||||||
|
|
||||||
@@ -103,7 +101,7 @@ fn ClientAdd(cx: Scope) -> Element {
|
|||||||
description: description.to_string(),
|
description: description.to_string(),
|
||||||
});
|
});
|
||||||
|
|
||||||
navigator.push(Route::ClientList {});
|
dioxus_router::router().push(Route::ClientList {});
|
||||||
},
|
},
|
||||||
|
|
||||||
fieldset {
|
fieldset {
|
||||||
|
|||||||
+9
-14
@@ -5,26 +5,21 @@ fn main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn app(cx: Scope) -> Element {
|
fn app(cx: Scope) -> Element {
|
||||||
let eval_provider = use_eval(cx);
|
let future = use_future(cx, (), |_| async move {
|
||||||
|
let eval = eval(
|
||||||
let future = use_future(cx, (), |_| {
|
r#"
|
||||||
to_owned![eval_provider];
|
|
||||||
async move {
|
|
||||||
let eval = eval_provider(
|
|
||||||
r#"
|
|
||||||
dioxus.send("Hi from JS!");
|
dioxus.send("Hi from JS!");
|
||||||
let msg = await dioxus.recv();
|
let msg = await dioxus.recv();
|
||||||
console.log(msg);
|
console.log(msg);
|
||||||
return "hello world";
|
return "hello world";
|
||||||
"#,
|
"#,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
eval.send("Hi from Rust!".into()).unwrap();
|
eval.send("Hi from Rust!".into()).unwrap();
|
||||||
let res = eval.recv().await.unwrap();
|
let res = eval.recv().await.unwrap();
|
||||||
println!("{:?}", eval.await);
|
println!("{:?}", eval.await);
|
||||||
res
|
res
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
match future.value() {
|
match future.value() {
|
||||||
|
|||||||
+16
-18
@@ -8,27 +8,25 @@ fn main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn app(cx: Scope) -> Element {
|
fn app(cx: Scope) -> Element {
|
||||||
let onsubmit = move |evt: FormEvent| {
|
let onsubmit = move |evt: FormEvent| async move {
|
||||||
cx.spawn(async move {
|
let resp = reqwest::Client::new()
|
||||||
let resp = reqwest::Client::new()
|
.post("http://localhost:8080/login")
|
||||||
.post("http://localhost:8080/login")
|
.form(&[
|
||||||
.form(&[
|
("username", &evt.values["username"]),
|
||||||
("username", &evt.values["username"]),
|
("password", &evt.values["password"]),
|
||||||
("password", &evt.values["password"]),
|
])
|
||||||
])
|
.send()
|
||||||
.send()
|
.await;
|
||||||
.await;
|
|
||||||
|
|
||||||
match resp {
|
match resp {
|
||||||
// Parse data from here, such as storing a response token
|
// Parse data from here, such as storing a response token
|
||||||
Ok(_data) => println!("Login successful!"),
|
Ok(_data) => println!("Login successful!"),
|
||||||
|
|
||||||
//Handle any errors from the fetch here
|
//Handle any errors from the fetch here
|
||||||
Err(_err) => {
|
Err(_err) => {
|
||||||
println!("Login failed - you need a login server running on localhost:8080.")
|
println!("Login failed - you need a login server running on localhost:8080.")
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
cx.render(rsx! {
|
cx.render(rsx! {
|
||||||
|
|||||||
@@ -5,14 +5,12 @@ fn main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn app(cx: Scope) -> Element {
|
fn app(cx: Scope) -> Element {
|
||||||
let window = dioxus_desktop::use_window(cx);
|
|
||||||
|
|
||||||
cx.render(rsx! {
|
cx.render(rsx! {
|
||||||
div {
|
div {
|
||||||
button {
|
button {
|
||||||
onclick: move |_| {
|
onclick: move |_| {
|
||||||
let dom = VirtualDom::new(popup);
|
let dom = VirtualDom::new(popup);
|
||||||
window.new_window(dom, Default::default());
|
dioxus_desktop::window().new_window(dom, Default::default());
|
||||||
},
|
},
|
||||||
"New Window"
|
"New Window"
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-4
@@ -1,13 +1,11 @@
|
|||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
use dioxus_desktop::{tao::dpi::PhysicalPosition, use_window, LogicalSize, WindowBuilder};
|
use dioxus_desktop::{tao::dpi::PhysicalPosition, LogicalSize, WindowBuilder};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus_desktop::launch_cfg(app, make_config());
|
dioxus_desktop::launch_cfg(app, make_config());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app(cx: Scope) -> Element {
|
fn app(cx: Scope) -> Element {
|
||||||
let window = use_window(cx);
|
|
||||||
|
|
||||||
cx.render(rsx! {
|
cx.render(rsx! {
|
||||||
div {
|
div {
|
||||||
width: "100%",
|
width: "100%",
|
||||||
@@ -19,7 +17,7 @@ fn app(cx: Scope) -> Element {
|
|||||||
width: "100%",
|
width: "100%",
|
||||||
height: "10px",
|
height: "10px",
|
||||||
background_color: "black",
|
background_color: "black",
|
||||||
onmousedown: move |_| window.drag(),
|
onmousedown: move |_| dioxus_desktop::window().drag(),
|
||||||
}
|
}
|
||||||
|
|
||||||
"This is an overlay!"
|
"This is an overlay!"
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
use dioxus_desktop::use_window;
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus_desktop::launch(app);
|
dioxus_desktop::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app(cx: Scope) -> Element {
|
fn app(cx: Scope) -> Element {
|
||||||
let window = use_window(cx);
|
|
||||||
let level = use_state(cx, || 1.0);
|
let level = use_state(cx, || 1.0);
|
||||||
|
|
||||||
cx.render(rsx! {
|
cx.render(rsx! {
|
||||||
@@ -16,7 +14,7 @@ fn app(cx: Scope) -> Element {
|
|||||||
oninput: |e| {
|
oninput: |e| {
|
||||||
if let Ok(new_zoom) = e.value.parse::<f64>() {
|
if let Ok(new_zoom) = e.value.parse::<f64>() {
|
||||||
level.set(new_zoom);
|
level.set(new_zoom);
|
||||||
window.webview.zoom(new_zoom);
|
dioxus_desktop::window().webview.zoom(new_zoom);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,17 @@ use wry::webview::WebView;
|
|||||||
|
|
||||||
pub type ProxyType = EventLoopProxy<UserWindowEvent>;
|
pub type ProxyType = EventLoopProxy<UserWindowEvent>;
|
||||||
|
|
||||||
|
/// Get an imperative handle to the current window without using a hook
|
||||||
|
///
|
||||||
|
/// ## Panics
|
||||||
|
///
|
||||||
|
/// This function will panic if it is called outside of the context of a Dioxus App.
|
||||||
|
pub fn window() -> DesktopContext {
|
||||||
|
dioxus_core::prelude::consume_context().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
/// Get an imperative handle to the current window
|
/// Get an imperative handle to the current window
|
||||||
|
#[deprecated = "Prefer the using the `window` function directly for cleaner code"]
|
||||||
pub fn use_window(cx: &ScopeState) -> &DesktopContext {
|
pub fn use_window(cx: &ScopeState) -> &DesktopContext {
|
||||||
cx.use_hook(|| cx.consume_context::<DesktopContext>())
|
cx.use_hook(|| cx.consume_context::<DesktopContext>())
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ use crate::shortcut::GlobalHotKeyEvent;
|
|||||||
pub use cfg::{Config, WindowCloseBehaviour};
|
pub use cfg::{Config, WindowCloseBehaviour};
|
||||||
pub use desktop_context::DesktopContext;
|
pub use desktop_context::DesktopContext;
|
||||||
pub use desktop_context::{
|
pub use desktop_context::{
|
||||||
use_window, use_wry_event_handler, DesktopService, WryEventHandler, WryEventHandlerId,
|
use_window, use_wry_event_handler, window, DesktopService, WryEventHandler, WryEventHandlerId,
|
||||||
};
|
};
|
||||||
use desktop_context::{EventData, UserWindowEvent, WebviewQueue, WindowEventHandlers};
|
use desktop_context::{EventData, UserWindowEvent, WebviewQueue, WindowEventHandlers};
|
||||||
use dioxus_core::*;
|
use dioxus_core::*;
|
||||||
|
|||||||
@@ -48,6 +48,15 @@ pub fn use_eval(cx: &ScopeState) -> &EvalCreator {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn eval(script: &str) -> Result<UseEval, EvalError> {
|
||||||
|
let eval_provider = dioxus_core::prelude::consume_context::<Rc<dyn EvalProvider>>()
|
||||||
|
.expect("evaluator not provided");
|
||||||
|
|
||||||
|
eval_provider
|
||||||
|
.new_evaluator(script.to_string())
|
||||||
|
.map(UseEval::new)
|
||||||
|
}
|
||||||
|
|
||||||
/// A wrapper around the target platform's evaluator.
|
/// A wrapper around the target platform's evaluator.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct UseEval {
|
pub struct UseEval {
|
||||||
|
|||||||
@@ -112,7 +112,6 @@ fn Route2(cx: Scope, user_id: usize) -> Element {
|
|||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
fn Route3(cx: Scope, dynamic: String) -> Element {
|
fn Route3(cx: Scope, dynamic: String) -> Element {
|
||||||
let navigator = use_navigator(cx);
|
|
||||||
let current_route = use_route(cx)?;
|
let current_route = use_route(cx)?;
|
||||||
let current_route_str = use_ref(cx, String::new);
|
let current_route_str = use_ref(cx, String::new);
|
||||||
let parsed = Route::from_str(¤t_route_str.read());
|
let parsed = Route::from_str(¤t_route_str.read());
|
||||||
@@ -122,11 +121,11 @@ fn Route3(cx: Scope, dynamic: String) -> Element {
|
|||||||
.flat_map(|seg| seg.flatten().into_iter())
|
.flat_map(|seg| seg.flatten().into_iter())
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let navigator = use_navigator(cx);
|
||||||
|
|
||||||
render! {
|
render! {
|
||||||
input {
|
input {
|
||||||
oninput: move |evt| {
|
oninput: move |evt| *current_route_str.write() = evt.value.clone(),
|
||||||
*current_route_str.write() = evt.value.clone();
|
|
||||||
},
|
|
||||||
value: "{current_route_str.read()}"
|
value: "{current_route_str.read()}"
|
||||||
}
|
}
|
||||||
"dynamic: {dynamic}"
|
"dynamic: {dynamic}"
|
||||||
|
|||||||
@@ -1,5 +1,19 @@
|
|||||||
use crate::prelude::{ExternalNavigationFailure, IntoRoutable, RouterContext};
|
use crate::prelude::{ExternalNavigationFailure, IntoRoutable, RouterContext};
|
||||||
|
|
||||||
|
/// Acquire the navigator without subscribing to updates.
|
||||||
|
///
|
||||||
|
/// Can be called anywhere in the application provided a Router has been initialized.
|
||||||
|
///
|
||||||
|
/// ## Panics
|
||||||
|
///
|
||||||
|
/// Panics if there is no router present.
|
||||||
|
pub fn navigator() -> Navigator {
|
||||||
|
Navigator(
|
||||||
|
dioxus::core::prelude::consume_context::<RouterContext>()
|
||||||
|
.expect("A router must be present to use navigator"),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/// A view into the navigation state of a router.
|
/// A view into the navigation state of a router.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Navigator(pub(crate) RouterContext);
|
pub struct Navigator(pub(crate) RouterContext);
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ use crate::prelude::{Navigator, RouterContext};
|
|||||||
/// # let _ = vdom.rebuild();
|
/// # let _ = vdom.rebuild();
|
||||||
/// ```
|
/// ```
|
||||||
#[must_use]
|
#[must_use]
|
||||||
|
#[deprecated = "Prefer acquiring the router directly with `dioxus_router::router()`"]
|
||||||
pub fn use_navigator(cx: &ScopeState) -> &Navigator {
|
pub fn use_navigator(cx: &ScopeState) -> &Navigator {
|
||||||
&*cx.use_hook(|| {
|
&*cx.use_hook(|| {
|
||||||
let router = cx
|
let router = cx
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use dioxus::prelude::ScopeState;
|
|||||||
|
|
||||||
use crate::{prelude::RouterContext, utils::use_router_internal::use_router_internal};
|
use crate::{prelude::RouterContext, utils::use_router_internal::use_router_internal};
|
||||||
|
|
||||||
#[deprecated = "prefer the use_navigator or use_route functions"]
|
#[deprecated = "prefer the `router()` function or `use_route` functions"]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
/// A hook that provides access to information about the router.
|
/// A hook that provides access to information about the router.
|
||||||
pub fn use_router(cx: &ScopeState) -> &RouterContext {
|
pub fn use_router(cx: &ScopeState) -> &RouterContext {
|
||||||
@@ -10,3 +10,8 @@ pub fn use_router(cx: &ScopeState) -> &RouterContext {
|
|||||||
.as_ref()
|
.as_ref()
|
||||||
.expect("use_route must have access to a router")
|
.expect("use_route must have access to a router")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Aquire the router without subscribing to updates.
|
||||||
|
pub fn router() -> RouterContext {
|
||||||
|
dioxus::core::prelude::consume_context().unwrap()
|
||||||
|
}
|
||||||
@@ -53,6 +53,8 @@ pub mod hooks {
|
|||||||
pub use use_navigator::*;
|
pub use use_navigator::*;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub use hooks::router;
|
||||||
|
|
||||||
/// A collection of useful items most applications might need.
|
/// A collection of useful items most applications might need.
|
||||||
pub mod prelude {
|
pub mod prelude {
|
||||||
pub use crate::components::*;
|
pub use crate::components::*;
|
||||||
|
|||||||
Reference in new issue
Block a user