Proof of concept RPC

This commit is contained in:
Vladimir Borisov 2021-07-15 18:06:42 +03:00
parent 6fc17bbe42
commit 56d255f44a
3 changed files with 110 additions and 6 deletions

39
Cargo.lock generated
View file

@ -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",

View file

@ -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"
mpv = "0.2.3"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"

View file

@ -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<Vec<serde_json::Value>>,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
struct RPCResponseDataTransport {
properties: Vec<Vec<String>>,
signals: Vec<String>,
methods: Vec<Vec<String>>,
}
#[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<OnceCell<Controller>>,
}
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() {