From c881f9bf8243832001f280ae92b2e7a524039c33 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Sun, 5 Feb 2023 19:48:49 -0600 Subject: [PATCH 1/7] fix removing attributes in web bindings --- packages/interpreter/src/sledgehammer_bindings.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/interpreter/src/sledgehammer_bindings.rs b/packages/interpreter/src/sledgehammer_bindings.rs index 61e37c2cb..33f6b4420 100644 --- a/packages/interpreter/src/sledgehammer_bindings.rs +++ b/packages/interpreter/src/sledgehammer_bindings.rs @@ -217,7 +217,7 @@ mod js { } fn remove_attribute(id: u32, field: &str, ns: &str) { r#"{name = $field$; - node = this.nodes[$id$]; + node = nodes[$id$]; if (ns == "style") { node.style.removeProperty(name); } else if (ns !== null && ns !== undefined && ns !== "") { From 9ebafc46bbb0c649ae9bfe26342e43f612ae765d Mon Sep 17 00:00:00 2001 From: Jonathan Kelley Date: Mon, 6 Feb 2023 00:54:08 -0800 Subject: [PATCH 2/7] feat: allow 'static futures to be spawned from handlers --- examples/button.rs | 9 ++++++++- packages/core/src/events.rs | 21 +++++++++++++++++++++ packages/core/src/lib.rs | 8 ++++---- packages/core/src/scopes.rs | 7 ++++--- packages/html/src/events.rs | 2 +- 5 files changed, 38 insertions(+), 9 deletions(-) diff --git a/examples/button.rs b/examples/button.rs index 9d32819e8..2764f88b0 100644 --- a/examples/button.rs +++ b/examples/button.rs @@ -6,6 +6,13 @@ fn main() { fn app(cx: Scope) -> Element { cx.render(rsx! { - button { "hello, desktop!" } + button { + onclick: |e| async move { + println!("hello, desktop!"); + tokio::time::sleep(std::time::Duration::from_secs(1)).await; + println!("goodbye, desktop!"); + }, + "hello, desktop!" + } }) } diff --git a/packages/core/src/events.rs b/packages/core/src/events.rs index 849dd4d24..b7057fbcc 100644 --- a/packages/core/src/events.rs +++ b/packages/core/src/events.rs @@ -3,6 +3,10 @@ use std::{ rc::Rc, }; +use futures_util::Future; + +use crate::ScopeState; + /// A wrapper around some generic data that handles the event's state /// /// @@ -106,6 +110,23 @@ impl std::fmt::Debug for Event { } } +#[doc(hidden)] +pub trait EventReturn

: Sized { + fn spawn(self, _cx: &ScopeState) {} +} + +impl EventReturn<()> for () {} + +pub struct AsyncMarker; +impl EventReturn for T +where + T: Future + 'static, +{ + fn spawn(self, cx: &ScopeState) { + cx.spawn(self); + } +} + /// The callback type generated by the `rsx!` macro when an `on` field is specified for components. /// /// This makes it possible to pass `move |evt| {}` style closures into components as property fields. diff --git a/packages/core/src/lib.rs b/packages/core/src/lib.rs index 304197dab..4fd8e4a8a 100644 --- a/packages/core/src/lib.rs +++ b/packages/core/src/lib.rs @@ -71,10 +71,10 @@ pub(crate) mod innerlude { pub use crate::innerlude::{ fc_to_builder, AnyValue, Attribute, AttributeValue, BorrowedAttributeValue, CapturedError, - Component, DynamicNode, Element, ElementId, Event, Fragment, IntoDynNode, LazyNodes, Mutation, - Mutations, Properties, RenderReturn, Scope, ScopeId, ScopeState, Scoped, SuspenseContext, - TaskId, Template, TemplateAttribute, TemplateNode, VComponent, VNode, VPlaceholder, VText, - VirtualDom, + Component, DynamicNode, Element, ElementId, Event, EventReturn, Fragment, IntoDynNode, + LazyNodes, Mutation, Mutations, Properties, RenderReturn, Scope, ScopeId, ScopeState, Scoped, + SuspenseContext, TaskId, Template, TemplateAttribute, TemplateNode, VComponent, VNode, + VPlaceholder, VText, VirtualDom, }; /// The purpose of this module is to alleviate imports of many common types diff --git a/packages/core/src/scopes.rs b/packages/core/src/scopes.rs index bee7ea1db..201e1d424 100644 --- a/packages/core/src/scopes.rs +++ b/packages/core/src/scopes.rs @@ -7,7 +7,7 @@ use crate::{ innerlude::{ErrorBoundary, Scheduler, SchedulerMsg}, lazynodes::LazyNodes, nodes::{ComponentReturn, IntoAttributeValue, IntoDynNode, RenderReturn}, - AnyValue, Attribute, AttributeValue, Element, Event, Properties, TaskId, + AnyValue, Attribute, AttributeValue, Element, Event, EventReturn, Properties, TaskId, }; use bumpalo::{boxed::Box as BumpBox, Bump}; use bumpslab::{BumpSlab, Slot}; @@ -581,9 +581,9 @@ impl<'src> ScopeState { /// Create a new [`AttributeValue`] with the listener variant from a callback /// /// The callback must be confined to the lifetime of the ScopeState - pub fn listener( + pub fn listener>( &'src self, - mut callback: impl FnMut(Event) + 'src, + mut callback: impl FnMut(Event) -> E + 'src, ) -> AttributeValue<'src> { // safety: there's no other way to create a dynamicly-dispatched bump box other than alloc + from-raw // This is the suggested way to build a bumpbox @@ -596,6 +596,7 @@ impl<'src> ScopeState { propagates: event.propagates, data, }) + .spawn(self); } })) }; diff --git a/packages/html/src/events.rs b/packages/html/src/events.rs index d2aec70c1..604c3a955 100644 --- a/packages/html/src/events.rs +++ b/packages/html/src/events.rs @@ -8,7 +8,7 @@ macro_rules! impl_event { ) => { $( $( #[$attr] )* - pub fn $name<'a>(_cx: &'a ::dioxus_core::ScopeState, _f: impl FnMut(::dioxus_core::Event<$data>) + 'a) -> ::dioxus_core::Attribute<'a> { + pub fn $name<'a, E: ::dioxus_core::EventReturn, T>(_cx: &'a ::dioxus_core::ScopeState, _f: impl FnMut(::dioxus_core::Event<$data>) -> E + 'a) -> ::dioxus_core::Attribute<'a> { ::dioxus_core::Attribute { name: stringify!($name), value: _cx.listener(_f), From 5a99d8c98a437bf5519e9051e533ee4f3515252f Mon Sep 17 00:00:00 2001 From: Jonathan Kelley Date: Mon, 6 Feb 2023 01:59:49 -0800 Subject: [PATCH 3/7] chore: dont publish guide --- docs/guide/Cargo.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/guide/Cargo.toml b/docs/guide/Cargo.toml index eb8060552..87d5b9006 100644 --- a/docs/guide/Cargo.toml +++ b/docs/guide/Cargo.toml @@ -4,6 +4,7 @@ version = "0.0.1" edition = "2021" description = "Dioxus guide, including testable examples" license = "MIT/Apache-2.0" +publish = false [dev-dependencies] dioxus = { path = "../../packages/dioxus" } @@ -20,4 +21,4 @@ fermi = { path = "../../packages/fermi" } serde = { version = "1.0.138", features=["derive"] } reqwest = { version = "0.11.11", features = ["json"] } tokio = { version = "1.19.2" , features=[]} -axum = { version = "0.6.1", features = ["ws"] } \ No newline at end of file +axum = { version = "0.6.1", features = ["ws"] } From 14a1039808806ec500c77ceea4ebd2e273c4aeaf Mon Sep 17 00:00:00 2001 From: Jonathan Kelley Date: Mon, 6 Feb 2023 22:18:07 -0800 Subject: [PATCH 4/7] make clippy happy --- examples/button.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/button.rs b/examples/button.rs index 2764f88b0..f001ed531 100644 --- a/examples/button.rs +++ b/examples/button.rs @@ -7,7 +7,7 @@ fn main() { fn app(cx: Scope) -> Element { cx.render(rsx! { button { - onclick: |e| async move { + onclick: |_| async move { println!("hello, desktop!"); tokio::time::sleep(std::time::Duration::from_secs(1)).await; println!("goodbye, desktop!"); From 247d1b40d3049137a236a86608fe27b1cb27c5af Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Tue, 7 Feb 2023 08:04:10 -0600 Subject: [PATCH 5/7] fix the tui widgets example link --- docs/guide/src/en/getting_started/tui.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guide/src/en/getting_started/tui.md b/docs/guide/src/en/getting_started/tui.md index c776e24d9..e49cb84a8 100644 --- a/docs/guide/src/en/getting_started/tui.md +++ b/docs/guide/src/en/getting_started/tui.md @@ -12,7 +12,7 @@ TUI support is currently quite experimental. But, if you're willing to venture i - It uses flexbox for the layout - It only supports a subset of the attributes and elements -- Regular widgets will not work in the tui render, but the tui renderer has its own widget components that start with a capital letter. See the [widgets example](https://github.com/DioxusLabs/dioxus/blob/master/packages/tui/examples/tui_widgets.rs) +- Regular widgets will not work in the tui render, but the tui renderer has its own widget components that start with a capital letter. See the [widgets example](https://github.com/DioxusLabs/dioxus/blob/master/packages/tui/examples/widgets.rs) - 1px is one character line height. Your regular CSS px does not translate - If your app panics, your terminal is wrecked. This will be fixed eventually From 773a87d7015d117540927447af5e510bc08a6cda Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Tue, 7 Feb 2023 08:57:29 -0600 Subject: [PATCH 6/7] fix conditional compilation for hot reloading --- packages/desktop/src/desktop_context.rs | 2 ++ packages/desktop/src/lib.rs | 1 + packages/liveview/src/pool.rs | 21 +++++++++++---------- packages/tui/src/lib.rs | 15 +++++++++++---- 4 files changed, 25 insertions(+), 14 deletions(-) diff --git a/packages/desktop/src/desktop_context.rs b/packages/desktop/src/desktop_context.rs index e5f928222..edddd7887 100644 --- a/packages/desktop/src/desktop_context.rs +++ b/packages/desktop/src/desktop_context.rs @@ -9,6 +9,7 @@ use crate::Config; use crate::WebviewHandler; use dioxus_core::ScopeState; use dioxus_core::VirtualDom; +#[cfg(all(feature = "hot-reload", debug_assertions))] use dioxus_hot_reload::HotReloadMsg; use serde_json::Value; use slab::Slab; @@ -285,6 +286,7 @@ pub enum EventData { Ipc(IpcMessage), + #[cfg(all(feature = "hot-reload", debug_assertions))] HotReloadEvent(HotReloadMsg), NewWindow, diff --git a/packages/desktop/src/lib.rs b/packages/desktop/src/lib.rs index dea69e532..16f562464 100644 --- a/packages/desktop/src/lib.rs +++ b/packages/desktop/src/lib.rs @@ -185,6 +185,7 @@ pub fn launch_with_props(root: Component

, props: P, cfg: Config) } Event::UserEvent(event) => match event.0 { + #[cfg(all(feature = "hot-reload", debug_assertions))] EventData::HotReloadEvent(msg) => match msg { dioxus_hot_reload::HotReloadMsg::UpdateTemplate(template) => { for webview in webviews.values_mut() { diff --git a/packages/liveview/src/pool.rs b/packages/liveview/src/pool.rs index b3ed6bef5..022641d5c 100644 --- a/packages/liveview/src/pool.rs +++ b/packages/liveview/src/pool.rs @@ -134,7 +134,7 @@ where #[cfg(all(feature = "hot-reload", debug_assertions))] let hot_reload_wait = hot_reload_rx.recv(); #[cfg(not(all(feature = "hot-reload", debug_assertions)))] - let hot_reload_wait = std::future::pending(); + let hot_reload_wait: std::future::Pending> = std::future::pending(); tokio::select! { // poll any futures or suspense @@ -157,17 +157,18 @@ where } } - msg = hot_reload_wait => { - if let Some(msg) = msg { - match msg{ - dioxus_hot_reload::HotReloadMsg::UpdateTemplate(new_template) => { - vdom.replace_template(new_template); - } - dioxus_hot_reload::HotReloadMsg::Shutdown => { - std::process::exit(0); - }, + Some(msg) = hot_reload_wait => { + #[cfg(all(feature = "hot-reload", debug_assertions))] + match msg{ + dioxus_hot_reload::HotReloadMsg::UpdateTemplate(new_template) => { + vdom.replace_template(new_template); } + dioxus_hot_reload::HotReloadMsg::Shutdown => { + std::process::exit(0); + }, } + #[cfg(not(all(feature = "hot-reload", debug_assertions)))] + let () = msg; } } diff --git a/packages/tui/src/lib.rs b/packages/tui/src/lib.rs index c7f1dcc79..75c865de5 100644 --- a/packages/tui/src/lib.rs +++ b/packages/tui/src/lib.rs @@ -22,7 +22,7 @@ use std::{ use std::{io, time::Duration}; use taffy::Taffy; pub use taffy::{geometry::Point, prelude::*}; -use tokio::{select, sync::mpsc::unbounded_channel}; +use tokio::select; use tui::{backend::CrosstermBackend, layout::Rect, Terminal}; mod config; @@ -148,7 +148,7 @@ fn render_vdom( #[cfg(all(feature = "hot-reload", debug_assertions))] let mut hot_reload_rx = { let (hot_reload_tx, hot_reload_rx) = - unbounded_channel::(); + tokio::sync::mpsc::unbounded_channel::(); dioxus_hot_reload::connect(move |msg| { let _ = hot_reload_tx.send(msg); }); @@ -233,13 +233,14 @@ fn render_vdom( } } + #[cfg(all(feature = "hot-reload", debug_assertions))] let mut hot_reload_msg = None; { let wait = vdom.wait_for_work(); #[cfg(all(feature = "hot-reload", debug_assertions))] let hot_reload_wait = hot_reload_rx.recv(); #[cfg(not(all(feature = "hot-reload", debug_assertions)))] - let hot_reload_wait = std::future::pending(); + let hot_reload_wait: std::future::Pending> = std::future::pending(); pin_mut!(wait); @@ -269,12 +270,18 @@ fn render_vdom( } }, Some(msg) = hot_reload_wait => { - hot_reload_msg = Some(msg); + #[cfg(all(feature = "hot-reload", debug_assertions))] + { + hot_reload_msg = Some(msg); + } + #[cfg(not(all(feature = "hot-reload", debug_assertions)))] + let () = msg; } } } // if we have a new template, replace the old one + #[cfg(all(feature = "hot-reload", debug_assertions))] if let Some(msg) = hot_reload_msg { match msg { dioxus_hot_reload::HotReloadMsg::UpdateTemplate(template) => { From b33e0ed3ea58a65c5e06196d4170f15c27c450ed Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Tue, 7 Feb 2023 09:19:09 -0600 Subject: [PATCH 7/7] fix release build warnings --- packages/core/src/create.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/core/src/create.rs b/packages/core/src/create.rs index 3014a7bfe..12c11d1e9 100644 --- a/packages/core/src/create.rs +++ b/packages/core/src/create.rs @@ -11,6 +11,7 @@ use std::iter::Peekable; use std::rc::Rc; use TemplateNode::*; +#[cfg(debug_assertions)] fn sort_bfs(paths: &[&'static [u8]]) -> Vec<(usize, &'static [u8])> { let mut with_indecies = paths.iter().copied().enumerate().collect::>(); with_indecies.sort_unstable_by(|(_, a), (_, b)| { @@ -386,6 +387,8 @@ impl<'b> VirtualDom { } /// Insert a new template into the VirtualDom's template registry + // used in conditional compilation + #[allow(unused_mut)] pub(crate) fn register_template(&mut self, mut template: Template<'static>) { let (path, byte_index) = template.name.rsplit_once(':').unwrap(); let byte_index = byte_index.parse::().unwrap();