mirror of
https://github.com/Stremio/stremio-shell-ng.git
synced 2026-01-11 22:40:32 +00:00
Cmd line args, drag&drop, fs event
This commit is contained in:
parent
a905baf3ef
commit
6f1ba7f8a6
5 changed files with 230 additions and 20 deletions
141
Cargo.lock
generated
141
Cargo.lock
generated
|
|
@ -2,6 +2,26 @@
|
|||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "ansi_term"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.0.1"
|
||||
|
|
@ -26,6 +46,21 @@ version = "1.0.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "2.33.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002"
|
||||
dependencies = [
|
||||
"ansi_term",
|
||||
"atty",
|
||||
"bitflags",
|
||||
"strsim",
|
||||
"textwrap",
|
||||
"unicode-width",
|
||||
"vec_map",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "com"
|
||||
version = "0.2.0"
|
||||
|
|
@ -72,6 +107,24 @@ version = "0.1.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c"
|
||||
dependencies = [
|
||||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "0.4.7"
|
||||
|
|
@ -288,6 +341,30 @@ dependencies = [
|
|||
"toml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
|
||||
dependencies = [
|
||||
"proc-macro-error-attr",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error-attr"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.27"
|
||||
|
|
@ -396,6 +473,7 @@ dependencies = [
|
|||
"once_cell",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"structopt",
|
||||
"webview2",
|
||||
"webview2-sys",
|
||||
"winapi",
|
||||
|
|
@ -411,6 +489,36 @@ dependencies = [
|
|||
"libm",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||
|
||||
[[package]]
|
||||
name = "structopt"
|
||||
version = "0.3.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69b041cdcb67226aca307e6e7be44c8806423d83e018bd662360a93dabce4d71"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"lazy_static",
|
||||
"structopt-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "structopt-derive"
|
||||
version = "0.4.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7813934aecf5f51a54775e00068c237de98489463968231a51746bbbc03f9c10"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.73"
|
||||
|
|
@ -422,6 +530,15 @@ dependencies = [
|
|||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
|
||||
dependencies = [
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.5.8"
|
||||
|
|
@ -431,12 +548,36 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-segmentation"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||
|
||||
[[package]]
|
||||
name = "vec_map"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.74"
|
||||
|
|
|
|||
|
|
@ -14,4 +14,5 @@ webview2 = "0.1.0"
|
|||
webview2-sys = "0.1.0-beta.1"
|
||||
mpv = "0.2.3"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
serde_json = "1.0"
|
||||
structopt = "0.3"
|
||||
|
|
|
|||
36
src/main.rs
36
src/main.rs
|
|
@ -1,8 +1,20 @@
|
|||
use native_windows_gui::{self as nwg, NativeUi};
|
||||
use structopt::StructOpt;
|
||||
|
||||
mod stremio_app;
|
||||
use crate::stremio_app::{stremio_server::StremioServer, MainWindow};
|
||||
|
||||
const WEB_ENDPOINT: &str = "http://app.strem.io/shell-v4.4/";
|
||||
|
||||
#[derive(StructOpt, Debug)]
|
||||
#[structopt(name = "basic")]
|
||||
struct Opt {
|
||||
#[structopt(long)]
|
||||
development: bool,
|
||||
#[structopt(long, default_value = WEB_ENDPOINT)]
|
||||
webui_url: String,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// native-windows-gui has some basic high DPI support with the high-dpi
|
||||
// feature. It supports the "System DPI Awareness" mode, but not the more
|
||||
|
|
@ -14,10 +26,28 @@ fn main() {
|
|||
nwg::set_dpi_awareness()
|
||||
};
|
||||
|
||||
let streaming_server = StremioServer::new();
|
||||
let opt = Opt::from_args();
|
||||
|
||||
let streaming_server: Option<StremioServer> = if opt.development {
|
||||
None
|
||||
} else {
|
||||
Some(StremioServer::new())
|
||||
};
|
||||
|
||||
let webui_url = if opt.development && opt.webui_url == WEB_ENDPOINT {
|
||||
"http://localhost:11470".to_string()
|
||||
} else {
|
||||
opt.webui_url
|
||||
};
|
||||
|
||||
nwg::init().expect("Failed to init Native Windows GUI");
|
||||
let _app = MainWindow::build_ui(Default::default()).expect("Failed to build UI");
|
||||
let _app = MainWindow::build_ui(MainWindow {
|
||||
webui_url,
|
||||
..Default::default()
|
||||
})
|
||||
.expect("Failed to build UI");
|
||||
nwg::dispatch_thread_events();
|
||||
streaming_server.try_kill();
|
||||
if let Some(streaming_server) = streaming_server {
|
||||
streaming_server.try_kill();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,19 +43,26 @@ struct RPCResponse {
|
|||
|
||||
#[derive(Default, NwgUi)]
|
||||
pub struct MainWindow {
|
||||
pub webui_url: String,
|
||||
#[nwg_control(title: "Stremio", flags: "MAIN_WINDOW|VISIBLE")]
|
||||
#[nwg_events( OnWindowClose: [MainWindow::on_quit], OnInit: [MainWindow::on_init] )]
|
||||
window: nwg::Window,
|
||||
#[nwg_events( OnWindowClose: [MainWindow::on_quit], OnInit: [MainWindow::on_init], OnMinMaxInfo: [MainWindow::on_min_max(SELF, EVT_DATA)] )]
|
||||
pub window: nwg::Window,
|
||||
#[nwg_partial(parent: window)]
|
||||
webview: WebView,
|
||||
pub webview: WebView,
|
||||
#[nwg_partial(parent: window)]
|
||||
player: Player,
|
||||
pub player: Player,
|
||||
}
|
||||
|
||||
impl MainWindow {
|
||||
const MIN_WIDTH: i32 = 1000;
|
||||
const MIN_HEIGHT: i32 = 600;
|
||||
fn on_init(&self) {
|
||||
self.webview.endpoint.set(self.webui_url.clone()).ok();
|
||||
let small_side = cmp::min(nwg::Monitor::width(), nwg::Monitor::height()) * 70 / 100;
|
||||
let dimensions = (small_side * 16 / 9, small_side);
|
||||
let dimensions = (
|
||||
cmp::max(small_side * 16 / 9, Self::MIN_WIDTH),
|
||||
cmp::max(small_side, Self::MIN_HEIGHT),
|
||||
);
|
||||
let [total_width, total_height] = [nwg::Monitor::width(), nwg::Monitor::height()];
|
||||
let x = (total_width - dimensions.0) / 2;
|
||||
let y = (total_height - dimensions.1) / 2;
|
||||
|
|
@ -93,7 +100,7 @@ impl MainWindow {
|
|||
web_tx_player.send(resp_json).ok();
|
||||
} // recv
|
||||
}); // thread
|
||||
// read message from WebView
|
||||
|
||||
thread::spawn(move || loop {
|
||||
let rx = web_rx.lock().unwrap();
|
||||
if let Ok(msg) = rx.recv() {
|
||||
|
|
@ -131,7 +138,12 @@ impl MainWindow {
|
|||
let resp_json = serde_json::to_string(&args).unwrap();
|
||||
player_tx.send(resp_json).ok();
|
||||
} else {
|
||||
eprintln!("Unsupported command {:?}", args)
|
||||
match method {
|
||||
"toggle-fullscreen" => {
|
||||
println!("full screen toggle requested");
|
||||
}
|
||||
_ => eprintln!("Unsupported command {:?}", args),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -141,6 +153,10 @@ impl MainWindow {
|
|||
} // recv
|
||||
}); // thread
|
||||
}
|
||||
fn on_min_max(&self, data: &nwg::EventData) {
|
||||
let data = data.on_min_max();
|
||||
data.set_min_size(Self::MIN_WIDTH, Self::MIN_HEIGHT);
|
||||
}
|
||||
fn on_quit(&self) {
|
||||
nwg::stop_thread_dispatch();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use native_windows_gui::{self as nwg, PartialUi};
|
||||
use once_cell::unsync::OnceCell;
|
||||
use serde_json::json;
|
||||
use std::cell::RefCell;
|
||||
use std::mem;
|
||||
use std::rc::Rc;
|
||||
|
|
@ -12,6 +13,7 @@ use winapi::um::winuser::*;
|
|||
|
||||
#[derive(Default)]
|
||||
pub struct WebView {
|
||||
pub endpoint: Rc<OnceCell<String>>,
|
||||
controller: Rc<OnceCell<Controller>>,
|
||||
pub channel: RefCell<Option<(mpsc::Sender<String>, Arc<Mutex<mpsc::Receiver<String>>>)>>,
|
||||
notice: nwg::Notice,
|
||||
|
|
@ -31,7 +33,9 @@ impl WebView {
|
|||
controller.put_bounds(rect).ok();
|
||||
}
|
||||
controller.put_is_visible(true).ok();
|
||||
controller.move_focus(webview2::MoveFocusReason::Programmatic).ok();
|
||||
controller
|
||||
.move_focus(webview2::MoveFocusReason::Programmatic)
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -42,8 +46,9 @@ impl PartialUi for WebView {
|
|||
parent: Option<W>,
|
||||
) -> Result<(), nwg::NwgError> {
|
||||
let (tx, rx) = mpsc::channel::<String>();
|
||||
let (tx1, rx1) = mpsc::channel::<String>();
|
||||
data.channel = RefCell::new(Some((tx, Arc::new(Mutex::new(rx1)))));
|
||||
let tx_drag_drop = tx.clone();
|
||||
let (tx_web, rx_web) = mpsc::channel::<String>();
|
||||
data.channel = RefCell::new(Some((tx, Arc::new(Mutex::new(rx_web)))));
|
||||
|
||||
let parent = parent.expect("No parent window").into();
|
||||
|
||||
|
|
@ -53,6 +58,7 @@ impl PartialUi for WebView {
|
|||
.build(&mut data.notice)
|
||||
.ok();
|
||||
let controller_clone = data.controller.clone();
|
||||
let endpoint = data.endpoint.clone();
|
||||
let hwnd = hwnd as *mut HWND__;
|
||||
let result = webview2::EnvironmentBuilder::new()
|
||||
.with_additional_browser_arguments("--disable-gpu")
|
||||
|
|
@ -75,11 +81,13 @@ impl PartialUi for WebView {
|
|||
let webview = controller
|
||||
.get_webview()
|
||||
.expect("Cannot obtain webview from controller");
|
||||
if let Some(endpoint) = endpoint.get() {
|
||||
if let Err(e) = webview
|
||||
.navigate(endpoint.as_str()) {
|
||||
eprintln!("Cannot load WEB UI at '{}': {:?}", &endpoint, e);
|
||||
};
|
||||
}
|
||||
webview
|
||||
// .navigate("https://www.boyanpetrov.rip/stremio/index.html")
|
||||
.navigate("http://app.strem.io/shell-v4.4/")
|
||||
.expect("Cannot load the webUI");
|
||||
webview
|
||||
.add_script_to_execute_on_document_created(
|
||||
r##"
|
||||
window.qt={webChannelTransport:{send:window.chrome.webview.postMessage}};
|
||||
|
|
@ -89,9 +97,24 @@ impl PartialUi for WebView {
|
|||
|_| Ok(()),
|
||||
)
|
||||
.ok();
|
||||
let tx_fs = tx_web.clone();
|
||||
webview.add_web_message_received(move |_w, msg| {
|
||||
let msg = msg.try_get_web_message_as_string()?;
|
||||
tx1.send(msg).ok();
|
||||
tx_web.send(msg).ok();
|
||||
Ok(())
|
||||
}).ok();
|
||||
webview.add_new_window_requested(move |_w, msg| {
|
||||
let data = json!({
|
||||
"object": "transport",
|
||||
"type": 1,
|
||||
"args": ["dragdrop" ,[msg.get_uri().unwrap()]]
|
||||
});
|
||||
tx_drag_drop.send(data.to_string()).ok();
|
||||
msg.put_handled(true).ok();
|
||||
Ok(())
|
||||
}).ok();
|
||||
webview.add_contains_full_screen_element_changed(move |_w| {
|
||||
tx_fs.send(r#"{"id":1, "args": ["toggle-fullscreen"]}"#.to_string()).ok();
|
||||
Ok(())
|
||||
}).ok();
|
||||
WebView::resize_to_window_bounds_and_show(Some(&controller), Some(hwnd));
|
||||
|
|
@ -129,7 +152,6 @@ impl PartialUi for WebView {
|
|||
) {
|
||||
use nwg::Event as E;
|
||||
match evt {
|
||||
E::OnInit => {}
|
||||
E::OnResize | E::OnWindowMaximize => {
|
||||
WebView::resize_to_window_bounds_and_show(self.controller.get(), handle.hwnd());
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue