From 56d255f44a4760c359a99bdbae060e54e5b4bcdd Mon Sep 17 00:00:00 2001 From: Vladimir Borisov Date: Thu, 15 Jul 2021 18:06:42 +0300 Subject: [PATCH] Proof of concept RPC --- Cargo.lock | 39 ++++++++++ Cargo.toml | 4 +- .../stremio_wevbiew/stremio_wevbiew.rs | 73 +++++++++++++++++-- 3 files changed, 110 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 324b577..345f416 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -72,6 +72,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" +[[package]] +name = "itoa" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" + [[package]] name = "js-sys" version = "0.3.51" @@ -343,11 +349,42 @@ version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" +[[package]] +name = "ryu" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" + [[package]] name = "serde" version = "1.0.126" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "963a7dbc9895aeac7ac90e74f34a5d5261828f79df35cbed41e10189d3804d43" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79" +dependencies = [ + "itoa", + "ryu", + "serde", +] [[package]] name = "stremio-shell-ng" @@ -357,6 +394,8 @@ dependencies = [ "native-windows-derive", "native-windows-gui", "once_cell", + "serde", + "serde_json", "webview2", "webview2-sys", "winapi", diff --git a/Cargo.toml b/Cargo.toml index 2bc0166..68e8d7c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,4 +12,6 @@ winapi = { version = "0.3.9", features = [ ] } webview2 = "0.1.0" webview2-sys = "0.1.0-beta.1" -mpv = "0.2.3" \ No newline at end of file +mpv = "0.2.3" +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" \ No newline at end of file diff --git a/src/stremio_app/stremio_wevbiew/stremio_wevbiew.rs b/src/stremio_app/stremio_wevbiew/stremio_wevbiew.rs index 248232f..2bd1f5e 100644 --- a/src/stremio_app/stremio_wevbiew/stremio_wevbiew.rs +++ b/src/stremio_app/stremio_wevbiew/stremio_wevbiew.rs @@ -1,18 +1,50 @@ use native_windows_gui::{self as nwg, PartialUi}; use once_cell::unsync::OnceCell; +use serde::{Deserialize, Serialize}; +use serde_json; use std::mem; use std::rc::Rc; use webview2::Controller; use winapi::shared::windef::HWND__; use winapi::um::winuser::*; +#[derive(Serialize, Deserialize, Debug, Clone)] +struct RPCRequest { + id: u64, + args: Option>, +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +struct RPCResponseDataTransport { + properties: Vec>, + signals: Vec, + methods: Vec>, +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +struct RPCResponseData { + transport: RPCResponseDataTransport, +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +struct RPCResponse { + id: u64, + object: String, + #[serde(rename = "type")] + response_type: u32, + data: RPCResponseData, +} + #[derive(Default)] pub struct WebView { controller: Rc>, } impl WebView { - fn resize_to_window_bounds(controller: Option<&Controller>, hwnd: Option<*mut HWND__>) { + fn resize_to_window_bounds_and_show( + controller: Option<&Controller>, + hwnd: Option<*mut HWND__>, + ) { if let (Some(controller), Some(hwnd)) = (controller, hwnd) { unsafe { let mut rect = mem::zeroed(); @@ -38,7 +70,6 @@ impl PartialUi for WebView { env.expect("Cannot obtain webview environment") .create_controller(hwnd, move |controller| { let controller = controller.expect("Cannot obtain webview controller"); - WebView::resize_to_window_bounds(Some(&controller), parent.hwnd()); if let Ok(controller2) = controller.get_controller2() { controller2 .put_default_background_color(webview2_sys::Color { @@ -54,11 +85,43 @@ impl PartialUi for WebView { let webview = controller .get_webview() .expect("Cannot obtain webview from controller"); - // webview.navigate("edge://gpu").expect("Cannot load the webUI"); webview .navigate("https://www.boyanpetrov.rip/stremio/index.html") .expect("Cannot load the webUI"); - // controller.put_is_visible(true).expect("Cannot show the WebView"); + webview + .add_script_to_execute_on_document_created( + r##" + window.qt={webChannelTransport:{send:window.chrome.webview.postMessage}}; + window.chrome.webview.addEventListener('message',ev=>window.qt.webChannelTransport.onmessage(ev)); + window.onload=()=>initShellComm(); + "##, + |_| Ok(()), + ) + .ok(); + webview.add_web_message_received(|w, msg| { + let msg = msg.try_get_web_message_as_string()?; + let msg: RPCRequest = serde_json::from_str(&msg).unwrap(); + dbg!(msg.clone()); + if msg.id == 0 { + let resp: RPCResponse = RPCResponse { + id: 0, + object: "transport".to_string(), + response_type: 3, + data: RPCResponseData { + transport: RPCResponseDataTransport { + properties: vec![vec![], vec!["".to_string(), "shellVersion".to_string(), "".to_string(), "5.0.0".to_string()]], + signals: vec![], + methods: vec![vec!["onEvent".to_string(), "".to_string()]] + } + } + }; + let resp_json = serde_json::to_string(&resp).unwrap(); + dbg!(resp_json.clone()); + w.post_web_message_as_string(&resp_json).ok(); + } + Ok(()) + }).ok(); + WebView::resize_to_window_bounds_and_show(Some(&controller), parent.hwnd()); controller_clone .set(controller) .expect("Cannot update the controller"); @@ -83,7 +146,7 @@ impl PartialUi for WebView { use nwg::Event as E; match evt { E::OnResize | E::OnWindowMaximize => { - WebView::resize_to_window_bounds(self.controller.get(), handle.hwnd()); + WebView::resize_to_window_bounds_and_show(self.controller.get(), handle.hwnd()); } E::OnWindowMinimize => { if let Some(controller) = self.controller.get() {