瀏覽代碼

Feat: webview example

Jonathan Kelley 4 年之前
父節點
當前提交
7730fd4a8c
共有 7 個文件被更改,包括 122 次插入11 次删除
  1. 2 0
      .vscode/spellright.dict
  2. 6 3
      examples/Cargo.toml
  3. 23 0
      examples/webview.rs
  4. 5 0
      packages/core/src/lib.rs
  5. 2 1
      packages/webview/Cargo.toml
  6. 11 2
      packages/webview/README.md
  7. 73 5
      packages/webview/src/lib.rs

+ 2 - 0
.vscode/spellright.dict

@@ -4,3 +4,5 @@ tide_ssr
 Liveview
 Liveview
 Dioxus
 Dioxus
 VDoms
 VDoms
+Tauri
+webview

+ 6 - 3
examples/Cargo.toml

@@ -12,6 +12,7 @@ log = "0.4.1"
 dioxus = { path = "../packages/dioxus" }
 dioxus = { path = "../packages/dioxus" }
 dioxus-ssr = { path = "../packages/ssr" }
 dioxus-ssr = { path = "../packages/ssr" }
 rand = "0.8.2"
 rand = "0.8.2"
+anyhow = "*"
 
 
 
 
 [dev-dependencies]
 [dev-dependencies]
@@ -22,9 +23,7 @@ tide = { version = "0.15.0" }
 # For the doc generator
 # For the doc generator
 pulldown-cmark = { version = "0.8.0", default-features = false }
 pulldown-cmark = { version = "0.8.0", default-features = false }
 
 
-
-anyhow = "*"
-
+dioxus-webview = { path = "../packages/webview", version = "0.0.0" }
 
 
 [lib]
 [lib]
 path = "common.rs"
 path = "common.rs"
@@ -48,3 +47,7 @@ name = "router"
 [[example]]
 [[example]]
 path = "fc_macro.rs"
 path = "fc_macro.rs"
 name = "fc_macro"
 name = "fc_macro"
+
+[[example]]
+path = "webview.rs"
+name = "webview"

+ 23 - 0
examples/webview.rs

@@ -0,0 +1,23 @@
+use dioxus::prelude::*;
+
+fn main() {
+    let app = dioxus_webview::new::<()>(|ctx| {
+        let (count, set_count) = use_state(ctx, || 0);
+        html! {
+             <div>
+                 <h1> "Dioxus Desktop Demo" </h1>
+                 <p> "Count is {count}"</p>
+                 <button onclick=|_| set_count(count + 1) >
+                     "Click to increment"
+                 </button>
+             </div>
+        }
+    });
+
+    app.launch(());
+}
+
+fn use_state<T, G>(ctx: &mut Context<G>, init: impl Fn() -> T) -> (T, impl Fn(T)) {
+    let g = init();
+    (g, |_| {})
+}

+ 5 - 0
packages/core/src/lib.rs

