Kaynağa Gözat

Merge branch 'DioxusLabs:master' into events-2

ealmloff 1 yıl önce
ebeveyn
işleme
072ca3529b

+ 1 - 1
packages/cli/Cargo.toml

@@ -22,7 +22,7 @@ serde = { version = "1.0.136", features = ["derive"] }
 serde_json = "1.0.79"
 toml = "0.5.8"
 fs_extra = "1.2.0"
-cargo_toml = "0.11.4"
+cargo_toml = "0.16.0"
 futures = "0.3.21"
 notify = { version = "5.0.0-pre.16", features = ["serde"] }
 html_parser  = { workspace = true }

+ 4 - 4
packages/cli/src/cli/bundle.rs

@@ -132,10 +132,10 @@ impl Bundle {
             .project_out_directory(crate_config.out_dir)
             .package_settings(PackageSettings {
                 product_name: crate_config.dioxus_config.application.name.clone(),
-                version: package.version,
-                description: package.description.unwrap_or_default(),
-                homepage: package.homepage,
-                authors: Some(package.authors),
+                version: package.version().to_string(),
+                description: package.description().unwrap_or_default().to_string(),
+                homepage: Some(package.homepage().unwrap_or_default().to_string()),
+                authors: Some(Vec::from(package.authors())),
                 default_run: Some(crate_config.dioxus_config.application.name.clone()),
             })
             .binaries(binaries)

+ 6 - 6
packages/core/src/lib.rs

@@ -32,7 +32,7 @@ pub(crate) mod innerlude {
     pub use crate::nodes::RenderReturn;
     pub use crate::nodes::*;
     pub use crate::properties::*;
-    pub use crate::runtime::{in_runtime, override_runtime, Runtime};
+    pub use crate::runtime::{Runtime, RuntimeGuard};
     pub use crate::scheduler::*;
     pub use crate::scope_context::*;
     pub use crate::scopes::*;
@@ -87,11 +87,11 @@ pub use crate::innerlude::{
 pub mod prelude {
     pub use crate::innerlude::{
         consume_context, consume_context_from_scope, current_scope_id, fc_to_builder, has_context,
-        in_runtime, override_runtime, provide_context, provide_context_to_scope,
-        provide_root_context, push_future, remove_future, schedule_update_any, spawn,
-        spawn_forever, suspend, throw, AnyValue, Component, Element, Event, EventHandler, Fragment,
-        IntoAttributeValue, LazyNodes, Properties, Runtime, Scope, ScopeId, ScopeState, Scoped,
-        TaskId, Template, TemplateAttribute, TemplateNode, Throw, VNode, VirtualDom,
+        provide_context, provide_context_to_scope, provide_root_context, push_future,
+        remove_future, schedule_update_any, spawn, spawn_forever, suspend, throw, AnyValue,
+        Component, Element, Event, EventHandler, Fragment, IntoAttributeValue, LazyNodes,
+        Properties, Runtime, RuntimeGuard, Scope, ScopeId, ScopeState, Scoped, TaskId, Template,
+        TemplateAttribute, TemplateNode, Throw, VNode, VirtualDom,
     };
 }
 

+ 34 - 47
packages/core/src/runtime.rs

@@ -7,51 +7,6 @@ thread_local! {
     static RUNTIMES: RefCell<Vec<Rc<Runtime>>> = RefCell::new(vec![]);
 }
 
-/// Run some code within a runtime
-pub fn in_runtime<R>(runtime: Rc<Runtime>, f: impl FnOnce() -> R) -> R {
-    let _guard = RuntimeGuard::new(runtime);
-    f()
-}
-
-/// Override the current runtime. This must be used to override the current runtime when importing components from a dynamic library that has it's own runtime.
-///
-/// ```rust
-/// use dioxus::prelude::*;
-///
-/// fn main() {
-///     let virtual_dom = VirtualDom::new(app);
-/// }
-///
-/// fn app(cx: Scope) -> Element {
-///     render!{ Component { runtime: Runtime::current().unwrap() } }
-/// }
-///
-/// // In a dynamic library
-/// #[derive(Props)]
-/// struct ComponentProps {
-///    runtime: std::rc::Rc<Runtime>,
-/// }
-///
-/// impl PartialEq for ComponentProps {
-///     fn eq(&self, _other: &Self) -> bool {
-///         true
-///     }
-/// }
-///
-/// fn Component(cx: Scope<ComponentProps>) -> Element {
-///     cx.use_hook(|| override_runtime(cx.props.runtime.clone()));
-///
-///     render! { div {} }
-/// }
-/// ```
-pub fn override_runtime(runtime: Rc<Runtime>) {
-    RUNTIMES.with(|stack| {
-        let mut stack = stack.borrow_mut();
-        stack.pop();
-        stack.push(runtime);
-    });
-}
-
 /// Pushes a new scope onto the stack
 pub(crate) fn push_runtime(runtime: Rc<Runtime>) {
     RUNTIMES.with(|stack| stack.borrow_mut().push(runtime));
@@ -143,10 +98,42 @@ impl Runtime {
     }
 }
 
-pub(crate) struct RuntimeGuard(Rc<Runtime>);
+/// A gaurd for a new runtime. This must be used to override the current runtime when importing components from a dynamic library that has it's own runtime.
+///
+/// ```rust
+/// use dioxus::prelude::*;
+///
+/// fn main() {
+///     let virtual_dom = VirtualDom::new(app);
+/// }
+///
+/// fn app(cx: Scope) -> Element {
+///     render!{ Component { runtime: Runtime::current().unwrap() } }
+/// }
+///
+/// // In a dynamic library
+/// #[derive(Props)]
+/// struct ComponentProps {
+///    runtime: std::rc::Rc<Runtime>,
+/// }
+///
+/// impl PartialEq for ComponentProps {
+///     fn eq(&self, _other: &Self) -> bool {
+///         true
+///     }
+/// }
+///
+/// fn Component(cx: Scope<ComponentProps>) -> Element {
+///     cx.use_hook(|| RuntimeGuard::new(cx.props.runtime.clone()));
+///
+///     render! { div {} }
+/// }
+/// ```
+pub struct RuntimeGuard(Rc<Runtime>);
 
 impl RuntimeGuard {
-    pub(crate) fn new(runtime: Rc<Runtime>) -> Self {
+    /// Create a new runtime guard that sets the current Dioxus runtime. The runtime will be reset when the guard is dropped
+    pub fn new(runtime: Rc<Runtime>) -> Self {
         push_runtime(runtime.clone());
         Self(runtime)
     }

+ 1 - 0
packages/desktop/Cargo.toml

@@ -56,6 +56,7 @@ tokio_runtime = ["tokio"]
 fullscreen = ["wry/fullscreen"]
 transparent = ["wry/transparent"]
 devtools = ["wry/devtools"]
+tray = ["wry/tray"]
 dox = ["wry/dox"]
 hot-reload = ["dioxus-hot-reload"]
 

+ 18 - 18
packages/hooks/src/lib.rs

@@ -57,32 +57,32 @@ pub mod computed;
 mod use_on_unmount;
 pub use use_on_unmount::*;
 
-mod usecontext;
-pub use usecontext::*;
+mod use_context;
+pub use use_context::*;
 
-mod usestate;
-pub use usestate::{use_state, UseState};
+mod use_state;
+pub use use_state::{use_state, UseState};
 
-mod useref;
-pub use useref::*;
+mod use_ref;
+pub use use_ref::*;
 
 mod use_shared_state;
 pub use use_shared_state::*;
 
-mod usecoroutine;
-pub use usecoroutine::*;
+mod use_coroutine;
+pub use use_coroutine::*;
 
-mod usefuture;
-pub use usefuture::*;
+mod use_future;
+pub use use_future::*;
 
-mod useeffect;
-pub use useeffect::*;
+mod use_effect;
+pub use use_effect::*;
 
-mod usecallback;
-pub use usecallback::*;
+mod use_callback;
+pub use use_callback::*;
 
-mod usememo;
-pub use usememo::*;
+mod use_memo;
+pub use use_memo::*;
 
-mod userootcontext;
-pub use userootcontext::*;
+mod use_root_context;
+pub use use_root_context::*;

+ 0 - 0
packages/hooks/src/usecallback.rs → packages/hooks/src/use_callback.rs


+ 0 - 0
packages/hooks/src/usecollection.rs → packages/hooks/src/use_collection.rs


+ 0 - 0
packages/hooks/src/usecontext.rs → packages/hooks/src/use_context.rs


+ 0 - 0
packages/hooks/src/usecoroutine.rs → packages/hooks/src/use_coroutine.rs


+ 0 - 0
packages/hooks/src/useeffect.rs → packages/hooks/src/use_effect.rs


+ 0 - 0
packages/hooks/src/usefuture.rs → packages/hooks/src/use_future.rs


+ 0 - 0
packages/hooks/src/usememo.rs → packages/hooks/src/use_memo.rs


+ 0 - 0
packages/hooks/src/usemodel.rs → packages/hooks/src/use_model.rs


+ 0 - 0
packages/hooks/src/useref.rs → packages/hooks/src/use_ref.rs


+ 0 - 0
packages/hooks/src/userootcontext.rs → packages/hooks/src/use_root_context.rs


+ 0 - 0
packages/hooks/src/usesignal.rs → packages/hooks/src/use_signal.rs


+ 44 - 0
packages/hooks/src/usestate.rs → packages/hooks/src/use_state.rs

@@ -336,6 +336,50 @@ impl<T> PartialEq<UseState<T>> for UseState<T> {
     }
 }
 
+impl<T: std::cmp::PartialOrd> PartialOrd<T> for UseState<T> {
+    fn ge(&self, other: &T) -> bool {
+        *self.current_val >= *other
+    }
+
+    fn gt(&self, other: &T) -> bool {
+        *self.current_val > *other
+    }
+
+    fn le(&self, other: &T) -> bool {
+        *self.current_val <= *other
+    }
+
+    fn lt(&self, other: &T) -> bool {
+        *self.current_val < *other
+    }
+
+    fn partial_cmp(&self, other: &T) -> Option<std::cmp::Ordering> {
+        (*self.current_val).partial_cmp(other)
+    }
+}
+
+impl<T: std::cmp::PartialOrd> PartialOrd<UseState<T>> for UseState<T> {
+    fn ge(&self, other: &UseState<T>) -> bool {
+        self.current_val >= other.current_val
+    }
+
+    fn gt(&self, other: &UseState<T>) -> bool {
+        self.current_val > other.current_val
+    }
+
+    fn le(&self, other: &UseState<T>) -> bool {
+        self.current_val <= other.current_val
+    }
+
+    fn lt(&self, other: &UseState<T>) -> bool {
+        self.current_val < other.current_val
+    }
+
+    fn partial_cmp(&self, other: &UseState<T>) -> Option<std::cmp::Ordering> {
+        self.current_val.partial_cmp(&other.current_val)
+    }
+}
+
 impl<T: Debug> Debug for UseState<T> {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         write!(f, "{:?}", self.current_val)

+ 1 - 0
packages/html/src/elements.rs

@@ -1203,6 +1203,7 @@ builder_constructors! {
         value: String DEFAULT,
 
         selected: Bool volatile,
+        initial_selected: Bool DEFAULT,
     };
 
     /// Build a

+ 3 - 0
packages/interpreter/src/common.js

@@ -54,6 +54,9 @@ export function setAttributeInner(node, field, value, ns) {
       case "selected":
         node.selected = truthy(value);
         break;
+      case "initial_selected":
+        node.defaultSelected = truthy(value);
+        break;
       case "dangerous_inner_html":
         node.innerHTML = value;
         break;

+ 3 - 0
packages/interpreter/src/sledgehammer_bindings.rs

@@ -83,6 +83,9 @@ mod js {
                 case "selected":
                     node.selected = truthy(value);
                     break;
+                case "initial_selected":
+                    node.defaultSelected = truthy(value);
+                    break;
                 case "dangerous_inner_html":
                     node.innerHTML = value;
                     break;

+ 36 - 25
packages/liveview/examples/axum.rs

@@ -19,32 +19,43 @@ async fn main() {
     let addr: std::net::SocketAddr = ([127, 0, 0, 1], 3030).into();
 
     let view = dioxus_liveview::LiveViewPool::new();
+    let index_page_with_glue = |glue: &str| {
+        Html(format!(
+            r#"
+        <!DOCTYPE html>
+        <html>
+            <head> <title>Dioxus LiveView with axum</title>  </head>
+            <body> <div id="main"></div> </body>
+            {glue}
+        </html>
+        "#,
+        ))
+    };
 
-    let app = Router::new()
-        .route(
-            "/",
-            get(move || async move {
-                Html(format!(
-                    r#"
-            <!DOCTYPE html>
-            <html>
-                <head> <title>Dioxus LiveView with axum</title>  </head>
-                <body> <div id="main"></div> </body>
-                {glue}
-            </html>
-            "#,
-                    glue = dioxus_liveview::interpreter_glue(&format!("ws://{addr}/ws"))
-                ))
-            }),
-        )
-        .route(
-            "/ws",
-            get(move |ws: WebSocketUpgrade| async move {
-                ws.on_upgrade(move |socket| async move {
-                    _ = view.launch(dioxus_liveview::axum_socket(socket), app).await;
-                })
-            }),
-        );
+    let app =
+        Router::new()
+            .route(
+                "/",
+                get(move || async move {
+                    index_page_with_glue(&dioxus_liveview::interpreter_glue(&format!(
+                        "ws://{addr}/ws"
+                    )))
+                }),
+            )
+            .route(
+                "/as-path",
+                get(move || async move {
+                    index_page_with_glue(&dioxus_liveview::interpreter_glue("/ws"))
+                }),
+            )
+            .route(
+                "/ws",
+                get(move |ws: WebSocketUpgrade| async move {
+                    ws.on_upgrade(move |socket| async move {
+                        _ = view.launch(dioxus_liveview::axum_socket(socket), app).await;
+                    })
+                }),
+            );
 
     println!("Listening on http://{addr}");
 

+ 38 - 3
packages/liveview/src/lib.rs

@@ -94,14 +94,49 @@ static MAIN_JS: &str = include_str!("./main.js");
 /// This script that gets injected into your app connects this page to the websocket endpoint
 ///
 /// Once the endpoint is connected, it will send the initial state of the app, and then start
-/// processing user events and returning edits to the liveview instance
-pub fn interpreter_glue(url: &str) -> String {
+/// processing user events and returning edits to the liveview instance.
+///
+/// You can pass a relative path prefixed with "/", or enter a full URL including the protocol
+/// (`ws:` or `wss:`) as an argument.
+///
+/// If you enter a relative path, the web client automatically prefixes the host address in
+/// `window.location` when creating a web socket to LiveView.
+///
+/// ```
+/// // Creates websocket connection to same host as current page
+/// interpreter_glue("/api/liveview");
+///
+/// // Creates websocket connection to specified url
+/// interpreter_glue("ws://localhost:8080/api/liveview");
+/// ```
+pub fn interpreter_glue(url_or_path: &str) -> String {
+    // If the url starts with a `/`, generate glue which reuses current host
+    let get_ws_url = if url_or_path.starts_with('/') {
+        r#"
+  let loc = window.location; 
+  let new_url = "";
+  if (loc.protocol === "https:") {{
+      new_url = "wss:";
+  }} else {{
+      new_url = "ws:";
+  }}
+  new_url += "//" + loc.host + path;
+  return new_url;
+      "#
+    } else {
+        "return path;"
+    };
+
     let js = &*INTERPRETER_JS;
     let common = &*COMMON_JS;
     format!(
         r#"
 <script>
-    var WS_ADDR = "{url}";
+    function __dioxusGetWsUrl(path) {{
+      {get_ws_url}
+    }}
+    
+    var WS_ADDR = __dioxusGetWsUrl("{url_or_path}");
     {js}
     {common}
     {MAIN_JS}

+ 1 - 1
packages/server-macro/src/lib.rs

@@ -8,7 +8,7 @@ use syn::{
     Ident, ItemFn, Token,
 };
 
-/// Declares that a function is a [server function](dioxus_fullstack). This means that
+/// Declares that a function is a [server function](https://dioxuslabs.com/learn/0.4/reference/fullstack/server_functions). This means that
 /// its body will only run on the server, i.e., when the `ssr` feature is enabled.
 ///
 /// If you call a server function from the client (i.e., when the `csr` or `hydrate` features

+ 1 - 1
playwright-tests/playwright.config.js

@@ -90,7 +90,7 @@ module.exports = defineConfig({
     },
     {
       cwd: path.join(process.cwd(), 'fullstack'),
-      command: 'cargo run --package dioxus-cli -- build --features web --release\ncargo run --release --features ssr',
+      command: 'cargo run --package dioxus-cli -- build --features web --release && cargo run --release --features ssr',
       port: 3333,
       timeout: 10 * 60 * 1000,
       reuseExistingServer: !process.env.CI,