aboutsummaryrefslogtreecommitdiffhomepage
path: root/ui/src/adapter
diff options
context:
space:
mode:
authorelilchen <[email protected]>2023-02-12 00:48:38 +0800
committerelilchen <[email protected]>2023-02-12 00:48:38 +0800
commit7a0e300ff9d5190a31b49155df51dde5c0db2a29 (patch)
tree064916b7e8c0eb78f012cbcfbfa61567ebc32ada /ui/src/adapter
parentb2f381913df6583f215e50faa28dc5e1333d40e6 (diff)
downloadrustdesk-server-7a0e300ff9d5190a31b49155df51dde5c0db2a29.tar.gz
rustdesk-server-7a0e300ff9d5190a31b49155df51dde5c0db2a29.zip
UI
Diffstat (limited to 'ui/src/adapter')
-rw-r--r--ui/src/adapter/mod.rs5
-rw-r--r--ui/src/adapter/service/mod.rs3
-rw-r--r--ui/src/adapter/service/windows.rs130
-rw-r--r--ui/src/adapter/view/desktop.rs220
-rw-r--r--ui/src/adapter/view/mod.rs3
5 files changed, 361 insertions, 0 deletions
diff --git a/ui/src/adapter/mod.rs b/ui/src/adapter/mod.rs
new file mode 100644
index 0000000..a8a9a3c
--- /dev/null
+++ b/ui/src/adapter/mod.rs
@@ -0,0 +1,5 @@
+pub mod view;
+pub mod service;
+
+pub use view::*;
+pub use service::*;
diff --git a/ui/src/adapter/service/mod.rs b/ui/src/adapter/service/mod.rs
new file mode 100644
index 0000000..b64742e
--- /dev/null
+++ b/ui/src/adapter/service/mod.rs
@@ -0,0 +1,3 @@
+pub mod windows;
+
+pub use windows::*;
diff --git a/ui/src/adapter/service/windows.rs b/ui/src/adapter/service/windows.rs
new file mode 100644
index 0000000..3c1e9a8
--- /dev/null
+++ b/ui/src/adapter/service/windows.rs
@@ -0,0 +1,130 @@
+use std::{ffi::OsStr, process::Command};
+
+use crate::{path, usecase::service::*};
+use derive_new::new;
+use windows_service::{
+ service::ServiceAccess,
+ service_manager::{ServiceManager, ServiceManagerAccess},
+};
+
+#[derive(Debug, new)]
+pub struct WindowsDesktopService {
+ #[new(value = "DesktopServiceState::Stopped")]
+ pub state: DesktopServiceState,
+}
+
+impl IDesktopService for WindowsDesktopService {
+ fn start(&mut self) {
+ call(
+ [
+ "echo.",
+ "%nssm% stop hbbr",
+ "%nssm% remove hbbr confirm",
+ "%nssm% stop hbbs",
+ "%nssm% remove hbbs confirm",
+ "mkdir logs",
+ "echo.",
+ "service\\run.cmd hbbs",
+ "echo.",
+ "service\\run.cmd hbbr",
+ "echo.",
+ "@ping 127.1 -n 3 >nul",
+ ]
+ .join(" & "),
+ );
+ self.check();
+ }
+ fn stop(&mut self) {
+ call(
+ [
+ "echo.",
+ "%nssm% stop hbbr",
+ "%nssm% remove hbbr confirm",
+ "echo.",
+ "%nssm% stop hbbs",
+ "%nssm% remove hbbs confirm",
+ "echo.",
+ "@ping 127.1 -n 3 >nul",
+ ]
+ .join(" & "),
+ );
+ self.check();
+ }
+ fn restart(&mut self) {
+ nssm(["restart", "hbbs"].map(|x| x.to_owned()));
+ nssm(["restart", "hbbr"].map(|x| x.to_owned()));
+ self.check();
+ }
+ fn pause(&mut self) {
+ call(
+ [
+ "echo.",
+ "%nssm% stop hbbr",
+ "echo.",
+ "%nssm% stop hbbs",
+ "echo.",
+ "@ping 127.1 -n 3 >nul",
+ ]
+ .join(" & "),
+ );
+ self.check();
+ }
+ fn check(&mut self) -> DesktopServiceState {
+ self.state = match service_status("hbbs").as_str() {
+ "Running" => DesktopServiceState::Started,
+ // "Stopped" => DeskServerServiceState::Paused,
+ _ => DesktopServiceState::Stopped,
+ };
+ self.state.to_owned()
+ }
+}
+
+fn call(cmd: String) {
+ Command::new("cmd")
+ .current_dir(&path())
+ .env("nssm", "service\\nssm.exe")
+ .arg("/c")
+ .arg("start")
+ .arg("cmd")
+ .arg("/c")
+ .arg(cmd)
+ .output()
+ .expect("cmd exec error!");
+}
+
+fn exec<I, S>(program: S, args: I) -> String
+where
+ I: IntoIterator<Item = S>,
+ S: AsRef<OsStr>,
+{
+ match Command::new(program).args(args).output() {
+ Ok(out) => String::from_utf8(out.stdout).unwrap_or("".to_owned()),
+ Err(e) => e.to_string(),
+ }
+}
+
+fn nssm<I>(args: I) -> String
+where
+ I: IntoIterator<Item = String>,
+{
+ exec(
+ format!("{}\\service\\nssm.exe", path().to_str().unwrap_or_default()),
+ args,
+ )
+ .replace("\0", "")
+ .trim()
+ .to_owned()
+}
+
+fn service_status(name: &str) -> String {
+ match ServiceManager::local_computer(None::<&OsStr>, ServiceManagerAccess::CONNECT) {
+ Ok(manager) => match manager.open_service(name, ServiceAccess::QUERY_STATUS) {
+ Ok(service) => match service.query_status() {
+ Ok(status) => format!("{:?}", status.current_state),
+ Err(e) => e.to_string(),
+ },
+ Err(e) => e.to_string(),
+ },
+ Err(e) => e.to_string(),
+ }
+}
diff --git a/ui/src/adapter/view/desktop.rs b/ui/src/adapter/view/desktop.rs
new file mode 100644
index 0000000..328d587
--- /dev/null
+++ b/ui/src/adapter/view/desktop.rs
@@ -0,0 +1,220 @@
+use std::{
+ process::exit,
+ time::{Duration, Instant},
+};
+
+use crate::{
+ path,
+ usecase::{view::Event, DesktopServiceState},
+ BUFFER,
+};
+use async_std::task::sleep;
+use crossbeam_channel::{Receiver, Sender};
+use tauri::{
+ CustomMenuItem, Manager, Menu, MenuItem, Submenu, SystemTray, SystemTrayEvent, SystemTrayMenu,
+ SystemTrayMenuItem, WindowEvent,
+};
+
+pub async fn run(sender: Sender<Event>, receiver: Receiver<Event>) {
+ let setup_sender = sender.clone();
+ let menu_sender = sender.clone();
+ let tray_sender = sender.clone();
+ let menu = Menu::new()
+ .add_submenu(Submenu::new(
+ "Service",
+ Menu::new()
+ .add_item(CustomMenuItem::new("restart", "Restart"))
+ .add_native_item(MenuItem::Separator)
+ .add_item(CustomMenuItem::new("start", "Start"))
+ .add_item(CustomMenuItem::new("stop", "Stop")),
+ ))
+ .add_submenu(Submenu::new(
+ "Logs",
+ Menu::new()
+ .add_item(CustomMenuItem::new("hbbs.out", "hbbs.out"))
+ .add_item(CustomMenuItem::new("hbbs.err", "hbbs.err"))
+ .add_native_item(MenuItem::Separator)
+ .add_item(CustomMenuItem::new("hbbr.out", "hbbr.out"))
+ .add_item(CustomMenuItem::new("hbbr.err", "hbbr.err")),
+ ))
+ .add_submenu(Submenu::new(
+ "Configuration",
+ Menu::new().add_item(CustomMenuItem::new(".env", ".env")),
+ ));
+ let tray = SystemTray::new().with_menu(
+ SystemTrayMenu::new()
+ .add_item(CustomMenuItem::new("restart", "Restart"))
+ .add_native_item(SystemTrayMenuItem::Separator)
+ .add_item(CustomMenuItem::new("start", "Start"))
+ .add_item(CustomMenuItem::new("stop", "Stop"))
+ .add_native_item(SystemTrayMenuItem::Separator)
+ .add_item(CustomMenuItem::new("exit", "Exit GUI")),
+ );
+ let mut app = tauri::Builder::default()
+ .on_window_event(|event| match event.event() {
+ // WindowEvent::Resized(size) => {
+ // if size.width == 0 && size.height == 0 {
+ // event.window().hide().unwrap();
+ // }
+ // }
+ WindowEvent::CloseRequested { api, .. } => {
+ api.prevent_close();
+ event.window().hide().unwrap();
+ }
+ _ => {}
+ })
+ .menu(menu)
+ .on_menu_event(move |event| {
+ // println!(
+ // "send {}: {}",
+ // std::time::SystemTime::now()
+ // .duration_since(std::time::UNIX_EPOCH)
+ // .unwrap_or_default()
+ // .as_millis(),
+ // event.menu_item_id()
+ // );
+ menu_sender
+ .send(Event::ViewAction(event.menu_item_id().to_owned()))
+ .unwrap_or_default()
+ })
+ .system_tray(tray)
+ .on_system_tray_event(move |app, event| match event {
+ SystemTrayEvent::LeftClick { .. } => {
+ let main = app.get_window("main").unwrap();
+ if main.is_visible().unwrap() {
+ main.hide().unwrap();
+ } else {
+ main.show().unwrap();
+ main.unminimize().unwrap();
+ main.set_focus().unwrap();
+ }
+ }
+ SystemTrayEvent::MenuItemClick { id, .. } => {
+ tray_sender.send(Event::ViewAction(id)).unwrap_or_default();
+ }
+ _ => {}
+ })
+ .setup(move |app| {
+ setup_sender.send(Event::ViewInit).unwrap_or_default();
+ app.listen_global("__action__", move |msg| {
+ match msg.payload().unwrap_or_default() {
+ r#""__init__""# => setup_sender.send(Event::BroswerInit).unwrap_or_default(),
+ r#""restart""# => setup_sender
+ .send(Event::BrowserAction("restart".to_owned()))
+ .unwrap_or_default(),
+ _ => (),
+ }
+ });
+ Ok(())
+ })
+ .invoke_handler(tauri::generate_handler![root])
+ .build(tauri::generate_context!())
+ .expect("error while running tauri application");
+ let mut now = Instant::now();
+ let mut blink = false;
+ let mut span = 0;
+ let mut title = "".to_owned();
+ let product = "RustDesk Server";
+ let buffer = BUFFER.get().unwrap().to_owned();
+ loop {
+ for _ in 1..buffer {
+ match receiver.recv_timeout(Duration::from_nanos(1)) {
+ Ok(event) => {
+ let main = app.get_window("main").unwrap();
+ let menu = main.menu_handle();
+ let tray = app.tray_handle();
+ match event {
+ Event::BrowserUpdate((action, data)) => match action.as_str() {
+ "file" => {
+ let list = ["hbbs.out", "hbbs.err", "hbbr.out", "hbbr.err", ".env"];
+ let id = data.as_str();
+ if list.contains(&id) {
+ for file in list {
+ menu.get_item(file)
+ .set_selected(file == id)
+ .unwrap_or_default();
+ }
+ // println!(
+ // "emit {}: {}",
+ // std::time::SystemTime::now()
+ // .duration_since(std::time::UNIX_EPOCH)
+ // .unwrap_or_default()
+ // .as_millis(),
+ // data
+ // );
+ app.emit_all("__update__", (action, data))
+ .unwrap_or_default();
+ }
+ }
+ _ => (),
+ },
+ Event::ViewRenderAppExit => exit(0),
+ Event::ViewRenderServiceState(state) => {
+ let enabled = |id, enabled| {
+ menu.get_item(id).set_enabled(enabled).unwrap_or_default();
+ tray.get_item(id).set_enabled(enabled).unwrap_or_default();
+ };
+ title = format!("{} {:?}", product, state);
+ main.set_title(title.as_str()).unwrap_or_default();
+ match state {
+ DesktopServiceState::Started => {
+ enabled("start", false);
+ enabled("stop", true);
+ enabled("restart", true);
+ blink = false;
+ }
+ DesktopServiceState::Stopped => {
+ enabled("start", true);
+ enabled("stop", false);
+ enabled("restart", false);
+ blink = true;
+ }
+ _ => {
+ enabled("start", false);
+ enabled("stop", false);
+ enabled("restart", false);
+ blink = true;
+ }
+ }
+ }
+ _ => (),
+ }
+ }
+ Err(_) => break,
+ }
+ }
+ let elapsed = now.elapsed().as_micros();
+ if elapsed > 16666 {
+ now = Instant::now();
+ // println!("{}ms", elapsed as f64 * 0.001);
+ let iteration = app.run_iteration();
+ if iteration.window_count == 0 {
+ break;
+ }
+ if blink {
+ if span > 1000000 {
+ span = 0;
+ app.get_window("main")
+ .unwrap()
+ .set_title(title.as_str())
+ .unwrap_or_default();
+ } else {
+ span += elapsed;
+ if span > 500000 {
+ app.get_window("main")
+ .unwrap()
+ .set_title(product)
+ .unwrap_or_default();
+ }
+ }
+ }
+ } else {
+ sleep(Duration::from_micros(999)).await;
+ }
+ }
+}
+
+#[tauri::command]
+fn root() -> String {
+ path().to_str().unwrap_or_default().to_owned()
+}
diff --git a/ui/src/adapter/view/mod.rs b/ui/src/adapter/view/mod.rs
new file mode 100644
index 0000000..8569296
--- /dev/null
+++ b/ui/src/adapter/view/mod.rs
@@ -0,0 +1,3 @@
+pub mod desktop;
+
+pub use desktop::*;