2021-07-15 22:40:12 +00:00
|
|
|
use dioxus_core::*;
|
|
|
|
use std::{
|
|
|
|
collections::HashMap,
|
|
|
|
sync::{Arc, RwLock},
|
|
|
|
};
|
|
|
|
use wry::application::event::{Event, WindowEvent};
|
|
|
|
use wry::application::event_loop::{ControlFlow, EventLoop};
|
|
|
|
use wry::application::window::Fullscreen;
|
|
|
|
use wry::application::{
|
|
|
|
dpi::LogicalSize,
|
|
|
|
event::StartCause,
|
2021-07-16 20:11:25 +00:00
|
|
|
// platform::ios::{ScreenEdge, WindowBuilderExtIOS, WindowExtIOS},
|
|
|
|
// platform::ios::{ScreenEdge, WindowBuilderExtIOS, WindowExtIOS},
|
2021-07-15 22:40:12 +00:00
|
|
|
};
|
|
|
|
use wry::webview::WebViewBuilder;
|
|
|
|
use wry::{
|
|
|
|
application::window::{Window, WindowBuilder},
|
|
|
|
webview::{RpcRequest, RpcResponse},
|
|
|
|
};
|
|
|
|
mod dom;
|
|
|
|
use dom::*;
|
2021-05-15 16:03:08 +00:00
|
|
|
|
2021-07-15 22:40:12 +00:00
|
|
|
fn init_logging() {
|
|
|
|
simple_logger::SimpleLogger::new().init().unwrap();
|
2021-05-15 16:03:08 +00:00
|
|
|
}
|
|
|
|
|
2021-07-16 20:11:25 +00:00
|
|
|
static HTML_CONTENT: &'static str = include_str!("../../desktop/src/index.html");
|
2021-05-15 16:03:08 +00:00
|
|
|
|
2021-07-15 22:40:12 +00:00
|
|
|
pub fn launch(root: FC<()>, builder: fn(WindowBuilder) -> WindowBuilder) -> anyhow::Result<()> {
|
|
|
|
launch_with_props(root, (), builder)
|
|
|
|
}
|
2021-10-04 14:22:20 +00:00
|
|
|
pub fn launch_with_props<P: 'static + Send>(
|
2021-07-15 22:40:12 +00:00
|
|
|
root: FC<P>,
|
|
|
|
props: P,
|
|
|
|
builder: fn(WindowBuilder) -> WindowBuilder,
|
|
|
|
) -> anyhow::Result<()> {
|
|
|
|
WebviewRenderer::run(root, props, builder)
|
|
|
|
}
|
2021-05-15 16:03:08 +00:00
|
|
|
|
2021-07-15 22:40:12 +00:00
|
|
|
/// 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>,
|
|
|
|
}
|
|
|
|
enum RpcEvent<'a> {
|
|
|
|
Initialize {
|
|
|
|
//
|
|
|
|
edits: Vec<DomEdit<'a>>,
|
|
|
|
},
|
|
|
|
}
|
2021-05-15 16:03:08 +00:00
|
|
|
|
2021-10-04 14:22:20 +00:00
|
|
|
impl<T: 'static + Send> WebviewRenderer<T> {
|
2021-07-15 22:40:12 +00:00
|
|
|
pub fn run(
|
|
|
|
root: FC<T>,
|
|
|
|
props: T,
|
|
|
|
user_builder: fn(WindowBuilder) -> WindowBuilder,
|
|
|
|
) -> anyhow::Result<()> {
|
|
|
|
Self::run_with_edits(root, props, user_builder, None)
|
|
|
|
}
|
2021-05-15 16:03:08 +00:00
|
|
|
|
2021-07-15 22:40:12 +00:00
|
|
|
pub fn run_with_edits(
|
|
|
|
root: FC<T>,
|
|
|
|
props: T,
|
|
|
|
user_builder: fn(WindowBuilder) -> WindowBuilder,
|
|
|
|
redits: Option<Vec<DomEdit<'static>>>,
|
|
|
|
) -> anyhow::Result<()> {
|
|
|
|
// pub fn run_with_edits(
|
|
|
|
// root: FC<T>,
|
|
|
|
// props: T,
|
|
|
|
// user_builder: fn(WindowBuilder) -> WindowBuilder,
|
|
|
|
// redits: Option<Vec<DomEdit<'static>>>,
|
|
|
|
// ) -> anyhow::Result<()> {
|
|
|
|
let mut weviews = HashMap::new();
|
2021-05-15 16:03:08 +00:00
|
|
|
|
2021-07-15 22:40:12 +00:00
|
|
|
let vir = VirtualDom::new_with_props(root, props);
|
2021-05-15 16:03:08 +00:00
|
|
|
|
2021-07-15 22:40:12 +00:00
|
|
|
let vdom = Arc::new(RwLock::new(vir));
|
|
|
|
|
|
|
|
let event_loop = EventLoop::new();
|
|
|
|
event_loop.run(move |event, event_loop, control_flow| {
|
|
|
|
*control_flow = ControlFlow::Wait;
|
|
|
|
|
|
|
|
match event {
|
|
|
|
Event::NewEvents(StartCause::Init) => {
|
|
|
|
println!("Init");
|
|
|
|
|
|
|
|
let window = user_builder(WindowBuilder::new())
|
|
|
|
.build(&event_loop)
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
let registry = Arc::new(RwLock::new(Some(WebviewRegistry::new())));
|
|
|
|
|
|
|
|
let window = WindowBuilder::new().build(&event_loop).unwrap();
|
|
|
|
let window_id = window.id();
|
|
|
|
|
|
|
|
let vdom = vdom.clone();
|
|
|
|
let weview = WebViewBuilder::new(window)
|
|
|
|
.unwrap()
|
|
|
|
// .with_visible(false)
|
|
|
|
// .with_transparent(true)
|
|
|
|
.with_url(&format!("data:text/html,{}", HTML_CONTENT))
|
|
|
|
.unwrap()
|
|
|
|
.with_rpc_handler(move |_window: &Window, mut req: RpcRequest| {
|
|
|
|
match req.method.as_str() {
|
|
|
|
"initiate" => {
|
|
|
|
// let edits = if let Some(edits) = &redits {
|
|
|
|
// serde_json::to_value(edits).unwrap()
|
|
|
|
// } else
|
|
|
|
let edits = {
|
|
|
|
let mut lock = vdom.write().unwrap();
|
|
|
|
let mut reg_lock = registry.write().unwrap();
|
|
|
|
|
|
|
|
// Create the thin wrapper around the registry to collect the edits into
|
|
|
|
let mut real =
|
|
|
|
dom::WebviewDom::new(reg_lock.take().unwrap());
|
|
|
|
|
|
|
|
// Serialize the edit stream
|
|
|
|
let edits = {
|
2021-08-09 21:09:33 +00:00
|
|
|
let mut edits = Vec::<DomEdit>::new();
|
|
|
|
// lock.rebuild(&mut edits).unwrap();
|
2021-07-15 22:40:12 +00:00
|
|
|
serde_json::to_value(edits).unwrap()
|
|
|
|
};
|
|
|
|
|
|
|
|
// Give back the registry into its slot
|
|
|
|
*reg_lock = Some(real.consume());
|
|
|
|
edits
|
|
|
|
};
|
|
|
|
|
|
|
|
// Return the edits into the webview runtime
|
|
|
|
Some(RpcResponse::new_result(req.id.take(), Some(edits)))
|
|
|
|
}
|
|
|
|
"user_event" => {
|
|
|
|
let mut lock = vdom.write().unwrap();
|
|
|
|
let mut reg_lock = registry.write().unwrap();
|
2021-05-15 16:03:08 +00:00
|
|
|
|
2021-07-15 22:40:12 +00:00
|
|
|
// Create the thin wrapper around the registry to collect the edits into
|
|
|
|
let mut real = dom::WebviewDom::new(reg_lock.take().unwrap());
|
|
|
|
|
|
|
|
// Serialize the edit stream
|
|
|
|
let edits = {
|
2021-08-09 21:09:33 +00:00
|
|
|
let mut edits = Vec::<DomEdit>::new();
|
|
|
|
// lock.rebuild(&mut edits).unwrap();
|
2021-07-15 22:40:12 +00:00
|
|
|
serde_json::to_value(edits).unwrap()
|
|
|
|
};
|
|
|
|
|
|
|
|
// Give back the registry into its slot
|
|
|
|
*reg_lock = Some(real.consume());
|
|
|
|
|
|
|
|
// Return the edits into the webview runtime
|
|
|
|
Some(RpcResponse::new_result(req.id.take(), Some(edits)))
|
|
|
|
}
|
|
|
|
_ => todo!("this message failed"),
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.build()
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// let weview = WebViewBuilder::new(window)
|
|
|
|
// .unwrap()
|
|
|
|
// .with_url("https://tauri.studio")
|
|
|
|
// .unwrap()
|
|
|
|
// .build()
|
|
|
|
// .unwrap();
|
|
|
|
weviews.insert(window_id, weview);
|
|
|
|
}
|
|
|
|
Event::Resumed => {
|
|
|
|
println!("applicationDidBecomeActive");
|
|
|
|
}
|
|
|
|
Event::Suspended => {
|
|
|
|
println!("applicationWillResignActive");
|
|
|
|
}
|
|
|
|
Event::LoopDestroyed => {
|
|
|
|
println!("applicationWillTerminate");
|
|
|
|
}
|
|
|
|
Event::WindowEvent {
|
|
|
|
window_id,
|
|
|
|
event: WindowEvent::Touch(touch),
|
|
|
|
..
|
|
|
|
} => {
|
|
|
|
println!("touch on {:?} {:?}", window_id, touch);
|
|
|
|
}
|
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
});
|
2021-05-15 16:03:08 +00:00
|
|
|
}
|
|
|
|
}
|
2021-07-15 22:40:12 +00:00
|
|
|
|
|
|
|
fn main() {
|
|
|
|
init_logging();
|
|
|
|
let event_loop = EventLoop::new();
|
|
|
|
|
|
|
|
let mut weviews = HashMap::new();
|
|
|
|
|
|
|
|
event_loop.run(move |event, event_loop, control_flow| {
|
|
|
|
*control_flow = ControlFlow::Wait;
|
|
|
|
match event {
|
|
|
|
Event::NewEvents(StartCause::Init) => {
|
|
|
|
println!("Init");
|
|
|
|
|
|
|
|
let window = WindowBuilder::new().build(&event_loop).unwrap();
|
|
|
|
let window_id = window.id();
|
|
|
|
|
|
|
|
let weview = WebViewBuilder::new(window)
|
|
|
|
.unwrap()
|
|
|
|
.with_url("https://tauri.studio")
|
|
|
|
.unwrap()
|
|
|
|
.build()
|
|
|
|
.unwrap();
|
|
|
|
weviews.insert(window_id, weview);
|
|
|
|
}
|
|
|
|
Event::Resumed => {
|
|
|
|
println!("applicationDidBecomeActive");
|
|
|
|
}
|
|
|
|
Event::Suspended => {
|
|
|
|
println!("applicationWillResignActive");
|
|
|
|
}
|
|
|
|
Event::LoopDestroyed => {
|
|
|
|
println!("applicationWillTerminate");
|
|
|
|
}
|
|
|
|
Event::WindowEvent {
|
|
|
|
window_id,
|
|
|
|
event: WindowEvent::Touch(touch),
|
|
|
|
..
|
|
|
|
} => {
|
|
|
|
println!("touch on {:?} {:?}", window_id, touch);
|
|
|
|
}
|
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|