@@ -154,6 +154,11 @@ pub mod virtual_dom {
     }
     }
 
 
     impl<'a, T> Context<'a, T> {
     impl<'a, T> Context<'a, T> {
+        /// Access the children elements passed into the component
+        pub fn children(&self) -> Vec<VNode> {
+            todo!("Children API not yet implemented for component Context")
+        }
+
         /// Access a parent context
         /// Access a parent context
         pub fn parent_context<C>(&self) -> C {
         pub fn parent_context<C>(&self) -> C {
             todo!("Context API is not ready yet")
             todo!("Context API is not ready yet")

+ 2 - 1
packages/webview/Cargo.toml

@@ -7,4 +7,5 @@ edition = "2018"
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
 
 [dependencies]
 [dependencies]
-webview = "0.1.1"
+web-view = "0.7.2"
+dioxus-core = { path = "../core" }

+ 11 - 2
packages/webview/README.md

@@ -6,7 +6,8 @@ Dioxus-webview is an attempt at making a simpler "Tauri" where creating desktop
 
 
 ```rust
 ```rust
 // main.rs
 // main.rs
-fn main() {
+#[async_std::main]
+async fn main() {
    dioxus_webview::new(|ctx| {
    dioxus_webview::new(|ctx| {
        let (count, set_count) = use_state(ctx, || 0);
        let (count, set_count) = use_state(ctx, || 0);
        html! {
        html! {
@@ -22,7 +23,8 @@ fn main() {
    .configure_webview(|view| {
    .configure_webview(|view| {
       // custom webview config options 
       // custom webview config options 
    })
    })
-   .launch();
+   .launch()
+   .await;
 }
 }
 ```
 ```
 
 
@@ -37,3 +39,10 @@ dioxus bundle --platform macOS
 Because the host VirtualDOM is running in its own native process, native applications can unlock their full potential.  Dioxus-webview is designed to be a 100% rust alternative to ElectronJS without the memory overhead or bloat of ElectronJS apps.
 Because the host VirtualDOM is running in its own native process, native applications can unlock their full potential.  Dioxus-webview is designed to be a 100% rust alternative to ElectronJS without the memory overhead or bloat of ElectronJS apps.
 
 
 By bridging the native process, desktop apps can access full multithreading power, peripheral support, hardware access, and native filesystem controls without the hassle of web technologies. Our goal with Dioxus-webview is to make it easy to ship both a web and native application, and quickly see large performance boosts without having to re-write the whole stack. As the dioxus ecosystem grows, we hope to see 3rd parties providing wrappers for storage, offline mode, etc that supports both web and native technologies.
 By bridging the native process, desktop apps can access full multithreading power, peripheral support, hardware access, and native filesystem controls without the hassle of web technologies. Our goal with Dioxus-webview is to make it easy to ship both a web and native application, and quickly see large performance boosts without having to re-write the whole stack. As the dioxus ecosystem grows, we hope to see 3rd parties providing wrappers for storage, offline mode, etc that supports both web and native technologies.
+
+
+## Tech
+
+Dioxus-desktop is a pure liveview application where all of the state and event handlers are proxied through the liveview and into the native process. For pure server-based liveview, this would normally be too slow (in both render performance and latency), but because the VDom is local, desktop apps are just as fast as Electron.
+
+Dioxus-desktop leverages dioxus-liveview under the hood, but with convenience wrappers around setting up the VDom bridge, proxying events, and serving the initial WebSys-Renderer. The backend is served by Tide, so an async runtime is needed to 

+ 73 - 5
packages/webview/src/lib.rs

@@ -1,7 +1,75 @@
-#[cfg(test)]
-mod tests {
-    #[test]
-    fn it_works() {
-        assert_eq!(2 + 2, 4);
+use dioxus_core::prelude::*;
+use web_view::WebViewBuilder;
+
+pub fn new<T>(root: FC<T>) -> WebviewRenderer<T> {
+    WebviewRenderer::new(root)
+}
+
+/// The `WebviewRenderer` provides a way of rendering a Dioxus Virtual DOM through a bridge to a Webview instance.
+/// Components used in WebviewRenderer instances can directly use system libraries, access the filesystem, and multithread with ease.
+pub struct WebviewRenderer<T> {
+    /// The root component used to render the Webview
+    root: FC<T>,
+}
+
+impl<T> WebviewRenderer<T> {
+    /// Create a new text-renderer instance from a functional component root.
+    /// Automatically progresses the creation of the VNode tree to completion.
+    ///
+    /// A VDom is automatically created. If you want more granular control of the VDom, use `from_vdom`
+    pub fn new(root: FC<T>) -> Self {
+        Self { root }
+    }
+
+    /// Create a new text renderer from an existing Virtual DOM.
+    /// This will progress the existing VDom's events to completion.
+    pub fn from_vdom() -> Self {
+        todo!()
+    }
+
+    /// Pass new args to the root function
+    pub fn update(&mut self, new_val: T) {
+        todo!()
     }
     }
+
+    /// Modify the root function in place, forcing a re-render regardless if the props changed
+    pub fn update_mut(&mut self, modifier: impl Fn(&mut T)) {
+        todo!()
+    }
+
+    pub async fn launch(self, props: T) {
+        let mut ctx = Context { props: &props };
+        let WebviewRenderer { root } = self;
+        let content = root(&mut ctx);
+        let html_content = content.to_string();
+        /*
+        TODO: @Jon
+        Launch the webview with a premade VDom app
+        */
+
+        web_view::builder()
+            .title("My Project")
+            .content(web_view::Content::Html(html_content))
+            .size(320, 480)
+            .resizable(true)
+            .debug(true)
+            .user_data(())
+            .invoke_handler(|_webview, _arg| Ok(()))
+            .run()
+            .unwrap();
+    }
+}
+
+mod receiver {
+    use dioxus_core::prelude::*;
+
+    /// The receiver app is a container that builds a connection to the host process that shuttles events and patches.  
+    pub(crate) static ReceiverApp: FC<()> = |ctx| {
+        //
+        html! {
+            <div>
+                {}
+            </div>
+        }
+    };
 }
 }