Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: add global context functions #1572

Merged
merged 3 commits into from
Jan 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 0 additions & 18 deletions examples/button.rs

This file was deleted.

9 changes: 2 additions & 7 deletions examples/compose.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
//! This example shows how to create a popup window and send data back to the parent window.

use dioxus::prelude::*;
use dioxus_desktop::use_window;
use futures_util::StreamExt;

fn main() {
dioxus_desktop::launch(app);
}

fn app(cx: Scope) -> Element {
let window = use_window(cx);
let emails_sent = use_ref(cx, Vec::new);

let tx = use_coroutine(cx, |mut rx: UnboundedReceiver<String>| {
Expand Down Expand Up @@ -51,7 +49,6 @@ struct ComposeProps {

fn compose(cx: Scope<ComposeProps>) -> Element {
let user_input = use_state(cx, String::new);
let window = use_window(cx);

cx.render(rsx! {
div {
Expand All @@ -60,15 +57,13 @@ fn compose(cx: Scope<ComposeProps>) -> Element {
button {
onclick: move |_| {
cx.props.app_tx.send(user_input.get().clone());
window.close();
dioxus_desktop::window().close();
},
"Click to send"
}

input {
oninput: move |e| {
user_input.set(e.value.clone());
},
oninput: move |e| user_input.set(e.value.clone()),
value: "{user_input}"
}
}
Expand Down
4 changes: 1 addition & 3 deletions examples/crm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,6 @@ fn ClientAdd(cx: Scope) -> Element {
let last_name = use_state(cx, String::new);
let description = use_state(cx, String::new);

let navigator = use_navigator(cx);

cx.render(rsx! {
h2 { "Add new Client" }

Expand All @@ -103,7 +101,7 @@ fn ClientAdd(cx: Scope) -> Element {
description: description.to_string(),
});

navigator.push(Route::ClientList {});
dioxus_router::router().push(Route::ClientList {});
},

fieldset {
Expand Down
23 changes: 9 additions & 14 deletions examples/eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,21 @@ fn main() {
}

fn app(cx: Scope) -> Element {
let eval_provider = use_eval(cx);

let future = use_future(cx, (), |_| {
to_owned![eval_provider];
async move {
let eval = eval_provider(
r#"
let future = use_future(cx, (), |_| async move {
let eval = eval(
r#"
dioxus.send("Hi from JS!");
let msg = await dioxus.recv();
console.log(msg);
return "hello world";
"#,
)
.unwrap();
)
.unwrap();

eval.send("Hi from Rust!".into()).unwrap();
let res = eval.recv().await.unwrap();
println!("{:?}", eval.await);
res
}
eval.send("Hi from Rust!".into()).unwrap();
let res = eval.recv().await.unwrap();
println!("{:?}", eval.await);
res
});

match future.value() {
Expand Down
34 changes: 16 additions & 18 deletions examples/login_form.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,25 @@ fn main() {
}

fn app(cx: Scope) -> Element {
let onsubmit = move |evt: FormEvent| {
cx.spawn(async move {
let resp = reqwest::Client::new()
.post("http://localhost:8080/login")
.form(&[
("username", &evt.values["username"]),
("password", &evt.values["password"]),
])
.send()
.await;
let onsubmit = move |evt: FormEvent| async move {
let resp = reqwest::Client::new()
.post("http://localhost:8080/login")
.form(&[
("username", &evt.values["username"]),
("password", &evt.values["password"]),
])
.send()
.await;

match resp {
// Parse data from here, such as storing a response token
Ok(_data) => println!("Login successful!"),
match resp {
// Parse data from here, such as storing a response token
Ok(_data) => println!("Login successful!"),

//Handle any errors from the fetch here
Err(_err) => {
println!("Login failed - you need a login server running on localhost:8080.")
}
//Handle any errors from the fetch here
Err(_err) => {
println!("Login failed - you need a login server running on localhost:8080.")
}
});
}
};

cx.render(rsx! {
Expand Down
4 changes: 1 addition & 3 deletions examples/multiwindow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,12 @@ fn main() {
}

fn app(cx: Scope) -> Element {
let window = dioxus_desktop::use_window(cx);

cx.render(rsx! {
div {
button {
onclick: move |_| {
let dom = VirtualDom::new(popup);
window.new_window(dom, Default::default());
dioxus_desktop::window().new_window(dom, Default::default());
},
"New Window"
}
Expand Down
6 changes: 2 additions & 4 deletions examples/overlay.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
use dioxus::prelude::*;
use dioxus_desktop::{tao::dpi::PhysicalPosition, use_window, LogicalSize, WindowBuilder};
use dioxus_desktop::{tao::dpi::PhysicalPosition, LogicalSize, WindowBuilder};

fn main() {
dioxus_desktop::launch_cfg(app, make_config());
}

fn app(cx: Scope) -> Element {
let window = use_window(cx);

cx.render(rsx! {
div {
width: "100%",
Expand All @@ -19,7 +17,7 @@ fn app(cx: Scope) -> Element {
width: "100%",
height: "10px",
background_color: "black",
onmousedown: move |_| window.drag(),
onmousedown: move |_| dioxus_desktop::window().drag(),
}

"This is an overlay!"
Expand Down
4 changes: 1 addition & 3 deletions examples/window_zoom.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
use dioxus::prelude::*;
use dioxus_desktop::use_window;

fn main() {
dioxus_desktop::launch(app);
}

fn app(cx: Scope) -> Element {
let window = use_window(cx);
let level = use_state(cx, || 1.0);

cx.render(rsx! {
Expand All @@ -16,7 +14,7 @@ fn app(cx: Scope) -> Element {
oninput: |e| {
if let Ok(new_zoom) = e.value.parse::<f64>() {
level.set(new_zoom);
window.webview.zoom(new_zoom);
dioxus_desktop::window().webview.zoom(new_zoom);
}
}
}
Expand Down
10 changes: 10 additions & 0 deletions packages/desktop/src/desktop_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,17 @@ use wry::webview::WebView;

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
#[deprecated = "Prefer the using the `window` function directly for cleaner code"]
pub fn use_window(cx: &ScopeState) -> &DesktopContext {
cx.use_hook(|| cx.consume_context::<DesktopContext>())
.as_ref()
Expand Down
2 changes: 1 addition & 1 deletion packages/desktop/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use crate::shortcut::GlobalHotKeyEvent;
pub use cfg::{Config, WindowCloseBehaviour};
pub use desktop_context::DesktopContext;
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 dioxus_core::*;
Expand Down
9 changes: 9 additions & 0 deletions packages/html/src/eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
#[derive(Clone)]
pub struct UseEval {
Expand Down
7 changes: 3 additions & 4 deletions packages/router/examples/simple_routes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,6 @@ fn Route2(cx: Scope, user_id: usize) -> Element {

#[component]
fn Route3(cx: Scope, dynamic: String) -> Element {
let navigator = use_navigator(cx);
let current_route = use_route(cx)?;
let current_route_str = use_ref(cx, String::new);
let parsed = Route::from_str(&current_route_str.read());
Expand All @@ -122,11 +121,11 @@ fn Route3(cx: Scope, dynamic: String) -> Element {
.flat_map(|seg| seg.flatten().into_iter())
.collect::<Vec<_>>();

let navigator = use_navigator(cx);

render! {
input {
oninput: move |evt| {
*current_route_str.write() = evt.value.clone();
},
oninput: move |evt| *current_route_str.write() = evt.value.clone(),
value: "{current_route_str.read()}"
}
"dynamic: {dynamic}"
Expand Down
14 changes: 14 additions & 0 deletions packages/router/src/contexts/navigator.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
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.
#[derive(Clone)]
pub struct Navigator(pub(crate) RouterContext);
Expand Down
1 change: 1 addition & 0 deletions packages/router/src/hooks/use_navigator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ use crate::prelude::{Navigator, RouterContext};
/// # let _ = vdom.rebuild();
/// ```
#[must_use]
#[deprecated = "Prefer acquiring the router directly with `dioxus_router::router()`"]
pub fn use_navigator(cx: &ScopeState) -> &Navigator {
&*cx.use_hook(|| {
let router = cx
Expand Down
7 changes: 6 additions & 1 deletion packages/router/src/hooks/use_router.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,16 @@ use dioxus::prelude::ScopeState;

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]
/// A hook that provides access to information about the router.
pub fn use_router(cx: &ScopeState) -> &RouterContext {
use_router_internal(cx)
.as_ref()
.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()
}
2 changes: 2 additions & 0 deletions packages/router/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ pub mod hooks {
pub use use_navigator::*;
}

pub use hooks::router;

/// A collection of useful items most applications might need.
pub mod prelude {
pub use crate::components::*;
Expand Down
Loading