mirror of
https://github.com/Stremio/stremio-shell-ng.git
synced 2026-05-16 04:52:15 +00:00
impl RPCRequest. Less staircase code
This commit is contained in:
parent
81dbe73be0
commit
a66f625487
2 changed files with 95 additions and 81 deletions
|
|
@ -6,7 +6,7 @@ use std::sync::Arc;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use winapi::um::winuser::WS_EX_TOPMOST;
|
use winapi::um::winuser::WS_EX_TOPMOST;
|
||||||
|
|
||||||
use crate::stremio_app::ipc::{RPCRequest, RPCResponse, RPCResponseData, RPCResponseDataTransport};
|
use crate::stremio_app::ipc::{RPCRequest, RPCResponse};
|
||||||
use crate::stremio_app::splash::SplashImage;
|
use crate::stremio_app::splash::SplashImage;
|
||||||
use crate::stremio_app::stremio_player::Player;
|
use crate::stremio_app::stremio_player::Player;
|
||||||
use crate::stremio_app::stremio_wevbiew::WebView;
|
use crate::stremio_app::stremio_wevbiew::WebView;
|
||||||
|
|
@ -114,90 +114,60 @@ impl MainWindow {
|
||||||
let hide_splash_sender = self.hide_splash_notice.sender();
|
let hide_splash_sender = self.hide_splash_notice.sender();
|
||||||
thread::spawn(move || loop {
|
thread::spawn(move || loop {
|
||||||
let rx = web_rx.lock().unwrap();
|
let rx = web_rx.lock().unwrap();
|
||||||
if let Ok(msg) = rx.recv() {
|
if let Some(msg) = rx
|
||||||
if let Ok(msg) = serde_json::from_str::<RPCRequest>(&msg) {
|
.recv()
|
||||||
|
.ok()
|
||||||
|
.and_then(|s| serde_json::from_str::<RPCRequest>(&s).ok())
|
||||||
|
{
|
||||||
|
match msg.get_method() {
|
||||||
// The handshake. Here we send some useful data to the WEB UI
|
// The handshake. Here we send some useful data to the WEB UI
|
||||||
if msg.id == 0 {
|
None if msg.is_handshake() => {
|
||||||
let resp = RPCResponse {
|
web_tx_web.send(RPCResponse::get_handshake()).ok();
|
||||||
id: 0,
|
}
|
||||||
object: "transport".to_string(),
|
Some("win-set-visibility") => toggle_fullscreen_sender.notice(),
|
||||||
response_type: 3,
|
Some("quit") => quit_sender.notice(),
|
||||||
data: Some(RPCResponseData {
|
Some("app-ready") => {
|
||||||
transport: RPCResponseDataTransport {
|
hide_splash_sender.notice();
|
||||||
properties: vec![
|
web_tx_web
|
||||||
vec![],
|
.send(RPCResponse::visibility_change(true, 1, false))
|
||||||
vec![
|
.ok();
|
||||||
"".to_string(),
|
}
|
||||||
"shellVersion".to_string(),
|
Some("app-error") => {
|
||||||
"".to_string(),
|
hide_splash_sender.notice();
|
||||||
"5.0.0".to_string(),
|
if let Some(arg) = msg.get_params() {
|
||||||
],
|
// TODO: Make this modal dialog
|
||||||
],
|
eprintln!("Web App Error: {}", arg.to_string());
|
||||||
signals: vec![],
|
}
|
||||||
methods: vec![vec!["onEvent".to_string(), "".to_string()]],
|
}
|
||||||
},
|
Some("open-external") => {
|
||||||
}),
|
if let Some(arg) = msg.get_params() {
|
||||||
..Default::default()
|
// FIXME: THIS IS NOT SAFE BY ANY MEANS
|
||||||
};
|
// open::that("calc").ok(); does exactly that
|
||||||
let resp_json =
|
let arg = arg.to_string();
|
||||||
serde_json::to_string(&resp).expect("Cannot build response");
|
let arg_lc = arg.to_lowercase();
|
||||||
web_tx_web.send(resp_json).ok();
|
if arg_lc.starts_with("http://")
|
||||||
} else if let Some(args) = msg.args {
|
|| arg_lc.starts_with("https://")
|
||||||
if let Some(method) = args.first() {
|
|| arg_lc.starts_with("rtp://")
|
||||||
let method = method.as_str().unwrap_or("invalid-method");
|
|| arg_lc.starts_with("rtps://")
|
||||||
if method.starts_with("mpv-") {
|
|| arg_lc.starts_with("ftp://")
|
||||||
let resp_json =
|
|| arg_lc.starts_with("ipfs://")
|
||||||
serde_json::to_string(&args).expect("Cannot build response");
|
{
|
||||||
player_tx.send(resp_json).ok();
|
open::that(arg).ok();
|
||||||
} else {
|
|
||||||
match method {
|
|
||||||
"win-set-visibility" => {
|
|
||||||
toggle_fullscreen_sender.notice();
|
|
||||||
}
|
|
||||||
"quit" => {
|
|
||||||
quit_sender.notice();
|
|
||||||
}
|
|
||||||
"app-ready" => {
|
|
||||||
hide_splash_sender.notice();
|
|
||||||
web_tx_web
|
|
||||||
.send(RPCResponse::visibility_change(true, 1, false))
|
|
||||||
.ok();
|
|
||||||
}
|
|
||||||
"app-error" => {
|
|
||||||
hide_splash_sender.notice();
|
|
||||||
if args.len() > 1 {
|
|
||||||
// TODO: Make this modal dialog
|
|
||||||
eprintln!(
|
|
||||||
"Web App Error: {}",
|
|
||||||
args[1].as_str().unwrap_or("Unknown error")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"open-external" => {
|
|
||||||
if args.len() > 1 {
|
|
||||||
if let Some(arg) = args[1].as_str() {
|
|
||||||
// FIXME: THIS IS NOT SAFE BY ANY MEANS
|
|
||||||
// open::that("calc").ok(); does exactly that
|
|
||||||
let arg_lc = arg.to_lowercase();
|
|
||||||
if arg_lc.starts_with("http://")
|
|
||||||
|| arg_lc.starts_with("https://")
|
|
||||||
|| arg_lc.starts_with("rtp://")
|
|
||||||
|| arg_lc.starts_with("rtps://")
|
|
||||||
|| arg_lc.starts_with("ftp://")
|
|
||||||
|| arg_lc.starts_with("ipfs://")
|
|
||||||
{
|
|
||||||
open::that(arg).ok();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => eprintln!("Unsupported command {:?}", args),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
Some(player_command) if player_command.starts_with("mpv-") => {
|
||||||
eprintln!("Web UI sent invalid JSON: {:?}", msg);
|
// FIXME: filter out the run command
|
||||||
|
let resp_json = serde_json::to_string(
|
||||||
|
&msg.args.expect("Cannot have method without args"),
|
||||||
|
)
|
||||||
|
.expect("Cannot build response");
|
||||||
|
player_tx.send(resp_json).ok();
|
||||||
|
}
|
||||||
|
Some(unknown) => {
|
||||||
|
eprintln!("Unsupported command {}({:?})", unknown, msg.get_params())
|
||||||
|
}
|
||||||
|
None => {}
|
||||||
}
|
}
|
||||||
} // recv
|
} // recv
|
||||||
}); // thread
|
}); // thread
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,26 @@ pub struct RPCRequest {
|
||||||
pub args: Option<Vec<serde_json::Value>>,
|
pub args: Option<Vec<serde_json::Value>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl RPCRequest {
|
||||||
|
pub fn is_handshake(&self) -> bool {
|
||||||
|
self.id == 0
|
||||||
|
}
|
||||||
|
pub fn get_method(&self) -> Option<&str> {
|
||||||
|
self.args
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|args| args.first())
|
||||||
|
.and_then(|arg| arg.as_str())
|
||||||
|
}
|
||||||
|
pub fn get_params(&self) -> Option<serde_json::Value> {
|
||||||
|
self.args.as_ref().and_then(|args| {
|
||||||
|
if args.len() > 1 {
|
||||||
|
Some(args[1].clone())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
pub struct RPCResponseDataTransport {
|
pub struct RPCResponseDataTransport {
|
||||||
pub properties: Vec<Vec<String>>,
|
pub properties: Vec<Vec<String>>,
|
||||||
|
|
@ -37,6 +57,30 @@ pub struct RPCResponse {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RPCResponse {
|
impl RPCResponse {
|
||||||
|
pub fn get_handshake() -> String {
|
||||||
|
let resp = RPCResponse {
|
||||||
|
id: 0,
|
||||||
|
object: "transport".to_string(),
|
||||||
|
response_type: 3,
|
||||||
|
data: Some(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()]],
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
serde_json::to_string(&resp).expect("Cannot build response")
|
||||||
|
}
|
||||||
pub fn response_message(msg: Option<serde_json::Value>) -> String {
|
pub fn response_message(msg: Option<serde_json::Value>) -> String {
|
||||||
let resp = RPCResponse {
|
let resp = RPCResponse {
|
||||||
id: 1,
|
id: 1,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue