From 09f38502503aad860cce0a33c29f4c45bf624e49 Mon Sep 17 00:00:00 2001 From: 21pages Date: Wed, 8 May 2024 17:04:53 +0800 Subject: [PATCH] installed windows client save incoming recording to a specific directory (#7974) Signed-off-by: 21pages --- .../desktop/pages/desktop_setting_page.dart | 64 ++++++++++++++----- flutter/lib/mobile/pages/settings_page.dart | 2 +- flutter/lib/web/bridge.dart | 2 +- libs/scrap/src/common/record.rs | 22 +++---- src/client.rs | 2 +- src/flutter_ffi.rs | 4 +- src/lang/ar.rs | 2 + src/lang/bg.rs | 2 + src/lang/ca.rs | 2 + src/lang/cn.rs | 2 + src/lang/cs.rs | 2 + src/lang/da.rs | 2 + src/lang/de.rs | 2 + src/lang/el.rs | 2 + src/lang/eo.rs | 2 + src/lang/es.rs | 2 + src/lang/et.rs | 2 + src/lang/fa.rs | 2 + src/lang/fr.rs | 2 + src/lang/he.rs | 2 + src/lang/hr.rs | 2 + src/lang/hu.rs | 2 + src/lang/id.rs | 2 + src/lang/it.rs | 2 + src/lang/ja.rs | 2 + src/lang/ko.rs | 2 + src/lang/kz.rs | 2 + src/lang/lt.rs | 2 + src/lang/lv.rs | 2 + src/lang/nb.rs | 2 + src/lang/nl.rs | 2 + src/lang/pl.rs | 2 + src/lang/pt_PT.rs | 2 + src/lang/ptbr.rs | 2 + src/lang/ro.rs | 2 + src/lang/ru.rs | 2 + src/lang/sk.rs | 2 + src/lang/sl.rs | 2 + src/lang/sq.rs | 2 + src/lang/sr.rs | 2 + src/lang/sv.rs | 2 + src/lang/template.rs | 2 + src/lang/th.rs | 2 + src/lang/tr.rs | 2 + src/lang/tw.rs | 2 + src/lang/ua.rs | 2 + src/lang/vn.rs | 2 + src/server/video_service.rs | 8 ++- src/ui.rs | 6 +- src/ui/index.tis | 8 ++- src/ui_interface.rs | 18 +++++- 51 files changed, 173 insertions(+), 45 deletions(-) diff --git a/flutter/lib/desktop/pages/desktop_setting_page.dart b/flutter/lib/desktop/pages/desktop_setting_page.dart index f65a6e267..b1f245610 100644 --- a/flutter/lib/desktop/pages/desktop_setting_page.dart +++ b/flutter/lib/desktop/pages/desktop_setting_page.dart @@ -485,42 +485,72 @@ class _GeneralState extends State<_General> { } Widget record(BuildContext context) { + final showRootDir = isWindows && bind.mainIsInstalled(); return futureBuilder(future: () async { - String defaultDirectory = await bind.mainDefaultVideoSaveDirectory(); + String user_dir = await bind.mainVideoSaveDirectory(root: false); + String root_dir = + showRootDir ? await bind.mainVideoSaveDirectory(root: true) : ''; + bool user_dir_exists = await Directory(user_dir).exists(); + bool root_dir_exists = + showRootDir ? await Directory(root_dir).exists() : false; // canLaunchUrl blocked on windows portable, user SYSTEM - return {'dir': defaultDirectory, 'canlaunch': true}; + return { + 'user_dir': user_dir, + 'root_dir': root_dir, + 'user_dir_exists': user_dir_exists, + 'root_dir_exists': root_dir_exists, + }; }(), hasData: (data) { Map map = data as Map; - String dir = map['dir']!; - String customDirectory = - bind.mainGetOptionSync(key: 'video-save-directory'); - if (customDirectory.isNotEmpty) { - dir = customDirectory; - } - bool canlaunch = map['canlaunch']! as bool; - + String user_dir = map['user_dir']!; + String root_dir = map['root_dir']!; + bool root_dir_exists = map['root_dir_exists']!; + bool user_dir_exists = map['user_dir_exists']!; return _Card(title: 'Recording', children: [ _OptionCheckBox(context, 'Automatically record incoming sessions', 'allow-auto-record-incoming'), + if (showRootDir) + Row( + children: [ + Text('${translate("Incoming")}:'), + Expanded( + child: GestureDetector( + onTap: root_dir_exists + ? () => launchUrl(Uri.file(root_dir)) + : null, + child: Text( + root_dir, + softWrap: true, + style: root_dir_exists + ? const TextStyle( + decoration: TextDecoration.underline) + : null, + )).marginOnly(left: 10), + ), + ], + ).marginOnly(left: _kContentHMargin), Row( children: [ - Text('${translate("Directory")}:'), + Text('${translate(showRootDir ? "Outgoing" : "Directory")}:'), Expanded( child: GestureDetector( - onTap: canlaunch ? () => launchUrl(Uri.file(dir)) : null, + onTap: user_dir_exists + ? () => launchUrl(Uri.file(user_dir)) + : null, child: Text( - dir, + user_dir, softWrap: true, - style: - const TextStyle(decoration: TextDecoration.underline), + style: user_dir_exists + ? const TextStyle(decoration: TextDecoration.underline) + : null, )).marginOnly(left: 10), ), ElevatedButton( onPressed: () async { String? initialDirectory; - if (await Directory.fromUri(Uri.directory(dir)) + if (await Directory.fromUri(Uri.directory(user_dir)) .exists()) { - initialDirectory = dir; + initialDirectory = user_dir; } String? selectedDirectory = await FilePicker.platform .getDirectoryPath(initialDirectory: initialDirectory); diff --git a/flutter/lib/mobile/pages/settings_page.dart b/flutter/lib/mobile/pages/settings_page.dart index 9477cbe6a..fff7e3516 100644 --- a/flutter/lib/mobile/pages/settings_page.dart +++ b/flutter/lib/mobile/pages/settings_page.dart @@ -525,7 +525,7 @@ class _SettingsState extends State with WidgetsBindingObserver { builder: (ctx, data) => Offstage( offstage: !data.hasData, child: Text("${translate("Directory")}: ${data.data}")), - future: bind.mainDefaultVideoSaveDirectory()), + future: bind.mainVideoSaveDirectory(root: false)), initialValue: _autoRecordIncomingSession, onToggle: (v) async { await bind.mainSetOption( diff --git a/flutter/lib/web/bridge.dart b/flutter/lib/web/bridge.dart index 87a478508..668b41268 100644 --- a/flutter/lib/web/bridge.dart +++ b/flutter/lib/web/bridge.dart @@ -943,7 +943,7 @@ class RustdeskImpl { throw UnimplementedError(); } - Future mainDefaultVideoSaveDirectory({dynamic hint}) { + Future mainVideoSaveDirectory({required bool root, dynamic hint}) { throw UnimplementedError(); } diff --git a/libs/scrap/src/common/record.rs b/libs/scrap/src/common/record.rs index 70a2364fd..eecf80b4d 100644 --- a/libs/scrap/src/common/record.rs +++ b/libs/scrap/src/common/record.rs @@ -26,7 +26,7 @@ const MIN_SECS: u64 = 1; pub struct RecorderContext { pub server: bool, pub id: String, - pub default_dir: String, + pub dir: String, pub filename: String, pub width: usize, pub height: usize, @@ -36,18 +36,11 @@ pub struct RecorderContext { impl RecorderContext { pub fn set_filename(&mut self) -> ResultType<()> { - let mut dir = Config::get_option("video-save-directory"); - if !dir.is_empty() { - if !PathBuf::from(&dir).exists() { - std::fs::create_dir_all(&dir)?; - } - } else { - dir = self.default_dir.clone(); - if !dir.is_empty() && !PathBuf::from(&dir).exists() { - std::fs::create_dir_all(&dir)?; - } + if !PathBuf::from(&self.dir).exists() { + std::fs::create_dir_all(&self.dir)?; } - let file = if self.server { "s" } else { "c" }.to_string() + let file = if self.server { "incoming" } else { "outgoing" }.to_string() + + "_" + &self.id.clone() + &chrono::Local::now().format("_%Y%m%d%H%M%S%3f_").to_string() + &self.format.to_string().to_lowercase() @@ -59,7 +52,10 @@ impl RecorderContext { } else { ".mp4" }; - self.filename = PathBuf::from(&dir).join(file).to_string_lossy().to_string(); + self.filename = PathBuf::from(&self.dir) + .join(file) + .to_string_lossy() + .to_string(); log::info!("video will save to {}", self.filename); Ok(()) } diff --git a/src/client.rs b/src/client.rs index 8fb86cfa7..78cb91fcf 100644 --- a/src/client.rs +++ b/src/client.rs @@ -1112,7 +1112,7 @@ impl VideoHandler { self.recorder = Recorder::new(RecorderContext { server: false, id, - default_dir: crate::ui_interface::default_video_save_directory(), + dir: crate::ui_interface::video_save_directory(false), filename: "".to_owned(), width: w as _, height: h as _, diff --git a/src/flutter_ffi.rs b/src/flutter_ffi.rs index cf6e5fef3..6ac3570b2 100644 --- a/src/flutter_ffi.rs +++ b/src/flutter_ffi.rs @@ -1145,8 +1145,8 @@ pub fn main_change_language(lang: String) { send_to_cm(&crate::ipc::Data::Language(lang)); } -pub fn main_default_video_save_directory() -> String { - default_video_save_directory() +pub fn main_video_save_directory(root: bool) -> String { + video_save_directory(root) } pub fn main_set_user_default_option(key: String, value: String) { diff --git a/src/lang/ar.rs b/src/lang/ar.rs index 8eaa1c837..f0ec80aad 100644 --- a/src/lang/ar.rs +++ b/src/lang/ar.rs @@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Follow remote window focus", ""), ("default_proxy_tip", ""), ("no_audio_input_device_tip", ""), + ("Incoming", ""), + ("Outgoing", ""), ].iter().cloned().collect(); } diff --git a/src/lang/bg.rs b/src/lang/bg.rs index e85efb711..3c3025b8b 100644 --- a/src/lang/bg.rs +++ b/src/lang/bg.rs @@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Follow remote window focus", ""), ("default_proxy_tip", ""), ("no_audio_input_device_tip", ""), + ("Incoming", ""), + ("Outgoing", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ca.rs b/src/lang/ca.rs index d23f79e29..c4b54b704 100644 --- a/src/lang/ca.rs +++ b/src/lang/ca.rs @@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Follow remote window focus", ""), ("default_proxy_tip", ""), ("no_audio_input_device_tip", ""), + ("Incoming", ""), + ("Outgoing", ""), ].iter().cloned().collect(); } diff --git a/src/lang/cn.rs b/src/lang/cn.rs index 530522643..a6311f0ed 100644 --- a/src/lang/cn.rs +++ b/src/lang/cn.rs @@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Follow remote window focus", "跟随远程窗口焦点"), ("default_proxy_tip", "默认代理协议及端口为 Socks5 和 1080"), ("no_audio_input_device_tip", "未找到音频输入设备"), + ("Incoming", "被控"), + ("Outgoing", "主控"), ].iter().cloned().collect(); } diff --git a/src/lang/cs.rs b/src/lang/cs.rs index a077f612e..887fe27e2 100644 --- a/src/lang/cs.rs +++ b/src/lang/cs.rs @@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Follow remote window focus", "Sledovat zaměření vzdáleného okna"), ("default_proxy_tip", "Výchozí protokol a port jsou Socks5 a 1080"), ("no_audio_input_device_tip", "Nebylo nalezeno žádné vstupní zvukové zařízení."), + ("Incoming", ""), + ("Outgoing", ""), ].iter().cloned().collect(); } diff --git a/src/lang/da.rs b/src/lang/da.rs index 2aac97595..0916e06da 100644 --- a/src/lang/da.rs +++ b/src/lang/da.rs @@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Follow remote window focus", ""), ("default_proxy_tip", ""), ("no_audio_input_device_tip", ""), + ("Incoming", ""), + ("Outgoing", ""), ].iter().cloned().collect(); } diff --git a/src/lang/de.rs b/src/lang/de.rs index abdda6ff3..24d3ac0f7 100644 --- a/src/lang/de.rs +++ b/src/lang/de.rs @@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Follow remote window focus", "Dem Fokus des entfernten Fensters folgen"), ("default_proxy_tip", ""), ("no_audio_input_device_tip", ""), + ("Incoming", ""), + ("Outgoing", ""), ].iter().cloned().collect(); } diff --git a/src/lang/el.rs b/src/lang/el.rs index 61300e92f..fb0a30075 100644 --- a/src/lang/el.rs +++ b/src/lang/el.rs @@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Follow remote window focus", ""), ("default_proxy_tip", ""), ("no_audio_input_device_tip", ""), + ("Incoming", ""), + ("Outgoing", ""), ].iter().cloned().collect(); } diff --git a/src/lang/eo.rs b/src/lang/eo.rs index 30282bdbd..8bd0a24f1 100644 --- a/src/lang/eo.rs +++ b/src/lang/eo.rs @@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Follow remote window focus", ""), ("default_proxy_tip", ""), ("no_audio_input_device_tip", ""), + ("Incoming", ""), + ("Outgoing", ""), ].iter().cloned().collect(); } diff --git a/src/lang/es.rs b/src/lang/es.rs index c51dc0c97..5e857834b 100644 --- a/src/lang/es.rs +++ b/src/lang/es.rs @@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Follow remote window focus", "Seguir ventana remota activa"), ("default_proxy_tip", ""), ("no_audio_input_device_tip", ""), + ("Incoming", ""), + ("Outgoing", ""), ].iter().cloned().collect(); } diff --git a/src/lang/et.rs b/src/lang/et.rs index 09783fd90..aa438fb1f 100644 --- a/src/lang/et.rs +++ b/src/lang/et.rs @@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Follow remote window focus", ""), ("default_proxy_tip", ""), ("no_audio_input_device_tip", ""), + ("Incoming", ""), + ("Outgoing", ""), ].iter().cloned().collect(); } diff --git a/src/lang/fa.rs b/src/lang/fa.rs index 27a27dd5b..794991f28 100644 --- a/src/lang/fa.rs +++ b/src/lang/fa.rs @@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Follow remote window focus", ""), ("default_proxy_tip", ""), ("no_audio_input_device_tip", ""), + ("Incoming", ""), + ("Outgoing", ""), ].iter().cloned().collect(); } diff --git a/src/lang/fr.rs b/src/lang/fr.rs index 8b118908b..c9e076f4a 100644 --- a/src/lang/fr.rs +++ b/src/lang/fr.rs @@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Follow remote window focus", ""), ("default_proxy_tip", ""), ("no_audio_input_device_tip", ""), + ("Incoming", ""), + ("Outgoing", ""), ].iter().cloned().collect(); } diff --git a/src/lang/he.rs b/src/lang/he.rs index f231ed5ac..4684bfd9a 100644 --- a/src/lang/he.rs +++ b/src/lang/he.rs @@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Follow remote window focus", ""), ("default_proxy_tip", ""), ("no_audio_input_device_tip", ""), + ("Incoming", ""), + ("Outgoing", ""), ].iter().cloned().collect(); } diff --git a/src/lang/hr.rs b/src/lang/hr.rs index ecd5ab52a..0601e0244 100644 --- a/src/lang/hr.rs +++ b/src/lang/hr.rs @@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Follow remote window focus", ""), ("default_proxy_tip", ""), ("no_audio_input_device_tip", ""), + ("Incoming", ""), + ("Outgoing", ""), ].iter().cloned().collect(); } diff --git a/src/lang/hu.rs b/src/lang/hu.rs index b76c4f34d..9b2352937 100644 --- a/src/lang/hu.rs +++ b/src/lang/hu.rs @@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Follow remote window focus", ""), ("default_proxy_tip", ""), ("no_audio_input_device_tip", ""), + ("Incoming", ""), + ("Outgoing", ""), ].iter().cloned().collect(); } diff --git a/src/lang/id.rs b/src/lang/id.rs index 874e64547..35ad2a088 100644 --- a/src/lang/id.rs +++ b/src/lang/id.rs @@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Follow remote window focus", ""), ("default_proxy_tip", ""), ("no_audio_input_device_tip", ""), + ("Incoming", ""), + ("Outgoing", ""), ].iter().cloned().collect(); } diff --git a/src/lang/it.rs b/src/lang/it.rs index 5a8956d44..23896f128 100644 --- a/src/lang/it.rs +++ b/src/lang/it.rs @@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Follow remote window focus", "Segui focus finestra remota"), ("default_proxy_tip", "Protocollo e porta predefiniti sono Socks5 e 1080"), ("no_audio_input_device_tip", "Nessun dispositivo input audio trovato."), + ("Incoming", ""), + ("Outgoing", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ja.rs b/src/lang/ja.rs index ecdeaca6f..fa8105085 100644 --- a/src/lang/ja.rs +++ b/src/lang/ja.rs @@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Follow remote window focus", ""), ("default_proxy_tip", ""), ("no_audio_input_device_tip", ""), + ("Incoming", ""), + ("Outgoing", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ko.rs b/src/lang/ko.rs index 43e8d5983..b024506e1 100644 --- a/src/lang/ko.rs +++ b/src/lang/ko.rs @@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Follow remote window focus", ""), ("default_proxy_tip", ""), ("no_audio_input_device_tip", ""), + ("Incoming", ""), + ("Outgoing", ""), ].iter().cloned().collect(); } diff --git a/src/lang/kz.rs b/src/lang/kz.rs index f2c7874b1..0e4850921 100644 --- a/src/lang/kz.rs +++ b/src/lang/kz.rs @@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Follow remote window focus", ""), ("default_proxy_tip", ""), ("no_audio_input_device_tip", ""), + ("Incoming", ""), + ("Outgoing", ""), ].iter().cloned().collect(); } diff --git a/src/lang/lt.rs b/src/lang/lt.rs index 87895873a..c31c3726d 100644 --- a/src/lang/lt.rs +++ b/src/lang/lt.rs @@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Follow remote window focus", ""), ("default_proxy_tip", ""), ("no_audio_input_device_tip", ""), + ("Incoming", ""), + ("Outgoing", ""), ].iter().cloned().collect(); } diff --git a/src/lang/lv.rs b/src/lang/lv.rs index fccac8de1..fdd64cfe1 100644 --- a/src/lang/lv.rs +++ b/src/lang/lv.rs @@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Follow remote window focus", "Sekot attālā loga fokusam"), ("default_proxy_tip", ""), ("no_audio_input_device_tip", ""), + ("Incoming", ""), + ("Outgoing", ""), ].iter().cloned().collect(); } diff --git a/src/lang/nb.rs b/src/lang/nb.rs index fa79d639a..6cef742af 100644 --- a/src/lang/nb.rs +++ b/src/lang/nb.rs @@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Follow remote window focus", ""), ("default_proxy_tip", ""), ("no_audio_input_device_tip", ""), + ("Incoming", ""), + ("Outgoing", ""), ].iter().cloned().collect(); } diff --git a/src/lang/nl.rs b/src/lang/nl.rs index c5f9c58f7..119a4c8e0 100644 --- a/src/lang/nl.rs +++ b/src/lang/nl.rs @@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Follow remote window focus", "Volg de focus van het venster op afstand"), ("default_proxy_tip", ""), ("no_audio_input_device_tip", ""), + ("Incoming", ""), + ("Outgoing", ""), ].iter().cloned().collect(); } diff --git a/src/lang/pl.rs b/src/lang/pl.rs index ca0b208dd..a7122431a 100644 --- a/src/lang/pl.rs +++ b/src/lang/pl.rs @@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Follow remote window focus", "Podążaj za aktywnością zdalnych okien"), ("default_proxy_tip", ""), ("no_audio_input_device_tip", ""), + ("Incoming", ""), + ("Outgoing", ""), ].iter().cloned().collect(); } diff --git a/src/lang/pt_PT.rs b/src/lang/pt_PT.rs index e1a385213..99bb9f46e 100644 --- a/src/lang/pt_PT.rs +++ b/src/lang/pt_PT.rs @@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Follow remote window focus", ""), ("default_proxy_tip", ""), ("no_audio_input_device_tip", ""), + ("Incoming", ""), + ("Outgoing", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ptbr.rs b/src/lang/ptbr.rs index 838f3f873..677b7f08c 100644 --- a/src/lang/ptbr.rs +++ b/src/lang/ptbr.rs @@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Follow remote window focus", ""), ("default_proxy_tip", ""), ("no_audio_input_device_tip", ""), + ("Incoming", ""), + ("Outgoing", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ro.rs b/src/lang/ro.rs index 46df78d1c..3eddf80d3 100644 --- a/src/lang/ro.rs +++ b/src/lang/ro.rs @@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Follow remote window focus", ""), ("default_proxy_tip", ""), ("no_audio_input_device_tip", ""), + ("Incoming", ""), + ("Outgoing", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ru.rs b/src/lang/ru.rs index 3b7782209..ec9d6bdbf 100644 --- a/src/lang/ru.rs +++ b/src/lang/ru.rs @@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Follow remote window focus", "Следовать за фокусом удалённого окна"), ("default_proxy_tip", ""), ("no_audio_input_device_tip", ""), + ("Incoming", ""), + ("Outgoing", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sk.rs b/src/lang/sk.rs index 705c675cb..9c099fa97 100644 --- a/src/lang/sk.rs +++ b/src/lang/sk.rs @@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Follow remote window focus", "Nasledovať vzdialené zameranie okna"), ("default_proxy_tip", "Predvolený protokol a port sú Socks5 a 1080"), ("no_audio_input_device_tip", "Nenašlo sa žiadne vstupné zvukové zariadenie."), + ("Incoming", ""), + ("Outgoing", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sl.rs b/src/lang/sl.rs index cbc9f0121..241ed6ca8 100755 --- a/src/lang/sl.rs +++ b/src/lang/sl.rs @@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Follow remote window focus", ""), ("default_proxy_tip", ""), ("no_audio_input_device_tip", ""), + ("Incoming", ""), + ("Outgoing", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sq.rs b/src/lang/sq.rs index 213594e63..d323b924d 100644 --- a/src/lang/sq.rs +++ b/src/lang/sq.rs @@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Follow remote window focus", ""), ("default_proxy_tip", ""), ("no_audio_input_device_tip", ""), + ("Incoming", ""), + ("Outgoing", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sr.rs b/src/lang/sr.rs index 7937c0c46..bc4f9c6e9 100644 --- a/src/lang/sr.rs +++ b/src/lang/sr.rs @@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Follow remote window focus", ""), ("default_proxy_tip", ""), ("no_audio_input_device_tip", ""), + ("Incoming", ""), + ("Outgoing", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sv.rs b/src/lang/sv.rs index d607087a6..7466d1a5e 100644 --- a/src/lang/sv.rs +++ b/src/lang/sv.rs @@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Follow remote window focus", ""), ("default_proxy_tip", ""), ("no_audio_input_device_tip", ""), + ("Incoming", ""), + ("Outgoing", ""), ].iter().cloned().collect(); } diff --git a/src/lang/template.rs b/src/lang/template.rs index 9eb0a147f..3e83d16c8 100644 --- a/src/lang/template.rs +++ b/src/lang/template.rs @@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Follow remote window focus", ""), ("default_proxy_tip", ""), ("no_audio_input_device_tip", ""), + ("Incoming", ""), + ("Outgoing", ""), ].iter().cloned().collect(); } diff --git a/src/lang/th.rs b/src/lang/th.rs index 1c256ffb7..dc30f2431 100644 --- a/src/lang/th.rs +++ b/src/lang/th.rs @@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Follow remote window focus", ""), ("default_proxy_tip", ""), ("no_audio_input_device_tip", ""), + ("Incoming", ""), + ("Outgoing", ""), ].iter().cloned().collect(); } diff --git a/src/lang/tr.rs b/src/lang/tr.rs index e42aedfcc..20204388a 100644 --- a/src/lang/tr.rs +++ b/src/lang/tr.rs @@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Follow remote window focus", ""), ("default_proxy_tip", ""), ("no_audio_input_device_tip", ""), + ("Incoming", ""), + ("Outgoing", ""), ].iter().cloned().collect(); } diff --git a/src/lang/tw.rs b/src/lang/tw.rs index 157a76187..571d00261 100644 --- a/src/lang/tw.rs +++ b/src/lang/tw.rs @@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Follow remote window focus", "跟隨遠端視窗焦點"), ("default_proxy_tip", ""), ("no_audio_input_device_tip", ""), + ("Incoming", ""), + ("Outgoing", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ua.rs b/src/lang/ua.rs index 01aee813a..e21f48caf 100644 --- a/src/lang/ua.rs +++ b/src/lang/ua.rs @@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Follow remote window focus", ""), ("default_proxy_tip", ""), ("no_audio_input_device_tip", ""), + ("Incoming", ""), + ("Outgoing", ""), ].iter().cloned().collect(); } diff --git a/src/lang/vn.rs b/src/lang/vn.rs index 103bf3dce..4628aa182 100644 --- a/src/lang/vn.rs +++ b/src/lang/vn.rs @@ -607,5 +607,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Follow remote window focus", ""), ("default_proxy_tip", ""), ("no_audio_input_device_tip", ""), + ("Incoming", ""), + ("Outgoing", ""), ].iter().cloned().collect(); } diff --git a/src/server/video_service.rs b/src/server/video_service.rs index a75b1c5b4..8a66575c4 100644 --- a/src/server/video_service.rs +++ b/src/server/video_service.rs @@ -53,7 +53,7 @@ use scrap::{ codec::{Encoder, EncoderCfg, Quality}, record::{Recorder, RecorderContext}, vpxcodec::{VpxEncoderConfig, VpxVideoCodecId}, - CodecFormat, CodecName, Display, Frame, TraitCapturer, + CodecFormat, Display, Frame, TraitCapturer, }; #[cfg(windows)] use std::sync::Once; @@ -752,6 +752,10 @@ fn get_recorder( codec_format: &CodecFormat, record_incoming: bool, ) -> Arc>> { + #[cfg(windows)] + let root = crate::platform::is_root(); + #[cfg(not(windows))] + let root = false; let recorder = if record_incoming { use crate::hbbs_http::record_upload; @@ -765,7 +769,7 @@ fn get_recorder( Recorder::new(RecorderContext { server: true, id: Config::get_id(), - default_dir: crate::ui_interface::default_video_save_directory(), + dir: crate::ui_interface::video_save_directory(root), filename: "".to_owned(), width, height, diff --git a/src/ui.rs b/src/ui.rs index 39c94e233..813f6d7d1 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -600,8 +600,8 @@ impl UI { get_langs() } - fn default_video_save_directory(&self) -> String { - default_video_save_directory() + fn video_save_directory(&self, root: bool) -> String { + video_save_directory(root) } fn handle_relay_id(&self, id: String) -> String { @@ -723,7 +723,7 @@ impl sciter::EventHandler for UI { fn has_hwcodec(); fn has_vram(); fn get_langs(); - fn default_video_save_directory(); + fn video_save_directory(bool); fn handle_relay_id(String); fn get_login_device_info(); fn support_remove_wallpaper(); diff --git a/src/ui/index.tis b/src/ui/index.tis index 260e23e95..8b57edacb 100644 --- a/src/ui/index.tis +++ b/src/ui/index.tis @@ -248,8 +248,9 @@ class Enhancements: Reactor.Component { } else if (v.indexOf("allow-") == 0) { handler.set_option(v, handler.get_option(v) == 'Y' ? '' : 'Y'); } else if (v == 'screen-recording') { - var dir = handler.get_option("video-save-directory"); - if (!dir) dir = handler.default_video_save_directory(); + var show_root_dir = is_win && handler.is_installed(); + var user_dir = handler.video_save_directory(false); + var root_dir = show_root_dir ? handler.video_save_directory(true) : ""; var ts0 = handler.get_option("enable-record-session") == '' ? { checked: true } : {}; var ts1 = handler.get_option("allow-auto-record-incoming") == 'Y' ? { checked: true } : {}; msgbox("custom-recording", translate('Recording'), @@ -257,7 +258,8 @@ class Enhancements: Reactor.Component {
{translate('Enable recording session')}
{translate('Automatically record incoming sessions')}
-
{translate("Directory")}:  {dir}
+ {show_root_dir ?
{translate("Incoming")}:  {root_dir}
: ""} +
{translate(show_root_dir ? "Outgoing" : "Directory")}:  {user_dir}
diff --git a/src/ui_interface.rs b/src/ui_interface.rs index acc40e49e..e73226fa3 100644 --- a/src/ui_interface.rs +++ b/src/ui_interface.rs @@ -778,7 +778,7 @@ pub fn get_langs() -> String { } #[inline] -pub fn default_video_save_directory() -> String { +pub fn video_save_directory(root: bool) -> String { let appname = crate::get_app_name(); // ui process can show it correctly Once vidoe process created it. let try_create = |path: &std::path::Path| { @@ -792,6 +792,20 @@ pub fn default_video_save_directory() -> String { } }; + if root { + // Currently, only installed windows run as root + #[cfg(windows)] + { + let drive = std::env::var("SystemDrive").unwrap_or("C:".to_owned()); + let dir = + std::path::PathBuf::from(format!("{drive}\\ProgramData\\RustDesk\\recording",)); + return dir.to_string_lossy().to_string(); + } + } + let dir = Config::get_option("video-save-directory"); + if !dir.is_empty() { + return dir; + } #[cfg(any(target_os = "android", target_os = "ios"))] if let Ok(home) = config::APP_HOME_DIR.read() { let mut path = home.to_owned(); @@ -858,7 +872,7 @@ pub fn default_video_save_directory() -> String { return parent.to_string_lossy().to_string(); } } - "".to_owned() + Default::default() } #[inline]