Feat: webview example

This commit is contained in:
Jonathan Kelley 2021-01-21 11:10:31 -05:00
parent 9c01736895
commit 7730fd4a8c
7 changed files with 122 additions and 11 deletions

View file

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

View file

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

23
examples/webview.rs Normal file
View file

@ -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, |_| {})
}

View file

@ -154,6 +154,11 @@ pub mod virtual_dom {
}
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
pub fn parent_context<C>(&self) -> C {
todo!("Context API is not ready yet")

View file

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

View file

@ -6,7 +6,8 @@ Dioxus-webview is an attempt at making a simpler "Tauri" where creating desktop
```rust
// main.rs
fn main() {
#[async_std::main]
async fn main() {
dioxus_webview::new(|ctx| {
let (count, set_count) = use_state(ctx, || 0);
html! {
@ -22,7 +23,8 @@ fn main() {
.configure_webview(|view| {
// 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.
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

View file

@ -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>
}
};
}