From b372701d30a92b3536a2a91004f565c9e4a7aabb Mon Sep 17 00:00:00 2001 From: Granville Schmidt <1246157+gramidt@users.noreply.github.com> Date: Wed, 17 Jan 2024 18:13:58 -0700 Subject: [PATCH 01/25] fix wording in CLI building waiting message --- packages/cli/src/builder.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli/src/builder.rs b/packages/cli/src/builder.rs index 6ad009bd9..744f47916 100644 --- a/packages/cli/src/builder.rs +++ b/packages/cli/src/builder.rs @@ -443,7 +443,7 @@ fn prettier_build(cmd: subprocess::Exec) -> anyhow::Result> { .unwrap() .tick_chars("/|\\- "), ); - pb.set_message("💼 Waiting to start build the project..."); + pb.set_message("💼 Waiting to start building the project..."); let stdout = cmd.detached().stream_stdout()?; let reader = std::io::BufReader::new(stdout); From f8071d9a611156bec242bfdff368595a4b322dcc Mon Sep 17 00:00:00 2001 From: Ameyanagi Date: Thu, 18 Jan 2024 01:54:23 -0500 Subject: [PATCH 02/25] add MathML core elements --- packages/html/src/elements.rs | 192 ++++++++++++++++++++++++++++++++++ 1 file changed, 192 insertions(+) diff --git a/packages/html/src/elements.rs b/packages/html/src/elements.rs index 37e6bb682..4121fe154 100644 --- a/packages/html/src/elements.rs +++ b/packages/html/src/elements.rs @@ -1744,4 +1744,196 @@ builder_constructors! { r#use ["use", "http://www.w3.org/2000/svg"] { href: String DEFAULT, }; + + // MathML elements + + /// Build a + /// [``](https://w3c.github.io/mathml-core/#dfn-annotation) + /// element. + annotation "http://www.w3.org/1998/Math/MathML" {}; + + /// Build a + /// [``](https://w3c.github.io/mathml-core/#dfn-annotation-xml) + /// element. + annotation_xml ["annotation-xml", "http://www.w3.org/1998/Math/MathML"] {}; + + /// Build a + /// [``](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/merror) + /// element. + merror "http://www.w3.org/1998/Math/MathML" {}; + + /// Build a + /// [``](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/math) + /// element. + math "http://www.w3.org/1998/Math/MathML" { + // rust name of the attribute | unit (this is currently ignored, you can use String as a default) | the HTML attribute name (this can be DEFAULT for a stringified name or a custom string like "display2") + display: String DEFAULT, + }; + + /// Build a + /// [``](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mfrac) + /// element. + mfrac "http://www.w3.org/1998/Math/MathML" { + linethickness: usize DEFAULT, + }; + + /// Build a + /// [``](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mi) + /// element. + mi "http://www.w3.org/1998/Math/MathML" { + mathvariant: String DEFAULT, + }; + + /// Build a + /// [``](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mmultiscripts) + /// element. + mmultiscripts "http://www.w3.org/1998/math/mathml" {}; + + /// Build a + /// [``](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mn) + /// element. + mn "http://www.w3.org/1998/Math/MathML" {}; + + /// Build a + /// [``](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mo) + /// element. + mo "http://www.w3.org/1998/Math/MathML" { + fence: Bool DEFAULT, + largeop: Bool DEFAULT, + lspace: usize DEFAULT, + maxsize: usize DEFAULT, + minsize: usize DEFAULT, + movablelimits: Bool DEFAULT, + rspace: usize DEFAULT, + separator: Bool DEFAULT, + stretchy: Bool DEFAULT, + symmetric: Bool DEFAULT, + }; + + /// Build a + /// [``](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mover) + /// element. + mover "http://www.w3.org/1998/Math/MathML" { + accent: Bool DEFAULT, + }; + + /// Build a + /// [``](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mpadded) + /// element. + mpadded "http://www.w3.org/1998/Math/MathML" { + depth: usize DEFAULT, + height: usize DEFAULT, + lspace: usize DEFAULT, + voffset: usize DEFAULT, + width: usize DEFAULT, + }; + + /// Build a + /// [``](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mphantom) + /// element. + mphantom "http://www.w3.org/1998/Math/MathML" {}; + + /// Build a + /// [``](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mprescripts) + /// element. + mprescripts "http://www.w3.org/1998/Math/MathML" {}; + + /// Build a + /// [``](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mroot) + /// element. + mroot "http://www.w3.org/1998/Math/MathML" {}; + + /// Build a + /// [``](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mrow) + /// element. + mrow "http://www.w3.org/1998/Math/MathML" { + + }; + + /// Build a + /// [``](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/ms) + /// element. + ms "http://www.w3.org/1998/Math/MathML" { + lquote: String DEFAULT, + rquote: String DEFAULT, + }; + + /// Build a + /// [``](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mspace) + /// element. + mspace "http://www.w3.org/1998/Math/MathML" { + depth: usize DEFAULT, + height: usize DEFAULT, + width: usize DEFAULT, + }; + + /// Build a + /// [``](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/msqrt) + /// element. + msqrt "http://www.w3.org/1998/Math/MathML" {}; + + /// Build a + /// [``](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mstyle) + /// element. + mstyle "http://www.w3.org/1998/Math/MathML" {}; + + /// Build a + /// [``](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/msub) + /// element. + msub "http://www.w3.org/1998/Math/MathML" {}; + + /// Build a + /// [``](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/msubsup) + /// element. + msubsup "http://www.w3.org/1998/Math/MathML" {}; + + /// Build a + /// [``](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/msup) + /// element. + msup "http://www.w3.org/1998/Math/MathML" {}; + + /// Build a + /// [``](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mtable) + /// element. + mtable "http://www.w3.org/1998/Math/MathML" {}; + + /// Build a + /// [``](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mtd) + /// element. + mtd "http://www.w3.org/1998/Math/MathML" { + columnspan: usize DEFAULT, + rowspan: usize DEFAULT, + }; + + /// Build a + /// [``](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mtext) + /// element. + mtext "http://www.w3.org/1998/Math/MathML" {}; + + /// Build a + /// [``](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mtr) + /// element. + mtr "http://www.w3.org/1998/Math/MathML" {}; + + /// Build a + /// [``](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/munder) + /// element. + munder "http://www.w3.org/1998/Math/MathML" { + accentunder: Bool DEFAULT, + }; + + /// Build a + /// [``](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/munderover) + /// element. + munderover "http://www.w3.org/1998/Math/MathML" { + accent: Bool DEFAULT, + accentunder: Bool DEFAULT, + }; + + /// Build a + /// [``](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/semantics) + /// element. + symantics "http://www.w3.org/1998/Math/MathML" { + encoding: String DEFAULT, + }; } From 27254eecc69ca4b8e64d0401216ccaac406fef7d Mon Sep 17 00:00:00 2001 From: Ameyanagi <77273474+Ameyanagi@users.noreply.github.com> Date: Thu, 18 Jan 2024 17:13:55 -0500 Subject: [PATCH 03/25] added annotation-xml --- packages/html/src/elements.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/html/src/elements.rs b/packages/html/src/elements.rs index 4121fe154..2e54d452f 100644 --- a/packages/html/src/elements.rs +++ b/packages/html/src/elements.rs @@ -1750,12 +1750,16 @@ builder_constructors! { /// Build a /// [``](https://w3c.github.io/mathml-core/#dfn-annotation) /// element. - annotation "http://www.w3.org/1998/Math/MathML" {}; + annotation "http://www.w3.org/1998/Math/MathML" { + encoding: String DEFAULT, + }; /// Build a /// [``](https://w3c.github.io/mathml-core/#dfn-annotation-xml) /// element. - annotation_xml ["annotation-xml", "http://www.w3.org/1998/Math/MathML"] {}; + annotationXml ["annotation-xml", "http://www.w3.org/1998/Math/MathML"] { + encoding: String DEFAULT, + }; /// Build a /// [``](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/merror) @@ -1933,7 +1937,7 @@ builder_constructors! { /// Build a /// [``](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/semantics) /// element. - symantics "http://www.w3.org/1998/Math/MathML" { + semantics "http://www.w3.org/1998/Math/MathML" { encoding: String DEFAULT, }; } From a3f6d21beaba5536d57a537f9784eab56806f6c5 Mon Sep 17 00:00:00 2001 From: Ameyanagi <77273474+Ameyanagi@users.noreply.github.com> Date: Thu, 18 Jan 2024 17:54:57 -0500 Subject: [PATCH 04/25] deleted unused comment --- packages/html/src/elements.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/html/src/elements.rs b/packages/html/src/elements.rs index 2e54d452f..c5e5e3ab5 100644 --- a/packages/html/src/elements.rs +++ b/packages/html/src/elements.rs @@ -1770,7 +1770,6 @@ builder_constructors! { /// [``](https://developer.mozilla.org/en-US/docs/Web/MathML/Element/math) /// element. math "http://www.w3.org/1998/Math/MathML" { - // rust name of the attribute | unit (this is currently ignored, you can use String as a default) | the HTML attribute name (this can be DEFAULT for a stringified name or a custom string like "display2") display: String DEFAULT, }; From dd114788f4c43d0c4bbf3e86839d592c880edbbd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Jan 2024 15:27:44 +0000 Subject: [PATCH 05/25] Bump h2 from 0.3.23 to 0.3.24 Bumps [h2](https://github.com/hyperium/h2) from 0.3.23 to 0.3.24. - [Release notes](https://github.com/hyperium/h2/releases) - [Changelog](https://github.com/hyperium/h2/blob/v0.3.24/CHANGELOG.md) - [Commits](https://github.com/hyperium/h2/compare/v0.3.23...v0.3.24) --- updated-dependencies: - dependency-name: h2 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- Cargo.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 38b5f7ed1..1939afbe9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4721,9 +4721,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.23" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b553656127a00601c8ae5590fcfdc118e4083a7924b6cf4ffc1ea4b99dc429d7" +checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" dependencies = [ "bytes", "fnv", @@ -5074,14 +5074,14 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2 0.3.23", + "h2 0.3.24", "http 0.2.11", "http-body 0.4.6", "httparse", "httpdate", "itoa 1.0.10", "pin-project-lite", - "socket2 0.5.5", + "socket2 0.4.10", "tokio", "tower-service", "tracing", @@ -8302,7 +8302,7 @@ dependencies = [ "encoding_rs", "futures-core", "futures-util", - "h2 0.3.23", + "h2 0.3.24", "http 0.2.11", "http-body 0.4.6", "hyper 0.14.28", From baf505e330c2786d53c5bccb1f97e66dff724260 Mon Sep 17 00:00:00 2001 From: Jan-Mirko Otter Date: Fri, 19 Jan 2024 23:15:36 +0100 Subject: [PATCH 06/25] dioxus-web: Add `Config::rootelement` --- packages/web/src/cfg.rs | 21 ++++++++++++++++++--- packages/web/src/dom.rs | 40 ++++++++++++++++++++++++++-------------- 2 files changed, 44 insertions(+), 17 deletions(-) diff --git a/packages/web/src/cfg.rs b/packages/web/src/cfg.rs index 7483a7a8b..db6695035 100644 --- a/packages/web/src/cfg.rs +++ b/packages/web/src/cfg.rs @@ -10,7 +10,7 @@ pub struct Config { #[cfg(feature = "hydrate")] pub(crate) hydrate: bool, - pub(crate) rootname: String, + pub(crate) root: ConfigRoot, pub(crate) cached_strings: Vec, pub(crate) default_panic_hook: bool, } @@ -20,7 +20,7 @@ impl Default for Config { Self { #[cfg(feature = "hydrate")] hydrate: false, - rootname: "main".to_string(), + root: ConfigRoot::RootName("main".to_string()), cached_strings: Vec::new(), default_panic_hook: true, } @@ -50,8 +50,18 @@ impl Config { /// Set the name of the element that Dioxus will use as the root. /// /// This is akin to calling React.render() on the element with the specified name. + /// Note that this only works on the current document, i.e. `window.document`. + /// To use a different document (popup, iframe, ...) use [Self::rootelement] instead. pub fn rootname(mut self, name: impl Into) -> Self { - self.rootname = name.into(); + self.root = ConfigRoot::RootName(name.into()); + self + } + + /// Set the element that Dioxus will use as root. + /// + /// This is akin to calling React.render() on the given element. + pub fn rootelement(mut self, elem: web_sys::Element) -> Self { + self.root = ConfigRoot::RootElement(elem); self } @@ -72,3 +82,8 @@ impl Config { self } } + +pub(crate) enum ConfigRoot { + RootName(String), + RootElement(web_sys::Element), +} diff --git a/packages/web/src/dom.rs b/packages/web/src/dom.rs index 44c0628e6..94cc03c9e 100644 --- a/packages/web/src/dom.rs +++ b/packages/web/src/dom.rs @@ -37,24 +37,36 @@ pub struct UiEvent { pub data: PlatformEventData, } +//fn get_document(elem: &web_sys::Element) -> + impl WebsysDom { pub fn new(cfg: Config, event_channel: mpsc::UnboundedSender) -> Self { - // eventually, we just want to let the interpreter do all the work of decoding events into our event type - // a match here in order to avoid some error during runtime browser test - let document = load_document(); - let root = match document.get_element_by_id(&cfg.rootname) { - Some(root) => root, - None => { - web_sys::console::error_1( - &format!( - "element '#{}' not found. mounting to the body.", - cfg.rootname - ) - .into(), - ); - document.create_element("body").ok().unwrap() + let (document, root) = match cfg.root { + crate::cfg::ConfigRoot::RootName(rootname) => { + // eventually, we just want to let the interpreter do all the work of decoding events into our event type + // a match here in order to avoid some error during runtime browser test + let document = load_document(); + let root = match document.get_element_by_id(&rootname) { + Some(root) => root, + None => { + web_sys::console::error_1( + &format!("element '#{}' not found. mounting to the body.", rootname) + .into(), + ); + document.create_element("body").ok().unwrap() + } + }; + (document, root) + } + crate::cfg::ConfigRoot::RootElement(root) => { + let document = match root.owner_document() { + Some(document) => document, + None => load_document(), + }; + (document, root) } }; + let interpreter = Channel::default(); let handler: Closure = Closure::wrap(Box::new({ From 9e4f3456c0646e8af57efd5af630932858787922 Mon Sep 17 00:00:00 2001 From: Jeremy Chen Date: Sun, 21 Jan 2024 00:44:18 +0800 Subject: [PATCH 07/25] docs: move Chinese README to translate directory and update some translate issues. --- README.md | 2 +- .../ZH_CN.md => translations/zh-cn/README.md | 30 +++++++++---------- 2 files changed, 16 insertions(+), 16 deletions(-) rename notes/README/ZH_CN.md => translations/zh-cn/README.md (83%) diff --git a/README.md b/README.md index 65cd08263..c5c41090b 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ | Guide | - 中文 + 中文 | PT-BR | diff --git a/notes/README/ZH_CN.md b/translations/zh-cn/README.md similarity index 83% rename from notes/README/ZH_CN.md rename to translations/zh-cn/README.md index 45bf82f09..f218fcf34 100644 --- a/notes/README/ZH_CN.md +++ b/translations/zh-cn/README.md @@ -1,5 +1,5 @@

- +

@@ -66,17 +66,17 @@ fn app(cx: Scope) -> Element { } ``` -Dioxus 可用于生成 网页前端、桌面应用、静态网站、移动端应用、TUI程序、等多类平台应用。 +Dioxus 可用于生成 网页前端、桌面应用、静态网站、移动端应用、TUI程序、 liveview程序等多类平台应用,Dioxus完全与渲染器无关,可以作用于任何渲染平台。 如果你能够熟悉使用 React 框架,那 Dioxus 对你来说将非常简单。 ## 独特的特性: -- 桌面程序完全基于本地环境运行(并非 Electron 的封装) +- 只需不到10行代码就能原生运行桌面程序(并非 Electron 的封装) - 符合人体工程学的设计以及拥有强大的状态管理 - 全面的内联文档 - 包含所有 HTML 元素、监听器 和 事件 指南。 -- 极快的运行效率和极高的内存效率 -- 智能项目热更新和高效的项目迭代 -- 一流的异步支持🔥 +- 极快的运行效率🔥🔥和极高的内存效率 +- 智能项目热重载以便快速迭代 +- 使用协程和Suspense来进行一流的异步支持 - 更多内容请查看 [版本发布信息](https://dioxuslabs.com/blog/introducing-dioxus/). ## 已支持的平台 @@ -89,7 +89,7 @@ Dioxus 可用于生成 网页前端、桌面应用、静态网站、移动端应
  • 使用 WebAssembly 直接对 DOM 进行渲染
  • 为 SSR 提供预渲染或作为客户端使用
  • 简单的 "Hello World" 仅仅 65kb, 媲美 React 框架
  • -
  • CLI 提供热更新支持,方便项目快速迭代
  • +
  • 内置开发服务和热重载支持,方便项目快速迭代
  • @@ -98,7 +98,7 @@ Dioxus 可用于生成 网页前端、桌面应用、静态网站、移动端应
    • 使用 Webview 进行渲染 或 使用 WGPU 和 Skia(试验性的)
    • -
    • 无多余配置,使用 `cargo build` 即可快速构建
    • +
    • 无多余配置,简单的使用 `cargo build` 即可快速构建
    • 对原生系统的全面支持
    • 支持 Macos、Linux、Windows 等系统,极小的二进制文件
    @@ -118,9 +118,9 @@ Dioxus 可用于生成 网页前端、桌面应用、静态网站、移动端应 Liveview
      -
    • 使用服务器渲染组件与应用程序
    • +
    • 完全使用服务器渲染应用程序或单个组件
    • 与受欢迎的后端框架进行融合(Axum、Wrap)
    • -
    • 及低的延迟
    • +
    • 及低的延迟,可以同时支持10000个以上的终端程序
    @@ -130,22 +130,22 @@ Dioxus 可用于生成 网页前端、桌面应用、静态网站、移动端应
    • 在终端程序中渲染,类似于: ink.js
    • 支持 CSS 相关模型(类似于浏览器内的)
    • -
    • Built-in widgets like text input, buttons, and focus system
    • +
    • 内置类似文字输入,按钮和焦点系统的小组件
    -## Why Dioxus? +## 为什么选择Dioxus? 目前有非常多的应用开发选择,为什么偏偏要选择 Dioxus 呢? -首先,Dioxus将开发者的经验放在首位。这反映在 Dioxus 特有的各种功能上。 +首先,Dioxus将开发者的体验放在首位。这体现在 Dioxus 特有的各种功能上。 - 自动格式化 RSX 格式代码,并拥有 VSCode 插件作为支持。 - 热加载基于 RSX 代码解析器,同时支持桌面程序和网页程序。 -- 强调文档的重要性,我们对所有 HTML 元素都提供文档支持。 +- 强调文档的重要性--我们的指南是完整的,并且我们对所有 HTML 元素都提供文档支持。 Dioxus 也是一个可扩展化的平台。 @@ -160,7 +160,7 @@ Dioxus 那么优秀,但什么时候它不适合我呢? ## 贡献代码 - 在我们的 [问题追踪](https://github.com/dioxuslabs/dioxus/issues) 中汇报你遇到的问题。 -- 加入我们的 Discord 与我们交流。 +- [加入](https://discord.gg/XgGxMSkvUM)我们的 Discord 与我们交流。 From 91e378fc5eac205f94515c4d970eb89803b49dac Mon Sep 17 00:00:00 2001 From: Ege Gungordu Date: Sat, 20 Jan 2024 20:44:52 +0300 Subject: [PATCH 08/25] mark hot-reload flag incompatible with release --- packages/cli/src/cli/cfg.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/cli/src/cli/cfg.rs b/packages/cli/src/cli/cfg.rs index 877fdff33..6f0fe247f 100644 --- a/packages/cli/src/cli/cfg.rs +++ b/packages/cli/src/cli/cfg.rs @@ -78,6 +78,7 @@ impl From for ConfigOptsBuild { } #[derive(Clone, Debug, Default, Deserialize, Parser)] +#[command(group = clap::ArgGroup::new("release-incompatible").multiple(true).conflicts_with("release"))] pub struct ConfigOptsServe { /// Port of dev server #[clap(long)] @@ -116,8 +117,9 @@ pub struct ConfigOptsServe { #[clap(long, value_enum)] pub platform: Option, - /// Build with hot reloading rsx [default: false] + /// Build with hot reloading rsx. Will not work with release builds. [default: false] #[clap(long)] + #[clap(group = "release-incompatible")] #[serde(default)] pub hot_reload: bool, From 7aa3f2195429b4388e6b1b0548e7d99a61044a66 Mon Sep 17 00:00:00 2001 From: Ege Gungordu Date: Sun, 21 Jan 2024 18:26:48 +0300 Subject: [PATCH 09/25] fix attribute diff infinite loop (#1843) --- packages/core/src/diff.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/core/src/diff.rs b/packages/core/src/diff.rs index a116aee4d..2f5b84f25 100644 --- a/packages/core/src/diff.rs +++ b/packages/core/src/diff.rs @@ -160,6 +160,10 @@ impl<'b> VirtualDom { self.diff_attribute(left, right, mounted_id) } } + + // consume both + left_iter.next(); + right_iter.next(); } (Some(_), None) => { let left = left_iter.next().unwrap(); From 6111bdfdf0f90e1b8b9e2abaf4852532f7fcf4b3 Mon Sep 17 00:00:00 2001 From: Ege Gungordu Date: Sun, 21 Jan 2024 18:29:29 +0300 Subject: [PATCH 10/25] add attribute diff test --- packages/core/tests/diff_element.rs | 110 +++++++++++++++++++++++++++- 1 file changed, 109 insertions(+), 1 deletion(-) diff --git a/packages/core/tests/diff_element.rs b/packages/core/tests/diff_element.rs index a0b9bfa84..e201dbb38 100644 --- a/packages/core/tests/diff_element.rs +++ b/packages/core/tests/diff_element.rs @@ -1,6 +1,6 @@ use dioxus::core::Mutation::*; use dioxus::prelude::*; -use dioxus_core::ElementId; +use dioxus_core::{AttributeValue, ElementId}; #[test] fn text_diff() { @@ -82,3 +82,111 @@ fn element_swap() { ] ); } + +#[test] +fn attribute_diff() { + fn app(cx: Scope) -> Element { + let gen = cx.generation(); + + let attrs = cx.bump().alloc(match gen % 2 { + 0 => vec![Attribute::new( + "attr1", + AttributeValue::Text("hello"), + None, + false, + )], + 1 => vec![ + Attribute::new("attr1", AttributeValue::Text("hello"), None, false), + Attribute::new("attr2", AttributeValue::Float(1.0), None, false), + Attribute::new("attr3", AttributeValue::Int(1), None, false), + Attribute::new("attr4", AttributeValue::Bool(true), None, false), + ], + _ => unreachable!(), + }); + + cx.render(rsx!( + div { + ..*attrs, + "hello" + } + )) + } + + let mut vdom = VirtualDom::new(app); + _ = vdom.rebuild(); + + vdom.mark_dirty(ScopeId::ROOT); + assert_eq!( + vdom.render_immediate().santize().edits, + [ + SetAttribute { + name: "attr2", + value: (&AttributeValue::Float(1.0)).into(), + id: ElementId(1), + ns: None + }, + SetAttribute { + name: "attr3", + value: (&AttributeValue::Int(1)).into(), + id: ElementId(1), + ns: None + }, + SetAttribute { + name: "attr4", + value: (&AttributeValue::Bool(true)).into(), + id: ElementId(1), + ns: None + }, + ] + ); + + vdom.mark_dirty(ScopeId::ROOT); + assert_eq!( + vdom.render_immediate().santize().edits, + [ + SetAttribute { + name: "attr2", + value: (&AttributeValue::None).into(), + id: ElementId(1), + ns: None + }, + SetAttribute { + name: "attr3", + value: (&AttributeValue::None).into(), + id: ElementId(1), + ns: None + }, + SetAttribute { + name: "attr4", + value: (&AttributeValue::None).into(), + id: ElementId(1), + ns: None + }, + ] + ); + + vdom.mark_dirty(ScopeId::ROOT); + assert_eq!( + vdom.render_immediate().santize().edits, + [ + SetAttribute { + name: "attr2", + value: (&AttributeValue::Float(1.0)).into(), + id: ElementId(1), + ns: None + }, + SetAttribute { + name: "attr3", + value: (&AttributeValue::Int(1)).into(), + id: ElementId(1), + ns: None + }, + SetAttribute { + name: "attr4", + value: (&AttributeValue::Bool(true)).into(), + id: ElementId(1), + ns: None + }, + ] + ); +} From 43fe17d9c53ea9f71537c2c85cb72ab71d623890 Mon Sep 17 00:00:00 2001 From: Ege Gungordu Date: Mon, 22 Jan 2024 00:36:44 +0300 Subject: [PATCH 11/25] fix attribute diffs causing infinite loops with test --- packages/core/src/diff.rs | 36 +++++----- packages/core/tests/diff_element.rs | 105 +++++++++++++++------------- 2 files changed, 78 insertions(+), 63 deletions(-) diff --git a/packages/core/src/diff.rs b/packages/core/src/diff.rs index 2f5b84f25..b5f262b0c 100644 --- a/packages/core/src/diff.rs +++ b/packages/core/src/diff.rs @@ -145,25 +145,29 @@ impl<'b> VirtualDom { (Some(left), Some(right)) => { // check which name is greater match left.name.cmp(right.name) { - std::cmp::Ordering::Less => self.remove_attribute( - left.name, - left.namespace, - mounted_id, - ), - std::cmp::Ordering::Greater => self.write_attribute( - right_template, - right, - idx, - mounted_id, - ), + std::cmp::Ordering::Less => { + self.remove_attribute( + left.name, + left.namespace, + mounted_id, + ); + left_iter.next(); + } + std::cmp::Ordering::Greater => { + self.write_attribute( + right_template, + right, + idx, + mounted_id, + ); + right_iter.next(); + } std::cmp::Ordering::Equal => { - self.diff_attribute(left, right, mounted_id) + self.diff_attribute(left, right, mounted_id); + left_iter.next(); + right_iter.next(); } } - - // consume both - left_iter.next(); - right_iter.next(); } (Some(_), None) => { let left = left_iter.next().unwrap(); diff --git a/packages/core/tests/diff_element.rs b/packages/core/tests/diff_element.rs index e201dbb38..7169de609 100644 --- a/packages/core/tests/diff_element.rs +++ b/packages/core/tests/diff_element.rs @@ -88,21 +88,32 @@ fn attribute_diff() { fn app(cx: Scope) -> Element { let gen = cx.generation(); - let attrs = cx.bump().alloc(match gen % 2 { - 0 => vec![Attribute::new( - "attr1", + // attributes have to be sorted by name + let attrs = match gen % 5 { + 0 => cx.bump().alloc([Attribute::new( + "a", AttributeValue::Text("hello"), None, false, - )], - 1 => vec![ - Attribute::new("attr1", AttributeValue::Text("hello"), None, false), - Attribute::new("attr2", AttributeValue::Float(1.0), None, false), - Attribute::new("attr3", AttributeValue::Int(1), None, false), - Attribute::new("attr4", AttributeValue::Bool(true), None, false), - ], + )]) as &[Attribute], + 1 => cx.bump().alloc([ + Attribute::new("a", AttributeValue::Text("hello"), None, false), + Attribute::new("b", AttributeValue::Text("hello"), None, false), + Attribute::new("c", AttributeValue::Text("hello"), None, false), + ]) as &[Attribute], + 2 => cx.bump().alloc([ + Attribute::new("c", AttributeValue::Text("hello"), None, false), + Attribute::new("d", AttributeValue::Text("hello"), None, false), + Attribute::new("e", AttributeValue::Text("hello"), None, false), + ]) as &[Attribute], + 3 => cx.bump().alloc([Attribute::new( + "d", + AttributeValue::Text("world"), + None, + false, + )]) as &[Attribute], _ => unreachable!(), - }); + }; cx.render(rsx!( div { @@ -120,22 +131,16 @@ fn attribute_diff() { vdom.render_immediate().santize().edits, [ SetAttribute { - name: "attr2", - value: (&AttributeValue::Float(1.0)).into(), - id: ElementId(1), - ns: None + name: "b", + value: (&AttributeValue::Text("hello",)).into(), + id: ElementId(1,), + ns: None, }, SetAttribute { - name: "attr3", - value: (&AttributeValue::Int(1)).into(), - id: ElementId(1), - ns: None - }, - SetAttribute { - name: "attr4", - value: (&AttributeValue::Bool(true)).into(), - id: ElementId(1), - ns: None + name: "c", + value: (&AttributeValue::Text("hello",)).into(), + id: ElementId(1,), + ns: None, }, ] ); @@ -145,22 +150,28 @@ fn attribute_diff() { vdom.render_immediate().santize().edits, [ SetAttribute { - name: "attr2", + name: "a", value: (&AttributeValue::None).into(), - id: ElementId(1), - ns: None + id: ElementId(1,), + ns: None, }, SetAttribute { - name: "attr3", + name: "b", value: (&AttributeValue::None).into(), - id: ElementId(1), - ns: None + id: ElementId(1,), + ns: None, }, SetAttribute { - name: "attr4", - value: (&AttributeValue::None).into(), - id: ElementId(1), - ns: None + name: "d", + value: (&AttributeValue::Text("hello",)).into(), + id: ElementId(1,), + ns: None, + }, + SetAttribute { + name: "e", + value: (&AttributeValue::Text("hello",)).into(), + id: ElementId(1,), + ns: None, }, ] ); @@ -170,22 +181,22 @@ fn attribute_diff() { vdom.render_immediate().santize().edits, [ SetAttribute { - name: "attr2", - value: (&AttributeValue::Float(1.0)).into(), - id: ElementId(1), - ns: None + name: "c", + value: (&AttributeValue::None).into(), + id: ElementId(1,), + ns: None, }, SetAttribute { - name: "attr3", - value: (&AttributeValue::Int(1)).into(), - id: ElementId(1), - ns: None + name: "d", + value: (&AttributeValue::Text("world",)).into(), + id: ElementId(1,), + ns: None, }, SetAttribute { - name: "attr4", - value: (&AttributeValue::Bool(true)).into(), - id: ElementId(1), - ns: None + name: "e", + value: (&AttributeValue::None).into(), + id: ElementId(1,), + ns: None, }, ] ); From d3ded8c677b25237aee8d4951c6da347684c4266 Mon Sep 17 00:00:00 2001 From: Ege Gungordu Date: Tue, 23 Jan 2024 18:31:14 +0300 Subject: [PATCH 12/25] add isComposing support of KeyboardEvent --- packages/html/src/events/keyboard.rs | 18 ++++++++++++++++++ packages/html/src/web_sys_bind/events.rs | 4 ++++ packages/interpreter/src/interpreter.js | 2 ++ packages/rink/src/hooks.rs | 2 ++ 4 files changed, 26 insertions(+) diff --git a/packages/html/src/events/keyboard.rs b/packages/html/src/events/keyboard.rs index feb0ab313..1dac40d1c 100644 --- a/packages/html/src/events/keyboard.rs +++ b/packages/html/src/events/keyboard.rs @@ -33,6 +33,7 @@ impl std::fmt::Debug for KeyboardData { .field("modifiers", &self.modifiers()) .field("location", &self.location()) .field("is_auto_repeating", &self.is_auto_repeating()) + .field("is_composing", &self.is_composing()) .finish() } } @@ -44,6 +45,7 @@ impl PartialEq for KeyboardData { && self.modifiers() == other.modifiers() && self.location() == other.location() && self.is_auto_repeating() == other.is_auto_repeating() + && self.is_composing() == other.is_composing() } } @@ -75,6 +77,11 @@ impl KeyboardData { self.inner.is_auto_repeating() } + /// Indicates whether the key is fired within a composition session. + pub fn is_composing(&self) -> bool { + self.inner.is_composing() + } + /// Downcast this KeyboardData to a concrete type. pub fn downcast(&self) -> Option<&T> { self.inner.as_any().downcast_ref::() @@ -92,6 +99,7 @@ impl ModifiersInteraction for KeyboardData { #[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Clone)] pub struct SerializedKeyboardData { char_code: u32, + is_composing: bool, key: String, key_code: KeyCode, #[serde(deserialize_with = "resilient_deserialize_code")] @@ -114,9 +122,11 @@ impl SerializedKeyboardData { location: Location, is_auto_repeating: bool, modifiers: Modifiers, + is_composing: bool, ) -> Self { Self { char_code: key.legacy_charcode(), + is_composing, key: key.to_string(), key_code: KeyCode::from_raw_code( std::convert::TryInto::try_into(key.legacy_keycode()) @@ -144,6 +154,7 @@ impl From<&KeyboardData> for SerializedKeyboardData { data.location(), data.is_auto_repeating(), data.modifiers(), + data.is_composing(), ) } } @@ -166,6 +177,10 @@ impl HasKeyboardData for SerializedKeyboardData { self.repeat } + fn is_composing(&self) -> bool { + self.is_composing + } + fn as_any(&self) -> &dyn std::any::Any { self } @@ -236,6 +251,9 @@ pub trait HasKeyboardData: ModifiersInteraction + std::any::Any { /// `true` iff the key is being held down such that it is automatically repeating. fn is_auto_repeating(&self) -> bool; + /// Indicates whether the key is fired within a composition session. + fn is_composing(&self) -> bool; + /// return self as Any fn as_any(&self) -> &dyn std::any::Any; } diff --git a/packages/html/src/web_sys_bind/events.rs b/packages/html/src/web_sys_bind/events.rs index 40d14f28b..f5fb84760 100644 --- a/packages/html/src/web_sys_bind/events.rs +++ b/packages/html/src/web_sys_bind/events.rs @@ -78,6 +78,10 @@ impl HasKeyboardData for KeyboardEvent { self.repeat() } + fn is_composing(&self) -> bool { + self.is_composing() + } + fn as_any(&self) -> &dyn std::any::Any { self } diff --git a/packages/interpreter/src/interpreter.js b/packages/interpreter/src/interpreter.js index c8384a8b7..0e9800645 100644 --- a/packages/interpreter/src/interpreter.js +++ b/packages/interpreter/src/interpreter.js @@ -351,6 +351,7 @@ async function serialize_event(event) { case "keyup": { let { charCode, + isComposing, key, altKey, ctrlKey, @@ -364,6 +365,7 @@ async function serialize_event(event) { } = event; return { char_code: charCode, + is_composing: isComposing, key: key, alt_key: altKey, ctrl_key: ctrlKey, diff --git a/packages/rink/src/hooks.rs b/packages/rink/src/hooks.rs index d519273f0..81f6558b6 100644 --- a/packages/rink/src/hooks.rs +++ b/packages/rink/src/hooks.rs @@ -179,6 +179,7 @@ impl InnerInputState { k.location(), is_repeating, k.modifiers(), + k.is_composing(), ); } @@ -779,6 +780,7 @@ fn translate_key_event(event: crossterm::event::KeyEvent) -> Option { Location::Standard, false, modifiers, + false, ))) } From 8887d674ed9ff04b4196dc7d93f4ec16abf2b432 Mon Sep 17 00:00:00 2001 From: Ege Gungordu Date: Tue, 23 Jan 2024 18:33:28 +0300 Subject: [PATCH 13/25] add is_composing check to desktop headless tests --- packages/desktop/headless_tests/events.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/desktop/headless_tests/events.rs b/packages/desktop/headless_tests/events.rs index 69f743a1a..9f6f9fea7 100644 --- a/packages/desktop/headless_tests/events.rs +++ b/packages/desktop/headless_tests/events.rs @@ -154,7 +154,7 @@ fn app(cx: Scope) -> Element { ctrlKey: false, metaKey: false, shiftKey: false, - isComposing: false, + isComposing: true, which: 65, bubbles: true, })"#, @@ -356,6 +356,7 @@ fn app(cx: Scope) -> Element { assert_eq!(event.data.code().to_string(), "KeyA"); assert_eq!(event.data.location(), Location::Standard); assert!(event.data.is_auto_repeating()); + assert!(event.data.is_composing()); received_events.modify(|x| *x + 1) } } @@ -368,6 +369,7 @@ fn app(cx: Scope) -> Element { assert_eq!(event.data.code().to_string(), "KeyA"); assert_eq!(event.data.location(), Location::Standard); assert!(!event.data.is_auto_repeating()); + assert!(!event.data.is_composing()); received_events.modify(|x| *x + 1) } } @@ -380,6 +382,7 @@ fn app(cx: Scope) -> Element { assert_eq!(event.data.code().to_string(), "KeyA"); assert_eq!(event.data.location(), Location::Standard); assert!(!event.data.is_auto_repeating()); + assert!(!event.data.is_composing()); received_events.modify(|x| *x + 1) } } From 47d15fc8a1675af0044352aae1e08ba32a096325 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20S=C3=B6derstr=C3=B6m?= Date: Thu, 25 Jan 2024 21:28:39 +0100 Subject: [PATCH 14/25] fix: initialize linux wry webview In the wry 0.32 examples the linux webviews are initialized in a different way to render properly using tao::platform::unix::WindowExtUnix. Tested with Gnome 45.3 and Wayland. --- packages/desktop/src/webview.rs | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/packages/desktop/src/webview.rs b/packages/desktop/src/webview.rs index 168e5ff3c..700633234 100644 --- a/packages/desktop/src/webview.rs +++ b/packages/desktop/src/webview.rs @@ -91,7 +91,28 @@ impl WebviewInstance { } }; - let mut webview = WebViewBuilder::new(&window) + #[cfg(any( + target_os = "windows", + target_os = "macos", + target_os = "ios", + target_os = "android" + ))] + let mut webview = WebViewBuilder::new(&window); + + #[cfg(not(any( + target_os = "windows", + target_os = "macos", + target_os = "ios", + target_os = "android" + )))] + let mut webview = { + use tao::platform::unix::WindowExtUnix; + use wry::WebViewBuilderExtUnix; + let vbox = window.default_vbox().unwrap(); + WebViewBuilder::new_gtk(vbox) + }; + + webview = webview .with_transparent(cfg.window.window.transparent) .with_url("dioxus://index.html/") .unwrap() From f98a9adad2aff174edc65d0b45f9ae2b84169fac Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Thu, 25 Jan 2024 17:23:06 -0600 Subject: [PATCH 15/25] fix duplicate window menu in the default menubar --- packages/desktop/src/menubar.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/desktop/src/menubar.rs b/packages/desktop/src/menubar.rs index 8c9941cf8..731fb6a68 100644 --- a/packages/desktop/src/menubar.rs +++ b/packages/desktop/src/menubar.rs @@ -64,7 +64,7 @@ mod impl_ { ]) .unwrap(); - let edit_menu = Submenu::new("Window", true); + let edit_menu = Submenu::new("Edit", true); edit_menu .append_items(&[ &PredefinedMenuItem::undo(None), From f7041b118d23b5ae8f033be87e8c1b7c8c2d2b62 Mon Sep 17 00:00:00 2001 From: Andrew Voynov Date: Sat, 27 Jan 2024 21:52:52 +0300 Subject: [PATCH 16/25] chore(deps): bump cargo-generate from 0.18 to 0.19 When building the `dx` CLI there is 1 less dependency (from 710 to 709). --- Cargo.lock | 22 +++++++++++----------- packages/cli/Cargo.toml | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1939afbe9..9eece9cfd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1286,9 +1286,9 @@ dependencies = [ [[package]] name = "cargo-generate" -version = "0.18.5" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a2885ae054e000b117515ab33e91c10eca90c2788a7baec1b97ada1f1f51e57" +checksum = "92c1b6f44358912a9538fa3b6ac8d3aa3f585444f9dc32f12ed85d1545a9df9f" dependencies = [ "anyhow", "auth-git2", @@ -4142,9 +4142,9 @@ dependencies = [ [[package]] name = "gix-config" -version = "0.31.0" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cae98c6b4c66c09379bc35274b172587d6b0ac369a416c39128ad8c6454f9bb" +checksum = "0341471d55d8676e98b88e121d7065dfa4c9c5acea4b6d6ecdd2846e85cce0c3" dependencies = [ "bstr 1.9.0", "gix-config-value", @@ -4244,9 +4244,9 @@ dependencies = [ [[package]] name = "gix-object" -version = "0.38.0" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "740f2a44267f58770a1cb3a3d01d14e67b089c7136c48d4bddbb3cfd2bf86a51" +checksum = "febf79c5825720c1c63fe974c7bbe695d0cb54aabad73f45671c60ce0e501e33" dependencies = [ "bstr 1.9.0", "btoi", @@ -4276,9 +4276,9 @@ dependencies = [ [[package]] name = "gix-ref" -version = "0.38.0" +version = "0.39.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ec2f6d07ac88d2fb8007ee3fa3e801856fb9d82e7366ec0ca332eb2c9d74a52" +checksum = "3b2069adc212cf7f3317ef55f6444abd06c50f28479dbbac5a86acf3b05cbbfe" dependencies = [ "gix-actor", "gix-date", @@ -5081,7 +5081,7 @@ dependencies = [ "httpdate", "itoa 1.0.10", "pin-project-lite", - "socket2 0.4.10", + "socket2 0.5.5", "tokio", "tower-service", "tracing", @@ -6274,9 +6274,9 @@ checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" [[package]] name = "memmap2" -version = "0.7.1" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f49388d20533534cd19360ad3d6a7dadc885944aa802ba3995040c5ec11288c6" +checksum = "fe751422e4a8caa417e13c3ea66452215d7d63e19e604f4980461212f3ae1322" dependencies = [ "libc", ] diff --git a/packages/cli/Cargo.toml b/packages/cli/Cargo.toml index 8f0c0dc8a..7801f60fe 100644 --- a/packages/cli/Cargo.toml +++ b/packages/cli/Cargo.toml @@ -69,7 +69,7 @@ mlua = { version = "0.8.1", features = [ ], optional = true } ctrlc = "3.2.3" open = "4.1.0" -cargo-generate = "0.18" +cargo-generate = "0.19" toml_edit = "0.19.11" # bundling From fad060766741b8774e35b97c26335534e7cbdf35 Mon Sep 17 00:00:00 2001 From: marc2332 Date: Sat, 27 Jan 2024 22:27:23 +0100 Subject: [PATCH 17/25] feat: Reduce CLI deps --- Cargo.lock | 3 --- packages/cli/Cargo.toml | 3 --- packages/cli/src/cli/autoformat.rs | 2 +- packages/cli/src/cli/check.rs | 2 +- packages/cli/src/tools.rs | 2 +- 5 files changed, 3 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1939afbe9..c1d1ff9da 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2495,14 +2495,11 @@ dependencies = [ "serde", "serde_json", "subprocess", - "syn 2.0.48", "tar", "tauri-bundler", - "tauri-utils", "tempfile", "thiserror", "tokio", - "toml 0.5.11", "toml_edit 0.19.15", "tower", "tower-http 0.2.5", diff --git a/packages/cli/Cargo.toml b/packages/cli/Cargo.toml index 8f0c0dc8a..694025d36 100644 --- a/packages/cli/Cargo.toml +++ b/packages/cli/Cargo.toml @@ -21,7 +21,6 @@ log = "0.4.14" fern = { version = "0.6.0", features = ["colored"] } serde = { version = "1.0.136", features = ["derive"] } serde_json = "1.0.79" -toml = "0.5.8" fs_extra = "1.2.0" cargo_toml = "0.16.0" futures = "0.3.21" @@ -56,7 +55,6 @@ flate2 = "1.0.22" tar = "0.4.38" zip = "0.6.2" tower = "0.4.12" -syn = { version = "2.0", features = ["full", "extra-traits"] } lazy_static = "1.4.0" # plugin packages @@ -74,7 +72,6 @@ toml_edit = "0.19.11" # bundling tauri-bundler = { version = "=1.4.*", features = ["native-tls-vendored"] } -tauri-utils = "=1.5.*" manganis-cli-support = { workspace = true, features = ["webp", "html"] } diff --git a/packages/cli/src/cli/autoformat.rs b/packages/cli/src/cli/autoformat.rs index d1702ebf2..87d780524 100644 --- a/packages/cli/src/cli/autoformat.rs +++ b/packages/cli/src/cli/autoformat.rs @@ -1,5 +1,5 @@ use dioxus_autofmt::{IndentOptions, IndentType}; -use futures::{stream::FuturesUnordered, StreamExt}; +use futures_util::{stream::FuturesUnordered, StreamExt}; use std::{fs, path::Path, process::exit}; use super::*; diff --git a/packages/cli/src/cli/check.rs b/packages/cli/src/cli/check.rs index 0832647f2..614a0c4de 100644 --- a/packages/cli/src/cli/check.rs +++ b/packages/cli/src/cli/check.rs @@ -1,4 +1,4 @@ -use futures::{stream::FuturesUnordered, StreamExt}; +use futures_util::{stream::FuturesUnordered, StreamExt}; use std::{path::Path, process::exit}; use super::*; diff --git a/packages/cli/src/tools.rs b/packages/cli/src/tools.rs index 4045b236e..6bc4256d1 100644 --- a/packages/cli/src/tools.rs +++ b/packages/cli/src/tools.rs @@ -7,7 +7,7 @@ use std::{ use anyhow::Context; use flate2::read::GzDecoder; -use futures::StreamExt; +use futures_util::StreamExt; use tar::Archive; use tokio::io::AsyncWriteExt; From 63b82b279ba6964fafef4aa5458cb7d383cc7877 Mon Sep 17 00:00:00 2001 From: marc2332 Date: Sat, 27 Jan 2024 22:29:28 +0100 Subject: [PATCH 18/25] ok --- Cargo.lock | 3 ++- packages/cli/Cargo.toml | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c1d1ff9da..01980f050 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2476,7 +2476,7 @@ dependencies = [ "fern", "flate2", "fs_extra", - "futures", + "futures-util", "gitignore", "headers 0.3.9", "html_parser", @@ -2500,6 +2500,7 @@ dependencies = [ "tempfile", "thiserror", "tokio", + "toml 0.5.11", "toml_edit 0.19.15", "tower", "tower-http 0.2.5", diff --git a/packages/cli/Cargo.toml b/packages/cli/Cargo.toml index 694025d36..61dcdadf5 100644 --- a/packages/cli/Cargo.toml +++ b/packages/cli/Cargo.toml @@ -21,9 +21,10 @@ log = "0.4.14" fern = { version = "0.6.0", features = ["colored"] } serde = { version = "1.0.136", features = ["derive"] } serde_json = "1.0.79" +toml = "0.5.8" fs_extra = "1.2.0" cargo_toml = "0.16.0" -futures = "0.3.21" +futures-util = "0.3.30" notify = { version = "5.0.0-pre.16", features = ["serde"] } html_parser = { workspace = true } cargo_metadata = "0.15.0" From d83a6d683fdc8e22f86cdb9f5c6d7f478c747474 Mon Sep 17 00:00:00 2001 From: ealmloff Date: Sat, 27 Jan 2024 20:07:16 -0600 Subject: [PATCH 19/25] use the workspace version of futures utils --- packages/cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli/Cargo.toml b/packages/cli/Cargo.toml index 61dcdadf5..e67ff05fe 100644 --- a/packages/cli/Cargo.toml +++ b/packages/cli/Cargo.toml @@ -24,7 +24,7 @@ serde_json = "1.0.79" toml = "0.5.8" fs_extra = "1.2.0" cargo_toml = "0.16.0" -futures-util = "0.3.30" +futures-util.workspace = true notify = { version = "5.0.0-pre.16", features = ["serde"] } html_parser = { workspace = true } cargo_metadata = "0.15.0" From a0508861bc2859df4047b166e0c45213c51c2268 Mon Sep 17 00:00:00 2001 From: YuKun Liu Date: Sun, 28 Jan 2024 11:51:02 -0800 Subject: [PATCH 20/25] fix: upgrade crates & fixed repeat build error --- Cargo.lock | 128 ++++++++++++++------------ packages/cli/Cargo.toml | 14 +-- packages/cli/src/server/mod.rs | 163 +++++++++++++++++---------------- 3 files changed, 164 insertions(+), 141 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1939afbe9..127de7f05 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -625,7 +625,7 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41e7771d4ab6635cbd685ce8db215b29c78a468098126de77c57f3b2e6eb3757" dependencies = [ - "dirs 5.0.1", + "dirs", "git2", "terminal-prompt", ] @@ -1111,7 +1111,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf4918709cc4dd777ad2b6303ed03cb37f3ca0ccede8c1b0d28ac6db8f4710e0" dependencies = [ "once_cell", - "proc-macro-crate 2.0.1", + "proc-macro-crate 2.0.0", "proc-macro2", "quote", "syn 2.0.48", @@ -1286,9 +1286,9 @@ dependencies = [ [[package]] name = "cargo-generate" -version = "0.18.5" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a2885ae054e000b117515ab33e91c10eca90c2788a7baec1b97ada1f1f51e57" +checksum = "92c1b6f44358912a9538fa3b6ac8d3aa3f585444f9dc32f12ed85d1545a9df9f" dependencies = [ "anyhow", "auth-git2", @@ -1320,7 +1320,7 @@ dependencies = [ "serde", "tempfile", "thiserror", - "toml 0.8.2", + "toml 0.8.8", "walkdir", ] @@ -1386,6 +1386,20 @@ dependencies = [ "thiserror", ] +[[package]] +name = "cargo_metadata" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" +dependencies = [ + "camino", + "cargo-platform", + "semver", + "serde", + "serde_json", + "thiserror", +] + [[package]] name = "cargo_toml" version = "0.16.3" @@ -1393,7 +1407,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3f9629bc6c4388ea699781dc988c2b99766d7679b151c81990b4fa1208fafd3" dependencies = [ "serde", - "toml 0.8.2", + "toml 0.8.8", +] + +[[package]] +name = "cargo_toml" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "802b755090e39835a4b0440fb0bbee0df7495a8b337f63db21e616f7821c7e8c" +dependencies = [ + "serde", + "toml 0.8.8", ] [[package]] @@ -2459,8 +2483,8 @@ dependencies = [ "axum 0.5.17", "axum-server", "cargo-generate", - "cargo_metadata 0.15.4", - "cargo_toml", + "cargo_metadata 0.18.1", + "cargo_toml 0.18.0", "chrono", "clap 4.4.15", "colored 2.1.0", @@ -2472,7 +2496,7 @@ dependencies = [ "dioxus-hot-reload", "dioxus-html", "dioxus-rsx", - "dirs 4.0.0", + "dirs", "fern", "flate2", "fs_extra", @@ -2502,8 +2526,8 @@ dependencies = [ "tempfile", "thiserror", "tokio", - "toml 0.5.11", - "toml_edit 0.19.15", + "toml 0.8.8", + "toml_edit 0.21.0", "tower", "tower-http 0.2.5", "walkdir", @@ -2515,7 +2539,7 @@ dependencies = [ name = "dioxus-cli-config" version = "0.4.1" dependencies = [ - "cargo_toml", + "cargo_toml 0.16.3", "clap 4.4.15", "once_cell", "serde", @@ -3055,22 +3079,13 @@ dependencies = [ "syn 2.0.48", ] -[[package]] -name = "dirs" -version = "4.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" -dependencies = [ - "dirs-sys 0.3.7", -] - [[package]] name = "dirs" version = "5.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" dependencies = [ - "dirs-sys 0.4.1", + "dirs-sys", ] [[package]] @@ -3083,17 +3098,6 @@ dependencies = [ "dirs-sys-next", ] -[[package]] -name = "dirs-sys" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" -dependencies = [ - "libc", - "redox_users", - "winapi", -] - [[package]] name = "dirs-sys" version = "0.4.1" @@ -3562,7 +3566,7 @@ dependencies = [ "atomic 0.6.0", "pear", "serde", - "toml 0.8.2", + "toml 0.8.8", "uncased", "version_check", ] @@ -4142,9 +4146,9 @@ dependencies = [ [[package]] name = "gix-config" -version = "0.31.0" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cae98c6b4c66c09379bc35274b172587d6b0ac369a416c39128ad8c6454f9bb" +checksum = "0341471d55d8676e98b88e121d7065dfa4c9c5acea4b6d6ecdd2846e85cce0c3" dependencies = [ "bstr 1.9.0", "gix-config-value", @@ -4244,9 +4248,9 @@ dependencies = [ [[package]] name = "gix-object" -version = "0.38.0" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "740f2a44267f58770a1cb3a3d01d14e67b089c7136c48d4bddbb3cfd2bf86a51" +checksum = "febf79c5825720c1c63fe974c7bbe695d0cb54aabad73f45671c60ce0e501e33" dependencies = [ "bstr 1.9.0", "btoi", @@ -4276,9 +4280,9 @@ dependencies = [ [[package]] name = "gix-ref" -version = "0.38.0" +version = "0.39.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ec2f6d07ac88d2fb8007ee3fa3e801856fb9d82e7366ec0ca332eb2c9d74a52" +checksum = "3b2069adc212cf7f3317ef55f6444abd06c50f28479dbbac5a86acf3b05cbbfe" dependencies = [ "gix-actor", "gix-date", @@ -4375,7 +4379,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bb0228f477c0900c880fd78c8759b95c7636dbd7842707f49e132378aa2acdc" dependencies = [ "heck 0.4.1", - "proc-macro-crate 2.0.1", + "proc-macro-crate 2.0.0", "proc-macro-error", "proc-macro2", "quote", @@ -5081,7 +5085,7 @@ dependencies = [ "httpdate", "itoa 1.0.10", "pin-project-lite", - "socket2 0.4.10", + "socket2 0.5.5", "tokio", "tower-service", "tracing", @@ -6147,7 +6151,7 @@ dependencies = [ "anyhow", "cargo-lock 9.0.0", "cargo_metadata 0.17.0", - "cargo_toml", + "cargo_toml 0.16.3", "image", "imagequant", "lightningcss", @@ -6274,9 +6278,9 @@ checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" [[package]] name = "memmap2" -version = "0.7.1" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f49388d20533534cd19360ad3d6a7dadc885944aa802ba3995040c5ec11288c6" +checksum = "45fd3a57831bf88bc63f8cebc0cf956116276e97fef3966103e96416209f7c92" dependencies = [ "libc", ] @@ -6900,9 +6904,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "open" -version = "4.2.0" +version = "5.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a083c0c7e5e4a8ec4176346cf61f67ac674e8bfb059d9226e1c54a96b377c12" +checksum = "90878fb664448b54c4e592455ad02831e23a3f7e157374a8b95654731aac7349" dependencies = [ "is-wsl", "libc", @@ -7776,11 +7780,10 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "2.0.1" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97dc5fea232fc28d2f597b37c4876b348a40e33f3b02cc975c8d006d78d94b1a" +checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8" dependencies = [ - "toml_datetime", "toml_edit 0.20.2", ] @@ -8950,7 +8953,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5fa50756ef995d410bb1968b403a1eca169b54c3c0eb4be4bcb1da8c7591cb7d" dependencies = [ "cruet", - "proc-macro-crate 2.0.1", + "proc-macro-crate 2.0.0", "proc-macro2", "quote", "regex", @@ -10127,7 +10130,7 @@ dependencies = [ "cfg-expr 0.15.6", "heck 0.4.1", "pkg-config", - "toml 0.8.2", + "toml 0.8.8", "version-compare", ] @@ -10616,22 +10619,22 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.2" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "185d8ab0dfbb35cf1399a6344d8484209c088f75f8f68230da55d48d95d43e3d" +checksum = "a1a195ec8c9da26928f773888e0742ca3ca1040c6cd859c919c9f59c1954ab35" dependencies = [ "indexmap 2.1.0", "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.20.2", + "toml_edit 0.21.0", ] [[package]] name = "toml_datetime" -version = "0.6.3" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" dependencies = [ "serde", ] @@ -10654,6 +10657,17 @@ name = "toml_edit" version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" +dependencies = [ + "indexmap 2.1.0", + "toml_datetime", + "winnow", +] + +[[package]] +name = "toml_edit" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" dependencies = [ "indexmap 2.1.0", "serde", diff --git a/packages/cli/Cargo.toml b/packages/cli/Cargo.toml index 8f0c0dc8a..76b4995b1 100644 --- a/packages/cli/Cargo.toml +++ b/packages/cli/Cargo.toml @@ -21,13 +21,13 @@ log = "0.4.14" fern = { version = "0.6.0", features = ["colored"] } serde = { version = "1.0.136", features = ["derive"] } serde_json = "1.0.79" -toml = "0.5.8" +toml = "0.8.8" fs_extra = "1.2.0" -cargo_toml = "0.16.0" +cargo_toml = "0.18.0" futures = "0.3.21" notify = { version = "5.0.0-pre.16", features = ["serde"] } html_parser = { workspace = true } -cargo_metadata = "0.15.0" +cargo_metadata = "0.18.1" tokio = { version = "1.16.1", features = ["fs", "sync", "rt", "macros"] } atty = "0.2.14" chrono = "0.4.19" @@ -45,7 +45,7 @@ headers = "0.3.7" walkdir = "2" # tools download -dirs = "4.0.0" +dirs = "5.0.1" reqwest = { version = "0.11", features = [ "rustls-tls", "stream", @@ -68,9 +68,9 @@ mlua = { version = "0.8.1", features = [ "macros", ], optional = true } ctrlc = "3.2.3" -open = "4.1.0" -cargo-generate = "0.18" -toml_edit = "0.19.11" +open = "5.0.1" +cargo-generate = "0.19.0" +toml_edit = "0.21.0" # bundling tauri-bundler = { version = "=1.4.*", features = ["native-tls-vendored"] } diff --git a/packages/cli/src/server/mod.rs b/packages/cli/src/server/mod.rs index 1fe5f2ea5..0158f5c35 100644 --- a/packages/cli/src/server/mod.rs +++ b/packages/cli/src/server/mod.rs @@ -31,93 +31,102 @@ async fn setup_file_watcher Result + Send + 'static>( let mut watcher = notify::recommended_watcher(move |info: notify::Result| { let config = watcher_config.clone(); if let Ok(e) = info { - if chrono::Local::now().timestamp() > last_update_time { - let mut needs_full_rebuild; - if let Some(hot_reload) = &hot_reload { - // find changes to the rsx in the file - let mut rsx_file_map = hot_reload.file_map.lock().unwrap(); - let mut messages: Vec> = Vec::new(); + match e.kind { + notify::EventKind::Create(_) | notify::EventKind::Remove(_) | notify::EventKind::Modify(_) => { - // In hot reload mode, we only need to rebuild if non-rsx code is changed - needs_full_rebuild = false; + if chrono::Local::now().timestamp() > last_update_time { + let mut needs_full_rebuild; + if let Some(hot_reload) = &hot_reload { + // find changes to the rsx in the file + let mut rsx_file_map = hot_reload.file_map.lock().unwrap(); + let mut messages: Vec> = Vec::new(); - for path in &e.paths { - // if this is not a rust file, rebuild the whole project - if path.extension().and_then(|p| p.to_str()) != Some("rs") { + // In hot reload mode, we only need to rebuild if non-rsx code is changed + needs_full_rebuild = false; + + for path in &e.paths { + // if this is not a rust file, rebuild the whole project + if path.extension().and_then(|p| p.to_str()) != Some("rs") { + needs_full_rebuild = true; + break; + } + + // Workaround for notify and vscode-like editor: + // when edit & save a file in vscode, there will be two notifications, + // the first one is a file with empty content. + // filter the empty file notification to avoid false rebuild during hot-reload + if let Ok(metadata) = fs::metadata(path) { + if metadata.len() == 0 { + continue; + } + } + + match rsx_file_map.update_rsx(path, &config.crate_dir) { + Ok(UpdateResult::UpdatedRsx(msgs)) => { + messages.extend(msgs); + needs_full_rebuild = false; + } + Ok(UpdateResult::NeedsRebuild) => { + needs_full_rebuild = true; + } + Err(err) => { + log::error!("{}", err); + } + } + } + + if needs_full_rebuild { + // Reset the file map to the new state of the project + let FileMapBuildResult { + map: new_file_map, + errors, + } = FileMap::::create(config.crate_dir.clone()).unwrap(); + + for err in errors { + log::error!("{}", err); + } + + *rsx_file_map = new_file_map; + } else { + for msg in messages { + let _ = hot_reload.messages.send(msg); + } + } + } else { needs_full_rebuild = true; - break; } - // Workaround for notify and vscode-like editor: - // when edit & save a file in vscode, there will be two notifications, - // the first one is a file with empty content. - // filter the empty file notification to avoid false rebuild during hot-reload - if let Ok(metadata) = fs::metadata(path) { - if metadata.len() == 0 { - continue; - } - } + if needs_full_rebuild { + match build_with() { + Ok(res) => { + last_update_time = chrono::Local::now().timestamp(); - match rsx_file_map.update_rsx(path, &config.crate_dir) { - Ok(UpdateResult::UpdatedRsx(msgs)) => { - messages.extend(msgs); - needs_full_rebuild = false; - } - Ok(UpdateResult::NeedsRebuild) => { - needs_full_rebuild = true; - } - Err(err) => { - log::error!("{}", err); - } - } - } + #[allow(clippy::redundant_clone)] + print_console_info( + &config, + PrettierOptions { + changed: e.paths.clone(), + warnings: res.warnings, + elapsed_time: res.elapsed_time, + }, + web_info.clone(), + ); - if needs_full_rebuild { - // Reset the file map to the new state of the project - let FileMapBuildResult { - map: new_file_map, - errors, - } = FileMap::::create(config.crate_dir.clone()).unwrap(); - - for err in errors { - log::error!("{}", err); - } - - *rsx_file_map = new_file_map; - } else { - for msg in messages { - let _ = hot_reload.messages.send(msg); - } - } - } else { - needs_full_rebuild = true; - } - - if needs_full_rebuild { - match build_with() { - Ok(res) => { - last_update_time = chrono::Local::now().timestamp(); - - #[allow(clippy::redundant_clone)] - print_console_info( - &config, - PrettierOptions { - changed: e.paths.clone(), - warnings: res.warnings, - elapsed_time: res.elapsed_time, + #[cfg(feature = "plugin")] + let _ = PluginManager::on_serve_rebuild( + chrono::Local::now().timestamp(), + e.paths, + ); + } + Err(e) => { + last_update_time = chrono::Local::now().timestamp(); + log::error!("{:?}", e); }, - web_info.clone(), - ); - - #[cfg(feature = "plugin")] - let _ = PluginManager::on_serve_rebuild( - chrono::Local::now().timestamp(), - e.paths, - ); + } } - Err(e) => log::error!("{}", e), } - } + }, + _ => {}, } } }) From 492f49700a984bddd739a5138ba4dd39cea7fef2 Mon Sep 17 00:00:00 2001 From: YuKun Liu Date: Sun, 28 Jan 2024 11:52:42 -0800 Subject: [PATCH 21/25] fix: cargo fmt --- packages/cli/src/server/mod.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/cli/src/server/mod.rs b/packages/cli/src/server/mod.rs index 0158f5c35..d5fc7cf41 100644 --- a/packages/cli/src/server/mod.rs +++ b/packages/cli/src/server/mod.rs @@ -32,8 +32,9 @@ async fn setup_file_watcher Result + Send + 'static>( let config = watcher_config.clone(); if let Ok(e) = info { match e.kind { - notify::EventKind::Create(_) | notify::EventKind::Remove(_) | notify::EventKind::Modify(_) => { - + notify::EventKind::Create(_) + | notify::EventKind::Remove(_) + | notify::EventKind::Modify(_) => { if chrono::Local::now().timestamp() > last_update_time { let mut needs_full_rebuild; if let Some(hot_reload) = &hot_reload { @@ -121,12 +122,12 @@ async fn setup_file_watcher Result + Send + 'static>( Err(e) => { last_update_time = chrono::Local::now().timestamp(); log::error!("{:?}", e); - }, + } } } } - }, - _ => {}, + } + _ => {} } } }) From c22014571ec7aa7175ae0393e5dfcc35545d2675 Mon Sep 17 00:00:00 2001 From: Andrew Voynov Date: Tue, 30 Jan 2024 18:00:05 +0300 Subject: [PATCH 22/25] refactor(cli): added multiple nested errors support Before the top-level error message would print the dependent error message. Now multiple nested errors can be shown (with anyhow context). --- packages/cli/src/main.rs | 50 +++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/packages/cli/src/main.rs b/packages/cli/src/main.rs index 4114d629a..d09dea9e4 100644 --- a/packages/cli/src/main.rs +++ b/packages/cli/src/main.rs @@ -1,7 +1,7 @@ use dioxus_cli_config::DioxusConfig; use std::path::PathBuf; -use anyhow::anyhow; +use anyhow::Context; use clap::Parser; use dioxus_cli::*; @@ -19,24 +19,26 @@ fn get_bin(bin: Option) -> Result { .workspace_packages() .into_iter() .find(|p| p.name == bin) - .ok_or(format!("no such package: {}", bin)) - .map_err(Error::CargoError)? + .ok_or(Error::CargoError(format!("no such package: {}", bin)))? } else { metadata .root_package() - .ok_or("no root package?".into()) - .map_err(Error::CargoError)? + .ok_or(Error::CargoError("no root package?".to_string()))? }; let crate_dir = package .manifest_path .parent() - .ok_or("couldn't take parent dir".into()) - .map_err(Error::CargoError)?; + .ok_or(Error::CargoError("couldn't take parent dir".to_string()))?; Ok(crate_dir.into()) } +/// Simplifies error messages that use the same pattern. +fn error_wrapper(message: &str) -> String { + format!("🚫 {message}:") +} + #[tokio::main] async fn main() -> anyhow::Result<()> { let args = Cli::parse(); @@ -46,35 +48,35 @@ async fn main() -> anyhow::Result<()> { match args.action { Translate(opts) => opts .translate() - .map_err(|e| anyhow!("🚫 Translation of HTML into RSX failed: {}", e)), + .context(error_wrapper("Translation of HTML into RSX failed")), Create(opts) => opts .create() - .map_err(|e| anyhow!("🚫 Creating new project failed: {}", e)), + .context(error_wrapper("Creating new project failed")), Init(opts) => opts .init() - .map_err(|e| anyhow!("🚫 Initialising a new project failed: {}", e)), + .context(error_wrapper("Initialising a new project failed")), Config(opts) => opts .config() - .map_err(|e| anyhow!("🚫 Configuring new project failed: {}", e)), + .context(error_wrapper("Configuring new project failed")), #[cfg(feature = "plugin")] Plugin(opts) => opts .plugin() .await - .map_err(|e| anyhow!("🚫 Error with plugin: {}", e)), + .context(error_wrapper("Error with plugin")), Autoformat(opts) => opts .autoformat() .await - .map_err(|e| anyhow!("🚫 Error autoformatting RSX: {}", e)), + .context(error_wrapper("Error autoformatting RSX")), Check(opts) => opts .check() .await - .map_err(|e| anyhow!("🚫 Error checking RSX: {}", e)), + .context(error_wrapper("Error checking RSX")), Version(opt) => { let version = opt.version(); @@ -85,33 +87,33 @@ async fn main() -> anyhow::Result<()> { action => { let bin = get_bin(args.bin)?; let _dioxus_config = DioxusConfig::load(Some(bin.clone())) - .map_err(|e| anyhow!("Failed to load Dioxus config because: {e}"))? - .unwrap_or_else(|| { - log::info!("You appear to be creating a Dioxus project from scratch; we will use the default config"); - DioxusConfig::default() - }); + .context("Failed to load Dioxus config because")? + .unwrap_or_else(|| { + log::info!("You appear to be creating a Dioxus project from scratch; we will use the default config"); + DioxusConfig::default() + }); #[cfg(feature = "plugin")] PluginManager::init(_dioxus_config.plugin) - .map_err(|e| anyhow!("🚫 Plugin system initialization failed: {e}"))?; + .context(error_wrapper("Plugin system initialization failed"))?; match action { Build(opts) => opts .build(Some(bin.clone()), None) - .map_err(|e| anyhow!("🚫 Building project failed: {}", e)), + .context(error_wrapper("Building project failed")), Clean(opts) => opts .clean(Some(bin.clone())) - .map_err(|e| anyhow!("🚫 Cleaning project failed: {}", e)), + .context(error_wrapper("Cleaning project failed")), Serve(opts) => opts .serve(Some(bin.clone())) .await - .map_err(|e| anyhow!("🚫 Serving project failed: {}", e)), + .context(error_wrapper("Serving project failed")), Bundle(opts) => opts .bundle(Some(bin.clone())) - .map_err(|e| anyhow!("🚫 Bundling project failed: {}", e)), + .context(error_wrapper("Bundling project failed")), _ => unreachable!(), } From 87eb9744e094e027c6df85ee142086f18aaadc89 Mon Sep 17 00:00:00 2001 From: ealmloff Date: Tue, 30 Jan 2024 12:04:31 -0600 Subject: [PATCH 23/25] fix a tiny typo in the Routable macro docs: the route attribute only takes 2 parameters, not three --- packages/router-macro/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/router-macro/src/lib.rs b/packages/router-macro/src/lib.rs index 024570ae1..6a69ad99a 100644 --- a/packages/router-macro/src/lib.rs +++ b/packages/router-macro/src/lib.rs @@ -84,7 +84,7 @@ mod segment; /// /// # `#[route("path", component)]` /// -/// The `#[route]` attribute is used to define a route. It takes up to 3 parameters: +/// The `#[route]` attribute is used to define a route. It takes up to 2 parameters: /// - `path`: The path to the enum variant (relative to the parent nest) /// - (optional) `component`: The component to render when the route is matched. If not specified, the name of the variant is used /// From 1e013a7f24d46ebd7452fbb27d448acbc825e5e7 Mon Sep 17 00:00:00 2001 From: ealmloff Date: Tue, 30 Jan 2024 12:12:48 -0600 Subject: [PATCH 24/25] fix the layout docs as well --- packages/router-macro/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/router-macro/src/lib.rs b/packages/router-macro/src/lib.rs index 6a69ad99a..b7ae6505f 100644 --- a/packages/router-macro/src/lib.rs +++ b/packages/router-macro/src/lib.rs @@ -162,7 +162,7 @@ mod segment; /// /// # `#[layout(component)]` /// -/// The `#[layout]` attribute is used to define a layout. It takes 2 parameters: +/// The `#[layout]` attribute is used to define a layout. It takes 1 parameters: /// - `component`: The component to render when the route is matched. If not specified, the name of the variant is used /// /// The layout component allows you to wrap all children of the layout in a component. The child routes are rendered in the Outlet of the layout component. The layout component must take all dynamic parameters of the nests it is nested in. From 48957b11d8156a638c879bf0e55349c7f78fefc2 Mon Sep 17 00:00:00 2001 From: Andrew Voynov Date: Tue, 30 Jan 2024 21:03:44 +0300 Subject: [PATCH 25/25] refactor(cli-config): modified `CrateConfig` struct `out_dir` and `asset_dir` are now methods, because they derive from `crate_dir` and `dioxus_config`. --- packages/cli-config/src/config.rs | 29 ++++++++++++------- packages/cli/src/assets.rs | 4 +-- packages/cli/src/builder.rs | 40 +++++++++++++------------- packages/cli/src/cli/bundle.rs | 4 +-- packages/cli/src/plugin/mod.rs | 8 +++--- packages/cli/src/server/desktop/mod.rs | 2 +- packages/cli/src/server/web/mod.rs | 4 +-- 7 files changed, 49 insertions(+), 42 deletions(-) diff --git a/packages/cli-config/src/config.rs b/packages/cli-config/src/config.rs index 716b2bac4..bdfcf016b 100644 --- a/packages/cli-config/src/config.rs +++ b/packages/cli-config/src/config.rs @@ -338,11 +338,9 @@ pub struct WebHttpsConfig { #[derive(Debug, Clone, Serialize, Deserialize)] pub struct CrateConfig { - pub out_dir: PathBuf, pub crate_dir: PathBuf, pub workspace_dir: PathBuf, pub target_dir: PathBuf, - pub asset_dir: PathBuf, #[cfg(feature = "cli")] pub manifest: cargo_toml::Manifest, pub executable: ExecutableType, @@ -383,12 +381,8 @@ impl CrateConfig { let workspace_dir = meta.workspace_root; let target_dir = meta.target_directory; - let out_dir = crate_dir.join(&dioxus_config.application.out_dir); - let cargo_def = &crate_dir.join("Cargo.toml"); - let asset_dir = crate_dir.join(&dioxus_config.application.asset_dir); - let manifest = cargo_toml::Manifest::from_path(cargo_def).unwrap(); let mut output_filename = String::from("dioxus_app"); @@ -414,6 +408,7 @@ impl CrateConfig { let release = false; let hot_reload = false; + let cross_origin_policy = false; let verbose = false; let custom_profile = None; let features = None; @@ -421,26 +416,38 @@ impl CrateConfig { let cargo_args = vec![]; Ok(Self { - out_dir, crate_dir, workspace_dir, target_dir, - asset_dir, #[cfg(feature = "cli")] manifest, executable, - release, dioxus_config, + release, hot_reload, - cross_origin_policy: false, + cross_origin_policy, + verbose, custom_profile, features, - verbose, target, cargo_args, }) } + /// Compose an asset directory. Represents the typical "public" directory + /// with publicly available resources (configurable in the `Dioxus.toml`). + pub fn asset_dir(&self) -> PathBuf { + self.crate_dir + .join(&self.dioxus_config.application.asset_dir) + } + + /// Compose an out directory. Represents the typical "dist" directory that + /// is "distributed" after building an application (configurable in the + /// `Dioxus.toml`). + pub fn out_dir(&self) -> PathBuf { + self.crate_dir.join(&self.dioxus_config.application.out_dir) + } + pub fn as_example(&mut self, example_name: String) -> &mut Self { self.executable = ExecutableType::Example(example_name); self diff --git a/packages/cli/src/assets.rs b/packages/cli/src/assets.rs index 9248b47d5..c9fee435f 100644 --- a/packages/cli/src/assets.rs +++ b/packages/cli/src/assets.rs @@ -13,7 +13,7 @@ pub fn asset_manifest(crate_config: &CrateConfig) -> AssetManifest { /// Create a head file that contains all of the imports for assets that the user project uses pub fn create_assets_head(config: &CrateConfig, manifest: &AssetManifest) -> Result<()> { - let mut file = File::create(config.out_dir.join("__assets_head.html"))?; + let mut file = File::create(config.out_dir().join("__assets_head.html"))?; file.write_all(manifest.head().as_bytes())?; Ok(()) } @@ -29,7 +29,7 @@ pub(crate) fn process_assets(config: &CrateConfig, manifest: &AssetManifest) -> .clone() .unwrap_or_default(), ); - let static_asset_output_dir = config.out_dir.join(static_asset_output_dir); + let static_asset_output_dir = config.out_dir().join(static_asset_output_dir); manifest.copy_static_assets_to(static_asset_output_dir)?; diff --git a/packages/cli/src/builder.rs b/packages/cli/src/builder.rs index 744f47916..40563fccd 100644 --- a/packages/cli/src/builder.rs +++ b/packages/cli/src/builder.rs @@ -39,14 +39,14 @@ pub fn build(config: &CrateConfig, _: bool, skip_assets: bool) -> Result Result {} Err(_e) => { log::warn!("Error copying dir: {}", _e); } } for ignore in &ignore_files { - let ignore = ignore.strip_prefix(&config.asset_dir).unwrap(); - let ignore = config.out_dir.join(ignore); + let ignore = ignore.strip_prefix(&config.asset_dir()).unwrap(); + let ignore = out_dir.join(ignore); if ignore.is_file() { std::fs::remove_file(ignore)?; } @@ -369,13 +369,13 @@ pub fn build_desktop( file_name }; - if !config.out_dir.is_dir() { - create_dir_all(&config.out_dir)?; + if !config.out_dir().is_dir() { + create_dir_all(config.out_dir())?; } - copy(res_path, config.out_dir.join(target_file))?; + copy(res_path, config.out_dir().join(target_file))?; // this code will copy all public file to the output dir - if config.asset_dir.is_dir() { + if config.asset_dir().is_dir() { let copy_options = fs_extra::dir::CopyOptions { overwrite: true, skip_exist: false, @@ -385,20 +385,20 @@ pub fn build_desktop( depth: 0, }; - for entry in std::fs::read_dir(&config.asset_dir)? { + for entry in std::fs::read_dir(config.asset_dir())? { let path = entry?.path(); if path.is_file() { - std::fs::copy(&path, &config.out_dir.join(path.file_name().unwrap()))?; + std::fs::copy(&path, &config.out_dir().join(path.file_name().unwrap()))?; } else { - match fs_extra::dir::copy(&path, &config.out_dir, ©_options) { + match fs_extra::dir::copy(&path, &config.out_dir(), ©_options) { Ok(_) => {} Err(e) => { log::warn!("Error copying dir: {}", e); } } for ignore in &ignore_files { - let ignore = ignore.strip_prefix(&config.asset_dir).unwrap(); - let ignore = config.out_dir.join(ignore); + let ignore = ignore.strip_prefix(&config.asset_dir()).unwrap(); + let ignore = config.out_dir().join(ignore); if ignore.is_file() { std::fs::remove_file(ignore)?; } @@ -635,7 +635,7 @@ fn build_assets(config: &CrateConfig) -> Result> { if file == "*" { // if the sass open auto, we need auto-check the assets dir. - let asset_dir = config.asset_dir.clone(); + let asset_dir = config.asset_dir().clone(); if asset_dir.is_dir() { for entry in walkdir::WalkDir::new(&asset_dir) .into_iter() @@ -655,7 +655,7 @@ fn build_assets(config: &CrateConfig) -> Result> { temp.file_stem().unwrap().to_str().unwrap() ); let target_path = config - .out_dir + .out_dir() .join( temp.strip_prefix(&asset_dir) .unwrap() @@ -685,11 +685,11 @@ fn build_assets(config: &CrateConfig) -> Result> { } else { file }; - let path = config.asset_dir.join(relative_path); + let path = config.asset_dir().join(relative_path); let out_file = format!("{}.css", path.file_stem().unwrap().to_str().unwrap()); let target_path = config - .out_dir + .out_dir() .join(PathBuf::from(relative_path).parent().unwrap()) .join(out_file); if path.is_file() { @@ -719,11 +719,11 @@ fn build_assets(config: &CrateConfig) -> Result> { } else { path }; - let path = config.asset_dir.join(relative_path); + let path = config.asset_dir().join(relative_path); let out_file = format!("{}.css", path.file_stem().unwrap().to_str().unwrap()); let target_path = config - .out_dir + .out_dir() .join(PathBuf::from(relative_path).parent().unwrap()) .join(out_file); if path.is_file() { diff --git a/packages/cli/src/cli/bundle.rs b/packages/cli/src/cli/bundle.rs index a2231b31f..1bc3a4ff6 100644 --- a/packages/cli/src/cli/bundle.rs +++ b/packages/cli/src/cli/bundle.rs @@ -87,7 +87,7 @@ impl Bundle { build_desktop(&crate_config, false, false)?; // copy the binary to the out dir - let package = crate_config.manifest.package.unwrap(); + let package = crate_config.manifest.package.as_ref().unwrap(); let mut name: PathBuf = match &crate_config.executable { ExecutableType::Binary(name) @@ -149,7 +149,7 @@ impl Bundle { } let mut settings = SettingsBuilder::new() - .project_out_directory(crate_config.out_dir) + .project_out_directory(crate_config.out_dir()) .package_settings(PackageSettings { product_name: crate_config.dioxus_config.application.name.clone(), version: package.version().to_string(), diff --git a/packages/cli/src/plugin/mod.rs b/packages/cli/src/plugin/mod.rs index 481dd0984..2aa1f9868 100644 --- a/packages/cli/src/plugin/mod.rs +++ b/packages/cli/src/plugin/mod.rs @@ -184,8 +184,8 @@ impl PluginManager { let args = lua.create_table()?; args.set("name", crate_config.dioxus_config.application.name.clone())?; args.set("platform", platform)?; - args.set("out_dir", crate_config.out_dir.to_str().unwrap())?; - args.set("asset_dir", crate_config.asset_dir.to_str().unwrap())?; + args.set("out_dir", crate_config.out_dir().to_str().unwrap())?; + args.set("asset_dir", crate_config.asset_dir().to_str().unwrap())?; for i in 1..(manager.len()? as i32 + 1) { let info = manager.get::(i)?; @@ -208,8 +208,8 @@ impl PluginManager { let args = lua.create_table()?; args.set("name", crate_config.dioxus_config.application.name.clone())?; args.set("platform", platform)?; - args.set("out_dir", crate_config.out_dir.to_str().unwrap())?; - args.set("asset_dir", crate_config.asset_dir.to_str().unwrap())?; + args.set("out_dir", crate_config.out_dir().to_str().unwrap())?; + args.set("asset_dir", crate_config.asset_dir().to_str().unwrap())?; for i in 1..(manager.len()? as i32 + 1) { let info = manager.get::(i)?; diff --git a/packages/cli/src/server/desktop/mod.rs b/packages/cli/src/server/desktop/mod.rs index ad4b7bac8..c91ac1397 100644 --- a/packages/cli/src/server/desktop/mod.rs +++ b/packages/cli/src/server/desktop/mod.rs @@ -221,7 +221,7 @@ fn start_desktop(config: &CrateConfig, skip_assets: bool) -> Result<(RAIIChild, ExecutableType::Binary(name) | ExecutableType::Lib(name) | ExecutableType::Example(name) => { - let mut file = config.out_dir.join(name); + let mut file = config.out_dir().join(name); if cfg!(windows) { file.set_extension("exe"); } diff --git a/packages/cli/src/server/web/mod.rs b/packages/cli/src/server/web/mod.rs index 39366ee0c..f4d525ad0 100644 --- a/packages/cli/src/server/web/mod.rs +++ b/packages/cli/src/server/web/mod.rs @@ -290,7 +290,7 @@ async fn setup_router( std::fs::read_to_string( file_service_config .crate_dir - .join(file_service_config.out_dir) + .join(file_service_config.out_dir()) .join("index.html"), ) .ok() @@ -315,7 +315,7 @@ async fn setup_router( Ok(response) }, ) - .service(ServeDir::new(config.crate_dir.join(&config.out_dir))); + .service(ServeDir::new(config.crate_dir.join(config.out_dir()))); // Setup websocket let mut router = Router::new().route("/_dioxus/ws", get(ws_handler));