Compare commits
74 Commits
1
.gitignore
vendored
1
.gitignore
vendored
@@ -54,3 +54,4 @@ examples/**/target/
|
|||||||
vcpkg_installed
|
vcpkg_installed
|
||||||
flutter/lib/generated_plugin_registrant.dart
|
flutter/lib/generated_plugin_registrant.dart
|
||||||
libsciter.dylib
|
libsciter.dylib
|
||||||
|
flutter/web/
|
||||||
2
build.py
2
build.py
@@ -283,6 +283,8 @@ def generate_control_file(version):
|
|||||||
system2('/bin/rm -rf %s' % control_file_path)
|
system2('/bin/rm -rf %s' % control_file_path)
|
||||||
|
|
||||||
content = """Package: rustdesk
|
content = """Package: rustdesk
|
||||||
|
Section: net
|
||||||
|
Priority: optional
|
||||||
Version: %s
|
Version: %s
|
||||||
Architecture: %s
|
Architecture: %s
|
||||||
Maintainer: rustdesk <info@rustdesk.com>
|
Maintainer: rustdesk <info@rustdesk.com>
|
||||||
|
|||||||
@@ -1,20 +1,18 @@
|
|||||||
<p align="center">
|
<p align="center">
|
||||||
<img src="../res/logo-header.svg" alt="RustDesk - Ваша віддалена стільниця"><br>
|
<img src="../res/logo-header.svg" alt="RustDesk - Ваша віддалена стільниця"><br>
|
||||||
<a href="#безкоштовні-загальнодоступні-сервери">Сервери</a> •
|
<a href="#публічні-сервери">Сервери</a> •
|
||||||
<a href="#кроки-для-збірки">Збирання</a> •
|
<a href="#кроки-для-збірки">Збирання</a> •
|
||||||
<a href="#як-зібрати-за-допомогою-docker">Docker</a> •
|
<a href="#як-зібрати-за-допомогою-docker">Docker</a> •
|
||||||
<a href="#структура-файлів">Структура</a> •
|
<a href="#структура-файлів">Структура</a> •
|
||||||
<a href="#знімки">Знімки</a><br>
|
<a href="#знімки-екрана">Знімки екрана</a><br>
|
||||||
[<a href="../README.md">English</a>] | [<a href="docs/README-CS.md">česky</a>] | [<a href="docs/README-ZH.md">中文</a>] | [<a href="docs/README-HU.md">Magyar</a>] | [<a href="docs/README-ES.md">Español</a>] | [<a href="docs/README-FA.md">فارسی</a>] | [<a href="docs/README-FR.md">Français</a>] | [<a href="docs/README-DE.md">Deutsch</a>] | [<a href="docs/README-PL.md">Polski</a>] | [<a href="docs/README-ID.md">Indonesian</a>] | [<a href="docs/README-FI.md">Suomi</a>] | [<a href="docs/README-ML.md">മലയാളം</a>] | [<a href="docs/README-JP.md">日本語</a>] | [<a href="docs/README-NL.md">Nederlands</a>] | [<a href="docs/README-IT.md">Italiano</a>] | [<a href="docs/README-RU.md">Русский</a>] | [<a href="docs/README-PTBR.md">Português (Brasil)</a>] | [<a href="docs/README-EO.md">Esperanto</a>] | [<a href="docs/README-KR.md">한국어</a>] | [<a href="docs/README-AR.md">العربي</a>] | [<a href="docs/README-VN.md">Tiếng Việt</a>] | [<a href="docs/README-DA.md">Dansk</a>] | [<a href="docs/README-GR.md">Ελληνικά</a>] | [<a href="docs/README-TR.md">Türkçe</a>]<br>
|
[<a href="../README.md">English</a>] | [<a href="README-CS.md">česky</a>] | [<a href="README-ZH.md">中文</a>] | [<a href="README-HU.md">Magyar</a>] | [<a href="README-ES.md">Español</a>] | [<a href="README-FA.md">فارسی</a>] | [<a href="README-FR.md">Français</a>] | [<a href="README-DE.md">Deutsch</a>] | [<a href="README-PL.md">Polski</a>] | [<a href="README-ID.md">Indonesian</a>] | [<a href="README-FI.md">Suomi</a>] | [<a href="README-ML.md">മലയാളം</a>] | [<a href="README-JP.md">日本語</a>] | [<a href="README-NL.md">Nederlands</a>] | [<a href="README-IT.md">Italiano</a>] | [<a href="README-RU.md">Русский</a>] | [<a href="README-PTBR.md">Português (Brasil)</a>] | [<a href="README-EO.md">Esperanto</a>] | [<a href="README-KR.md">한국어</a>] | [<a href="README-AR.md">العربي</a>] | [<a href="README-VN.md">Tiếng Việt</a>] | [<a href="README-DA.md">Dansk</a>] | [<a href="README-GR.md">Ελληνικά</a>] | [<a href="README-TR.md">Türkçe</a>]<br>
|
||||||
<b>Нам потрібна ваша допомога для перекладу цього README, <a href="https://github.com/rustdesk/rustdesk/tree/master/src/lang">інтерфейсу</a> та <a href="https://github.com/rustdesk/doc.rustdesk.com">документації</a> RustDesk на вашу рідну мову</B>
|
<b>Нам потрібна ваша допомога для перекладу цього README, <a href="https://github.com/rustdesk/rustdesk/tree/master/src/lang">інтерфейсу</a> та <a href="https://github.com/rustdesk/doc.rustdesk.com">документації</a> RustDesk вашою рідною мовою</B>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
Спілкування з нами: [Discord](https://discord.gg/nDceKgxnkV) | [Twitter](https://twitter.com/rustdesk) | [Reddit](https://www.reddit.com/r/rustdesk)
|
Спілкування з нами: [Discord](https://discord.gg/nDceKgxnkV) | [Twitter](https://twitter.com/rustdesk) | [Reddit](https://www.reddit.com/r/rustdesk)
|
||||||
|
|
||||||
[](https://ko-fi.com/I2I04VU09)
|
[](https://ko-fi.com/I2I04VU09)
|
||||||
|
|
||||||
[](https://console.algora.io/org/rustdesk/bounties?status=open)
|
|
||||||
|
|
||||||
Ще один застосунок для віддаленого керування стільницею, написаний на Rust. Працює з коробки, не потребує налаштування. Ви повністю контролюєте свої дані, не турбуючись про безпеку. Ви можете використовувати наш сервер ретрансляції, [налаштувати свій власний](https://rustdesk.com/server), або [написати свій власний сервер ретрансляції](https://github.com/rustdesk/rustdesk-server-demo).
|
Ще один застосунок для віддаленого керування стільницею, написаний на Rust. Працює з коробки, не потребує налаштування. Ви повністю контролюєте свої дані, не турбуючись про безпеку. Ви можете використовувати наш сервер ретрансляції, [налаштувати свій власний](https://rustdesk.com/server), або [написати свій власний сервер ретрансляції](https://github.com/rustdesk/rustdesk-server-demo).
|
||||||
|
|
||||||

|

|
||||||
@@ -61,19 +59,19 @@ RustDesk вітає внесок кожного. Ознайомтеся з [CONT
|
|||||||
```sh
|
```sh
|
||||||
sudo apt install -y zip g++ gcc git curl wget nasm yasm libgtk-3-dev clang libxcb-randr0-dev libxdo-dev \
|
sudo apt install -y zip g++ gcc git curl wget nasm yasm libgtk-3-dev clang libxcb-randr0-dev libxdo-dev \
|
||||||
libxfixes-dev libxcb-shape0-dev libxcb-xfixes0-dev libasound2-dev libpulse-dev cmake make \
|
libxfixes-dev libxcb-shape0-dev libxcb-xfixes0-dev libasound2-dev libpulse-dev cmake make \
|
||||||
libclang-dev ninja-build libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev
|
libclang-dev ninja-build libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libpam0g-dev
|
||||||
```
|
```
|
||||||
|
|
||||||
### openSUSE Tumbleweed
|
### openSUSE Tumbleweed
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
sudo zypper install gcc-c++ git curl wget nasm yasm gcc gtk3-devel clang libxcb-devel libXfixes-devel cmake alsa-lib-devel gstreamer-devel gstreamer-plugins-base-devel xdotool-devel
|
sudo zypper install gcc-c++ git curl wget nasm yasm gcc gtk3-devel clang libxcb-devel libXfixes-devel cmake alsa-lib-devel gstreamer-devel gstreamer-plugins-base-devel xdotool-devel pam-devel
|
||||||
```
|
```
|
||||||
|
|
||||||
### Fedora 28 (CentOS 8)
|
### Fedora 28 (CentOS 8)
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
sudo yum -y install gcc-c++ git curl wget nasm yasm gcc gtk3-devel clang libxcb-devel libxdo-devel libXfixes-devel pulseaudio-libs-devel cmake alsa-lib-devel
|
sudo yum -y install gcc-c++ git curl wget nasm yasm gcc gtk3-devel clang libxcb-devel libxdo-devel libXfixes-devel pulseaudio-libs-devel cmake alsa-lib-devel gstreamer1-devel gstreamer1-plugins-base-devel pam-devel
|
||||||
```
|
```
|
||||||
|
|
||||||
### Arch (Manjaro)
|
### Arch (Manjaro)
|
||||||
@@ -158,18 +156,22 @@ target/release/rustdesk
|
|||||||
- **[libs/clipboard](https://github.com/rustdesk/rustdesk/tree/master/libs/clipboard)**: реалізація копіювання та вставлення файлів для Windows, Linux, macOS.
|
- **[libs/clipboard](https://github.com/rustdesk/rustdesk/tree/master/libs/clipboard)**: реалізація копіювання та вставлення файлів для Windows, Linux, macOS.
|
||||||
- **[src/ui](https://github.com/rustdesk/rustdesk/tree/master/src/ui)**: графічний інтерфейс користувача
|
- **[src/ui](https://github.com/rustdesk/rustdesk/tree/master/src/ui)**: графічний інтерфейс користувача
|
||||||
- **[src/server](https://github.com/rustdesk/rustdesk/tree/master/src/server)**: сервіси аудіо/буфера обміну/вводу/відео та мережевих підключень
|
- **[src/server](https://github.com/rustdesk/rustdesk/tree/master/src/server)**: сервіси аудіо/буфера обміну/вводу/відео та мережевих підключень
|
||||||
- **[src/client.rs](https://github.com/rustdesk/rustdesk/tree/master/src/client.rs)**: однорангове з'єднання
|
- **[src/client.rs](https://github.com/rustdesk/rustdesk/tree/master/src/client.rs)**: однорангове зʼєднання
|
||||||
- **[src/rendezvous_mediator.rs](https://github.com/rustdesk/rustdesk/tree/master/src/rendezvous_mediator.rs)**: комунікація з [rustdesk-server](https://github.com/rustdesk/rustdesk-server), очікування віддаленого прямого (обхід TCP NAT) або ретрансльованого з'єднання
|
- **[src/rendezvous_mediator.rs](https://github.com/rustdesk/rustdesk/tree/master/src/rendezvous_mediator.rs)**: комунікація з [rustdesk-server](https://github.com/rustdesk/rustdesk-server), очікування віддаленого прямого (обхід TCP NAT) або ретрансльованого зʼєднання
|
||||||
- **[src/platform](https://github.com/rustdesk/rustdesk/tree/master/src/platform)**: специфічний для платформи код
|
- **[src/platform](https://github.com/rustdesk/rustdesk/tree/master/src/platform)**: специфічний для платформи код
|
||||||
- **[flutter](https://github.com/rustdesk/rustdesk/tree/master/flutter)**: код Flutter для мобільних пристроїв
|
- **[flutter](https://github.com/rustdesk/rustdesk/tree/master/flutter)**: код Flutter для мобільних пристроїв
|
||||||
- **[flutter/web/js](https://github.com/rustdesk/rustdesk/tree/master/flutter/web/js)**: JavaScript для Flutter веб клієнту
|
- **[flutter/web/js](https://github.com/rustdesk/rustdesk/tree/master/flutter/web/js)**: JavaScript для веб клієнта на Flutter
|
||||||
|
|
||||||
## Знімки
|
## Знімки екрана
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
## [Публічні сервери](#публічні-сервери)
|
||||||
|
|
||||||
|
RustDesk підтримується безкоштовним європейським сервером, любʼязно наданим [Codext GmbH](https://codext.link/rustdesk?utm_source=github)
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
"sources": [
|
"sources": [
|
||||||
{
|
{
|
||||||
"type": "archive",
|
"type": "archive",
|
||||||
"url": "https://github.com/linux-pam/linux-pam/releases/download/v1.3.2/Linux-PAM-1.3.2.tar.xz",
|
"url": "https://github.com/linux-pam/linux-pam/releases/download/v1.3.1/Linux-PAM-1.3.1.tar.xz",
|
||||||
"sha256": "eff47a4ecd833fbf18de9686632a70ee8d0794b79aecb217ebd0ce11db4cd0db"
|
"sha256": "eff47a4ecd833fbf18de9686632a70ee8d0794b79aecb217ebd0ce11db4cd0db"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
1
flutter/assets/message_24dp_5F6368.svg
Normal file
1
flutter/assets/message_24dp_5F6368.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="-4 -4 32 32" width="24px" fill="#5f6368"><path d="M0 0h24v24H0z" fill="none"/><path d="M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-2 12H6v-2h12v2zm0-3H6V9h12v2zm0-3H6V6h12v2z"/></svg>
|
||||||
|
After Width: | Height: | Size: 277 B |
@@ -30,6 +30,7 @@ import 'common/widgets/overlay.dart';
|
|||||||
import 'mobile/pages/file_manager_page.dart';
|
import 'mobile/pages/file_manager_page.dart';
|
||||||
import 'mobile/pages/remote_page.dart';
|
import 'mobile/pages/remote_page.dart';
|
||||||
import 'desktop/pages/remote_page.dart' as desktop_remote;
|
import 'desktop/pages/remote_page.dart' as desktop_remote;
|
||||||
|
import 'desktop/pages/file_manager_page.dart' as desktop_file_manager;
|
||||||
import 'package:flutter_hbb/desktop/widgets/remote_toolbar.dart';
|
import 'package:flutter_hbb/desktop/widgets/remote_toolbar.dart';
|
||||||
import 'models/model.dart';
|
import 'models/model.dart';
|
||||||
import 'models/platform_model.dart';
|
import 'models/platform_model.dart';
|
||||||
@@ -554,7 +555,7 @@ class MyTheme {
|
|||||||
return themeModeFromString(bind.mainGetLocalOption(key: kCommConfKeyTheme));
|
return themeModeFromString(bind.mainGetLocalOption(key: kCommConfKeyTheme));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void changeDarkMode(ThemeMode mode) async {
|
static Future<void> changeDarkMode(ThemeMode mode) async {
|
||||||
Get.changeThemeMode(mode);
|
Get.changeThemeMode(mode);
|
||||||
if (desktopType == DesktopType.main || isAndroid || isIOS || isWeb) {
|
if (desktopType == DesktopType.main || isAndroid || isIOS || isWeb) {
|
||||||
if (mode == ThemeMode.system) {
|
if (mode == ThemeMode.system) {
|
||||||
@@ -680,10 +681,12 @@ closeConnection({String? id}) {
|
|||||||
overlays: SystemUiOverlay.values);
|
overlays: SystemUiOverlay.values);
|
||||||
gFFI.chatModel.hideChatOverlay();
|
gFFI.chatModel.hideChatOverlay();
|
||||||
Navigator.popUntil(globalKey.currentContext!, ModalRoute.withName("/"));
|
Navigator.popUntil(globalKey.currentContext!, ModalRoute.withName("/"));
|
||||||
|
stateGlobal.isInMainPage = true;
|
||||||
}();
|
}();
|
||||||
} else {
|
} else {
|
||||||
if (isWeb) {
|
if (isWeb) {
|
||||||
Navigator.popUntil(globalKey.currentContext!, ModalRoute.withName("/"));
|
Navigator.popUntil(globalKey.currentContext!, ModalRoute.withName("/"));
|
||||||
|
stateGlobal.isInMainPage = true;
|
||||||
} else {
|
} else {
|
||||||
final controller = Get.find<DesktopTabController>();
|
final controller = Get.find<DesktopTabController>();
|
||||||
controller.closeBy(id);
|
controller.closeBy(id);
|
||||||
@@ -2035,6 +2038,8 @@ Future<bool> restoreWindowPosition(WindowType type,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var webInitialLink = "";
|
||||||
|
|
||||||
/// Initialize uni links for macos/windows
|
/// Initialize uni links for macos/windows
|
||||||
///
|
///
|
||||||
/// [Availability]
|
/// [Availability]
|
||||||
@@ -2051,7 +2056,12 @@ Future<bool> initUniLinks() async {
|
|||||||
if (initialLink == null || initialLink.isEmpty) {
|
if (initialLink == null || initialLink.isEmpty) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (isWeb) {
|
||||||
|
webInitialLink = initialLink;
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
return handleUriLink(uriString: initialLink);
|
return handleUriLink(uriString: initialLink);
|
||||||
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
debugPrintStack(label: "$err");
|
debugPrintStack(label: "$err");
|
||||||
return false;
|
return false;
|
||||||
@@ -2064,7 +2074,7 @@ Future<bool> initUniLinks() async {
|
|||||||
///
|
///
|
||||||
/// Returns a [StreamSubscription] which can listen the uni links.
|
/// Returns a [StreamSubscription] which can listen the uni links.
|
||||||
StreamSubscription? listenUniLinks({handleByFlutter = true}) {
|
StreamSubscription? listenUniLinks({handleByFlutter = true}) {
|
||||||
if (isLinux) {
|
if (isLinux || isWeb) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2368,11 +2378,25 @@ connect(BuildContext context, String id,
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (isFileTransfer) {
|
if (isFileTransfer) {
|
||||||
|
if (isAndroid) {
|
||||||
if (!await AndroidPermissionManager.check(kManageExternalStorage)) {
|
if (!await AndroidPermissionManager.check(kManageExternalStorage)) {
|
||||||
if (!await AndroidPermissionManager.request(kManageExternalStorage)) {
|
if (!await AndroidPermissionManager.request(kManageExternalStorage)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (isWeb) {
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (BuildContext context) =>
|
||||||
|
desktop_file_manager.FileManagerPage(
|
||||||
|
id: id,
|
||||||
|
password: password,
|
||||||
|
isSharedPassword: isSharedPassword),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
@@ -2380,8 +2404,9 @@ connect(BuildContext context, String id,
|
|||||||
id: id, password: password, isSharedPassword: isSharedPassword),
|
id: id, password: password, isSharedPassword: isSharedPassword),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (isWebDesktop) {
|
if (isWeb) {
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
@@ -2405,6 +2430,7 @@ connect(BuildContext context, String id,
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
stateGlobal.isInMainPage = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
FocusScopeNode currentFocus = FocusScope.of(context);
|
FocusScopeNode currentFocus = FocusScope.of(context);
|
||||||
@@ -3158,6 +3184,9 @@ importConfig(List<TextEditingController>? controllers, List<RxString>? errMsgs,
|
|||||||
if (text != null && text.isNotEmpty) {
|
if (text != null && text.isNotEmpty) {
|
||||||
try {
|
try {
|
||||||
final sc = ServerConfig.decode(text);
|
final sc = ServerConfig.decode(text);
|
||||||
|
if (isWeb || isIOS) {
|
||||||
|
sc.relayServer = '';
|
||||||
|
}
|
||||||
if (sc.idServer.isNotEmpty) {
|
if (sc.idServer.isNotEmpty) {
|
||||||
Future<bool> success = setServerConfig(controllers, errMsgs, sc);
|
Future<bool> success = setServerConfig(controllers, errMsgs, sc);
|
||||||
success.then((value) {
|
success.then((value) {
|
||||||
@@ -3597,3 +3626,7 @@ List<SubWindowResizeEdge>? get subWindowManagerEnableResizeEdges => isWindows
|
|||||||
SubWindowResizeEdge.topRight,
|
SubWindowResizeEdge.topRight,
|
||||||
]
|
]
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
|
void earlyAssert() {
|
||||||
|
assert('\1' == '1');
|
||||||
|
}
|
||||||
|
|||||||
38
flutter/lib/common/widgets/connection_page_title.dart
Normal file
38
flutter/lib/common/widgets/connection_page_title.dart
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
import 'package:auto_size_text/auto_size_text.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
|
import '../../common.dart';
|
||||||
|
|
||||||
|
Widget getConnectionPageTitle(BuildContext context, bool isWeb) {
|
||||||
|
return Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
AutoSizeText(
|
||||||
|
translate('Control Remote Desktop'),
|
||||||
|
maxLines: 1,
|
||||||
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.titleLarge
|
||||||
|
?.merge(TextStyle(height: 1)),
|
||||||
|
).marginOnly(right: 4),
|
||||||
|
Tooltip(
|
||||||
|
waitDuration: Duration(milliseconds: 300),
|
||||||
|
message: translate(isWeb ? "web_id_input_tip" : "id_input_tip"),
|
||||||
|
child: Icon(
|
||||||
|
Icons.help_outline_outlined,
|
||||||
|
size: 16,
|
||||||
|
color: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.titleLarge
|
||||||
|
?.color
|
||||||
|
?.withOpacity(0.5),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -58,27 +58,33 @@ class _PeerCardState extends State<_PeerCard>
|
|||||||
stateGlobal.isPortrait.isTrue ? _buildPortrait() : _buildLandscape());
|
stateGlobal.isPortrait.isTrue ? _buildPortrait() : _buildLandscape());
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildPortrait() {
|
Widget gestureDetector({required Widget child}) {
|
||||||
final peer = super.widget.peer;
|
|
||||||
final PeerTabModel peerTabModel = Provider.of(context);
|
final PeerTabModel peerTabModel = Provider.of(context);
|
||||||
return Card(
|
final peer = super.widget.peer;
|
||||||
margin: EdgeInsets.symmetric(horizontal: 2),
|
return GestureDetector(
|
||||||
child: GestureDetector(
|
onDoubleTap: peerTabModel.multiSelectionMode
|
||||||
|
? null
|
||||||
|
: () => widget.connect(context, peer.id),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
if (peerTabModel.multiSelectionMode) {
|
if (peerTabModel.multiSelectionMode) {
|
||||||
peerTabModel.select(peer);
|
peerTabModel.select(peer);
|
||||||
} else {
|
} else {
|
||||||
if (!isWebDesktop) {
|
if (isMobile) {
|
||||||
connectInPeerTab(context, peer, widget.tab);
|
widget.connect(context, peer.id);
|
||||||
}
|
} else {
|
||||||
}
|
|
||||||
},
|
|
||||||
onDoubleTap: isWebDesktop
|
|
||||||
? () => connectInPeerTab(context, peer, widget.tab)
|
|
||||||
: null,
|
|
||||||
onLongPress: () {
|
|
||||||
peerTabModel.select(peer);
|
peerTabModel.select(peer);
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
onLongPress: () => peerTabModel.select(peer),
|
||||||
|
child: child);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildPortrait() {
|
||||||
|
final peer = super.widget.peer;
|
||||||
|
return Card(
|
||||||
|
margin: EdgeInsets.symmetric(horizontal: 2),
|
||||||
|
child: gestureDetector(
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: EdgeInsets.only(left: 12, top: 8, bottom: 8),
|
padding: EdgeInsets.only(left: 12, top: 8, bottom: 8),
|
||||||
child: _buildPeerTile(context, peer, null)),
|
child: _buildPeerTile(context, peer, null)),
|
||||||
@@ -86,7 +92,6 @@ class _PeerCardState extends State<_PeerCard>
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildLandscape() {
|
Widget _buildLandscape() {
|
||||||
final PeerTabModel peerTabModel = Provider.of(context);
|
|
||||||
final peer = super.widget.peer;
|
final peer = super.widget.peer;
|
||||||
var deco = Rx<BoxDecoration?>(
|
var deco = Rx<BoxDecoration?>(
|
||||||
BoxDecoration(
|
BoxDecoration(
|
||||||
@@ -115,30 +120,21 @@ class _PeerCardState extends State<_PeerCard>
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
child: GestureDetector(
|
child: gestureDetector(
|
||||||
onDoubleTap:
|
|
||||||
peerTabModel.multiSelectionMode || peerTabModel.isShiftDown
|
|
||||||
? null
|
|
||||||
: () => widget.connect(context, peer.id),
|
|
||||||
onTap: () => peerTabModel.select(peer),
|
|
||||||
onLongPress: () => peerTabModel.select(peer),
|
|
||||||
child: Obx(() => peerCardUiType.value == PeerUiType.grid
|
child: Obx(() => peerCardUiType.value == PeerUiType.grid
|
||||||
? _buildPeerCard(context, peer, deco)
|
? _buildPeerCard(context, peer, deco)
|
||||||
: _buildPeerTile(context, peer, deco))),
|
: _buildPeerTile(context, peer, deco))),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildPeerTile(
|
makeChild(bool isPortrait, Peer peer) {
|
||||||
BuildContext context, Peer peer, Rx<BoxDecoration?>? deco) {
|
|
||||||
hideUsernameOnCard ??=
|
|
||||||
bind.mainGetBuildinOption(key: kHideUsernameOnCard) == 'Y';
|
|
||||||
final name = hideUsernameOnCard == true
|
final name = hideUsernameOnCard == true
|
||||||
? peer.hostname
|
? peer.hostname
|
||||||
: '${peer.username}${peer.username.isNotEmpty && peer.hostname.isNotEmpty ? '@' : ''}${peer.hostname}';
|
: '${peer.username}${peer.username.isNotEmpty && peer.hostname.isNotEmpty ? '@' : ''}${peer.hostname}';
|
||||||
final greyStyle = TextStyle(
|
final greyStyle = TextStyle(
|
||||||
fontSize: 11,
|
fontSize: 11,
|
||||||
color: Theme.of(context).textTheme.titleLarge?.color?.withOpacity(0.6));
|
color: Theme.of(context).textTheme.titleLarge?.color?.withOpacity(0.6));
|
||||||
makeChild(bool isPortrait) => Row(
|
return Row(
|
||||||
mainAxisSize: MainAxisSize.max,
|
mainAxisSize: MainAxisSize.max,
|
||||||
children: [
|
children: [
|
||||||
Container(
|
Container(
|
||||||
@@ -210,6 +206,12 @@ class _PeerCardState extends State<_PeerCard>
|
|||||||
)
|
)
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildPeerTile(
|
||||||
|
BuildContext context, Peer peer, Rx<BoxDecoration?>? deco) {
|
||||||
|
hideUsernameOnCard ??=
|
||||||
|
bind.mainGetBuildinOption(key: kHideUsernameOnCard) == 'Y';
|
||||||
final colors = _frontN(peer.tags, 25)
|
final colors = _frontN(peer.tags, 25)
|
||||||
.map((e) => gFFI.abModel.getCurrentAbTagColor(e))
|
.map((e) => gFFI.abModel.getCurrentAbTagColor(e))
|
||||||
.toList();
|
.toList();
|
||||||
@@ -220,11 +222,12 @@ class _PeerCardState extends State<_PeerCard>
|
|||||||
? '${translate('Tags')}: ${peer.tags.join(', ')}'
|
? '${translate('Tags')}: ${peer.tags.join(', ')}'
|
||||||
: '',
|
: '',
|
||||||
child: Stack(children: [
|
child: Stack(children: [
|
||||||
Obx(() => deco == null
|
Obx(
|
||||||
? makeChild(stateGlobal.isPortrait.isTrue)
|
() => deco == null
|
||||||
|
? makeChild(stateGlobal.isPortrait.isTrue, peer)
|
||||||
: Container(
|
: Container(
|
||||||
foregroundDecoration: deco.value,
|
foregroundDecoration: deco.value,
|
||||||
child: makeChild(stateGlobal.isPortrait.isTrue),
|
child: makeChild(stateGlobal.isPortrait.isTrue, peer),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (colors.isNotEmpty)
|
if (colors.isNotEmpty)
|
||||||
@@ -876,7 +879,7 @@ class RecentPeerCard extends BasePeerCard {
|
|||||||
BuildContext context) async {
|
BuildContext context) async {
|
||||||
final List<MenuEntryBase<String>> menuItems = [
|
final List<MenuEntryBase<String>> menuItems = [
|
||||||
_connectAction(context),
|
_connectAction(context),
|
||||||
if (!isWeb) _transferFileAction(context),
|
_transferFileAction(context),
|
||||||
];
|
];
|
||||||
|
|
||||||
final List favs = (await bind.mainGetFav()).toList();
|
final List favs = (await bind.mainGetFav()).toList();
|
||||||
@@ -935,7 +938,7 @@ class FavoritePeerCard extends BasePeerCard {
|
|||||||
BuildContext context) async {
|
BuildContext context) async {
|
||||||
final List<MenuEntryBase<String>> menuItems = [
|
final List<MenuEntryBase<String>> menuItems = [
|
||||||
_connectAction(context),
|
_connectAction(context),
|
||||||
if (!isWeb) _transferFileAction(context),
|
_transferFileAction(context),
|
||||||
];
|
];
|
||||||
if (isDesktop && peer.platform != kPeerPlatformAndroid) {
|
if (isDesktop && peer.platform != kPeerPlatformAndroid) {
|
||||||
menuItems.add(_tcpTunnelingAction(context));
|
menuItems.add(_tcpTunnelingAction(context));
|
||||||
@@ -988,7 +991,7 @@ class DiscoveredPeerCard extends BasePeerCard {
|
|||||||
BuildContext context) async {
|
BuildContext context) async {
|
||||||
final List<MenuEntryBase<String>> menuItems = [
|
final List<MenuEntryBase<String>> menuItems = [
|
||||||
_connectAction(context),
|
_connectAction(context),
|
||||||
if (!isWeb) _transferFileAction(context),
|
_transferFileAction(context),
|
||||||
];
|
];
|
||||||
|
|
||||||
final List favs = (await bind.mainGetFav()).toList();
|
final List favs = (await bind.mainGetFav()).toList();
|
||||||
@@ -1041,7 +1044,7 @@ class AddressBookPeerCard extends BasePeerCard {
|
|||||||
BuildContext context) async {
|
BuildContext context) async {
|
||||||
final List<MenuEntryBase<String>> menuItems = [
|
final List<MenuEntryBase<String>> menuItems = [
|
||||||
_connectAction(context),
|
_connectAction(context),
|
||||||
if (!isWeb) _transferFileAction(context),
|
_transferFileAction(context),
|
||||||
];
|
];
|
||||||
if (isDesktop && peer.platform != kPeerPlatformAndroid) {
|
if (isDesktop && peer.platform != kPeerPlatformAndroid) {
|
||||||
menuItems.add(_tcpTunnelingAction(context));
|
menuItems.add(_tcpTunnelingAction(context));
|
||||||
@@ -1173,7 +1176,7 @@ class MyGroupPeerCard extends BasePeerCard {
|
|||||||
BuildContext context) async {
|
BuildContext context) async {
|
||||||
final List<MenuEntryBase<String>> menuItems = [
|
final List<MenuEntryBase<String>> menuItems = [
|
||||||
_connectAction(context),
|
_connectAction(context),
|
||||||
if (!isWeb) _transferFileAction(context),
|
_transferFileAction(context),
|
||||||
];
|
];
|
||||||
if (isDesktop && peer.platform != kPeerPlatformAndroid) {
|
if (isDesktop && peer.platform != kPeerPlatformAndroid) {
|
||||||
menuItems.add(_tcpTunnelingAction(context));
|
menuItems.add(_tcpTunnelingAction(context));
|
||||||
@@ -1271,9 +1274,8 @@ void _rdpDialog(String id) async {
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: TextField(
|
child: TextField(
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: isDesktop
|
labelText:
|
||||||
? null
|
isDesktop ? null : translate('Username')),
|
||||||
: translate('Username')),
|
|
||||||
controller: userController,
|
controller: userController,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -1294,11 +1296,11 @@ void _rdpDialog(String id) async {
|
|||||||
obscureText: secure.value,
|
obscureText: secure.value,
|
||||||
maxLength: maxLength,
|
maxLength: maxLength,
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: isDesktop
|
labelText:
|
||||||
? null
|
isDesktop ? null : translate('Password'),
|
||||||
: translate('Password'),
|
|
||||||
suffixIcon: IconButton(
|
suffixIcon: IconButton(
|
||||||
onPressed: () => secure.value = !secure.value,
|
onPressed: () =>
|
||||||
|
secure.value = !secure.value,
|
||||||
icon: Icon(secure.value
|
icon: Icon(secure.value
|
||||||
? Icons.visibility_off
|
? Icons.visibility_off
|
||||||
: Icons.visibility))),
|
: Icons.visibility))),
|
||||||
|
|||||||
@@ -332,7 +332,12 @@ class _PeersViewState extends State<_PeersView>
|
|||||||
_queryOnlines(false);
|
_queryOnlines(false);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (_isActive && (_queryCount < _maxQueryCount || !p)) {
|
final skipIfIsWeb =
|
||||||
|
isWeb && !(stateGlobal.isWebVisible && stateGlobal.isInMainPage);
|
||||||
|
final skipIfMobile =
|
||||||
|
(isAndroid || isIOS) && !stateGlobal.isInMainPage;
|
||||||
|
final skipIfNotActive = skipIfIsWeb || skipIfMobile || !_isActive;
|
||||||
|
if (!skipIfNotActive && (_queryCount < _maxQueryCount || !p)) {
|
||||||
if (now.difference(_lastQueryTime) >= _queryInterval) {
|
if (now.difference(_lastQueryTime) >= _queryInterval) {
|
||||||
if (_curPeers.isNotEmpty) {
|
if (_curPeers.isNotEmpty) {
|
||||||
bind.queryOnlines(ids: _curPeers.toList(growable: false));
|
bind.queryOnlines(ids: _curPeers.toList(growable: false));
|
||||||
|
|||||||
@@ -201,7 +201,7 @@ const double kMinFps = 5;
|
|||||||
const double kDefaultFps = 30;
|
const double kDefaultFps = 30;
|
||||||
const double kMaxFps = 120;
|
const double kMaxFps = 120;
|
||||||
|
|
||||||
const double kMinQuality = 10;
|
const double kMinQuality = 5;
|
||||||
const double kDefaultQuality = 50;
|
const double kDefaultQuality = 50;
|
||||||
const double kMaxQuality = 100;
|
const double kMaxQuality = 100;
|
||||||
const double kMaxMoreQuality = 2000;
|
const double kMaxMoreQuality = 2000;
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:auto_size_text/auto_size_text.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_hbb/common/widgets/connection_page_title.dart';
|
||||||
import 'package:flutter_hbb/consts.dart';
|
import 'package:flutter_hbb/consts.dart';
|
||||||
import 'package:flutter_hbb/models/state_model.dart';
|
import 'package:flutter_hbb/models/state_model.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
@@ -323,36 +323,7 @@ class _ConnectionPageState extends State<ConnectionPage>
|
|||||||
child: Ink(
|
child: Ink(
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
Row(
|
getConnectionPageTitle(context, false).marginOnly(bottom: 15),
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
AutoSizeText(
|
|
||||||
translate('Control Remote Desktop'),
|
|
||||||
maxLines: 1,
|
|
||||||
style: Theme.of(context)
|
|
||||||
.textTheme
|
|
||||||
.titleLarge
|
|
||||||
?.merge(TextStyle(height: 1)),
|
|
||||||
).marginOnly(right: 4),
|
|
||||||
Tooltip(
|
|
||||||
waitDuration: Duration(milliseconds: 300),
|
|
||||||
message: translate("id_input_tip"),
|
|
||||||
child: Icon(
|
|
||||||
Icons.help_outline_outlined,
|
|
||||||
size: 16,
|
|
||||||
color: Theme.of(context)
|
|
||||||
.textTheme
|
|
||||||
.titleLarge
|
|
||||||
?.color
|
|
||||||
?.withOpacity(0.5),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
)),
|
|
||||||
],
|
|
||||||
).marginOnly(bottom: 15),
|
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
|
|||||||
@@ -369,8 +369,8 @@ class _GeneralState extends State<_General> {
|
|||||||
|
|
||||||
Widget theme() {
|
Widget theme() {
|
||||||
final current = MyTheme.getThemeModePreference().toShortString();
|
final current = MyTheme.getThemeModePreference().toShortString();
|
||||||
onChanged(String value) {
|
onChanged(String value) async {
|
||||||
MyTheme.changeDarkMode(MyTheme.themeModeFromString(value));
|
await MyTheme.changeDarkMode(MyTheme.themeModeFromString(value));
|
||||||
setState(() {});
|
setState(() {});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1451,6 +1451,7 @@ class _NetworkState extends State<_Network> with AutomaticKeepAliveClientMixin {
|
|||||||
children: [
|
children: [
|
||||||
Obx(() => _LabeledTextField(context, 'ID Server', idController,
|
Obx(() => _LabeledTextField(context, 'ID Server', idController,
|
||||||
idErrMsg.value, enabled, secure)),
|
idErrMsg.value, enabled, secure)),
|
||||||
|
if (!isWeb)
|
||||||
Obx(() => _LabeledTextField(context, 'Relay Server',
|
Obx(() => _LabeledTextField(context, 'Relay Server',
|
||||||
relayController, relayErrMsg.value, enabled, secure)),
|
relayController, relayErrMsg.value, enabled, secure)),
|
||||||
Obx(() => _LabeledTextField(context, 'API Server',
|
Obx(() => _LabeledTextField(context, 'API Server',
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ import 'package:flutter_hbb/models/file_model.dart';
|
|||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:wakelock_plus/wakelock_plus.dart';
|
import 'package:wakelock_plus/wakelock_plus.dart';
|
||||||
|
import 'package:flutter_hbb/web/dummy.dart'
|
||||||
|
if (dart.library.html) 'package:flutter_hbb/web/web_unique.dart';
|
||||||
|
|
||||||
import '../../consts.dart';
|
import '../../consts.dart';
|
||||||
import '../../desktop/widgets/material_mod_popup_menu.dart' as mod_menu;
|
import '../../desktop/widgets/material_mod_popup_menu.dart' as mod_menu;
|
||||||
@@ -55,14 +57,14 @@ class FileManagerPage extends StatefulWidget {
|
|||||||
required this.id,
|
required this.id,
|
||||||
required this.password,
|
required this.password,
|
||||||
required this.isSharedPassword,
|
required this.isSharedPassword,
|
||||||
required this.tabController,
|
this.tabController,
|
||||||
this.forceRelay})
|
this.forceRelay})
|
||||||
: super(key: key);
|
: super(key: key);
|
||||||
final String id;
|
final String id;
|
||||||
final String? password;
|
final String? password;
|
||||||
final bool? isSharedPassword;
|
final bool? isSharedPassword;
|
||||||
final bool? forceRelay;
|
final bool? forceRelay;
|
||||||
final DesktopTabController tabController;
|
final DesktopTabController? tabController;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<StatefulWidget> createState() => _FileManagerPageState();
|
State<StatefulWidget> createState() => _FileManagerPageState();
|
||||||
@@ -97,11 +99,14 @@ class _FileManagerPageState extends State<FileManagerPage>
|
|||||||
if (!isLinux) {
|
if (!isLinux) {
|
||||||
WakelockPlus.enable();
|
WakelockPlus.enable();
|
||||||
}
|
}
|
||||||
|
if (isWeb) {
|
||||||
|
_ffi.ffiModel.updateEventListener(_ffi.sessionId, widget.id);
|
||||||
|
}
|
||||||
debugPrint("File manager page init success with id ${widget.id}");
|
debugPrint("File manager page init success with id ${widget.id}");
|
||||||
_ffi.dialogManager.setOverlayState(_overlayKeyState);
|
_ffi.dialogManager.setOverlayState(_overlayKeyState);
|
||||||
// Call onSelected in post frame callback, since we cannot guarantee that the callback will not call setState.
|
// Call onSelected in post frame callback, since we cannot guarantee that the callback will not call setState.
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
widget.tabController.onSelected?.call(widget.id);
|
widget.tabController?.onSelected?.call(widget.id);
|
||||||
});
|
});
|
||||||
WidgetsBinding.instance.addObserver(this);
|
WidgetsBinding.instance.addObserver(this);
|
||||||
}
|
}
|
||||||
@@ -140,6 +145,7 @@ class _FileManagerPageState extends State<FileManagerPage>
|
|||||||
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
|
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
|
||||||
body: Row(
|
body: Row(
|
||||||
children: [
|
children: [
|
||||||
|
if (!isWeb)
|
||||||
Flexible(
|
Flexible(
|
||||||
flex: 3,
|
flex: 3,
|
||||||
child: dropArea(FileManagerView(
|
child: dropArea(FileManagerView(
|
||||||
@@ -192,7 +198,13 @@ class _FileManagerPageState extends State<FileManagerPage>
|
|||||||
return Icon(Icons.delete_outline, color: color);
|
return Icon(Icons.delete_outline, color: color);
|
||||||
default:
|
default:
|
||||||
return Transform.rotate(
|
return Transform.rotate(
|
||||||
angle: job.isRemoteToLocal ? pi : 0,
|
angle: isWeb
|
||||||
|
? job.isRemoteToLocal
|
||||||
|
? pi / 2
|
||||||
|
: pi / 2 * 3
|
||||||
|
: job.isRemoteToLocal
|
||||||
|
? pi
|
||||||
|
: 0,
|
||||||
child: Icon(Icons.arrow_forward_ios, color: color),
|
child: Icon(Icons.arrow_forward_ios, color: color),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -478,6 +490,9 @@ class _FileManagerViewState extends State<FileManagerView> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget headTools() {
|
Widget headTools() {
|
||||||
|
var uploadButtonTapPosition = RelativeRect.fill;
|
||||||
|
RxBool isUploadFolder =
|
||||||
|
(bind.mainGetLocalOption(key: 'upload-folder-button') == 'Y').obs;
|
||||||
return Container(
|
return Container(
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
@@ -800,6 +815,66 @@ class _FileManagerViewState extends State<FileManagerView> {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
if (isWeb)
|
||||||
|
Obx(() => ElevatedButton.icon(
|
||||||
|
style: ButtonStyle(
|
||||||
|
padding: MaterialStateProperty.all<EdgeInsetsGeometry>(
|
||||||
|
isLocal
|
||||||
|
? EdgeInsets.only(left: 10)
|
||||||
|
: EdgeInsets.only(right: 10)),
|
||||||
|
backgroundColor: MaterialStateProperty.all(
|
||||||
|
selectedItems.items.isEmpty
|
||||||
|
? MyTheme.accent80
|
||||||
|
: MyTheme.accent,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
onPressed: () =>
|
||||||
|
{webselectFiles(is_folder: isUploadFolder.value)},
|
||||||
|
label: InkWell(
|
||||||
|
hoverColor: Colors.transparent,
|
||||||
|
splashColor: Colors.transparent,
|
||||||
|
highlightColor: Colors.transparent,
|
||||||
|
focusColor: Colors.transparent,
|
||||||
|
onTapDown: (e) {
|
||||||
|
final x = e.globalPosition.dx;
|
||||||
|
final y = e.globalPosition.dy;
|
||||||
|
uploadButtonTapPosition =
|
||||||
|
RelativeRect.fromLTRB(x, y, x, y);
|
||||||
|
},
|
||||||
|
onTap: () async {
|
||||||
|
final value = await showMenu<bool>(
|
||||||
|
context: context,
|
||||||
|
position: uploadButtonTapPosition,
|
||||||
|
items: [
|
||||||
|
PopupMenuItem<bool>(
|
||||||
|
value: false,
|
||||||
|
child: Text(translate('Upload files')),
|
||||||
|
),
|
||||||
|
PopupMenuItem<bool>(
|
||||||
|
value: true,
|
||||||
|
child: Text(translate('Upload folder')),
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
if (value != null) {
|
||||||
|
isUploadFolder.value = value;
|
||||||
|
bind.mainSetLocalOption(
|
||||||
|
key: 'upload-folder-button',
|
||||||
|
value: value ? 'Y' : '');
|
||||||
|
webselectFiles(is_folder: value);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Icon(Icons.arrow_drop_down),
|
||||||
|
),
|
||||||
|
icon: Text(
|
||||||
|
translate(isUploadFolder.isTrue
|
||||||
|
? 'Upload folder'
|
||||||
|
: 'Upload files'),
|
||||||
|
textAlign: TextAlign.right,
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
).marginOnly(left: 8),
|
||||||
|
)).marginOnly(left: 16),
|
||||||
Obx(() => ElevatedButton.icon(
|
Obx(() => ElevatedButton.icon(
|
||||||
style: ButtonStyle(
|
style: ButtonStyle(
|
||||||
padding: MaterialStateProperty.all<EdgeInsetsGeometry>(
|
padding: MaterialStateProperty.all<EdgeInsetsGeometry>(
|
||||||
@@ -833,11 +908,14 @@ class _FileManagerViewState extends State<FileManagerView> {
|
|||||||
: Colors.white,
|
: Colors.white,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
: isWeb
|
||||||
|
? Offstage()
|
||||||
: RotatedBox(
|
: RotatedBox(
|
||||||
quarterTurns: 2,
|
quarterTurns: 2,
|
||||||
child: SvgPicture.asset(
|
child: SvgPicture.asset(
|
||||||
"assets/arrow.svg",
|
"assets/arrow.svg",
|
||||||
colorFilter: svgColor(selectedItems.items.isEmpty
|
colorFilter: svgColor(
|
||||||
|
selectedItems.items.isEmpty
|
||||||
? Theme.of(context).brightness ==
|
? Theme.of(context).brightness ==
|
||||||
Brightness.light
|
Brightness.light
|
||||||
? MyTheme.grayBg
|
? MyTheme.grayBg
|
||||||
@@ -857,7 +935,7 @@ class _FileManagerViewState extends State<FileManagerView> {
|
|||||||
: Colors.white),
|
: Colors.white),
|
||||||
)
|
)
|
||||||
: Text(
|
: Text(
|
||||||
translate('Receive'),
|
translate(isWeb ? 'Download' : 'Receive'),
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: selectedItems.items.isEmpty
|
color: selectedItems.items.isEmpty
|
||||||
? Theme.of(context).brightness ==
|
? Theme.of(context).brightness ==
|
||||||
@@ -1020,7 +1098,7 @@ class _FileManagerViewState extends State<FileManagerView> {
|
|||||||
if (!entry.isDrive &&
|
if (!entry.isDrive &&
|
||||||
versionCmp(_ffi.ffiModel.pi.version, "1.3.0") >= 0)
|
versionCmp(_ffi.ffiModel.pi.version, "1.3.0") >= 0)
|
||||||
mod_menu.PopupMenuItem(
|
mod_menu.PopupMenuItem(
|
||||||
child: Text("Rename"),
|
child: Text(translate("Rename")),
|
||||||
height: CustomPopupMenuTheme.height,
|
height: CustomPopupMenuTheme.height,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
controller.renameAction(entry, isLocal);
|
controller.renameAction(entry, isLocal);
|
||||||
|
|||||||
@@ -436,6 +436,7 @@ class _RemoteToolbarState extends State<RemoteToolbar> {
|
|||||||
shadowColor: MyTheme.color(context).shadow,
|
shadowColor: MyTheme.color(context).shadow,
|
||||||
borderRadius: borderRadius,
|
borderRadius: borderRadius,
|
||||||
child: _DraggableShowHide(
|
child: _DraggableShowHide(
|
||||||
|
id: widget.id,
|
||||||
sessionId: widget.ffi.sessionId,
|
sessionId: widget.ffi.sessionId,
|
||||||
dragging: _dragging,
|
dragging: _dragging,
|
||||||
fractionX: _fractionX,
|
fractionX: _fractionX,
|
||||||
@@ -478,8 +479,8 @@ class _RemoteToolbarState extends State<RemoteToolbar> {
|
|||||||
setFullscreen: _setFullscreen,
|
setFullscreen: _setFullscreen,
|
||||||
));
|
));
|
||||||
toolbarItems.add(_KeyboardMenu(id: widget.id, ffi: widget.ffi));
|
toolbarItems.add(_KeyboardMenu(id: widget.id, ffi: widget.ffi));
|
||||||
if (!isWeb) {
|
|
||||||
toolbarItems.add(_ChatMenu(id: widget.id, ffi: widget.ffi));
|
toolbarItems.add(_ChatMenu(id: widget.id, ffi: widget.ffi));
|
||||||
|
if (!isWeb) {
|
||||||
toolbarItems.add(_VoiceCallMenu(id: widget.id, ffi: widget.ffi));
|
toolbarItems.add(_VoiceCallMenu(id: widget.id, ffi: widget.ffi));
|
||||||
}
|
}
|
||||||
if (!isWeb) toolbarItems.add(_RecordMenu());
|
if (!isWeb) toolbarItems.add(_RecordMenu());
|
||||||
@@ -1780,6 +1781,9 @@ class _ChatMenuState extends State<_ChatMenu> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
if (isWeb) {
|
||||||
|
return buildTextChatButton();
|
||||||
|
} else {
|
||||||
return _IconSubmenuButton(
|
return _IconSubmenuButton(
|
||||||
tooltip: 'Chat',
|
tooltip: 'Chat',
|
||||||
key: chatButtonKey,
|
key: chatButtonKey,
|
||||||
@@ -1789,25 +1793,37 @@ class _ChatMenuState extends State<_ChatMenu> {
|
|||||||
hoverColor: _ToolbarTheme.hoverBlueColor,
|
hoverColor: _ToolbarTheme.hoverBlueColor,
|
||||||
menuChildrenGetter: () => [textChat(), voiceCall()]);
|
menuChildrenGetter: () => [textChat(), voiceCall()]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buildTextChatButton() {
|
||||||
|
return _IconMenuButton(
|
||||||
|
assetName: 'assets/message_24dp_5F6368.svg',
|
||||||
|
tooltip: 'Text chat',
|
||||||
|
key: chatButtonKey,
|
||||||
|
onPressed: _textChatOnPressed,
|
||||||
|
color: _ToolbarTheme.blueColor,
|
||||||
|
hoverColor: _ToolbarTheme.hoverBlueColor,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
textChat() {
|
textChat() {
|
||||||
return MenuButton(
|
return MenuButton(
|
||||||
child: Text(translate('Text chat')),
|
child: Text(translate('Text chat')),
|
||||||
ffi: widget.ffi,
|
ffi: widget.ffi,
|
||||||
onPressed: () {
|
onPressed: _textChatOnPressed);
|
||||||
|
}
|
||||||
|
|
||||||
|
_textChatOnPressed() {
|
||||||
RenderBox? renderBox =
|
RenderBox? renderBox =
|
||||||
chatButtonKey.currentContext?.findRenderObject() as RenderBox?;
|
chatButtonKey.currentContext?.findRenderObject() as RenderBox?;
|
||||||
|
|
||||||
Offset? initPos;
|
Offset? initPos;
|
||||||
if (renderBox != null) {
|
if (renderBox != null) {
|
||||||
final pos = renderBox.localToGlobal(Offset.zero);
|
final pos = renderBox.localToGlobal(Offset.zero);
|
||||||
initPos = Offset(pos.dx, pos.dy + _ToolbarTheme.dividerHeight);
|
initPos = Offset(pos.dx, pos.dy + _ToolbarTheme.dividerHeight);
|
||||||
}
|
}
|
||||||
|
widget.ffi.chatModel
|
||||||
widget.ffi.chatModel.changeCurrentKey(
|
.changeCurrentKey(MessageKey(widget.ffi.id, ChatModel.clientModeID));
|
||||||
MessageKey(widget.ffi.id, ChatModel.clientModeID));
|
|
||||||
widget.ffi.chatModel.toggleChatOverlay(chatInitPos: initPos);
|
widget.ffi.chatModel.toggleChatOverlay(chatInitPos: initPos);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
voiceCall() {
|
voiceCall() {
|
||||||
@@ -2218,6 +2234,7 @@ class RdoMenuButton<T> extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _DraggableShowHide extends StatefulWidget {
|
class _DraggableShowHide extends StatefulWidget {
|
||||||
|
final String id;
|
||||||
final SessionID sessionId;
|
final SessionID sessionId;
|
||||||
final RxDouble fractionX;
|
final RxDouble fractionX;
|
||||||
final RxBool dragging;
|
final RxBool dragging;
|
||||||
@@ -2229,6 +2246,7 @@ class _DraggableShowHide extends StatefulWidget {
|
|||||||
|
|
||||||
const _DraggableShowHide({
|
const _DraggableShowHide({
|
||||||
Key? key,
|
Key? key,
|
||||||
|
required this.id,
|
||||||
required this.sessionId,
|
required this.sessionId,
|
||||||
required this.fractionX,
|
required this.fractionX,
|
||||||
required this.dragging,
|
required this.dragging,
|
||||||
@@ -2318,15 +2336,33 @@ class _DraggableShowHideState extends State<_DraggableShowHide> {
|
|||||||
);
|
);
|
||||||
final isFullscreen = stateGlobal.fullscreen;
|
final isFullscreen = stateGlobal.fullscreen;
|
||||||
const double iconSize = 20;
|
const double iconSize = 20;
|
||||||
|
|
||||||
|
buttonWrapper(VoidCallback? onPressed, Widget child,
|
||||||
|
{Color hoverColor = _ToolbarTheme.blueColor}) {
|
||||||
|
final bgColor = buttonStyle.backgroundColor?.resolve({});
|
||||||
|
return TextButton(
|
||||||
|
onPressed: onPressed,
|
||||||
|
child: child,
|
||||||
|
style: buttonStyle.copyWith(
|
||||||
|
backgroundColor: MaterialStateProperty.resolveWith((states) {
|
||||||
|
if (states.contains(MaterialState.hovered)) {
|
||||||
|
return (bgColor ?? hoverColor).withOpacity(0.15);
|
||||||
|
}
|
||||||
|
return bgColor;
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
final child = Row(
|
final child = Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
_buildDraggable(context),
|
_buildDraggable(context),
|
||||||
Obx(() => TextButton(
|
Obx(() => buttonWrapper(
|
||||||
onPressed: () {
|
() {
|
||||||
widget.setFullscreen(!isFullscreen.value);
|
widget.setFullscreen(!isFullscreen.value);
|
||||||
},
|
},
|
||||||
child: Tooltip(
|
Tooltip(
|
||||||
message: translate(
|
message: translate(
|
||||||
isFullscreen.isTrue ? 'Exit Fullscreen' : 'Fullscreen'),
|
isFullscreen.isTrue ? 'Exit Fullscreen' : 'Fullscreen'),
|
||||||
child: Icon(
|
child: Icon(
|
||||||
@@ -2337,12 +2373,12 @@ class _DraggableShowHideState extends State<_DraggableShowHide> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
)),
|
)),
|
||||||
if (!isMacOS)
|
if (!isMacOS && !isWebDesktop)
|
||||||
Obx(() => Offstage(
|
Obx(() => Offstage(
|
||||||
offstage: isFullscreen.isFalse,
|
offstage: isFullscreen.isFalse,
|
||||||
child: TextButton(
|
child: buttonWrapper(
|
||||||
onPressed: () => widget.setMinimize(),
|
widget.setMinimize,
|
||||||
child: Tooltip(
|
Tooltip(
|
||||||
message: translate('Minimize'),
|
message: translate('Minimize'),
|
||||||
child: Icon(
|
child: Icon(
|
||||||
Icons.remove,
|
Icons.remove,
|
||||||
@@ -2351,11 +2387,11 @@ class _DraggableShowHideState extends State<_DraggableShowHide> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
)),
|
)),
|
||||||
TextButton(
|
buttonWrapper(
|
||||||
onPressed: () => setState(() {
|
() => setState(() {
|
||||||
widget.toolbarState.switchShow(widget.sessionId);
|
widget.toolbarState.switchShow(widget.sessionId);
|
||||||
}),
|
}),
|
||||||
child: Obx((() => Tooltip(
|
Obx((() => Tooltip(
|
||||||
message:
|
message:
|
||||||
translate(show.isTrue ? 'Hide Toolbar' : 'Show Toolbar'),
|
translate(show.isTrue ? 'Hide Toolbar' : 'Show Toolbar'),
|
||||||
child: Icon(
|
child: Icon(
|
||||||
@@ -2364,6 +2400,25 @@ class _DraggableShowHideState extends State<_DraggableShowHide> {
|
|||||||
),
|
),
|
||||||
))),
|
))),
|
||||||
),
|
),
|
||||||
|
if (isWebDesktop)
|
||||||
|
Obx(() {
|
||||||
|
if (show.isTrue) {
|
||||||
|
return Offstage();
|
||||||
|
} else {
|
||||||
|
return buttonWrapper(
|
||||||
|
() => closeConnection(id: widget.id),
|
||||||
|
Tooltip(
|
||||||
|
message: translate('Close'),
|
||||||
|
child: Icon(
|
||||||
|
Icons.close,
|
||||||
|
size: iconSize,
|
||||||
|
color: _ToolbarTheme.redColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
hoverColor: _ToolbarTheme.redColor,
|
||||||
|
).paddingOnly(left: iconSize / 2);
|
||||||
|
}
|
||||||
|
})
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
return TextButtonTheme(
|
return TextButtonTheme(
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ WindowType? kWindowType;
|
|||||||
late List<String> kBootArgs;
|
late List<String> kBootArgs;
|
||||||
|
|
||||||
Future<void> main(List<String> args) async {
|
Future<void> main(List<String> args) async {
|
||||||
|
earlyAssert();
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
debugPrint("launch args: $args");
|
debugPrint("launch args: $args");
|
||||||
@@ -161,7 +162,7 @@ void runMobileApp() async {
|
|||||||
await Future.wait([gFFI.abModel.loadCache(), gFFI.groupModel.loadCache()]);
|
await Future.wait([gFFI.abModel.loadCache(), gFFI.groupModel.loadCache()]);
|
||||||
gFFI.userModel.refreshCurrentUser();
|
gFFI.userModel.refreshCurrentUser();
|
||||||
runApp(App());
|
runApp(App());
|
||||||
if (!isWeb) await initUniLinks();
|
await initUniLinks();
|
||||||
}
|
}
|
||||||
|
|
||||||
void runMultiWindow(
|
void runMultiWindow(
|
||||||
@@ -444,7 +445,9 @@ class _AppState extends State<App> with WidgetsBindingObserver {
|
|||||||
child: GetMaterialApp(
|
child: GetMaterialApp(
|
||||||
navigatorKey: globalKey,
|
navigatorKey: globalKey,
|
||||||
debugShowCheckedModeBanner: false,
|
debugShowCheckedModeBanner: false,
|
||||||
title: 'RustDesk',
|
title: isWeb
|
||||||
|
? '${bind.mainGetAppNameSync()} Web Client V2 (Preview)'
|
||||||
|
: bind.mainGetAppNameSync(),
|
||||||
theme: MyTheme.lightTheme,
|
theme: MyTheme.lightTheme,
|
||||||
darkTheme: MyTheme.darkTheme,
|
darkTheme: MyTheme.darkTheme,
|
||||||
themeMode: MyTheme.currentThemeMode(),
|
themeMode: MyTheme.currentThemeMode(),
|
||||||
@@ -475,7 +478,8 @@ class _AppState extends State<App> with WidgetsBindingObserver {
|
|||||||
: (context, child) {
|
: (context, child) {
|
||||||
child = _keepScaleBuilder(context, child);
|
child = _keepScaleBuilder(context, child);
|
||||||
child = botToastBuilder(context, child);
|
child = botToastBuilder(context, child);
|
||||||
if (isDesktop && desktopType == DesktopType.main) {
|
if ((isDesktop && desktopType == DesktopType.main) ||
|
||||||
|
isWebDesktop) {
|
||||||
child = keyListenerBuilder(context, child);
|
child = keyListenerBuilder(context, child);
|
||||||
}
|
}
|
||||||
if (isLinux) {
|
if (isLinux) {
|
||||||
@@ -503,7 +507,7 @@ _registerEventHandler() {
|
|||||||
platformFFI.registerEventHandler('theme', 'theme', (evt) async {
|
platformFFI.registerEventHandler('theme', 'theme', (evt) async {
|
||||||
String? dark = evt['dark'];
|
String? dark = evt['dark'];
|
||||||
if (dark != null) {
|
if (dark != null) {
|
||||||
MyTheme.changeDarkMode(MyTheme.themeModeFromString(dark));
|
await MyTheme.changeDarkMode(MyTheme.themeModeFromString(dark));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
platformFFI.registerEventHandler('language', 'language', (_) async {
|
platformFFI.registerEventHandler('language', 'language', (_) async {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import 'dart:async';
|
|||||||
import 'package:auto_size_text_field/auto_size_text_field.dart';
|
import 'package:auto_size_text_field/auto_size_text_field.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_hbb/common/formatter/id_formatter.dart';
|
import 'package:flutter_hbb/common/formatter/id_formatter.dart';
|
||||||
|
import 'package:flutter_hbb/common/widgets/connection_page_title.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
@@ -211,6 +212,8 @@ class _ConnectionPageState extends State<ConnectionPage> {
|
|||||||
FocusNode fieldFocusNode,
|
FocusNode fieldFocusNode,
|
||||||
VoidCallback onFieldSubmitted) {
|
VoidCallback onFieldSubmitted) {
|
||||||
fieldTextEditingController.text = _idController.text;
|
fieldTextEditingController.text = _idController.text;
|
||||||
|
Get.put<TextEditingController>(
|
||||||
|
fieldTextEditingController);
|
||||||
fieldFocusNode.addListener(() async {
|
fieldFocusNode.addListener(() async {
|
||||||
_idEmpty.value =
|
_idEmpty.value =
|
||||||
fieldTextEditingController.text.isEmpty;
|
fieldTextEditingController.text.isEmpty;
|
||||||
@@ -349,9 +352,15 @@ class _ConnectionPageState extends State<ConnectionPage> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
final child = Column(children: [
|
||||||
|
if (isWebDesktop)
|
||||||
|
getConnectionPageTitle(context, true)
|
||||||
|
.marginOnly(bottom: 10, top: 15, left: 12),
|
||||||
|
w
|
||||||
|
]);
|
||||||
return Align(
|
return Align(
|
||||||
alignment: Alignment.topCenter,
|
alignment: Alignment.topCenter,
|
||||||
child: Container(constraints: kMobilePageConstraints, child: w));
|
child: Container(constraints: kMobilePageConstraints, child: child));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -361,6 +370,9 @@ class _ConnectionPageState extends State<ConnectionPage> {
|
|||||||
if (Get.isRegistered<IDTextEditingController>()) {
|
if (Get.isRegistered<IDTextEditingController>()) {
|
||||||
Get.delete<IDTextEditingController>();
|
Get.delete<IDTextEditingController>();
|
||||||
}
|
}
|
||||||
|
if (Get.isRegistered<TextEditingController>()) {
|
||||||
|
Get.delete<TextEditingController>();
|
||||||
|
}
|
||||||
if (!bind.isCustomClient()) {
|
if (!bind.isCustomClient()) {
|
||||||
platformFFI.unregisterEventHandler(
|
platformFFI.unregisterEventHandler(
|
||||||
kCheckSoftwareUpdateFinish, kCheckSoftwareUpdateFinish);
|
kCheckSoftwareUpdateFinish, kCheckSoftwareUpdateFinish);
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import 'package:get/get.dart';
|
|||||||
import '../../common.dart';
|
import '../../common.dart';
|
||||||
import '../../common/widgets/chat_page.dart';
|
import '../../common/widgets/chat_page.dart';
|
||||||
import '../../models/platform_model.dart';
|
import '../../models/platform_model.dart';
|
||||||
|
import '../../models/state_model.dart';
|
||||||
import 'connection_page.dart';
|
import 'connection_page.dart';
|
||||||
|
|
||||||
abstract class PageShape extends Widget {
|
abstract class PageShape extends Widget {
|
||||||
@@ -159,14 +160,75 @@ class WebHomePage extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
stateGlobal.isInMainPage = true;
|
||||||
|
handleUnilink(context);
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
// backgroundColor: MyTheme.grayBg,
|
// backgroundColor: MyTheme.grayBg,
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
centerTitle: true,
|
centerTitle: true,
|
||||||
title: Text(bind.mainGetAppNameSync()),
|
title: Text("${bind.mainGetAppNameSync()} (Preview)"),
|
||||||
actions: connectionPage.appBarActions,
|
actions: connectionPage.appBarActions,
|
||||||
),
|
),
|
||||||
body: connectionPage,
|
body: connectionPage,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleUnilink(BuildContext context) {
|
||||||
|
if (webInitialLink.isEmpty) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final link = webInitialLink;
|
||||||
|
webInitialLink = '';
|
||||||
|
final splitter = ["/#/", "/#", "#/", "#"];
|
||||||
|
var fakelink = '';
|
||||||
|
for (var s in splitter) {
|
||||||
|
if (link.contains(s)) {
|
||||||
|
var list = link.split(s);
|
||||||
|
if (list.length < 2 || list[1].isEmpty) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
list.removeAt(0);
|
||||||
|
fakelink = "rustdesk://${list.join(s)}";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (fakelink.isEmpty) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final uri = Uri.tryParse(fakelink);
|
||||||
|
if (uri == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final args = urlLinkToCmdArgs(uri);
|
||||||
|
if (args == null || args.isEmpty) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
bool isFileTransfer = false;
|
||||||
|
String? id;
|
||||||
|
String? password;
|
||||||
|
for (int i = 0; i < args.length; i++) {
|
||||||
|
switch (args[i]) {
|
||||||
|
case '--connect':
|
||||||
|
case '--play':
|
||||||
|
isFileTransfer = false;
|
||||||
|
id = args[i + 1];
|
||||||
|
i++;
|
||||||
|
break;
|
||||||
|
case '--file-transfer':
|
||||||
|
isFileTransfer = true;
|
||||||
|
id = args[i + 1];
|
||||||
|
i++;
|
||||||
|
break;
|
||||||
|
case '--password':
|
||||||
|
password = args[i + 1];
|
||||||
|
i++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (id != null) {
|
||||||
|
connect(context, id, isFileTransfer: isFileTransfer, password: password);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,6 +57,9 @@ class _RemotePageState extends State<RemotePage> {
|
|||||||
|
|
||||||
final TextEditingController _textController =
|
final TextEditingController _textController =
|
||||||
TextEditingController(text: initText);
|
TextEditingController(text: initText);
|
||||||
|
// This timer is used to check the composing status of the soft keyboard.
|
||||||
|
// It is used for Android, Korean(and other similar) input method.
|
||||||
|
Timer? _composingTimer;
|
||||||
|
|
||||||
_RemotePageState(String id) {
|
_RemotePageState(String id) {
|
||||||
initSharedStates(id);
|
initSharedStates(id);
|
||||||
@@ -104,6 +107,7 @@ class _RemotePageState extends State<RemotePage> {
|
|||||||
_physicalFocusNode.dispose();
|
_physicalFocusNode.dispose();
|
||||||
await gFFI.close();
|
await gFFI.close();
|
||||||
_timer?.cancel();
|
_timer?.cancel();
|
||||||
|
_composingTimer?.cancel();
|
||||||
gFFI.dialogManager.dismissAll();
|
gFFI.dialogManager.dismissAll();
|
||||||
await SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,
|
await SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,
|
||||||
overlays: SystemUiOverlay.values);
|
overlays: SystemUiOverlay.values);
|
||||||
@@ -139,6 +143,7 @@ class _RemotePageState extends State<RemotePage> {
|
|||||||
gFFI.ffiModel.pi.version.isNotEmpty) {
|
gFFI.ffiModel.pi.version.isNotEmpty) {
|
||||||
gFFI.invokeMethod("enable_soft_keyboard", false);
|
gFFI.invokeMethod("enable_soft_keyboard", false);
|
||||||
}
|
}
|
||||||
|
_composingTimer?.cancel();
|
||||||
} else {
|
} else {
|
||||||
_timer?.cancel();
|
_timer?.cancel();
|
||||||
_timer = Timer(kMobileDelaySoftKeyboardFocus, () {
|
_timer = Timer(kMobileDelaySoftKeyboardFocus, () {
|
||||||
@@ -155,9 +160,9 @@ class _RemotePageState extends State<RemotePage> {
|
|||||||
var oldValue = _value;
|
var oldValue = _value;
|
||||||
_value = newValue;
|
_value = newValue;
|
||||||
var i = newValue.length - 1;
|
var i = newValue.length - 1;
|
||||||
for (; i >= 0 && newValue[i] != '\1'; --i) {}
|
for (; i >= 0 && newValue[i] != '1'; --i) {}
|
||||||
var j = oldValue.length - 1;
|
var j = oldValue.length - 1;
|
||||||
for (; j >= 0 && oldValue[j] != '\1'; --j) {}
|
for (; j >= 0 && oldValue[j] != '1'; --j) {}
|
||||||
if (i < j) j = i;
|
if (i < j) j = i;
|
||||||
var subNewValue = newValue.substring(j + 1);
|
var subNewValue = newValue.substring(j + 1);
|
||||||
var subOldValue = oldValue.substring(j + 1);
|
var subOldValue = oldValue.substring(j + 1);
|
||||||
@@ -202,12 +207,19 @@ class _RemotePageState extends State<RemotePage> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _handleNonIOSSoftKeyboardInput(String newValue) {
|
void _handleNonIOSSoftKeyboardInput(String newValue) {
|
||||||
|
_composingTimer?.cancel();
|
||||||
|
if (_textController.value.isComposingRangeValid) {
|
||||||
|
_composingTimer = Timer(Duration(milliseconds: 25), () {
|
||||||
|
_handleNonIOSSoftKeyboardInput(_textController.value.text);
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
var oldValue = _value;
|
var oldValue = _value;
|
||||||
_value = newValue;
|
_value = newValue;
|
||||||
if (oldValue.isNotEmpty &&
|
if (oldValue.isNotEmpty &&
|
||||||
newValue.isNotEmpty &&
|
newValue.isNotEmpty &&
|
||||||
oldValue[0] == '\1' &&
|
oldValue[0] == '1' &&
|
||||||
newValue[0] != '\1') {
|
newValue[0] != '1') {
|
||||||
// clipboard
|
// clipboard
|
||||||
oldValue = '';
|
oldValue = '';
|
||||||
}
|
}
|
||||||
@@ -242,10 +254,14 @@ class _RemotePageState extends State<RemotePage> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle mobile virtual keyboard
|
Future<void> handleSoftKeyboardInput(String newValue) async {
|
||||||
void handleSoftKeyboardInput(String newValue) {
|
|
||||||
if (isIOS) {
|
if (isIOS) {
|
||||||
_handleIOSSoftKeyboardInput(newValue);
|
// fix: TextFormField onChanged event triggered multiple times when Korean input
|
||||||
|
// https://github.com/rustdesk/rustdesk/pull/9644
|
||||||
|
await Future.delayed(const Duration(milliseconds: 10));
|
||||||
|
|
||||||
|
if (newValue != _textController.text) return;
|
||||||
|
_handleIOSSoftKeyboardInput(_textController.text);
|
||||||
} else {
|
} else {
|
||||||
_handleNonIOSSoftKeyboardInput(newValue);
|
_handleNonIOSSoftKeyboardInput(newValue);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -205,6 +205,7 @@ void showServerSettingsWithValue(
|
|||||||
)
|
)
|
||||||
] +
|
] +
|
||||||
[
|
[
|
||||||
|
if (isAndroid)
|
||||||
TextFormField(
|
TextFormField(
|
||||||
controller: relayCtrl,
|
controller: relayCtrl,
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
|
|||||||
@@ -235,13 +235,14 @@ class ChatModel with ChangeNotifier {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_isChatOverlayHide() => ((!isDesktop && chatIconOverlayEntry == null) ||
|
_isChatOverlayHide() =>
|
||||||
|
((!(isDesktop || isWebDesktop) && chatIconOverlayEntry == null) ||
|
||||||
chatWindowOverlayEntry == null);
|
chatWindowOverlayEntry == null);
|
||||||
|
|
||||||
toggleChatOverlay({Offset? chatInitPos}) {
|
toggleChatOverlay({Offset? chatInitPos}) {
|
||||||
if (_isChatOverlayHide()) {
|
if (_isChatOverlayHide()) {
|
||||||
gFFI.invokeMethod("enable_soft_keyboard", true);
|
gFFI.invokeMethod("enable_soft_keyboard", true);
|
||||||
if (!isDesktop) {
|
if (!(isDesktop || isWebDesktop)) {
|
||||||
showChatIconOverlay();
|
showChatIconOverlay();
|
||||||
}
|
}
|
||||||
showChatWindowOverlay(chatInitPos: chatInitPos);
|
showChatWindowOverlay(chatInitPos: chatInitPos);
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ import 'package:flutter_hbb/common/widgets/dialog.dart';
|
|||||||
import 'package:flutter_hbb/utils/event_loop.dart';
|
import 'package:flutter_hbb/utils/event_loop.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:path/path.dart' as path;
|
import 'package:path/path.dart' as path;
|
||||||
|
import 'package:flutter_hbb/web/dummy.dart'
|
||||||
|
if (dart.library.html) 'package:flutter_hbb/web/web_unique.dart';
|
||||||
|
|
||||||
import '../consts.dart';
|
import '../consts.dart';
|
||||||
import 'model.dart';
|
import 'model.dart';
|
||||||
@@ -74,7 +76,7 @@ class FileModel {
|
|||||||
|
|
||||||
Future<void> onReady() async {
|
Future<void> onReady() async {
|
||||||
await evtLoop.onReady();
|
await evtLoop.onReady();
|
||||||
await localController.onReady();
|
if (!isWeb) await localController.onReady();
|
||||||
await remoteController.onReady();
|
await remoteController.onReady();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,7 +88,7 @@ class FileModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> refreshAll() async {
|
Future<void> refreshAll() async {
|
||||||
await localController.refresh();
|
if (!isWeb) await localController.refresh();
|
||||||
await remoteController.refresh();
|
await remoteController.refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -228,6 +230,33 @@ class FileModel {
|
|||||||
);
|
);
|
||||||
}, useAnimation: false);
|
}, useAnimation: false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void onSelectedFiles(dynamic obj) {
|
||||||
|
localController.selectedItems.clear();
|
||||||
|
|
||||||
|
try {
|
||||||
|
int handleIndex = int.parse(obj['handleIndex']);
|
||||||
|
final file = jsonDecode(obj['file']);
|
||||||
|
var entry = Entry.fromJson(file);
|
||||||
|
entry.path = entry.name;
|
||||||
|
final otherSideData = remoteController.directoryData();
|
||||||
|
final toPath = otherSideData.directory.path;
|
||||||
|
final isWindows = otherSideData.options.isWindows;
|
||||||
|
final showHidden = otherSideData.options.showHidden;
|
||||||
|
final jobID = jobController.addTransferJob(entry, false);
|
||||||
|
webSendLocalFiles(
|
||||||
|
handleIndex: handleIndex,
|
||||||
|
actId: jobID,
|
||||||
|
path: entry.path,
|
||||||
|
to: PathUtil.join(toPath, entry.name, isWindows),
|
||||||
|
fileNum: 0,
|
||||||
|
includeHidden: showHidden,
|
||||||
|
isRemote: false,
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
debugPrint("Failed to decode onSelectedFiles: $e");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class DirectoryData {
|
class DirectoryData {
|
||||||
@@ -462,7 +491,8 @@ class FileController {
|
|||||||
to: PathUtil.join(toPath, from.name, isWindows),
|
to: PathUtil.join(toPath, from.name, isWindows),
|
||||||
fileNum: 0,
|
fileNum: 0,
|
||||||
includeHidden: showHidden,
|
includeHidden: showHidden,
|
||||||
isRemote: isRemoteToLocal);
|
isRemote: isRemoteToLocal,
|
||||||
|
isDir: from.isDirectory);
|
||||||
debugPrint(
|
debugPrint(
|
||||||
"path: ${from.path}, toPath: $toPath, to: ${PathUtil.join(toPath, from.name, isWindows)}");
|
"path: ${from.path}, toPath: $toPath, to: ${PathUtil.join(toPath, from.name, isWindows)}");
|
||||||
}
|
}
|
||||||
@@ -489,7 +519,7 @@ class FileController {
|
|||||||
} else if (item.isDirectory) {
|
} else if (item.isDirectory) {
|
||||||
title = translate("Not an empty directory");
|
title = translate("Not an empty directory");
|
||||||
dialogManager?.showLoading(translate("Waiting"));
|
dialogManager?.showLoading(translate("Waiting"));
|
||||||
final fd = await fileFetcher.fetchDirectoryRecursive(
|
final fd = await fileFetcher.fetchDirectoryRecursiveToRemove(
|
||||||
jobID, item.path, items.isLocal, true);
|
jobID, item.path, items.isLocal, true);
|
||||||
if (fd.path.isEmpty) {
|
if (fd.path.isEmpty) {
|
||||||
fd.path = item.path;
|
fd.path = item.path;
|
||||||
@@ -809,7 +839,6 @@ class JobController {
|
|||||||
job.speed = double.parse(evt['speed']);
|
job.speed = double.parse(evt['speed']);
|
||||||
job.finishedSize = int.parse(evt['finished_size']);
|
job.finishedSize = int.parse(evt['finished_size']);
|
||||||
job.recvJobRes = true;
|
job.recvJobRes = true;
|
||||||
debugPrint("update job $id with $evt");
|
|
||||||
jobTable.refresh();
|
jobTable.refresh();
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -1116,11 +1145,11 @@ class FileFetcher {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<FileDirectory> fetchDirectoryRecursive(
|
Future<FileDirectory> fetchDirectoryRecursiveToRemove(
|
||||||
int actID, String path, bool isLocal, bool showHidden) async {
|
int actID, String path, bool isLocal, bool showHidden) async {
|
||||||
// TODO test Recursive is show hidden default?
|
// TODO test Recursive is show hidden default?
|
||||||
try {
|
try {
|
||||||
await bind.sessionReadDirRecursive(
|
await bind.sessionReadDirToRemoveRecursive(
|
||||||
sessionId: sessionId,
|
sessionId: sessionId,
|
||||||
actId: actID,
|
actId: actID,
|
||||||
path: path,
|
path: path,
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import 'dart:math';
|
|||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
import 'dart:ui' as ui;
|
import 'dart:ui' as ui;
|
||||||
|
|
||||||
|
import 'package:bot_toast/bot_toast.dart';
|
||||||
import 'package:desktop_multi_window/desktop_multi_window.dart';
|
import 'package:desktop_multi_window/desktop_multi_window.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
@@ -269,6 +270,8 @@ class FfiModel with ChangeNotifier {
|
|||||||
var name = evt['name'];
|
var name = evt['name'];
|
||||||
if (name == 'msgbox') {
|
if (name == 'msgbox') {
|
||||||
handleMsgBox(evt, sessionId, peerId);
|
handleMsgBox(evt, sessionId, peerId);
|
||||||
|
} else if (name == 'toast') {
|
||||||
|
handleToast(evt, sessionId, peerId);
|
||||||
} else if (name == 'set_multiple_windows_session') {
|
} else if (name == 'set_multiple_windows_session') {
|
||||||
handleMultipleWindowsSession(evt, sessionId, peerId);
|
handleMultipleWindowsSession(evt, sessionId, peerId);
|
||||||
} else if (name == 'peer_info') {
|
} else if (name == 'peer_info') {
|
||||||
@@ -372,7 +375,7 @@ class FfiModel with ChangeNotifier {
|
|||||||
} else if (name == 'plugin_option') {
|
} else if (name == 'plugin_option') {
|
||||||
handleOption(evt);
|
handleOption(evt);
|
||||||
} else if (name == "sync_peer_hash_password_to_personal_ab") {
|
} else if (name == "sync_peer_hash_password_to_personal_ab") {
|
||||||
if (desktopType == DesktopType.main) {
|
if (desktopType == DesktopType.main || isWeb) {
|
||||||
final id = evt['id'];
|
final id = evt['id'];
|
||||||
final hash = evt['hash'];
|
final hash = evt['hash'];
|
||||||
if (id != null && hash != null) {
|
if (id != null && hash != null) {
|
||||||
@@ -390,6 +393,10 @@ class FfiModel with ChangeNotifier {
|
|||||||
handleFollowCurrentDisplay(evt, sessionId, peerId);
|
handleFollowCurrentDisplay(evt, sessionId, peerId);
|
||||||
} else if (name == 'use_texture_render') {
|
} else if (name == 'use_texture_render') {
|
||||||
_handleUseTextureRender(evt, sessionId, peerId);
|
_handleUseTextureRender(evt, sessionId, peerId);
|
||||||
|
} else if (name == "selected_files") {
|
||||||
|
if (isWeb) {
|
||||||
|
parent.target?.fileModel.onSelectedFiles(evt);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
debugPrint('Event is not handled in the fixed branch: $name');
|
debugPrint('Event is not handled in the fixed branch: $name');
|
||||||
}
|
}
|
||||||
@@ -591,6 +598,37 @@ class FfiModel with ChangeNotifier {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleToast(Map<String, dynamic> evt, SessionID sessionId, String peerId) {
|
||||||
|
final type = evt['type'] ?? 'info';
|
||||||
|
final text = evt['text'] ?? '';
|
||||||
|
final durMsc = evt['dur_msec'] ?? 2000;
|
||||||
|
final duration = Duration(milliseconds: durMsc);
|
||||||
|
if ((text).isEmpty) {
|
||||||
|
BotToast.showLoading(
|
||||||
|
duration: duration,
|
||||||
|
clickClose: true,
|
||||||
|
allowClick: true,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
if (type.contains('error')) {
|
||||||
|
BotToast.showText(
|
||||||
|
contentColor: Colors.red,
|
||||||
|
text: translate(text),
|
||||||
|
duration: duration,
|
||||||
|
clickClose: true,
|
||||||
|
onlyOne: true,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
BotToast.showText(
|
||||||
|
text: translate(text),
|
||||||
|
duration: duration,
|
||||||
|
clickClose: true,
|
||||||
|
onlyOne: true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Show a message box with [type], [title] and [text].
|
/// Show a message box with [type], [title] and [text].
|
||||||
showMsgBox(SessionID sessionId, String type, String title, String text,
|
showMsgBox(SessionID sessionId, String type, String title, String text,
|
||||||
String link, bool hasRetry, OverlayDialogManager dialogManager,
|
String link, bool hasRetry, OverlayDialogManager dialogManager,
|
||||||
@@ -1187,6 +1225,27 @@ class ImageModel with ChangeNotifier {
|
|||||||
|
|
||||||
clearImage() => _image = null;
|
clearImage() => _image = null;
|
||||||
|
|
||||||
|
bool _webDecodingRgba = false;
|
||||||
|
final List<Uint8List> _webRgbaList = List.empty(growable: true);
|
||||||
|
webOnRgba(int display, Uint8List rgba) async {
|
||||||
|
// deep copy needed, otherwise "instantiateCodec failed: TypeError: Cannot perform Construct on a detached ArrayBuffer"
|
||||||
|
_webRgbaList.add(Uint8List.fromList(rgba));
|
||||||
|
if (_webDecodingRgba) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_webDecodingRgba = true;
|
||||||
|
try {
|
||||||
|
while (_webRgbaList.isNotEmpty) {
|
||||||
|
final rgba2 = _webRgbaList.last;
|
||||||
|
_webRgbaList.clear();
|
||||||
|
await decodeAndUpdate(display, rgba2);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
debugPrint('onRgba error: $e');
|
||||||
|
}
|
||||||
|
_webDecodingRgba = false;
|
||||||
|
}
|
||||||
|
|
||||||
onRgba(int display, Uint8List rgba) async {
|
onRgba(int display, Uint8List rgba) async {
|
||||||
try {
|
try {
|
||||||
await decodeAndUpdate(display, rgba);
|
await decodeAndUpdate(display, rgba);
|
||||||
|
|||||||
@@ -48,6 +48,12 @@ class PlatformFFI {
|
|||||||
|
|
||||||
static get isMain => instance._appType == kAppTypeMain;
|
static get isMain => instance._appType == kAppTypeMain;
|
||||||
|
|
||||||
|
static String getByName(String name, [String arg = '']) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setByName(String name, [String value = '']) {}
|
||||||
|
|
||||||
static Future<String> getVersion() async {
|
static Future<String> getVersion() async {
|
||||||
PackageInfo packageInfo = await PackageInfo.fromPlatform();
|
PackageInfo packageInfo = await PackageInfo.fromPlatform();
|
||||||
return packageInfo.version;
|
return packageInfo.version;
|
||||||
@@ -276,4 +282,6 @@ class PlatformFFI {
|
|||||||
void syncAndroidServiceAppDirConfigPath() {
|
void syncAndroidServiceAppDirConfigPath() {
|
||||||
invokeMethod(AndroidChannel.kSyncAppDirConfigPath, _dir);
|
invokeMethod(AndroidChannel.kSyncAppDirConfigPath, _dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setFullscreenCallback(void Function(bool) fun) {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ class PeerTabModel with ChangeNotifier {
|
|||||||
// https://github.com/flutter/flutter/issues/101275#issuecomment-1604541700
|
// https://github.com/flutter/flutter/issues/101275#issuecomment-1604541700
|
||||||
// After onTap, the shift key should be pressed for a while when not in multiselection mode,
|
// After onTap, the shift key should be pressed for a while when not in multiselection mode,
|
||||||
// because onTap is delayed when onDoubleTap is not null
|
// because onTap is delayed when onDoubleTap is not null
|
||||||
if (isDesktop && !_isShiftDown) return;
|
if (isDesktop || isWebDesktop) return;
|
||||||
_multiSelectionMode = true;
|
_multiSelectionMode = true;
|
||||||
}
|
}
|
||||||
final cached = _currentTabCachedPeers.map((e) => e.id).toList();
|
final cached = _currentTabCachedPeers.map((e) => e.id).toList();
|
||||||
|
|||||||
@@ -6,3 +6,11 @@ final platformFFI = PlatformFFI.instance;
|
|||||||
final localeName = PlatformFFI.localeName;
|
final localeName = PlatformFFI.localeName;
|
||||||
|
|
||||||
RustdeskImpl get bind => platformFFI.ffiBind;
|
RustdeskImpl get bind => platformFFI.ffiBind;
|
||||||
|
|
||||||
|
String ffiGetByName(String name, [String arg = '']) {
|
||||||
|
return PlatformFFI.getByName(name, arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ffiSetByName(String name, [String value = '']) {
|
||||||
|
PlatformFFI.setByName(name, value);
|
||||||
|
}
|
||||||
|
|||||||
@@ -19,6 +19,9 @@ class StateGlobal {
|
|||||||
final RxBool showRemoteToolBar = false.obs;
|
final RxBool showRemoteToolBar = false.obs;
|
||||||
final svcStatus = SvcStatus.notReady.obs;
|
final svcStatus = SvcStatus.notReady.obs;
|
||||||
final RxBool isFocused = false.obs;
|
final RxBool isFocused = false.obs;
|
||||||
|
// for mobile and web
|
||||||
|
bool isInMainPage = true;
|
||||||
|
bool isWebVisible = true;
|
||||||
|
|
||||||
final isPortrait = false.obs;
|
final isPortrait = false.obs;
|
||||||
|
|
||||||
@@ -70,25 +73,38 @@ class StateGlobal {
|
|||||||
if (_fullscreen.value != v) {
|
if (_fullscreen.value != v) {
|
||||||
_fullscreen.value = v;
|
_fullscreen.value = v;
|
||||||
_showTabBar.value = !_fullscreen.value;
|
_showTabBar.value = !_fullscreen.value;
|
||||||
|
if (isWebDesktop) {
|
||||||
|
procFullscreenWeb();
|
||||||
|
} else {
|
||||||
|
procFullscreenNative(procWnd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
procFullscreenWeb() {
|
||||||
|
final isFullscreen = ffiGetByName('fullscreen') == 'Y';
|
||||||
|
String fullscreenValue = '';
|
||||||
|
if (isFullscreen && _fullscreen.isFalse) {
|
||||||
|
fullscreenValue = 'N';
|
||||||
|
} else if (!isFullscreen && fullscreen.isTrue) {
|
||||||
|
fullscreenValue = 'Y';
|
||||||
|
}
|
||||||
|
if (fullscreenValue.isNotEmpty) {
|
||||||
|
ffiSetByName('fullscreen', fullscreenValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
procFullscreenNative(bool procWnd) {
|
||||||
refreshResizeEdgeSize();
|
refreshResizeEdgeSize();
|
||||||
print(
|
print("fullscreen: $fullscreen, resizeEdgeSize: ${_resizeEdgeSize.value}");
|
||||||
"fullscreen: $fullscreen, resizeEdgeSize: ${_resizeEdgeSize.value}");
|
|
||||||
_windowBorderWidth.value = fullscreen.isTrue ? 0 : kWindowBorderWidth;
|
_windowBorderWidth.value = fullscreen.isTrue ? 0 : kWindowBorderWidth;
|
||||||
if (procWnd) {
|
if (procWnd) {
|
||||||
final wc = WindowController.fromWindowId(windowId);
|
final wc = WindowController.fromWindowId(windowId);
|
||||||
wc.setFullscreen(_fullscreen.isTrue).then((_) {
|
wc.setFullscreen(_fullscreen.isTrue).then((_) {
|
||||||
// https://github.com/leanflutter/window_manager/issues/131#issuecomment-1111587982
|
// We remove the redraw (width + 1, height + 1), because this issue cannot be reproduced.
|
||||||
if (isWindows && !v) {
|
// https://github.com/rustdesk/rustdesk/issues/9675
|
||||||
Future.delayed(Duration.zero, () async {
|
|
||||||
final frame = await wc.getFrame();
|
|
||||||
final newRect = Rect.fromLTWH(
|
|
||||||
frame.left, frame.top, frame.width + 1, frame.height + 1);
|
|
||||||
await wc.setFrame(newRect);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
refreshResizeEdgeSize() => _resizeEdgeSize.value = fullscreen.isTrue
|
refreshResizeEdgeSize() => _resizeEdgeSize.value = fullscreen.isTrue
|
||||||
@@ -109,7 +125,13 @@ class StateGlobal {
|
|||||||
_inputSource = bind.mainGetInputSource();
|
_inputSource = bind.mainGetInputSource();
|
||||||
}
|
}
|
||||||
|
|
||||||
StateGlobal._();
|
StateGlobal._() {
|
||||||
|
if (isWebDesktop) {
|
||||||
|
platformFFI.setFullscreenCallback((v) {
|
||||||
|
_fullscreen.value = v;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static final StateGlobal instance = StateGlobal._();
|
static final StateGlobal instance = StateGlobal._();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
// ignore_for_file: avoid_web_libraries_in_flutter
|
// ignore_for_file: avoid_web_libraries_in_flutter
|
||||||
|
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
import 'dart:js_interop';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
import 'dart:js';
|
import 'dart:js';
|
||||||
import 'dart:html';
|
import 'dart:html';
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:flutter_hbb/models/state_model.dart';
|
||||||
|
|
||||||
import 'package:flutter_hbb/web/bridge.dart';
|
import 'package:flutter_hbb/web/bridge.dart';
|
||||||
import 'package:flutter_hbb/common.dart';
|
import 'package:flutter_hbb/common.dart';
|
||||||
@@ -28,7 +30,15 @@ class PlatformFFI {
|
|||||||
context.callMethod('setByName', [name, value]);
|
context.callMethod('setByName', [name, value]);
|
||||||
}
|
}
|
||||||
|
|
||||||
PlatformFFI._();
|
PlatformFFI._() {
|
||||||
|
window.document.addEventListener(
|
||||||
|
'visibilitychange',
|
||||||
|
(event) => {
|
||||||
|
stateGlobal.isWebVisible =
|
||||||
|
window.document.visibilityState == 'visible'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
static final PlatformFFI instance = PlatformFFI._();
|
static final PlatformFFI instance = PlatformFFI._();
|
||||||
|
|
||||||
static get localeName => window.navigator.language;
|
static get localeName => window.navigator.language;
|
||||||
@@ -98,6 +108,10 @@ class PlatformFFI {
|
|||||||
sessionId: sessionId, display: display, ptr: ptr);
|
sessionId: sessionId, display: display, ptr: ptr);
|
||||||
|
|
||||||
Future<void> init(String appType) async {
|
Future<void> init(String appType) async {
|
||||||
|
Completer completer = Completer();
|
||||||
|
context["onInitFinished"] = () {
|
||||||
|
completer.complete();
|
||||||
|
};
|
||||||
context.callMethod('init');
|
context.callMethod('init');
|
||||||
version = getByName('version');
|
version = getByName('version');
|
||||||
window.onContextMenu.listen((event) {
|
window.onContextMenu.listen((event) {
|
||||||
@@ -112,6 +126,7 @@ class PlatformFFI {
|
|||||||
print('json.decode fail(): $e');
|
print('json.decode fail(): $e');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
return completer.future;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setEventCallback(void Function(Map<String, dynamic>) fun) {
|
void setEventCallback(void Function(Map<String, dynamic>) fun) {
|
||||||
@@ -157,4 +172,10 @@ class PlatformFFI {
|
|||||||
|
|
||||||
// just for compilation
|
// just for compilation
|
||||||
void syncAndroidServiceAppDirConfigPath() {}
|
void syncAndroidServiceAppDirConfigPath() {}
|
||||||
|
|
||||||
|
void setFullscreenCallback(void Function(bool) fun) {
|
||||||
|
context["onFullscreenChanged"] = (bool v) {
|
||||||
|
fun(v);
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -124,6 +124,9 @@ class RustDeskMultiWindowManager {
|
|||||||
bool withScreenRect,
|
bool withScreenRect,
|
||||||
) async {
|
) async {
|
||||||
final windowController = await DesktopMultiWindow.createWindow(msg);
|
final windowController = await DesktopMultiWindow.createWindow(msg);
|
||||||
|
if (isWindows) {
|
||||||
|
windowController.setInitBackgroundColor(Colors.black);
|
||||||
|
}
|
||||||
final windowId = windowController.windowId;
|
final windowId = windowController.windowId;
|
||||||
if (!withScreenRect) {
|
if (!withScreenRect) {
|
||||||
windowController
|
windowController
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
14
flutter/lib/web/dummy.dart
Normal file
14
flutter/lib/web/dummy.dart
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
Future<void> webselectFiles({required bool is_folder}) async {
|
||||||
|
throw UnimplementedError("webselectFiles");
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> webSendLocalFiles(
|
||||||
|
{required int handleIndex,
|
||||||
|
required int actId,
|
||||||
|
required String path,
|
||||||
|
required String to,
|
||||||
|
required int fileNum,
|
||||||
|
required bool includeHidden,
|
||||||
|
required bool isRemote}) {
|
||||||
|
throw UnimplementedError("webSendLocalFiles");
|
||||||
|
}
|
||||||
@@ -1,23 +1,12 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_hbb/desktop/pages/desktop_setting_page.dart';
|
import 'package:flutter_hbb/desktop/pages/desktop_setting_page.dart';
|
||||||
import 'package:flutter_hbb/mobile/pages/scan_page.dart';
|
|
||||||
import 'package:flutter_hbb/mobile/pages/settings_page.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
|
|
||||||
import '../../common.dart';
|
|
||||||
import '../../common/widgets/login.dart';
|
|
||||||
import '../../models/model.dart';
|
|
||||||
|
|
||||||
class WebSettingsPage extends StatelessWidget {
|
class WebSettingsPage extends StatelessWidget {
|
||||||
const WebSettingsPage({Key? key}) : super(key: key);
|
const WebSettingsPage({Key? key}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
if (isWebDesktop) {
|
|
||||||
return _buildDesktopButton(context);
|
return _buildDesktopButton(context);
|
||||||
} else {
|
|
||||||
return _buildMobileMenu(context);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildDesktopButton(BuildContext context) {
|
Widget _buildDesktopButton(BuildContext context) {
|
||||||
@@ -34,65 +23,4 @@ class WebSettingsPage extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildMobileMenu(BuildContext context) {
|
|
||||||
Provider.of<FfiModel>(context);
|
|
||||||
return PopupMenuButton<String>(
|
|
||||||
tooltip: "",
|
|
||||||
icon: const Icon(Icons.more_vert),
|
|
||||||
itemBuilder: (context) {
|
|
||||||
return (isIOS
|
|
||||||
? [
|
|
||||||
const PopupMenuItem(
|
|
||||||
value: "scan",
|
|
||||||
child: Icon(Icons.qr_code_scanner, color: Colors.black),
|
|
||||||
)
|
|
||||||
]
|
|
||||||
: <PopupMenuItem<String>>[]) +
|
|
||||||
[
|
|
||||||
PopupMenuItem(
|
|
||||||
value: "server",
|
|
||||||
child: Text(translate('ID/Relay Server')),
|
|
||||||
)
|
|
||||||
] +
|
|
||||||
[
|
|
||||||
PopupMenuItem(
|
|
||||||
value: "login",
|
|
||||||
child: Text(gFFI.userModel.userName.value.isEmpty
|
|
||||||
? translate("Login")
|
|
||||||
: '${translate("Logout")} (${gFFI.userModel.userName.value})'),
|
|
||||||
)
|
|
||||||
] +
|
|
||||||
[
|
|
||||||
PopupMenuItem(
|
|
||||||
value: "about",
|
|
||||||
child: Text(translate('About RustDesk')),
|
|
||||||
)
|
|
||||||
];
|
|
||||||
},
|
|
||||||
onSelected: (value) {
|
|
||||||
if (value == 'server') {
|
|
||||||
showServerSettings(gFFI.dialogManager);
|
|
||||||
}
|
}
|
||||||
if (value == 'about') {
|
|
||||||
showAbout(gFFI.dialogManager);
|
|
||||||
}
|
|
||||||
if (value == 'login') {
|
|
||||||
if (gFFI.userModel.userName.value.isEmpty) {
|
|
||||||
loginDialog();
|
|
||||||
} else {
|
|
||||||
logOutConfirmDialog();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (value == 'scan') {
|
|
||||||
Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(
|
|
||||||
builder: (BuildContext context) => ScanPage(),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
30
flutter/lib/web/web_unique.dart
Normal file
30
flutter/lib/web/web_unique.dart
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:js' as js;
|
||||||
|
|
||||||
|
Future<void> webselectFiles({required bool is_folder}) async {
|
||||||
|
return Future(
|
||||||
|
() => js.context.callMethod('setByName', ['select_files', is_folder]));
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> webSendLocalFiles(
|
||||||
|
{required int handleIndex,
|
||||||
|
required int actId,
|
||||||
|
required String path,
|
||||||
|
required String to,
|
||||||
|
required int fileNum,
|
||||||
|
required bool includeHidden,
|
||||||
|
required bool isRemote}) {
|
||||||
|
return Future(() => js.context.callMethod('setByName', [
|
||||||
|
'send_local_files',
|
||||||
|
jsonEncode({
|
||||||
|
'id': actId,
|
||||||
|
'handle_index': handleIndex,
|
||||||
|
'path': path,
|
||||||
|
'to': to,
|
||||||
|
'file_num': fileNum,
|
||||||
|
'include_hidden': includeHidden,
|
||||||
|
'is_remote': isRemote,
|
||||||
|
})
|
||||||
|
]));
|
||||||
|
}
|
||||||
@@ -335,7 +335,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
path: "."
|
path: "."
|
||||||
ref: HEAD
|
ref: HEAD
|
||||||
resolved-ref: "80b063b9d4e015f62e17f42a5aa0b3d20a365926"
|
resolved-ref: "519350f1f40746798299e94786197d058353bac9"
|
||||||
url: "https://github.com/rustdesk-org/rustdesk_desktop_multi_window"
|
url: "https://github.com/rustdesk-org/rustdesk_desktop_multi_window"
|
||||||
source: git
|
source: git
|
||||||
version: "0.1.0"
|
version: "0.1.0"
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ pub trait TraitPixelBuffer {
|
|||||||
#[cfg(not(any(target_os = "ios")))]
|
#[cfg(not(any(target_os = "ios")))]
|
||||||
pub enum Frame<'a> {
|
pub enum Frame<'a> {
|
||||||
PixelBuffer(PixelBuffer<'a>),
|
PixelBuffer(PixelBuffer<'a>),
|
||||||
Texture(*mut c_void),
|
Texture((*mut c_void, usize)),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(any(target_os = "ios")))]
|
#[cfg(not(any(target_os = "ios")))]
|
||||||
@@ -164,7 +164,7 @@ impl Frame<'_> {
|
|||||||
pub fn valid<'a>(&'a self) -> bool {
|
pub fn valid<'a>(&'a self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Frame::PixelBuffer(pixelbuffer) => !pixelbuffer.data().is_empty(),
|
Frame::PixelBuffer(pixelbuffer) => !pixelbuffer.data().is_empty(),
|
||||||
Frame::Texture(texture) => !texture.is_null(),
|
Frame::Texture((texture, _)) => !texture.is_null(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,7 +186,7 @@ impl Frame<'_> {
|
|||||||
|
|
||||||
pub enum EncodeInput<'a> {
|
pub enum EncodeInput<'a> {
|
||||||
YUV(&'a [u8]),
|
YUV(&'a [u8]),
|
||||||
Texture(*mut c_void),
|
Texture((*mut c_void, usize)),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> EncodeInput<'a> {
|
impl<'a> EncodeInput<'a> {
|
||||||
@@ -197,7 +197,7 @@ impl<'a> EncodeInput<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn texture(&self) -> ResultType<*mut c_void> {
|
pub fn texture(&self) -> ResultType<(*mut c_void, usize)> {
|
||||||
match self {
|
match self {
|
||||||
Self::Texture(f) => Ok(*f),
|
Self::Texture(f) => Ok(*f),
|
||||||
_ => bail!("not texture frame"),
|
_ => bail!("not texture frame"),
|
||||||
|
|||||||
@@ -101,7 +101,12 @@ impl EncoderApi for VRamEncoder {
|
|||||||
frame: EncodeInput,
|
frame: EncodeInput,
|
||||||
ms: i64,
|
ms: i64,
|
||||||
) -> ResultType<hbb_common::message_proto::VideoFrame> {
|
) -> ResultType<hbb_common::message_proto::VideoFrame> {
|
||||||
let texture = frame.texture()?;
|
let (texture, rotation) = frame.texture()?;
|
||||||
|
if rotation != 0 {
|
||||||
|
// to-do: support rotation
|
||||||
|
// Both the encoder and display(w,h) information need to be changed.
|
||||||
|
bail!("rotation not supported");
|
||||||
|
}
|
||||||
let mut vf = VideoFrame::new();
|
let mut vf = VideoFrame::new();
|
||||||
let mut frames = Vec::new();
|
let mut frames = Vec::new();
|
||||||
for frame in self
|
for frame in self
|
||||||
|
|||||||
@@ -253,7 +253,17 @@ impl Capturer {
|
|||||||
|
|
||||||
pub fn frame<'a>(&'a mut self, timeout: UINT) -> io::Result<Frame<'a>> {
|
pub fn frame<'a>(&'a mut self, timeout: UINT) -> io::Result<Frame<'a>> {
|
||||||
if self.output_texture {
|
if self.output_texture {
|
||||||
Ok(Frame::Texture(self.get_texture(timeout)?))
|
let rotation = match self.display.rotation() {
|
||||||
|
DXGI_MODE_ROTATION_IDENTITY | DXGI_MODE_ROTATION_UNSPECIFIED => 0,
|
||||||
|
DXGI_MODE_ROTATION_ROTATE90 => 90,
|
||||||
|
DXGI_MODE_ROTATION_ROTATE180 => 180,
|
||||||
|
DXGI_MODE_ROTATION_ROTATE270 => 270,
|
||||||
|
_ => {
|
||||||
|
// Unsupported rotation, try anyway
|
||||||
|
0
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Ok(Frame::Texture((self.get_texture(timeout)?, rotation)))
|
||||||
} else {
|
} else {
|
||||||
let width = self.width;
|
let width = self.width;
|
||||||
let height = self.height;
|
let height = self.height;
|
||||||
|
|||||||
@@ -14,16 +14,11 @@ case $1 in
|
|||||||
rm /etc/systemd/system/rustdesk.service /usr/lib/systemd/system/rustdesk.service || true
|
rm /etc/systemd/system/rustdesk.service /usr/lib/systemd/system/rustdesk.service || true
|
||||||
|
|
||||||
# workaround temp dev build between 1.1.9 and 1.2.0
|
# workaround temp dev build between 1.1.9 and 1.2.0
|
||||||
ubuntuVersion=$(grep -oP 'VERSION_ID="\K[\d]+' /etc/os-release | bc -l)
|
|
||||||
waylandSupportVersion=21
|
|
||||||
if [ "$ubuntuVersion" != "" ] && [ "$ubuntuVersion" -ge "$waylandSupportVersion" ]
|
|
||||||
then
|
|
||||||
serverUser=$(ps -ef | grep -E 'rustdesk +--server' | grep -v 'sudo ' | awk '{print $1}' | head -1)
|
serverUser=$(ps -ef | grep -E 'rustdesk +--server' | grep -v 'sudo ' | awk '{print $1}' | head -1)
|
||||||
if [ "$serverUser" != "" ] && [ "$serverUser" != "root" ]
|
if [ "$serverUser" != "" ] && [ "$serverUser" != "root" ]
|
||||||
then
|
then
|
||||||
systemctl --machine=${serverUser}@.host --user stop rustdesk >/dev/null 2>&1 || true
|
systemctl --machine=${serverUser}@.host --user stop rustdesk >/dev/null 2>&1 || true
|
||||||
fi
|
fi
|
||||||
fi
|
|
||||||
rm /usr/lib/systemd/user/rustdesk.service >/dev/null 2>&1 || true
|
rm /usr/lib/systemd/user/rustdesk.service >/dev/null 2>&1 || true
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
|
|||||||
@@ -602,6 +602,7 @@ pub fn session_send_files(
|
|||||||
file_num: i32,
|
file_num: i32,
|
||||||
include_hidden: bool,
|
include_hidden: bool,
|
||||||
is_remote: bool,
|
is_remote: bool,
|
||||||
|
_is_dir: bool,
|
||||||
) {
|
) {
|
||||||
if let Some(session) = sessions::get_session_by_session_id(&session_id) {
|
if let Some(session) = sessions::get_session_by_session_id(&session_id) {
|
||||||
session.send_files(act_id, path, to, file_num, include_hidden, is_remote);
|
session.send_files(act_id, path, to, file_num, include_hidden, is_remote);
|
||||||
@@ -633,7 +634,7 @@ pub fn session_remove_file(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn session_read_dir_recursive(
|
pub fn session_read_dir_to_remove_recursive(
|
||||||
session_id: SessionID,
|
session_id: SessionID,
|
||||||
act_id: i32,
|
act_id: i32,
|
||||||
path: String,
|
path: String,
|
||||||
|
|||||||
@@ -121,6 +121,7 @@ pub struct ClipboardNonFile {
|
|||||||
pub height: i32,
|
pub height: i32,
|
||||||
// message.proto: ClipboardFormat
|
// message.proto: ClipboardFormat
|
||||||
pub format: i32,
|
pub format: i32,
|
||||||
|
pub special_name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
|
|||||||
@@ -647,5 +647,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("one-way-file-transfer-tip", ""),
|
("one-way-file-transfer-tip", ""),
|
||||||
("Authentication Required", ""),
|
("Authentication Required", ""),
|
||||||
("Authenticate", ""),
|
("Authenticate", ""),
|
||||||
|
("web_id_input_tip", ""),
|
||||||
|
("Download", ""),
|
||||||
|
("Upload folder", ""),
|
||||||
|
("Upload files", ""),
|
||||||
|
("Clipboard is synchronized", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -647,5 +647,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("one-way-file-transfer-tip", ""),
|
("one-way-file-transfer-tip", ""),
|
||||||
("Authentication Required", ""),
|
("Authentication Required", ""),
|
||||||
("Authenticate", ""),
|
("Authenticate", ""),
|
||||||
|
("web_id_input_tip", ""),
|
||||||
|
("Download", ""),
|
||||||
|
("Upload folder", ""),
|
||||||
|
("Upload files", ""),
|
||||||
|
("Clipboard is synchronized", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -647,5 +647,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("one-way-file-transfer-tip", ""),
|
("one-way-file-transfer-tip", ""),
|
||||||
("Authentication Required", ""),
|
("Authentication Required", ""),
|
||||||
("Authenticate", ""),
|
("Authenticate", ""),
|
||||||
|
("web_id_input_tip", ""),
|
||||||
|
("Download", ""),
|
||||||
|
("Upload folder", ""),
|
||||||
|
("Upload files", ""),
|
||||||
|
("Clipboard is synchronized", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
925
src/lang/ca.rs
925
src/lang/ca.rs
File diff suppressed because it is too large
Load Diff
@@ -310,7 +310,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Start the screen sharing service on boot, requires special permissions", "开机自动启动屏幕共享服务,此功能需要一些特殊权限。"),
|
("Start the screen sharing service on boot, requires special permissions", "开机自动启动屏幕共享服务,此功能需要一些特殊权限。"),
|
||||||
("Connection not allowed", "对方不允许连接"),
|
("Connection not allowed", "对方不允许连接"),
|
||||||
("Legacy mode", "传统模式"),
|
("Legacy mode", "传统模式"),
|
||||||
("Map mode", "1:1 传输"),
|
("Map mode", "1:1 传输"),
|
||||||
("Translate mode", "翻译模式"),
|
("Translate mode", "翻译模式"),
|
||||||
("Use permanent password", "使用固定密码"),
|
("Use permanent password", "使用固定密码"),
|
||||||
("Use both passwords", "同时使用两种密码"),
|
("Use both passwords", "同时使用两种密码"),
|
||||||
@@ -563,7 +563,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Plug out all", "拔出所有"),
|
("Plug out all", "拔出所有"),
|
||||||
("True color (4:4:4)", "真彩模式(4:4:4)"),
|
("True color (4:4:4)", "真彩模式(4:4:4)"),
|
||||||
("Enable blocking user input", "允许阻止用户输入"),
|
("Enable blocking user input", "允许阻止用户输入"),
|
||||||
("id_input_tip", "可以输入 ID、直连 IP,或域名和端口号(<域名>:<端口号>)。\n要访问另一台服务器上的设备,请附加服务器地址(<ID>@<服务器地址>?key=<密钥>)。比如,\n9123456234@192.168.16.1:21117?key=5Qbwsde3unUcJBtrx9ZkvUmwFNoExHzpryHuPUdqlWM=。\n要访问公共服务器上的设备,请输入 \"<ID>@public\", 无需密钥。\n\n如果您想要在首次连接时,强制走中继连接,请在 ID 的后面添加 \"/r\",例如,\"9123456234/r\"。"),
|
("id_input_tip", "可以输入 ID、直连 IP,或域名和端口号(<域名>:<端口号>)。\n要访问另一台服务器上的设备,请附加服务器地址(<ID>@<服务器地址>?key=<密钥>)。比如,\n9123456234@192.168.16.1:21117?key=5Qbwsde3unUcJBtrx9ZkvUmwFNoExHzpryHuPUdqlWM=。\n要访问公共服务器上的设备,请输入 \"<ID>@public\",无需密钥。\n\n如果您想要在首次连接时,强制走中继连接,请在 ID 的后面添加 \"/r\",例如,\"9123456234/r\"。"),
|
||||||
("privacy_mode_impl_mag_tip", "模式 1"),
|
("privacy_mode_impl_mag_tip", "模式 1"),
|
||||||
("privacy_mode_impl_virtual_display_tip", "模式 2"),
|
("privacy_mode_impl_virtual_display_tip", "模式 2"),
|
||||||
("Enter privacy mode", "进入隐私模式"),
|
("Enter privacy mode", "进入隐私模式"),
|
||||||
@@ -647,5 +647,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("one-way-file-transfer-tip", "被控端启用了单向文件传输"),
|
("one-way-file-transfer-tip", "被控端启用了单向文件传输"),
|
||||||
("Authentication Required", "需要身份验证"),
|
("Authentication Required", "需要身份验证"),
|
||||||
("Authenticate", "认证"),
|
("Authenticate", "认证"),
|
||||||
|
("web_id_input_tip", "可以输入同一个服务器内的 ID,web 客户端不支持直接 IP 访问。\n要访问另一台服务器上的设备,请附加服务器地址(<ID>@<服务器地址>?key=<密钥>)。比如,\n9123456234@192.168.16.1:21117?key=5Qbwsde3unUcJBtrx9ZkvUmwFNoExHzpryHuPUdqlWM=。\n要访问公共服务器上的设备,请输入 \"<ID>@public\",无需密钥。"),
|
||||||
|
("Download", "下载"),
|
||||||
|
("Upload folder", "上传文件夹"),
|
||||||
|
("Upload files", "上传文件"),
|
||||||
|
("Clipboard is synchronized", "剪贴板已同步"),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -647,5 +647,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("one-way-file-transfer-tip", ""),
|
("one-way-file-transfer-tip", ""),
|
||||||
("Authentication Required", ""),
|
("Authentication Required", ""),
|
||||||
("Authenticate", ""),
|
("Authenticate", ""),
|
||||||
|
("web_id_input_tip", ""),
|
||||||
|
("Download", ""),
|
||||||
|
("Upload folder", ""),
|
||||||
|
("Upload files", ""),
|
||||||
|
("Clipboard is synchronized", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -647,5 +647,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("one-way-file-transfer-tip", ""),
|
("one-way-file-transfer-tip", ""),
|
||||||
("Authentication Required", ""),
|
("Authentication Required", ""),
|
||||||
("Authenticate", ""),
|
("Authenticate", ""),
|
||||||
|
("web_id_input_tip", ""),
|
||||||
|
("Download", ""),
|
||||||
|
("Upload folder", ""),
|
||||||
|
("Upload files", ""),
|
||||||
|
("Clipboard is synchronized", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -563,7 +563,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Plug out all", "Alle ausschalten"),
|
("Plug out all", "Alle ausschalten"),
|
||||||
("True color (4:4:4)", "True Color (4:4:4)"),
|
("True color (4:4:4)", "True Color (4:4:4)"),
|
||||||
("Enable blocking user input", "Blockieren von Benutzereingaben aktivieren"),
|
("Enable blocking user input", "Blockieren von Benutzereingaben aktivieren"),
|
||||||
("id_input_tip", "Sie können eine ID, eine direkte IP oder eine Domäne mit einem Port (<domain>:<port>) eingeben.\nWenn Sie auf ein Gerät auf einem anderen Server zugreifen möchten, fügen Sie bitte die Serveradresse (<id>@<server_address>?key=<key_value>) hinzu, zum Beispiel\n9123456234@192.168.16.1:21117?key=5Qbwsde3unUcJBtrx9ZkvUmwFNoExHzpryHuPUdqlWM=.\nWenn Sie auf ein Gerät auf einem öffentlichen Server zugreifen wollen, geben Sie bitte \"<id>@public\" ein. Der Schlüssel wird für öffentliche Server nicht benötigt.\n\nWenn Sie bei der ersten Verbindung die Verwendung einer Relay-Verbindung erzwingen wollen, fügen Sie \"/r\" am Ende der ID hinzu, zum Beispiel \"9123456234/r\"."),
|
("id_input_tip", "Sie können eine ID, eine direkte IP oder eine Domäne mit einem Port (<domain>:<port>) eingeben.\nWenn Sie auf ein Gerät auf einem anderen Server zugreifen wollen, fügen Sie bitte die Serveradresse (<id>@<server_address>?key=<key_value>) hinzu, zum Beispiel\n9123456234@192.168.16.1:21117?key=5Qbwsde3unUcJBtrx9ZkvUmwFNoExHzpryHuPUdqlWM=.\nWenn Sie auf ein Gerät auf einem öffentlichen Server zugreifen wollen, geben Sie bitte \"<id>@public\" ein. Der Schlüssel wird für öffentliche Server nicht benötigt.\n\nWenn Sie bei der ersten Verbindung die Verwendung einer Relay-Verbindung erzwingen wollen, fügen Sie \"/r\" am Ende der ID hinzu, zum Beispiel \"9123456234/r\"."),
|
||||||
("privacy_mode_impl_mag_tip", "Modus 1"),
|
("privacy_mode_impl_mag_tip", "Modus 1"),
|
||||||
("privacy_mode_impl_virtual_display_tip", "Modus 2"),
|
("privacy_mode_impl_virtual_display_tip", "Modus 2"),
|
||||||
("Enter privacy mode", "Datenschutzmodus aktivieren"),
|
("Enter privacy mode", "Datenschutzmodus aktivieren"),
|
||||||
@@ -647,5 +647,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("one-way-file-transfer-tip", "Die einseitige Dateiübertragung ist auf der kontrollierten Seite aktiviert."),
|
("one-way-file-transfer-tip", "Die einseitige Dateiübertragung ist auf der kontrollierten Seite aktiviert."),
|
||||||
("Authentication Required", "Authentifizierung erforderlich"),
|
("Authentication Required", "Authentifizierung erforderlich"),
|
||||||
("Authenticate", "Authentifizieren"),
|
("Authenticate", "Authentifizieren"),
|
||||||
|
("web_id_input_tip", "Sie können eine ID auf demselben Server eingeben, direkter IP-Zugriff wird im Web-Client nicht unterstützt.\nWenn Sie auf ein Gerät auf einem anderen Server zugreifen wollen, fügen Sie bitte die Serveradresse (<id>@<server_address>?key=<key_value>) hinzu, zum Beispiel\n9123456234@192.168.16.1:21117?key=5Qbwsde3unUcJBtrx9ZkvUmwFNoExHzpryHuPUdqlWM=.\nWenn Sie auf ein Gerät auf einem öffentlichen Server zugreifen wollen, geben Sie bitte \"<id>@public\" ein. Der Schlüssel wird für öffentliche Server nicht benötigt."),
|
||||||
|
("Download", "Herunterladen"),
|
||||||
|
("Upload folder", "Ordner hochladen"),
|
||||||
|
("Upload files", "Dateien hochladen"),
|
||||||
|
("Clipboard is synchronized", "Zwischenablage ist synchronisiert"),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -647,5 +647,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("one-way-file-transfer-tip", ""),
|
("one-way-file-transfer-tip", ""),
|
||||||
("Authentication Required", ""),
|
("Authentication Required", ""),
|
||||||
("Authenticate", ""),
|
("Authenticate", ""),
|
||||||
|
("web_id_input_tip", ""),
|
||||||
|
("Download", ""),
|
||||||
|
("Upload folder", ""),
|
||||||
|
("Upload files", ""),
|
||||||
|
("Clipboard is synchronized", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -235,5 +235,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("network_error_tip", "Please check your network connection, then click retry."),
|
("network_error_tip", "Please check your network connection, then click retry."),
|
||||||
("enable-trusted-devices-tip", "Skip 2FA verification on trusted devices"),
|
("enable-trusted-devices-tip", "Skip 2FA verification on trusted devices"),
|
||||||
("one-way-file-transfer-tip", "One-way file transfer is enabled on the controlled side."),
|
("one-way-file-transfer-tip", "One-way file transfer is enabled on the controlled side."),
|
||||||
|
("web_id_input_tip", "You can input an ID in the same server, direct IP access is not supported in web client.\nIf you want to access a device on another server, please append the server address (<id>@<server_address>?key=<key_value>), for example,\n9123456234@192.168.16.1:21117?key=5Qbwsde3unUcJBtrx9ZkvUmwFNoExHzpryHuPUdqlWM=.\nIf you want to access a device on a public server, please input \"<id>@public\", the key is not needed for public server."),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
245
src/lang/eo.rs
245
src/lang/eo.rs
@@ -6,11 +6,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("desk_tip", "Via aparato povas esti alirita kun tiu identigilo kaj pasvorto"),
|
("desk_tip", "Via aparato povas esti alirita kun tiu identigilo kaj pasvorto"),
|
||||||
("Password", "Pasvorto"),
|
("Password", "Pasvorto"),
|
||||||
("Ready", "Preta"),
|
("Ready", "Preta"),
|
||||||
("Established", ""),
|
("Established", "Establis"),
|
||||||
("connecting_status", "Konektante al la reto RustDesk..."),
|
("connecting_status", "Konektante al la reto RustDesk..."),
|
||||||
("Enable service", "Ebligi servon"),
|
("Enable service", "Ebligi servon"),
|
||||||
("Start service", "Starti servon"),
|
("Start service", "Starti servon"),
|
||||||
("Service is running", ""),
|
("Service is running", "La servo funkcias"),
|
||||||
("Service is not running", "La servo ne funkcias"),
|
("Service is not running", "La servo ne funkcias"),
|
||||||
("not_ready_status", "Ne preta, bonvolu kontroli la retkonekto"),
|
("not_ready_status", "Ne preta, bonvolu kontroli la retkonekto"),
|
||||||
("Control Remote Desktop", "Kontroli foran aparaton"),
|
("Control Remote Desktop", "Kontroli foran aparaton"),
|
||||||
@@ -29,33 +29,33 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Enable TCP tunneling", "Ebligi tunelado TCP"),
|
("Enable TCP tunneling", "Ebligi tunelado TCP"),
|
||||||
("IP Whitelisting", "Listo de IP akceptataj"),
|
("IP Whitelisting", "Listo de IP akceptataj"),
|
||||||
("ID/Relay Server", "Identigila/Relajsa servilo"),
|
("ID/Relay Server", "Identigila/Relajsa servilo"),
|
||||||
("Import server config", "Enporti servilan agordon"),
|
("Import server config", "Importi servilan agordon"),
|
||||||
("Export Server Config", ""),
|
("Export Server Config", "Eksporti servilan agordon"),
|
||||||
("Import server configuration successfully", "Importi servilan agordon sukcese"),
|
("Import server configuration successfully", "Importi servilan agordon sukcese"),
|
||||||
("Export server configuration successfully", ""),
|
("Export server configuration successfully", "Eksporti servilan agordon sukcese"),
|
||||||
("Invalid server configuration", "Nevalida servila agordo"),
|
("Invalid server configuration", "Nevalida servila agordo"),
|
||||||
("Clipboard is empty", "La poŝo estas malplena"),
|
("Clipboard is empty", "La poŝo estas malplena"),
|
||||||
("Stop service", "Haltu servon"),
|
("Stop service", "Haltu servon"),
|
||||||
("Change ID", "Ŝanĝi identigilon"),
|
("Change ID", "Ŝanĝi identigilon"),
|
||||||
("Your new ID", ""),
|
("Your new ID", "Via nova identigilo"),
|
||||||
("length %min% to %max%", ""),
|
("length %min% to %max%", "longeco %min% al %max%"),
|
||||||
("starts with a letter", ""),
|
("starts with a letter", "komencas kun letero"),
|
||||||
("allowed characters", ""),
|
("allowed characters", "permesitaj signoj"),
|
||||||
("id_change_tip", "Nur la signoj a-z, A-Z, 0-9, _ (substreko) povas esti uzataj. La unua litero povas esti inter a-z, A-Z. La longeco devas esti inter 6 kaj 16."),
|
("id_change_tip", "Nur la signoj a-z, A-Z, 0-9, _ (substreko) povas esti uzataj. La unua litero povas esti inter a-z, A-Z. La longeco devas esti inter 6 kaj 16."),
|
||||||
("Website", "Retejo"),
|
("Website", "Retejo"),
|
||||||
("About", "Pri"),
|
("About", "Pri"),
|
||||||
("Slogan_tip", ""),
|
("Slogan_tip", "Farita kun koro en ĉi tiu ĥaosa mondo!"),
|
||||||
("Privacy Statement", ""),
|
("Privacy Statement", "Deklaro Pri Privateco"),
|
||||||
("Mute", "Muta"),
|
("Mute", "Muta"),
|
||||||
("Build Date", ""),
|
("Build Date", "konstruada dato"),
|
||||||
("Version", ""),
|
("Version", "Versio"),
|
||||||
("Home", ""),
|
("Home", "Hejmo"),
|
||||||
("Audio Input", "Aŭdia enigo"),
|
("Audio Input", "Aŭdia Enigo"),
|
||||||
("Enhancements", ""),
|
("Enhancements", "Plibonigoj"),
|
||||||
("Hardware Codec", ""),
|
("Hardware Codec", "Aparataro Kodeko"),
|
||||||
("Adaptive bitrate", ""),
|
("Adaptive bitrate", "Adapta bitrapido"),
|
||||||
("ID Server", "Servilo de identigiloj"),
|
("ID Server", "Servilo de identigiloj"),
|
||||||
("Relay Server", "Relajsa servilo"),
|
("Relay Server", "Relajsa Servilo"),
|
||||||
("API Server", "Servilo de API"),
|
("API Server", "Servilo de API"),
|
||||||
("invalid_http", "Devas komenci kun http:// aŭ https://"),
|
("invalid_http", "Devas komenci kun http:// aŭ https://"),
|
||||||
("Invalid IP", "IP nevalida"),
|
("Invalid IP", "IP nevalida"),
|
||||||
@@ -83,35 +83,35 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Successful", "Sukceso"),
|
("Successful", "Sukceso"),
|
||||||
("Connected, waiting for image...", "Konektita, atendante bildon..."),
|
("Connected, waiting for image...", "Konektita, atendante bildon..."),
|
||||||
("Name", "Nomo"),
|
("Name", "Nomo"),
|
||||||
("Type", ""),
|
("Type", "Tipo"),
|
||||||
("Modified", "Modifita"),
|
("Modified", "Modifita"),
|
||||||
("Size", "Grandeco"),
|
("Size", "Grandeco"),
|
||||||
("Show Hidden Files", "Montri kaŝitajn dosierojn"),
|
("Show Hidden Files", "Montri kaŝitajn dosierojn"),
|
||||||
("Receive", "Akcepti"),
|
("Receive", "Akcepti"),
|
||||||
("Send", "Sendi"),
|
("Send", "Sendi"),
|
||||||
("Refresh File", ""),
|
("Refresh File", "Aktualigu Dosieron"),
|
||||||
("Local", ""),
|
("Local", "Loka"),
|
||||||
("Remote", ""),
|
("Remote", "Fora"),
|
||||||
("Remote Computer", "Fora komputilo"),
|
("Remote Computer", "Fora komputilo"),
|
||||||
("Local Computer", "Loka komputilo"),
|
("Local Computer", "Loka komputilo"),
|
||||||
("Confirm Delete", "Konfermi la forigo"),
|
("Confirm Delete", "Konfermi la forigo"),
|
||||||
("Delete", ""),
|
("Delete", "Forigi"),
|
||||||
("Properties", ""),
|
("Properties", "Propraĵoj"),
|
||||||
("Multi Select", ""),
|
("Multi Select", "Pluropa Elekto"),
|
||||||
("Select All", ""),
|
("Select All", "Elektu Ĉiujn"),
|
||||||
("Unselect All", ""),
|
("Unselect All", "Malelektu Ĉiujn"),
|
||||||
("Empty Directory", ""),
|
("Empty Directory", "Malplena Dosierujo"),
|
||||||
("Not an empty directory", ""),
|
("Not an empty directory", "Ne Malplena Dosierujo"),
|
||||||
("Are you sure you want to delete this file?", "Ĉu vi vere volas forigi tiun dosieron?"),
|
("Are you sure you want to delete this file?", "Ĉu vi certas, ke vi volas forigi ĉi tiun dosieron?"),
|
||||||
("Are you sure you want to delete this empty directory?", ""),
|
("Are you sure you want to delete this empty directory?", "Ĉu vi certas, ke vi volas forigi ĉi tiun malplenan dosierujon?"),
|
||||||
("Are you sure you want to delete the file of this directory?", ""),
|
("Are you sure you want to delete the file of this directory?", "Ĉu vi certa. ke vi volas forigi la dosieron de ĉi tiu dosierujo"),
|
||||||
("Do this for all conflicts", "Same por ĉiuj konfliktoj"),
|
("Do this for all conflicts", "Same por ĉiuj konfliktoj"),
|
||||||
("This is irreversible!", ""),
|
("This is irreversible!", "Ĉi tio estas neinversigebla!"),
|
||||||
("Deleting", "Forigado"),
|
("Deleting", "Forigado"),
|
||||||
("files", "dosiero"),
|
("files", "dosiero"),
|
||||||
("Waiting", "Atendante..."),
|
("Waiting", "Atendante..."),
|
||||||
("Finished", "Finita"),
|
("Finished", "Finita"),
|
||||||
("Speed", ""),
|
("Speed", "Rapideco"),
|
||||||
("Custom Image Quality", "Agordi bildan kvaliton"),
|
("Custom Image Quality", "Agordi bildan kvaliton"),
|
||||||
("Privacy mode", "Modo privata"),
|
("Privacy mode", "Modo privata"),
|
||||||
("Block user input", "Bloki uzanta enigo"),
|
("Block user input", "Bloki uzanta enigo"),
|
||||||
@@ -127,7 +127,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Optimize reaction time", "Optimigi reakcia tempo"),
|
("Optimize reaction time", "Optimigi reakcia tempo"),
|
||||||
("Custom", ""),
|
("Custom", ""),
|
||||||
("Show remote cursor", "Montri foran kursoron"),
|
("Show remote cursor", "Montri foran kursoron"),
|
||||||
("Show quality monitor", ""),
|
("Show quality monitor", "Montri kvalito monitoron"),
|
||||||
("Disable clipboard", "Malebligi poŝon"),
|
("Disable clipboard", "Malebligi poŝon"),
|
||||||
("Lock after session end", "Ŝlosi foran komputilon post malkonektado"),
|
("Lock after session end", "Ŝlosi foran komputilon post malkonektado"),
|
||||||
("Insert", "Enmeti"),
|
("Insert", "Enmeti"),
|
||||||
@@ -170,8 +170,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Action", "Ago"),
|
("Action", "Ago"),
|
||||||
("Add", "Aldoni"),
|
("Add", "Aldoni"),
|
||||||
("Local Port", "Loka pordo"),
|
("Local Port", "Loka pordo"),
|
||||||
("Local Address", ""),
|
("Local Address", "Loka Adreso"),
|
||||||
("Change Local Port", ""),
|
("Change Local Port", "Ŝanĝi Loka Pordo"),
|
||||||
("setup_server_tip", "Se vi bezonas pli rapida konekcio, vi povas krei vian propran servilon"),
|
("setup_server_tip", "Se vi bezonas pli rapida konekcio, vi povas krei vian propran servilon"),
|
||||||
("Too short, at least 6 characters.", "Tro mallonga, almenaŭ 6 signoj."),
|
("Too short, at least 6 characters.", "Tro mallonga, almenaŭ 6 signoj."),
|
||||||
("The confirmation is not identical.", "Ambaŭ enigoj ne kongruas"),
|
("The confirmation is not identical.", "Ambaŭ enigoj ne kongruas"),
|
||||||
@@ -203,23 +203,23 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Reboot required", "Restarto deviga"),
|
("Reboot required", "Restarto deviga"),
|
||||||
("Unsupported display server", "La aktuala bilda servilo ne estas subtenita"),
|
("Unsupported display server", "La aktuala bilda servilo ne estas subtenita"),
|
||||||
("x11 expected", "Bonvolu uzi x11"),
|
("x11 expected", "Bonvolu uzi x11"),
|
||||||
("Port", ""),
|
("Port", "Pordo"),
|
||||||
("Settings", "Agordoj"),
|
("Settings", "Agordoj"),
|
||||||
("Username", " Uzanta nomo"),
|
("Username", " Uzanta nomo"),
|
||||||
("Invalid port", "Pordo nevalida"),
|
("Invalid port", "Pordo nevalida"),
|
||||||
("Closed manually by the peer", "Manuale fermita de la samtavolano"),
|
("Closed manually by the peer", "Manuale fermita de la samtavolano"),
|
||||||
("Enable remote configuration modification", "Permesi foran redaktadon de la konfiguracio"),
|
("Enable remote configuration modification", "Permesi foran redaktadon de la konfiguracio"),
|
||||||
("Run without install", "Plenumi sen instali"),
|
("Run without install", "Plenumi sen instali"),
|
||||||
("Connect via relay", ""),
|
("Connect via relay", "Konekti per relajso"),
|
||||||
("Always connect via relay", "Ĉiam konekti per relajso"),
|
("Always connect via relay", "Ĉiam konekti per relajso"),
|
||||||
("whitelist_tip", "Nur la IP en la blanka listo povas kontroli mian komputilon"),
|
("whitelist_tip", "Nur la IP en la blanka listo povas kontroli mian komputilon"),
|
||||||
("Login", "Konekti"),
|
("Login", "Ensaluti"),
|
||||||
("Verify", ""),
|
("Verify", "Kontrolis"),
|
||||||
("Remember me", ""),
|
("Remember me", "Memori min"),
|
||||||
("Trust this device", ""),
|
("Trust this device", "Fidu ĉi tiun aparaton"),
|
||||||
("Verification code", ""),
|
("Verification code", "Konfirmkodo"),
|
||||||
("verification_tip", ""),
|
("verification_tip", "Konfirmkodo estis sendita al la registrita retpoŝta adreso, enigu la konfirmkodon por daŭrigi ensaluti."),
|
||||||
("Logout", "Malkonekti"),
|
("Logout", "Elsaluti"),
|
||||||
("Tags", "Etikedi"),
|
("Tags", "Etikedi"),
|
||||||
("Search ID", "Serĉi ID"),
|
("Search ID", "Serĉi ID"),
|
||||||
("whitelist_sep", "Vi povas uzi komon, punktokomon, spacon aŭ linsalton kiel apartigilo"),
|
("whitelist_sep", "Vi povas uzi komon, punktokomon, spacon aŭ linsalton kiel apartigilo"),
|
||||||
@@ -241,86 +241,86 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Socks5 Proxy", "Socks5 prokura servilo"),
|
("Socks5 Proxy", "Socks5 prokura servilo"),
|
||||||
("Socks5/Http(s) Proxy", "Socks5/Http(s) prokura servilo"),
|
("Socks5/Http(s) Proxy", "Socks5/Http(s) prokura servilo"),
|
||||||
("Discovered", "Malkovritaj"),
|
("Discovered", "Malkovritaj"),
|
||||||
("install_daemon_tip", ""),
|
("install_daemon_tip", "Por komenci ĉe ekŝargo, oni devas instali sisteman servon."),
|
||||||
("Remote ID", "Fora identigilo"),
|
("Remote ID", "Fora identigilo"),
|
||||||
("Paste", "Alglui"),
|
("Paste", "Alglui"),
|
||||||
("Paste here?", ""),
|
("Paste here?", "Alglui ĉi tie?"),
|
||||||
("Are you sure to close the connection?", "Ĉu vi vere volas fermi la konekton?"),
|
("Are you sure to close the connection?", "Ĉu vi vere volas fermi la konekton?"),
|
||||||
("Download new version", "Elŝuti la novan version"),
|
("Download new version", "Elŝuti la novan version"),
|
||||||
("Touch mode", "Tuŝa modo"),
|
("Touch mode", "Tuŝa modo"),
|
||||||
("Mouse mode", ""),
|
("Mouse mode", "musa modo"),
|
||||||
("One-Finger Tap", ""),
|
("One-Finger Tap", "Unufingra Frapeto"),
|
||||||
("Left Mouse", ""),
|
("Left Mouse", "Maldekstra Muso"),
|
||||||
("One-Long Tap", ""),
|
("One-Long Tap", "Unulonga Frapeto"),
|
||||||
("Two-Finger Tap", ""),
|
("Two-Finger Tap", "Dufingra Frapeto"),
|
||||||
("Right Mouse", ""),
|
("Right Mouse", "Deskra Muso"),
|
||||||
("One-Finger Move", ""),
|
("One-Finger Move", "Unufingra Movo"),
|
||||||
("Double Tap & Move", ""),
|
("Double Tap & Move", "Duobla Frapeto & Movo"),
|
||||||
("Mouse Drag", ""),
|
("Mouse Drag", "Muso Trenadi"),
|
||||||
("Three-Finger vertically", ""),
|
("Three-Finger vertically", "Tri Figroj Vertikale"),
|
||||||
("Mouse Wheel", ""),
|
("Mouse Wheel", "Musa Rado"),
|
||||||
("Two-Finger Move", ""),
|
("Two-Finger Move", "Dufingra Movo"),
|
||||||
("Canvas Move", ""),
|
("Canvas Move", "Kanvasa Movo"),
|
||||||
("Pinch to Zoom", ""),
|
("Pinch to Zoom", "Pinĉi al Zomo"),
|
||||||
("Canvas Zoom", ""),
|
("Canvas Zoom", "Kanvasa Zomo"),
|
||||||
("Reset canvas", "Restarigi kanvaso"),
|
("Reset canvas", "Restarigi kanvaso"),
|
||||||
("No permission of file transfer", "Neniu permeso de dosiertransigo"),
|
("No permission of file transfer", "Neniu permeso de dosiertransigo"),
|
||||||
("Note", "Notu"),
|
("Note", "Notu"),
|
||||||
("Connection", ""),
|
("Connection", "Konekto"),
|
||||||
("Share Screen", ""),
|
("Share Screen", "Kunhavigi Ekranon"),
|
||||||
("Chat", ""),
|
("Chat", "Babilo"),
|
||||||
("Total", ""),
|
("Total", "Sumo"),
|
||||||
("items", ""),
|
("items", "eroj"),
|
||||||
("Selected", ""),
|
("Selected", "Elektita"),
|
||||||
("Screen Capture", ""),
|
("Screen Capture", "Ekrankapto"),
|
||||||
("Input Control", ""),
|
("Input Control", "Eniga Kontrolo"),
|
||||||
("Audio Capture", ""),
|
("Audio Capture", "Sonkontrolo"),
|
||||||
("File Connection", ""),
|
("File Connection", "Dosiero Konekto"),
|
||||||
("Screen Connection", ""),
|
("Screen Connection", "Ekrono konekto"),
|
||||||
("Do you accept?", ""),
|
("Do you accept?", "Ĉu vi akceptas?"),
|
||||||
("Open System Setting", ""),
|
("Open System Setting", "Malfermi Sistemajn Agordojn"),
|
||||||
("How to get Android input permission?", ""),
|
("How to get Android input permission?", "Kiel akiri Android enigajn permesojn"),
|
||||||
("android_input_permission_tip1", ""),
|
("android_input_permission_tip1", "Por ke fora aparato regu vian Android-aparaton per muso aŭ tuŝo, vi devas permesi al RustDesk uzi la servon \"Alirebleco\"."),
|
||||||
("android_input_permission_tip2", ""),
|
("android_input_permission_tip2", "Bonvolu iri al la sekva paĝo de sistemaj agordoj, trovi kaj eniri [Instatajn Servojn], ŝalti la servon [RustDesk Enigo]."),
|
||||||
("android_new_connection_tip", ""),
|
("android_new_connection_tip", "Nova kontrolpeto estis ricevita, kiu volas kontroli vian nunan aparaton."),
|
||||||
("android_service_will_start_tip", ""),
|
("android_service_will_start_tip", "Ŝalti \"Ekrankapto\" aŭtomate startos la servon, permesante al aliaj aparatoj peti konekton al via aparato."),
|
||||||
("android_stop_service_tip", ""),
|
("android_stop_service_tip", "Fermante la servon aŭtomate fermos ĉiujn establitajn konektojn."),
|
||||||
("android_version_audio_tip", ""),
|
("android_version_audio_tip", "La nuna versio da Android ne subtenas sonkapton, bonvolu ĝisdatigi al Android 10 aŭ pli alta."),
|
||||||
("android_start_service_tip", ""),
|
("android_start_service_tip", "Frapu [Komenci servo] aŭ ebligu la permeson de [Ekrankapto] por komenci la servon de kundivido de ekrano."),
|
||||||
("android_permission_may_not_change_tip", ""),
|
("android_permission_may_not_change_tip", "Permesoj por establitaj konektoj neble estas ŝanĝitaj tuj ĝis rekonektitaj."),
|
||||||
("Account", ""),
|
("Account", "Konto"),
|
||||||
("Overwrite", ""),
|
("Overwrite", "anstataŭigi"),
|
||||||
("This file exists, skip or overwrite this file?", ""),
|
("This file exists, skip or overwrite this file?", "Ĉi tiu dosiero ekzistas, ĉu preterlasi aŭ anstataŭi ĉi tiun dosieron?"),
|
||||||
("Quit", ""),
|
("Quit", "Forlasi"),
|
||||||
("Help", ""),
|
("Help", "Helpi"),
|
||||||
("Failed", ""),
|
("Failed", "Malsukcesa"),
|
||||||
("Succeeded", ""),
|
("Succeeded", "Sukcesa"),
|
||||||
("Someone turns on privacy mode, exit", ""),
|
("Someone turns on privacy mode, exit", "Iu ŝaltas modon privata, Eliro"),
|
||||||
("Unsupported", ""),
|
("Unsupported", "Nesubtenata"),
|
||||||
("Peer denied", ""),
|
("Peer denied", "Samulo rifuzita"),
|
||||||
("Please install plugins", ""),
|
("Please install plugins", "Bonvolu instali kromprogramojn"),
|
||||||
("Peer exit", ""),
|
("Peer exit", "Samulo eliras"),
|
||||||
("Failed to turn off", ""),
|
("Failed to turn off", "Malsukcesis malŝalti"),
|
||||||
("Turned off", ""),
|
("Turned off", "Malŝaltita"),
|
||||||
("Language", ""),
|
("Language", "Lingvo"),
|
||||||
("Keep RustDesk background service", ""),
|
("Keep RustDesk background service", "Tenu RustDesk fonan servon"),
|
||||||
("Ignore Battery Optimizations", ""),
|
("Ignore Battery Optimizations", "Ignoru Bateria Optimumigojn"),
|
||||||
("android_open_battery_optimizations_tip", ""),
|
("android_open_battery_optimizations_tip", "Se vi volas malŝalti ĉi tiun funkcion, bonvolu iri al la sekva paĝo de agordoj de la aplikaĵo de RustDesk, trovi kaj eniri [Baterio], Malmarku [Senrestrikta]"),
|
||||||
("Start on boot", ""),
|
("Start on boot", "Komencu ĉe ekfunkciigo"),
|
||||||
("Start the screen sharing service on boot, requires special permissions", ""),
|
("Start the screen sharing service on boot, requires special permissions", "Komencu la servon de kundivido de ekrano ĉe lanĉo, postulas specialajn permesojn"),
|
||||||
("Connection not allowed", ""),
|
("Connection not allowed", "Konekto ne rajtas"),
|
||||||
("Legacy mode", ""),
|
("Legacy mode", ""),
|
||||||
("Map mode", ""),
|
("Map mode", "Mapa modo"),
|
||||||
("Translate mode", ""),
|
("Translate mode", "Traduki modo"),
|
||||||
("Use permanent password", ""),
|
("Use permanent password", "Uzu permanenta pasvorto"),
|
||||||
("Use both passwords", ""),
|
("Use both passwords", "Uzu ambaŭ pasvorto"),
|
||||||
("Set permanent password", ""),
|
("Set permanent password", "Starigi permanenta pasvorto"),
|
||||||
("Enable remote restart", ""),
|
("Enable remote restart", "Permesi fora restartas"),
|
||||||
("Restart remote device", ""),
|
("Restart remote device", "Restartu fora aparato"),
|
||||||
("Are you sure you want to restart", ""),
|
("Are you sure you want to restart", "Ĉu vi certas, ke vi volas restarti"),
|
||||||
("Restarting remote device", ""),
|
("Restarting remote device", "Restartas fora aparato"),
|
||||||
("remote_restarting_tip", ""),
|
("remote_restarting_tip", "Fora aparato restartiĝas, bonvolu fermi ĉi tiun mesaĝkeston kaj rekonekti kun permanenta pasvorto post iom da tempo"),
|
||||||
("Copied", ""),
|
("Copied", "Kopiita"),
|
||||||
("Exit Fullscreen", "Eliru Plenekranon"),
|
("Exit Fullscreen", "Eliru Plenekranon"),
|
||||||
("Fullscreen", "Plenekrane"),
|
("Fullscreen", "Plenekrane"),
|
||||||
("Mobile Actions", "Poŝtelefonaj Agoj"),
|
("Mobile Actions", "Poŝtelefonaj Agoj"),
|
||||||
@@ -330,8 +330,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Ratio", "Proporcio"),
|
("Ratio", "Proporcio"),
|
||||||
("Image Quality", "Bilda Kvalito"),
|
("Image Quality", "Bilda Kvalito"),
|
||||||
("Scroll Style", "Ruluma Stilo"),
|
("Scroll Style", "Ruluma Stilo"),
|
||||||
("Show Toolbar", ""),
|
("Show Toolbar", "Montri Ilobreton"),
|
||||||
("Hide Toolbar", ""),
|
("Hide Toolbar", "Kaŝi Ilobreton"),
|
||||||
("Direct Connection", "Rekta Konekto"),
|
("Direct Connection", "Rekta Konekto"),
|
||||||
("Relay Connection", "Relajsa Konekto"),
|
("Relay Connection", "Relajsa Konekto"),
|
||||||
("Secure Connection", "Sekura Konekto"),
|
("Secure Connection", "Sekura Konekto"),
|
||||||
@@ -647,5 +647,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("one-way-file-transfer-tip", ""),
|
("one-way-file-transfer-tip", ""),
|
||||||
("Authentication Required", ""),
|
("Authentication Required", ""),
|
||||||
("Authenticate", ""),
|
("Authenticate", ""),
|
||||||
|
("web_id_input_tip", ""),
|
||||||
|
("Download", ""),
|
||||||
|
("Upload folder", ""),
|
||||||
|
("Upload files", ""),
|
||||||
|
("Clipboard is synchronized", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -647,5 +647,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("one-way-file-transfer-tip", "La transferencia en un sentido está habilitada en el lado controlado."),
|
("one-way-file-transfer-tip", "La transferencia en un sentido está habilitada en el lado controlado."),
|
||||||
("Authentication Required", "Se requiere autenticación"),
|
("Authentication Required", "Se requiere autenticación"),
|
||||||
("Authenticate", "Autenticar"),
|
("Authenticate", "Autenticar"),
|
||||||
|
("web_id_input_tip", "Puedes introducir una ID en el mismo servidor, el cliente web no soporta acceso vía IP.\nSi quieres acceder a un dispositivo en otro servidor, por favor, agrega la dirección del servidor (<id>@<direccion_servidor>?clave=<clave_valor>), por ejemplo,\n9123456234@192.168.16.1:21117?key=5Qbwsde3unUcJBtrx9ZkvUmwFNoExHzpryHuPUdqlWM=.\nSi quieres accedder a un dispositivo en un servidor público, por favor, introduce \"<id>@public\", la clave no es necesaria para el servidor público."),
|
||||||
|
("Download", "Descarga"),
|
||||||
|
("Upload folder", "Subir carpeta"),
|
||||||
|
("Upload files", "Subir archivos"),
|
||||||
|
("Clipboard is synchronized", "Portapapeles sincronizado"),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -647,5 +647,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("one-way-file-transfer-tip", ""),
|
("one-way-file-transfer-tip", ""),
|
||||||
("Authentication Required", ""),
|
("Authentication Required", ""),
|
||||||
("Authenticate", ""),
|
("Authenticate", ""),
|
||||||
|
("web_id_input_tip", ""),
|
||||||
|
("Download", ""),
|
||||||
|
("Upload folder", ""),
|
||||||
|
("Upload files", ""),
|
||||||
|
("Clipboard is synchronized", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -647,5 +647,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("one-way-file-transfer-tip", ""),
|
("one-way-file-transfer-tip", ""),
|
||||||
("Authentication Required", ""),
|
("Authentication Required", ""),
|
||||||
("Authenticate", ""),
|
("Authenticate", ""),
|
||||||
|
("web_id_input_tip", ""),
|
||||||
|
("Download", ""),
|
||||||
|
("Upload folder", ""),
|
||||||
|
("Upload files", ""),
|
||||||
|
("Clipboard is synchronized", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -647,5 +647,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("one-way-file-transfer-tip", ""),
|
("one-way-file-transfer-tip", ""),
|
||||||
("Authentication Required", ""),
|
("Authentication Required", ""),
|
||||||
("Authenticate", ""),
|
("Authenticate", ""),
|
||||||
|
("web_id_input_tip", ""),
|
||||||
|
("Download", ""),
|
||||||
|
("Upload folder", ""),
|
||||||
|
("Upload files", ""),
|
||||||
|
("Clipboard is synchronized", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -647,5 +647,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("one-way-file-transfer-tip", ""),
|
("one-way-file-transfer-tip", ""),
|
||||||
("Authentication Required", ""),
|
("Authentication Required", ""),
|
||||||
("Authenticate", ""),
|
("Authenticate", ""),
|
||||||
|
("web_id_input_tip", ""),
|
||||||
|
("Download", ""),
|
||||||
|
("Upload folder", ""),
|
||||||
|
("Upload files", ""),
|
||||||
|
("Clipboard is synchronized", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -647,5 +647,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("one-way-file-transfer-tip", ""),
|
("one-way-file-transfer-tip", ""),
|
||||||
("Authentication Required", ""),
|
("Authentication Required", ""),
|
||||||
("Authenticate", ""),
|
("Authenticate", ""),
|
||||||
|
("web_id_input_tip", ""),
|
||||||
|
("Download", ""),
|
||||||
|
("Upload folder", ""),
|
||||||
|
("Upload files", ""),
|
||||||
|
("Clipboard is synchronized", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -647,5 +647,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("one-way-file-transfer-tip", ""),
|
("one-way-file-transfer-tip", ""),
|
||||||
("Authentication Required", ""),
|
("Authentication Required", ""),
|
||||||
("Authenticate", ""),
|
("Authenticate", ""),
|
||||||
|
("web_id_input_tip", ""),
|
||||||
|
("Download", ""),
|
||||||
|
("Upload folder", ""),
|
||||||
|
("Upload files", ""),
|
||||||
|
("Clipboard is synchronized", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -647,5 +647,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("one-way-file-transfer-tip", ""),
|
("one-way-file-transfer-tip", ""),
|
||||||
("Authentication Required", ""),
|
("Authentication Required", ""),
|
||||||
("Authenticate", ""),
|
("Authenticate", ""),
|
||||||
|
("web_id_input_tip", ""),
|
||||||
|
("Download", ""),
|
||||||
|
("Upload folder", ""),
|
||||||
|
("Upload files", ""),
|
||||||
|
("Clipboard is synchronized", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
199
src/lang/id.rs
199
src/lang/id.rs
@@ -2,8 +2,8 @@ lazy_static::lazy_static! {
|
|||||||
pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||||
[
|
[
|
||||||
("Status", "Status"),
|
("Status", "Status"),
|
||||||
("Your Desktop", "Desktop Anda"),
|
("Your Desktop", "Layar Utama"),
|
||||||
("desk_tip", "Desktop Anda dapat diakses dengan ID dan kata sandi ini."),
|
("desk_tip", "Layar kamu dapat diakses dengan ID dan kata sandi ini."),
|
||||||
("Password", "Kata sandi"),
|
("Password", "Kata sandi"),
|
||||||
("Ready", "Sudah siap"),
|
("Ready", "Sudah siap"),
|
||||||
("Established", "Didirikan"),
|
("Established", "Didirikan"),
|
||||||
@@ -12,17 +12,17 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Start service", "Mulai Layanan"),
|
("Start service", "Mulai Layanan"),
|
||||||
("Service is running", "Layanan berjalan"),
|
("Service is running", "Layanan berjalan"),
|
||||||
("Service is not running", "Layanan tidak berjalan"),
|
("Service is not running", "Layanan tidak berjalan"),
|
||||||
("not_ready_status", "Belum siap. Silakan periksa koneksi Anda"),
|
("not_ready_status", "Belum siap digunakan. Silakan periksa koneksi"),
|
||||||
("Control Remote Desktop", "Kontrol Remote Desktop"),
|
("Control Remote Desktop", "Kontrol PC dari jarak jauh"),
|
||||||
("Transfer file", "File Transfer"),
|
("Transfer file", "Transfer File"),
|
||||||
("Connect", "Hubungkan"),
|
("Connect", "Sambungkan"),
|
||||||
("Recent sessions", "Sesi Terkini"),
|
("Recent sessions", "Sesi Terkini"),
|
||||||
("Address book", "Buku Alamat"),
|
("Address book", "Buku Alamat"),
|
||||||
("Confirmation", "Konfirmasi"),
|
("Confirmation", "Konfirmasi"),
|
||||||
("TCP tunneling", "Tunneling TCP"),
|
("TCP tunneling", "Tunneling TCP"),
|
||||||
("Remove", "Hapus"),
|
("Remove", "Hapus"),
|
||||||
("Refresh random password", "Perbarui kata sandi acak"),
|
("Refresh random password", "Perbarui kata sandi acak"),
|
||||||
("Set your own password", "Tetapkan kata sandi Anda"),
|
("Set your own password", "Tetapkan kata sandi"),
|
||||||
("Enable keyboard/mouse", "Aktifkan Keyboard/Mouse"),
|
("Enable keyboard/mouse", "Aktifkan Keyboard/Mouse"),
|
||||||
("Enable clipboard", "Aktifkan Papan Klip"),
|
("Enable clipboard", "Aktifkan Papan Klip"),
|
||||||
("Enable file transfer", "Aktifkan Transfer file"),
|
("Enable file transfer", "Aktifkan Transfer file"),
|
||||||
@@ -37,7 +37,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Clipboard is empty", "Papan klip kosong"),
|
("Clipboard is empty", "Papan klip kosong"),
|
||||||
("Stop service", "Hentikan Layanan"),
|
("Stop service", "Hentikan Layanan"),
|
||||||
("Change ID", "Ubah ID"),
|
("Change ID", "Ubah ID"),
|
||||||
("Your new ID", "ID baru anda"),
|
("Your new ID", "ID baru"),
|
||||||
("length %min% to %max%", "panjang %min% s/d %max%"),
|
("length %min% to %max%", "panjang %min% s/d %max%"),
|
||||||
("starts with a letter", "Dimulai dengan huruf"),
|
("starts with a letter", "Dimulai dengan huruf"),
|
||||||
("allowed characters", "Karakter yang dapat digunakan"),
|
("allowed characters", "Karakter yang dapat digunakan"),
|
||||||
@@ -69,10 +69,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Retry", "Coba lagi"),
|
("Retry", "Coba lagi"),
|
||||||
("OK", "Oke"),
|
("OK", "Oke"),
|
||||||
("Password Required", "Kata sandi tidak boleh kosong"),
|
("Password Required", "Kata sandi tidak boleh kosong"),
|
||||||
("Please enter your password", "Silahkan masukkan kata sandi anda"),
|
("Please enter your password", "Silahkan masukkan kata sandi"),
|
||||||
("Remember password", "Ingat kata sandi"),
|
("Remember password", "Ingat kata sandi"),
|
||||||
("Wrong Password", "Kata sandi Salah"),
|
("Wrong Password", "Kata sandi Salah"),
|
||||||
("Do you want to enter again?", "Apakah anda ingin masuk lagi?"),
|
("Do you want to enter again?", "Apakah kamu ingin mencoba lagi?"),
|
||||||
("Connection Error", "Kesalahan koneksi"),
|
("Connection Error", "Kesalahan koneksi"),
|
||||||
("Error", "Kesalahan"),
|
("Error", "Kesalahan"),
|
||||||
("Reset by the peer", "Direset oleh rekan"),
|
("Reset by the peer", "Direset oleh rekan"),
|
||||||
@@ -102,9 +102,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Unselect All", "Batalkan Pilihan Semua"),
|
("Unselect All", "Batalkan Pilihan Semua"),
|
||||||
("Empty Directory", "Folder Kosong"),
|
("Empty Directory", "Folder Kosong"),
|
||||||
("Not an empty directory", "Folder tidak kosong"),
|
("Not an empty directory", "Folder tidak kosong"),
|
||||||
("Are you sure you want to delete this file?", "Apakah anda yakin untuk menghapus file ini?"),
|
("Are you sure you want to delete this file?", "Apakah kamu yakin untuk menghapus file ini?"),
|
||||||
("Are you sure you want to delete this empty directory?", "Apakah anda yakin untuk menghapus folder ini?"),
|
("Are you sure you want to delete this empty directory?", "Apakah yakin yakin untuk menghapus folder ini?"),
|
||||||
("Are you sure you want to delete the file of this directory?", "Apakah anda yakin untuk menghapus file dan folder ini?"),
|
("Are you sure you want to delete the file of this directory?", "Apakah yakin yakin untuk menghapus file dan folder ini?"),
|
||||||
("Do this for all conflicts", "Lakukan untuk semua konflik"),
|
("Do this for all conflicts", "Lakukan untuk semua konflik"),
|
||||||
("This is irreversible!", "Ini tidak dapat diubah!"),
|
("This is irreversible!", "Ini tidak dapat diubah!"),
|
||||||
("Deleting", "Menghapus"),
|
("Deleting", "Menghapus"),
|
||||||
@@ -150,20 +150,20 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Click to download", "Klik untuk unduh"),
|
("Click to download", "Klik untuk unduh"),
|
||||||
("Click to update", "Klik untuk memperbarui"),
|
("Click to update", "Klik untuk memperbarui"),
|
||||||
("Configure", "Konfigurasi"),
|
("Configure", "Konfigurasi"),
|
||||||
("config_acc", "Untuk mengontrol Desktop Anda dari jarak jauh, Anda perlu memberikan izin \"Aksesibilitas\" RustDesk."),
|
("config_acc", "Agar bisa mengontrol Desktopmu dari jarak jauh, Kamu harus memberikan izin \"Aksesibilitas\" untuk RustDesk."),
|
||||||
("config_screen", "Untuk mengakses Desktop Anda dari jarak jauh, Anda perlu memberikan izin \"Perekaman Layar\" RustDesk."),
|
("config_screen", "Agar bisa mengakses Desktopmu dari jarak jauh, kamu harus memberikan izin \"Perekaman Layar\" untuk RustDesk."),
|
||||||
("Installing ...", "Menginstall"),
|
("Installing ...", "Menginstall"),
|
||||||
("Install", "Instal"),
|
("Install", "Instal"),
|
||||||
("Installation", "Instalasi"),
|
("Installation", "Instalasi"),
|
||||||
("Installation Path", "Direktori Instalasi"),
|
("Installation Path", "Direktori Instalasi"),
|
||||||
("Create start menu shortcuts", "Buat pintasan start menu"),
|
("Create start menu shortcuts", "Buat pintasan start menu"),
|
||||||
("Create desktop icon", "Buat icon desktop"),
|
("Create desktop icon", "Buat icon desktop"),
|
||||||
("agreement_tip", "Dengan memulai instalasi, Anda menerima perjanjian lisensi."),
|
("agreement_tip", "Dengan memulai proses instalasi, Kamu menerima perjanjian lisensi."),
|
||||||
("Accept and Install", "Terima dan Install"),
|
("Accept and Install", "Terima dan Install"),
|
||||||
("End-user license agreement", "Perjanjian lisensi pengguna"),
|
("End-user license agreement", "Perjanjian lisensi pengguna"),
|
||||||
("Generating ...", "Memproses..."),
|
("Generating ...", "Memproses..."),
|
||||||
("Your installation is lower version.", "Instalasi Anda adalah versi yang lebih rendah."),
|
("Your installation is lower version.", "Kamu menggunakan versi instalasi yang lebih rendah."),
|
||||||
("not_close_tcp_tip", "Jangan tutup jendela ini saat menggunakan tunnel"),
|
("not_close_tcp_tip", "Pastikan jendela ini tetap terbuka saat menggunakan tunnel."),
|
||||||
("Listening ...", "Menghubungkan..."),
|
("Listening ...", "Menghubungkan..."),
|
||||||
("Remote Host", "Host Remote"),
|
("Remote Host", "Host Remote"),
|
||||||
("Remote Port", "Port Remote"),
|
("Remote Port", "Port Remote"),
|
||||||
@@ -172,24 +172,24 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Local Port", "Port Lokal"),
|
("Local Port", "Port Lokal"),
|
||||||
("Local Address", "Alamat lokal"),
|
("Local Address", "Alamat lokal"),
|
||||||
("Change Local Port", "Ubah Port Lokal"),
|
("Change Local Port", "Ubah Port Lokal"),
|
||||||
("setup_server_tip", "Untuk mendapatkan koneksi yang lebih baik, disarankan untuk menginstal di server anda sendiri"),
|
("setup_server_tip", "Untuk koneksi yang lebih baik, silakan konfigurasi di server pribadi"),
|
||||||
("Too short, at least 6 characters.", "Terlalu pendek, setidaknya 6 karekter."),
|
("Too short, at least 6 characters.", "Terlalu pendek, setidaknya 6 karekter."),
|
||||||
("The confirmation is not identical.", "Konfirmasi tidak identik."),
|
("The confirmation is not identical.", "Konfirmasi tidak identik."),
|
||||||
("Permissions", "Perizinan"),
|
("Permissions", "Perizinan"),
|
||||||
("Accept", "Terima"),
|
("Accept", "Terima"),
|
||||||
("Dismiss", "Hentikan"),
|
("Dismiss", "Hentikan"),
|
||||||
("Disconnect", "Terputus"),
|
("Disconnect", "Terputus"),
|
||||||
("Enable file copy and paste", "Izinkan salin dan tempel file"),
|
("Enable file copy and paste", "Izinkan copy dan paste"),
|
||||||
("Connected", "Terhubung"),
|
("Connected", "Terhubung"),
|
||||||
("Direct and encrypted connection", "Koneksi langsung dan terenkripsi"),
|
("Direct and encrypted connection", "Koneksi langsung dan terenkripsi"),
|
||||||
("Relayed and encrypted connection", "Koneksi relay dan terenkripsi"),
|
("Relayed and encrypted connection", "Koneksi relay dan terenkripsi"),
|
||||||
("Direct and unencrypted connection", "Koneksi langsung dan tanpa enkripsi"),
|
("Direct and unencrypted connection", "Koneksi langsung dan tanpa enkripsi"),
|
||||||
("Relayed and unencrypted connection", "Koneksi relay dan tanpa enkripsi"),
|
("Relayed and unencrypted connection", "Koneksi relay dan tanpa enkripsi"),
|
||||||
("Enter Remote ID", "Masukkan ID Remote"),
|
("Enter Remote ID", "Masukkan ID Remote"),
|
||||||
("Enter your password", "Masukkan kata sandi anda"),
|
("Enter your password", "Masukkan kata sandi"),
|
||||||
("Logging in...", "Masuk..."),
|
("Logging in...", "Masuk..."),
|
||||||
("Enable RDP session sharing", "Aktifkan berbagi sesi RDP"),
|
("Enable RDP session sharing", "Aktifkan berbagi sesi RDP"),
|
||||||
("Auto Login", "Login Otomatis (Hanya berlaku jika Anda mengatur \"Kunci setelah sesi berakhir\")"),
|
("Auto Login", "Login Otomatis (Hanya berlaku jika sudah mengatur \"Kunci setelah sesi berakhir\")"),
|
||||||
("Enable direct IP access", "Aktifkan Akses IP Langsung"),
|
("Enable direct IP access", "Aktifkan Akses IP Langsung"),
|
||||||
("Rename", "Ubah nama"),
|
("Rename", "Ubah nama"),
|
||||||
("Space", "Spasi"),
|
("Space", "Spasi"),
|
||||||
@@ -199,7 +199,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Please enter the folder name", "Silahkan masukkan nama folder"),
|
("Please enter the folder name", "Silahkan masukkan nama folder"),
|
||||||
("Fix it", "Perbaiki"),
|
("Fix it", "Perbaiki"),
|
||||||
("Warning", "Peringatan"),
|
("Warning", "Peringatan"),
|
||||||
("Login screen using Wayland is not supported", "Layar masuk menggunakan Wayland tidak didukung"),
|
("Login screen using Wayland is not supported", "Login screen dengan Wayland tidak didukung"),
|
||||||
("Reboot required", "Diperlukan boot ulang"),
|
("Reboot required", "Diperlukan boot ulang"),
|
||||||
("Unsupported display server", "Server tampilan tidak didukung "),
|
("Unsupported display server", "Server tampilan tidak didukung "),
|
||||||
("x11 expected", "Diperlukan x11"),
|
("x11 expected", "Diperlukan x11"),
|
||||||
@@ -241,11 +241,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Socks5 Proxy", "Proksi Socks5"),
|
("Socks5 Proxy", "Proksi Socks5"),
|
||||||
("Socks5/Http(s) Proxy", "Proksi Socks5/Http(s)"),
|
("Socks5/Http(s) Proxy", "Proksi Socks5/Http(s)"),
|
||||||
("Discovered", "Telah ditemukan"),
|
("Discovered", "Telah ditemukan"),
|
||||||
("install_daemon_tip", "Untuk memulai saat boot, Anda perlu menginstal system service."),
|
("install_daemon_tip", "Untuk dapat berjalan saat sistem menyala, kamu perlu menginstal layanan sistem (system service/daemon)."),
|
||||||
("Remote ID", "ID Remote"),
|
("Remote ID", "ID Remote"),
|
||||||
("Paste", "Tempel"),
|
("Paste", "Tempel"),
|
||||||
("Paste here?", "Tempel disini?"),
|
("Paste here?", "Tempel disini?"),
|
||||||
("Are you sure to close the connection?", "Apakah anda yakin akan menutup koneksi?"),
|
("Are you sure to close the connection?", "Apakah kamu yakin akan menutup koneksi?"),
|
||||||
("Download new version", "Unduh versi baru"),
|
("Download new version", "Unduh versi baru"),
|
||||||
("Touch mode", "Mode Layar Sentuh"),
|
("Touch mode", "Mode Layar Sentuh"),
|
||||||
("Mouse mode", "Mode Mouse"),
|
("Mouse mode", "Mode Mouse"),
|
||||||
@@ -373,7 +373,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Write a message", "Tulis pesan"),
|
("Write a message", "Tulis pesan"),
|
||||||
("Prompt", ""),
|
("Prompt", ""),
|
||||||
("Please wait for confirmation of UAC...", "Harap tunggu konfirmasi UAC"),
|
("Please wait for confirmation of UAC...", "Harap tunggu konfirmasi UAC"),
|
||||||
("elevated_foreground_window_tip", "Jendela remote desktop ini memerlukan hak akses khusus, jadi anda tidak bisa menggunakan mouse dan keyboard untuk sementara. Anda bisa meminta pihak pengguna yang diremote untuk menyembunyikan jendela ini atau klik tombol elevasi di jendela pengaturan koneksi. Untuk menghindari masalah ini, direkomendasikan untuk menginstall aplikasi secara permanen"),
|
("elevated_foreground_window_tip", "Jendela yang sedang aktif di remote desktop memerlukan hak istimewa yang lebih tinggi untuk beroperasi, sehingga mouse dan keyboard tidak dapat digunakan sementara waktu. Kamu bisa meminta pengguna jarak jauh untuk meminimalkan jendela saat ini, atau klik tombol elevasi di jendela manajemen koneksi. Untuk menghindari masalah ini, disarankan untuk menginstal software di perangkat remote secara permanen."),
|
||||||
("Disconnected", "Terputus"),
|
("Disconnected", "Terputus"),
|
||||||
("Other", "Lainnya"),
|
("Other", "Lainnya"),
|
||||||
("Confirm before closing multiple tabs", "Konfirmasi sebelum menutup banyak tab"),
|
("Confirm before closing multiple tabs", "Konfirmasi sebelum menutup banyak tab"),
|
||||||
@@ -394,9 +394,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Accept sessions via click", "Izinkan sesi dengan klik"),
|
("Accept sessions via click", "Izinkan sesi dengan klik"),
|
||||||
("Accept sessions via both", "Izinkan sesi dengan keduanya"),
|
("Accept sessions via both", "Izinkan sesi dengan keduanya"),
|
||||||
("Please wait for the remote side to accept your session request...", "Harap tunggu pihak pengguna remote untuk menerima permintaan sesi..."),
|
("Please wait for the remote side to accept your session request...", "Harap tunggu pihak pengguna remote untuk menerima permintaan sesi..."),
|
||||||
("One-time Password", "Kata sandi sekali pakai"),
|
("One-time Password", "Kata sandi sementara"),
|
||||||
("Use one-time password", "Gunakan kata sandi sekali pakai"),
|
("Use one-time password", "Gunakan kata sandi sementara"),
|
||||||
("One-time password length", "Panjang kata sandi sekali pakai"),
|
("One-time password length", "Panjang kata sandi sementara"),
|
||||||
("Request access to your device", "Permintaan akses ke perangkat ini"),
|
("Request access to your device", "Permintaan akses ke perangkat ini"),
|
||||||
("Hide connection management window", "Sembunyikan jendela pengaturan koneksi"),
|
("Hide connection management window", "Sembunyikan jendela pengaturan koneksi"),
|
||||||
("hide_cm_tip", "Izinkan untuk menyembunyikan hanya jika menerima sesi melalui kata sandi dan menggunakan kata sandi permanen"),
|
("hide_cm_tip", "Izinkan untuk menyembunyikan hanya jika menerima sesi melalui kata sandi dan menggunakan kata sandi permanen"),
|
||||||
@@ -569,83 +569,88 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Enter privacy mode", "Masuk mode privasi"),
|
("Enter privacy mode", "Masuk mode privasi"),
|
||||||
("Exit privacy mode", "Keluar mode privasi"),
|
("Exit privacy mode", "Keluar mode privasi"),
|
||||||
("idd_not_support_under_win10_2004_tip", "Driver grafis yang Anda gunakan tidak kompatibel dengan versi Windows Anda dan memerlukan Windows 10 versi 2004 atau yang lebih baru"),
|
("idd_not_support_under_win10_2004_tip", "Driver grafis yang Anda gunakan tidak kompatibel dengan versi Windows Anda dan memerlukan Windows 10 versi 2004 atau yang lebih baru"),
|
||||||
("input_source_1_tip", ""),
|
("input_source_1_tip", "Sumber input 1"),
|
||||||
("input_source_2_tip", ""),
|
("input_source_2_tip", "Sumber input 2"),
|
||||||
("Swap control-command key", ""),
|
("Swap control-command key", "Menukar tombol control-command"),
|
||||||
("swap-left-right-mouse", ""),
|
("swap-left-right-mouse", "Tukar fungsi tombol kiri dan kanan pada mouse"),
|
||||||
("2FA code", ""),
|
("2FA code", "Kode 2FA"),
|
||||||
("More", ""),
|
("More", "Lainnya"),
|
||||||
("enable-2fa-title", ""),
|
("enable-2fa-title", "Aktifkan autentikasi 2FA"),
|
||||||
("enable-2fa-desc", ""),
|
("enable-2fa-desc", "Silakan atur autentikator Anda sekarang. Anda dapat menggunakan aplikasi autentikator seperti Authy, Microsoft Authenticator, atau Google Authenticator di ponsel atau desktop Anda\n\nPindai kode QR dengan aplikasi Anda dan masukkan kode yang ditampilkan oleh aplikasi untuk mengaktifkan autentikasi 2FA."),
|
||||||
("wrong-2fa-code", ""),
|
("wrong-2fa-code", "Tidak dapat memverifikasi kode. Pastikan bahwa kode dan pengaturan waktu lokal sudah sesuai"),
|
||||||
("enter-2fa-title", ""),
|
("enter-2fa-title", "Autentikasi dua faktor"),
|
||||||
("Email verification code must be 6 characters.", ""),
|
("Email verification code must be 6 characters.", "Kode verifikasi email harus terdiri dari 6 karakter."),
|
||||||
("2FA code must be 6 digits.", ""),
|
("2FA code must be 6 digits.", "Kode 2FA harus terdiri dari 6 digit."),
|
||||||
("Multiple Windows sessions found", ""),
|
("Multiple Windows sessions found", "Terdapat beberapa sesi Windows"),
|
||||||
("Please select the session you want to connect to", ""),
|
("Please select the session you want to connect to", "Silakan pilih sesi yang ingin Anda sambungkan."),
|
||||||
("powered_by_me", ""),
|
("powered_by_me", "Didukung oleh RustDesk"),
|
||||||
("outgoing_only_desk_tip", ""),
|
("outgoing_only_desk_tip", "Ini adalah edisi yang sudah kustomisasi.\nAnda dapat terhubung ke perangkat lain, tetapi perangkat lain tidak dapat terhubung ke perangkat Anda."),
|
||||||
("preset_password_warning", ""),
|
("preset_password_warning", "Edisi yang dikustomisasi ini dilengkapi dengan kata sandi bawaan. Siapa pun yang mengetahui kata sandi ini dapat memperoleh kontrol penuh atas perangkat Anda. Jika Anda tidak mengharapkan ini, segera hapus pemasangan aplikasi tersebut."),
|
||||||
("Security Alert", ""),
|
("Security Alert", "Peringatan Keamanan"),
|
||||||
("My address book", ""),
|
("My address book", "Daftar Kontak"),
|
||||||
("Personal", ""),
|
("Personal", "Personal"),
|
||||||
("Owner", ""),
|
("Owner", "Pemilik"),
|
||||||
("Set shared password", ""),
|
("Set shared password", "Atus kata sandi kolaboratif"),
|
||||||
("Exist in", ""),
|
("Exist in", "Ada di"),
|
||||||
("Read-only", ""),
|
("Read-only", ""),
|
||||||
("Read/Write", ""),
|
("Read/Write", ""),
|
||||||
("Full Control", ""),
|
("Full Control", ""),
|
||||||
("share_warning_tip", ""),
|
("share_warning_tip", "Informasi di atas bersifat publik dan dapat dilihat oleh orang lain."),
|
||||||
("Everyone", ""),
|
("Everyone", ""),
|
||||||
("ab_web_console_tip", ""),
|
("ab_web_console_tip", "Detail Lain di Konsol Web"),
|
||||||
("allow-only-conn-window-open-tip", ""),
|
("allow-only-conn-window-open-tip", "Koneksi hanya diperbolehkan jika jendela RustDesk sedang terbuka."),
|
||||||
("no_need_privacy_mode_no_physical_displays_tip", ""),
|
("no_need_privacy_mode_no_physical_displays_tip", "Karena tidak ada layar fisik, mode privasi tidak perlu diaktifkan."),
|
||||||
("Follow remote cursor", ""),
|
("Follow remote cursor", "Ikuti kursor yang terhubung"),
|
||||||
("Follow remote window focus", ""),
|
("Follow remote window focus", "Ikuti jendela remote yang sedang aktif"),
|
||||||
("default_proxy_tip", ""),
|
("default_proxy_tip", "Pengaturan standar untuk protokol dan port adalah Socks5 dan 1080."),
|
||||||
("no_audio_input_device_tip", ""),
|
("no_audio_input_device_tip", "Perangkat input audio tidak terdeteksi."),
|
||||||
("Incoming", ""),
|
("Incoming", ""),
|
||||||
("Outgoing", ""),
|
("Outgoing", ""),
|
||||||
("Clear Wayland screen selection", ""),
|
("Clear Wayland screen selection", "Kosongkan pilihan layar Wayland"),
|
||||||
("clear_Wayland_screen_selection_tip", ""),
|
("clear_Wayland_screen_selection_tip", "Setelah mengosongkan pilihan layar, Kamu bisa memilih kembali layar untuk dibagi"),
|
||||||
("confirm_clear_Wayland_screen_selection_tip", ""),
|
("confirm_clear_Wayland_screen_selection_tip", "Kamu yakin ingin membersihkan pemilihan layar Wayland?"),
|
||||||
("android_new_voice_call_tip", ""),
|
("android_new_voice_call_tip", "Kamu mendapatkan permintaan panggilan suara baru. Jika diterima, audio akan berubah menjadi komunikasi suara."),
|
||||||
("texture_render_tip", ""),
|
("texture_render_tip", "Aktifkan rendering tekstur untuk membuat tampilan gambar lebih mulus. Kamu dapat menonaktifkan opsi ini jika terjadi masalah saat merender."),
|
||||||
("Use texture rendering", ""),
|
("Use texture rendering", "Aktifkan rendering tekstur"),
|
||||||
("Floating window", ""),
|
("Floating window", ""),
|
||||||
("floating_window_tip", ""),
|
("floating_window_tip", "Untuk menjaga layanan/service RustDesk agar tetap aktif"),
|
||||||
("Keep screen on", ""),
|
("Keep screen on", "Biarkan layar tetap menyala"),
|
||||||
("Never", ""),
|
("Never", "Tidak pernah"),
|
||||||
("During controlled", ""),
|
("During controlled", "Dalam proses pengendalian"),
|
||||||
("During service is on", ""),
|
("During service is on", ""),
|
||||||
("Capture screen using DirectX", ""),
|
("Capture screen using DirectX", "Rekam layar dengan DirectX"),
|
||||||
("Back", ""),
|
("Back", "Kembali"),
|
||||||
("Apps", ""),
|
("Apps", "App"),
|
||||||
("Volume up", ""),
|
("Volume up", "Naikkan volume"),
|
||||||
("Volume down", ""),
|
("Volume down", "Turunkan volume"),
|
||||||
("Power", ""),
|
("Power", ""),
|
||||||
("Telegram bot", ""),
|
("Telegram bot", ""),
|
||||||
("enable-bot-tip", ""),
|
("enable-bot-tip", "Jika fitur ini diaktifkan, Kamu dapat menerima kode 2FA dari bot, serta mendapatkan notifikasi tentang koneksi."),
|
||||||
("enable-bot-desc", ""),
|
("enable-bot-desc", "1. Buka chat dengan @BotFather.\n2. Kirim perintah \"/newbot\". Setelah menyelesaikan langkah ini, Kamu akan mendapatkan token\n3. Mulai percakapan dengan bot yang baru dibuat. Kirim pesan yang dimulai dengan garis miring (\"/\") seperti \"/hello\" untuk mengaktifkannya."),
|
||||||
("cancel-2fa-confirm-tip", ""),
|
("cancel-2fa-confirm-tip", "Apakah Kamu yakin ingin membatalkan 2FA?"),
|
||||||
("cancel-bot-confirm-tip", ""),
|
("cancel-bot-confirm-tip", "Apakah Kamu yakin ingin membatalkan bot Telegram?"),
|
||||||
("About RustDesk", ""),
|
("About RustDesk", "Tentang RustDesk"),
|
||||||
("Send clipboard keystrokes", ""),
|
("Send clipboard keystrokes", "Kirim keystrokes clipboard"),
|
||||||
("network_error_tip", ""),
|
("network_error_tip", "Periksa koneksi internet, lalu klik \"Coba lagi\"."),
|
||||||
("Unlock with PIN", ""),
|
("Unlock with PIN", "Buka menggunakan PIN"),
|
||||||
("Requires at least {} characters", ""),
|
("Requires at least {} characters", "Memerlukan setidaknya {} karakter."),
|
||||||
("Wrong PIN", ""),
|
("Wrong PIN", "PIN salah"),
|
||||||
("Set PIN", ""),
|
("Set PIN", "Atur PIN"),
|
||||||
("Enable trusted devices", ""),
|
("Enable trusted devices", "Izinkan perangkat tepercaya"),
|
||||||
("Manage trusted devices", ""),
|
("Manage trusted devices", "Kelola perangkat tepercaya"),
|
||||||
("Platform", ""),
|
("Platform", "Platform"),
|
||||||
("Days remaining", ""),
|
("Days remaining", "Sisa hari"),
|
||||||
("enable-trusted-devices-tip", ""),
|
("enable-trusted-devices-tip", "Tidak memerlukan verifikasi 2FA pada perangkat tepercaya."),
|
||||||
("Parent directory", ""),
|
("Parent directory", "Direktori utama"),
|
||||||
("Resume", ""),
|
("Resume", "Lanjutkan"),
|
||||||
("Invalid file name", ""),
|
("Invalid file name", "Nama file tidak valid"),
|
||||||
("one-way-file-transfer-tip", ""),
|
("one-way-file-transfer-tip", "Transfer file satu arah (One-way) telah diaktifkan pada sisi yang dikendalikan."),
|
||||||
("Authentication Required", ""),
|
("Authentication Required", "Diperlukan autentikasi"),
|
||||||
("Authenticate", ""),
|
("Authenticate", "Autentikasi"),
|
||||||
|
("web_id_input_tip", "Kamu bisa memasukkan ID pada server yang sama, akses IP langsung tidak didukung di klien web.\nJika Anda ingin mengakses perangkat di server lain, silakan tambahkan alamat server (<id>@<server_address>?key=<key_value>), contohnya:\n9123456234@192.168.16.1:21117?key=5Qbwsde3unUcJBtrx9ZkvUmwFNoExHzpryHuPUdqlWM=.\nUntuk mengakses perangkat di server publik, cukup masukkan \"<id>@public\", tanpa kunci/key."),
|
||||||
|
("Download", ""),
|
||||||
|
("Upload folder", ""),
|
||||||
|
("Upload files", ""),
|
||||||
|
("Clipboard is synchronized", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -369,7 +369,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Stop session recording", "Ferma registrazione sessione"),
|
("Stop session recording", "Ferma registrazione sessione"),
|
||||||
("Enable recording session", "Abilita registrazione sessione"),
|
("Enable recording session", "Abilita registrazione sessione"),
|
||||||
("Enable LAN discovery", "Abilita rilevamento LAN"),
|
("Enable LAN discovery", "Abilita rilevamento LAN"),
|
||||||
("Deny LAN discovery", "Disabilita rilevamento LAN"),
|
("Deny LAN discovery", "Non effettuare rilevamento LAN"),
|
||||||
("Write a message", "Scrivi un messaggio"),
|
("Write a message", "Scrivi un messaggio"),
|
||||||
("Prompt", "Richiedi"),
|
("Prompt", "Richiedi"),
|
||||||
("Please wait for confirmation of UAC...", "Attendi la conferma dell'UAC..."),
|
("Please wait for confirmation of UAC...", "Attendi la conferma dell'UAC..."),
|
||||||
@@ -559,7 +559,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Big tiles", "Icone grandi"),
|
("Big tiles", "Icone grandi"),
|
||||||
("Small tiles", "Icone piccole"),
|
("Small tiles", "Icone piccole"),
|
||||||
("List", "Elenco"),
|
("List", "Elenco"),
|
||||||
("Virtual display", "Scehrmo virtuale"),
|
("Virtual display", "Schermo virtuale"),
|
||||||
("Plug out all", "Scollega tutto"),
|
("Plug out all", "Scollega tutto"),
|
||||||
("True color (4:4:4)", "Colore reale (4:4:4)"),
|
("True color (4:4:4)", "Colore reale (4:4:4)"),
|
||||||
("Enable blocking user input", "Abilita blocco input utente"),
|
("Enable blocking user input", "Abilita blocco input utente"),
|
||||||
@@ -647,5 +647,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("one-way-file-transfer-tip", "Sul lato controllato è abilitato il trasferimento file unidirezionale."),
|
("one-way-file-transfer-tip", "Sul lato controllato è abilitato il trasferimento file unidirezionale."),
|
||||||
("Authentication Required", "Richiesta autenticazione"),
|
("Authentication Required", "Richiesta autenticazione"),
|
||||||
("Authenticate", "Autentica"),
|
("Authenticate", "Autentica"),
|
||||||
|
("web_id_input_tip", "È possibile inserire un ID nello stesso server, nel client web non è supportato l'accesso con IP diretto.\nSe vuoi accedere ad un dispositivo in un altro server, aggiungi l'indirizzo del server (<id>@<indirizzo_server>?key=<valore_chiave >), ad esempio,\n9123456234@192.168.16.1:21117?key=5Qbwsde3unUcJBtrx9ZkvUmwFNoExHzpryHuPUdqlWM=.\nSe vuoi accedere ad un dispositivo in un server pubblico, inserisci \"<id>@public\", la chiave non è necessaria per il server pubblico."),
|
||||||
|
("Download", "Download"),
|
||||||
|
("Upload folder", "Cartella upload"),
|
||||||
|
("Upload files", "File upload"),
|
||||||
|
("Clipboard is synchronized", "Gli appunti sono sincronizzati"),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -647,5 +647,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("one-way-file-transfer-tip", ""),
|
("one-way-file-transfer-tip", ""),
|
||||||
("Authentication Required", ""),
|
("Authentication Required", ""),
|
||||||
("Authenticate", ""),
|
("Authenticate", ""),
|
||||||
|
("web_id_input_tip", ""),
|
||||||
|
("Download", ""),
|
||||||
|
("Upload folder", ""),
|
||||||
|
("Upload files", ""),
|
||||||
|
("Clipboard is synchronized", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -647,5 +647,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("one-way-file-transfer-tip", "단방향 파일 전송은 제어되는 쪽에서 활성화됩니다."),
|
("one-way-file-transfer-tip", "단방향 파일 전송은 제어되는 쪽에서 활성화됩니다."),
|
||||||
("Authentication Required", "인증 필요함"),
|
("Authentication Required", "인증 필요함"),
|
||||||
("Authenticate", "인증"),
|
("Authenticate", "인증"),
|
||||||
|
("web_id_input_tip", ""),
|
||||||
|
("Download", ""),
|
||||||
|
("Upload folder", ""),
|
||||||
|
("Upload files", ""),
|
||||||
|
("Clipboard is synchronized", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -647,5 +647,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("one-way-file-transfer-tip", ""),
|
("one-way-file-transfer-tip", ""),
|
||||||
("Authentication Required", ""),
|
("Authentication Required", ""),
|
||||||
("Authenticate", ""),
|
("Authenticate", ""),
|
||||||
|
("web_id_input_tip", ""),
|
||||||
|
("Download", ""),
|
||||||
|
("Upload folder", ""),
|
||||||
|
("Upload files", ""),
|
||||||
|
("Clipboard is synchronized", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -647,5 +647,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("one-way-file-transfer-tip", ""),
|
("one-way-file-transfer-tip", ""),
|
||||||
("Authentication Required", ""),
|
("Authentication Required", ""),
|
||||||
("Authenticate", ""),
|
("Authenticate", ""),
|
||||||
|
("web_id_input_tip", ""),
|
||||||
|
("Download", ""),
|
||||||
|
("Upload folder", ""),
|
||||||
|
("Upload files", ""),
|
||||||
|
("Clipboard is synchronized", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -647,5 +647,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("one-way-file-transfer-tip", "Kontrolējamajā pusē ir iespējota vienvirziena failu pārsūtīšana."),
|
("one-way-file-transfer-tip", "Kontrolējamajā pusē ir iespējota vienvirziena failu pārsūtīšana."),
|
||||||
("Authentication Required", "Nepieciešama autentifikācija"),
|
("Authentication Required", "Nepieciešama autentifikācija"),
|
||||||
("Authenticate", "Autentificēt"),
|
("Authenticate", "Autentificēt"),
|
||||||
|
("web_id_input_tip", "Varat ievadīt ID tajā pašā serverī, tīmekļa klientā tiešā IP piekļuve netiek atbalstīta.\nJa vēlaties piekļūt ierīcei citā serverī, lūdzu, pievienojiet servera adresi (<id>@<server_address>?key=<key_value>), piemēram,\n9123456234@192.168.16.1:21117?key=5Qbwsde3unUcJBtrx9ZkvUmwFNoExHzpryHuPUdqlWM=.\nJa vēlaties piekļūt ierīcei publiskajā serverī, lūdzu, ievadiet \"<id>@public\", publiskajam serverim atslēga nav nepieciešama."),
|
||||||
|
("Download", "Lejupielādēt"),
|
||||||
|
("Upload folder", "Augšupielādēt mapi"),
|
||||||
|
("Upload files", "Augšupielādēt failus"),
|
||||||
|
("Clipboard is synchronized", "Starpliktuve ir sinhronizēta"),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -647,5 +647,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("one-way-file-transfer-tip", ""),
|
("one-way-file-transfer-tip", ""),
|
||||||
("Authentication Required", ""),
|
("Authentication Required", ""),
|
||||||
("Authenticate", ""),
|
("Authenticate", ""),
|
||||||
|
("web_id_input_tip", ""),
|
||||||
|
("Download", ""),
|
||||||
|
("Upload folder", ""),
|
||||||
|
("Upload files", ""),
|
||||||
|
("Clipboard is synchronized", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -647,5 +647,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("one-way-file-transfer-tip", "Eenzijdige bestandsoverdracht is ingeschakeld aan de gecontroleerde kant."),
|
("one-way-file-transfer-tip", "Eenzijdige bestandsoverdracht is ingeschakeld aan de gecontroleerde kant."),
|
||||||
("Authentication Required", "Verificatie vereist"),
|
("Authentication Required", "Verificatie vereist"),
|
||||||
("Authenticate", "Verificatie"),
|
("Authenticate", "Verificatie"),
|
||||||
|
("web_id_input_tip", "Je kunt een ID invoeren op dezelfde server, directe IP-toegang wordt niet ondersteund in de webclient.\nAls je toegang wilt tot een apparaat op een andere server, voeg je het serveradres toe (<id>@<server_adres>?key=<key_value>), bijvoorbeeld,\n9123456234@192.168.16.1:21117?key=5Qbwsde3unUcJBtrx9ZkvUmwFNoExHzpryHuPUdqlWM=.\nAls je toegang wilt krijgen tot een apparaat op een publieke server, voer dan \"<id>@public\" in, sleutel is niet nodig voor de publieke server."),
|
||||||
|
("Download", ""),
|
||||||
|
("Upload folder", ""),
|
||||||
|
("Upload files", ""),
|
||||||
|
("Clipboard is synchronized", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -647,5 +647,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("one-way-file-transfer-tip", ""),
|
("one-way-file-transfer-tip", ""),
|
||||||
("Authentication Required", ""),
|
("Authentication Required", ""),
|
||||||
("Authenticate", ""),
|
("Authenticate", ""),
|
||||||
|
("web_id_input_tip", ""),
|
||||||
|
("Download", ""),
|
||||||
|
("Upload folder", ""),
|
||||||
|
("Upload files", ""),
|
||||||
|
("Clipboard is synchronized", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -647,5 +647,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("one-way-file-transfer-tip", ""),
|
("one-way-file-transfer-tip", ""),
|
||||||
("Authentication Required", ""),
|
("Authentication Required", ""),
|
||||||
("Authenticate", ""),
|
("Authenticate", ""),
|
||||||
|
("web_id_input_tip", ""),
|
||||||
|
("Download", ""),
|
||||||
|
("Upload folder", ""),
|
||||||
|
("Upload files", ""),
|
||||||
|
("Clipboard is synchronized", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -647,5 +647,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("one-way-file-transfer-tip", ""),
|
("one-way-file-transfer-tip", ""),
|
||||||
("Authentication Required", ""),
|
("Authentication Required", ""),
|
||||||
("Authenticate", ""),
|
("Authenticate", ""),
|
||||||
|
("web_id_input_tip", ""),
|
||||||
|
("Download", ""),
|
||||||
|
("Upload folder", ""),
|
||||||
|
("Upload files", ""),
|
||||||
|
("Clipboard is synchronized", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -647,5 +647,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("one-way-file-transfer-tip", ""),
|
("one-way-file-transfer-tip", ""),
|
||||||
("Authentication Required", ""),
|
("Authentication Required", ""),
|
||||||
("Authenticate", ""),
|
("Authenticate", ""),
|
||||||
|
("web_id_input_tip", ""),
|
||||||
|
("Download", ""),
|
||||||
|
("Upload folder", ""),
|
||||||
|
("Upload files", ""),
|
||||||
|
("Clipboard is synchronized", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -647,5 +647,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("one-way-file-transfer-tip", "На управляемой стороне включена односторонняя передача файлов."),
|
("one-way-file-transfer-tip", "На управляемой стороне включена односторонняя передача файлов."),
|
||||||
("Authentication Required", "Требуется аутентификация"),
|
("Authentication Required", "Требуется аутентификация"),
|
||||||
("Authenticate", "Аутентификация"),
|
("Authenticate", "Аутентификация"),
|
||||||
|
("web_id_input_tip", "Можно ввести ID на том же сервере, прямой доступ по IP в веб-клиенте не поддерживается.\nЕсли вы хотите получить доступ к устройству на другом сервере, добавьте адрес сервера (<id>@<адрес_сервера>?key=<ключ>), например,\n9123456234@192.168.16.1:21117?key=5Qbwsde3unUcJBtrx9ZkvUmwFNoExHzpryHuPUdqlWM=.\nЕсли вы хотите получить доступ к устройству на публичном сервере, введите \"<id>@public\", для публичного сервера ключ не нужен."),
|
||||||
|
("Download", ""),
|
||||||
|
("Upload folder", ""),
|
||||||
|
("Upload files", ""),
|
||||||
|
("Clipboard is synchronized", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -647,5 +647,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("one-way-file-transfer-tip", ""),
|
("one-way-file-transfer-tip", ""),
|
||||||
("Authentication Required", ""),
|
("Authentication Required", ""),
|
||||||
("Authenticate", ""),
|
("Authenticate", ""),
|
||||||
|
("web_id_input_tip", ""),
|
||||||
|
("Download", ""),
|
||||||
|
("Upload folder", ""),
|
||||||
|
("Upload files", ""),
|
||||||
|
("Clipboard is synchronized", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
533
src/lang/sl.rs
533
src/lang/sl.rs
@@ -37,19 +37,19 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Clipboard is empty", "Odložišče je prazno"),
|
("Clipboard is empty", "Odložišče je prazno"),
|
||||||
("Stop service", "Ustavi storitev"),
|
("Stop service", "Ustavi storitev"),
|
||||||
("Change ID", "Spremeni ID"),
|
("Change ID", "Spremeni ID"),
|
||||||
("Your new ID", ""),
|
("Your new ID", "Vaš nov ID"),
|
||||||
("length %min% to %max%", ""),
|
("length %min% to %max%", "dolžina od %min% do %max%"),
|
||||||
("starts with a letter", ""),
|
("starts with a letter", "začne se s črko"),
|
||||||
("allowed characters", ""),
|
("allowed characters", "dovoljeni znaki"),
|
||||||
("id_change_tip", "Dovoljeni znaki so a-z, A-Z (brez šumnikov), 0-9 in _. Prvi znak mora biti črka, dolžina od 6 do 16 znakov."),
|
("id_change_tip", "Dovoljeni znaki so a-z, A-Z (brez šumnikov), 0-9 in _. Prvi znak mora biti črka, dolžina od 6 do 16 znakov."),
|
||||||
("Website", "Spletna stran"),
|
("Website", "Spletna stran"),
|
||||||
("About", "O programu"),
|
("About", "O programu"),
|
||||||
("Slogan_tip", ""),
|
("Slogan_tip", ""),
|
||||||
("Privacy Statement", ""),
|
("Privacy Statement", "Izjava o zasebnosti"),
|
||||||
("Mute", "Izklopi zvok"),
|
("Mute", "Izklopi zvok"),
|
||||||
("Build Date", ""),
|
("Build Date", "Datum graditve"),
|
||||||
("Version", ""),
|
("Version", "Različica"),
|
||||||
("Home", ""),
|
("Home", "Začetek"),
|
||||||
("Audio Input", "Avdio vhod"),
|
("Audio Input", "Avdio vhod"),
|
||||||
("Enhancements", "Izboljšave"),
|
("Enhancements", "Izboljšave"),
|
||||||
("Hardware Codec", "Strojni kodek"),
|
("Hardware Codec", "Strojni kodek"),
|
||||||
@@ -210,27 +210,27 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Closed manually by the peer", "Povezavo ročno prekinil odjemalec"),
|
("Closed manually by the peer", "Povezavo ročno prekinil odjemalec"),
|
||||||
("Enable remote configuration modification", "Omogoči oddaljeno spreminjanje nastavitev"),
|
("Enable remote configuration modification", "Omogoči oddaljeno spreminjanje nastavitev"),
|
||||||
("Run without install", "Zaženi brez namestitve"),
|
("Run without install", "Zaženi brez namestitve"),
|
||||||
("Connect via relay", ""),
|
("Connect via relay", "Poveži preko posrednika"),
|
||||||
("Always connect via relay", "Vedno poveži preko posrednika"),
|
("Always connect via relay", "Vedno poveži preko posrednika"),
|
||||||
("whitelist_tip", "Dostop je možen samo iz dovoljenih IPjev"),
|
("whitelist_tip", "Dostop je možen samo iz dovoljenih IPjev"),
|
||||||
("Login", "Prijavi"),
|
("Login", "Prijavi"),
|
||||||
("Verify", ""),
|
("Verify", "Preveri"),
|
||||||
("Remember me", ""),
|
("Remember me", "Zapomni si me"),
|
||||||
("Trust this device", ""),
|
("Trust this device", "Zaupaj tej napravi"),
|
||||||
("Verification code", ""),
|
("Verification code", "Koda za preverjanje"),
|
||||||
("verification_tip", ""),
|
("verification_tip", "Kodo za preverjanje prejmete na registrirani e-poštni naslov"),
|
||||||
("Logout", "Odjavi"),
|
("Logout", "Odjavi"),
|
||||||
("Tags", "Oznake"),
|
("Tags", "Oznake"),
|
||||||
("Search ID", "Išči ID"),
|
("Search ID", "Išči ID"),
|
||||||
("whitelist_sep", "Naslovi ločeni z vejico, podpičjem, presledkom ali novo vrstico"),
|
("whitelist_sep", "Naslovi ločeni z vejico, podpičjem, presledkom ali novo vrstico"),
|
||||||
("Add ID", "Dodaj ID"),
|
("Add ID", "Dodaj ID"),
|
||||||
("Add Tag", "Dodaj oznako"),
|
("Add Tag", "Dodaj oznako"),
|
||||||
("Unselect all tags", ""),
|
("Unselect all tags", "Odznači vse oznake"),
|
||||||
("Network error", "Omrežna napaka"),
|
("Network error", "Omrežna napaka"),
|
||||||
("Username missed", "Up. ime izpuščeno"),
|
("Username missed", "Up. ime izpuščeno"),
|
||||||
("Password missed", "Geslo izpuščeno"),
|
("Password missed", "Geslo izpuščeno"),
|
||||||
("Wrong credentials", "Napačne poverilnice"),
|
("Wrong credentials", "Napačne poverilnice"),
|
||||||
("The verification code is incorrect or has expired", ""),
|
("The verification code is incorrect or has expired", "Koda za preverjanje je napačna, ali pa je potekla"),
|
||||||
("Edit Tag", "Uredi oznako"),
|
("Edit Tag", "Uredi oznako"),
|
||||||
("Forget Password", "Pozabi geslo"),
|
("Forget Password", "Pozabi geslo"),
|
||||||
("Favorites", "Priljubljene"),
|
("Favorites", "Priljubljene"),
|
||||||
@@ -248,7 +248,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Are you sure to close the connection?", "Ali želite prekiniti povezavo?"),
|
("Are you sure to close the connection?", "Ali želite prekiniti povezavo?"),
|
||||||
("Download new version", "Prenesi novo različico"),
|
("Download new version", "Prenesi novo različico"),
|
||||||
("Touch mode", "Način dotika"),
|
("Touch mode", "Način dotika"),
|
||||||
("Mouse mode", "Način mišle"),
|
("Mouse mode", "Način miške"),
|
||||||
("One-Finger Tap", "Tap z enim prstom"),
|
("One-Finger Tap", "Tap z enim prstom"),
|
||||||
("Left Mouse", "Leva tipka miške"),
|
("Left Mouse", "Leva tipka miške"),
|
||||||
("One-Long Tap", "Dolg tap z enim prstom"),
|
("One-Long Tap", "Dolg tap z enim prstom"),
|
||||||
@@ -286,8 +286,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("android_service_will_start_tip", "Z vklopom zajema zaslona se bo samodejno zagnala storitev, ki omogoča da oddaljene naprave pošljejo zahtevo za povezavo na vašo napravo."),
|
("android_service_will_start_tip", "Z vklopom zajema zaslona se bo samodejno zagnala storitev, ki omogoča da oddaljene naprave pošljejo zahtevo za povezavo na vašo napravo."),
|
||||||
("android_stop_service_tip", "Z zaustavitvijo storitve bodo samodejno prekinjene vse oddaljene povezave."),
|
("android_stop_service_tip", "Z zaustavitvijo storitve bodo samodejno prekinjene vse oddaljene povezave."),
|
||||||
("android_version_audio_tip", "Trenutna različica Androida ne omogoča zajema zvoka. Za zajem zvoka nadgradite na Android 10 ali novejši."),
|
("android_version_audio_tip", "Trenutna različica Androida ne omogoča zajema zvoka. Za zajem zvoka nadgradite na Android 10 ali novejši."),
|
||||||
("android_start_service_tip", ""),
|
("android_start_service_tip", "Tapnite [Zaženi storitev] ali pa omogočite pravico [Zajemanje zaslona] za zagon storitve deljenja zaslona."),
|
||||||
("android_permission_may_not_change_tip", ""),
|
("android_permission_may_not_change_tip", "Pravic za že vzpostavljene povezave ne morete spremeniti brez ponovne vzpostavitve povezave."),
|
||||||
("Account", "Račun"),
|
("Account", "Račun"),
|
||||||
("Overwrite", "Prepiši"),
|
("Overwrite", "Prepiši"),
|
||||||
("This file exists, skip or overwrite this file?", "Datoteka obstaja, izpusti ali prepiši?"),
|
("This file exists, skip or overwrite this file?", "Datoteka obstaja, izpusti ali prepiši?"),
|
||||||
@@ -306,8 +306,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Keep RustDesk background service", "Ohrani RustDeskovo storitev v ozadju"),
|
("Keep RustDesk background service", "Ohrani RustDeskovo storitev v ozadju"),
|
||||||
("Ignore Battery Optimizations", "Prezri optimizacije baterije"),
|
("Ignore Battery Optimizations", "Prezri optimizacije baterije"),
|
||||||
("android_open_battery_optimizations_tip", "Če želite izklopiti to možnost, pojdite v nastavitve aplikacije RustDesk, poiščite »Baterija« in izklopite »Neomejeno«"),
|
("android_open_battery_optimizations_tip", "Če želite izklopiti to možnost, pojdite v nastavitve aplikacije RustDesk, poiščite »Baterija« in izklopite »Neomejeno«"),
|
||||||
("Start on boot", ""),
|
("Start on boot", "Zaženi ob vklopu"),
|
||||||
("Start the screen sharing service on boot, requires special permissions", ""),
|
("Start the screen sharing service on boot, requires special permissions", "Zaženi storitev deljenja zaslona ob vklopu, zahteva posebna dovoljenja"),
|
||||||
("Connection not allowed", "Povezava ni dovoljena"),
|
("Connection not allowed", "Povezava ni dovoljena"),
|
||||||
("Legacy mode", "Stari način"),
|
("Legacy mode", "Stari način"),
|
||||||
("Map mode", "Način preslikave"),
|
("Map mode", "Način preslikave"),
|
||||||
@@ -330,8 +330,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Ratio", "Razmerje"),
|
("Ratio", "Razmerje"),
|
||||||
("Image Quality", "Kakovost slike"),
|
("Image Quality", "Kakovost slike"),
|
||||||
("Scroll Style", "Način drsenja"),
|
("Scroll Style", "Način drsenja"),
|
||||||
("Show Toolbar", ""),
|
("Show Toolbar", "Prikaži orodno vrstico"),
|
||||||
("Hide Toolbar", ""),
|
("Hide Toolbar", "Skrij orodno vrstico"),
|
||||||
("Direct Connection", "Neposredna povezava"),
|
("Direct Connection", "Neposredna povezava"),
|
||||||
("Relay Connection", "Posredovana povezava"),
|
("Relay Connection", "Posredovana povezava"),
|
||||||
("Secure Connection", "Zavarovana povezava"),
|
("Secure Connection", "Zavarovana povezava"),
|
||||||
@@ -342,7 +342,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Security", "Varnost"),
|
("Security", "Varnost"),
|
||||||
("Theme", "Tema"),
|
("Theme", "Tema"),
|
||||||
("Dark Theme", "Temna tema"),
|
("Dark Theme", "Temna tema"),
|
||||||
("Light Theme", ""),
|
("Light Theme", "Svetla tema"),
|
||||||
("Dark", "Temna"),
|
("Dark", "Temna"),
|
||||||
("Light", "Svetla"),
|
("Light", "Svetla"),
|
||||||
("Follow System", "Sistemska"),
|
("Follow System", "Sistemska"),
|
||||||
@@ -359,8 +359,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Audio Input Device", "Vhodna naprava za zvok"),
|
("Audio Input Device", "Vhodna naprava za zvok"),
|
||||||
("Use IP Whitelisting", "Omogoči seznam dovoljenih IP naslovov"),
|
("Use IP Whitelisting", "Omogoči seznam dovoljenih IP naslovov"),
|
||||||
("Network", "Mreža"),
|
("Network", "Mreža"),
|
||||||
("Pin Toolbar", ""),
|
("Pin Toolbar", "Pripni orodno vrstico"),
|
||||||
("Unpin Toolbar", ""),
|
("Unpin Toolbar", "Odpni orodno vrstico"),
|
||||||
("Recording", "Snemanje"),
|
("Recording", "Snemanje"),
|
||||||
("Directory", "Imenik"),
|
("Directory", "Imenik"),
|
||||||
("Automatically record incoming sessions", "Samodejno snemaj vhodne seje"),
|
("Automatically record incoming sessions", "Samodejno snemaj vhodne seje"),
|
||||||
@@ -409,243 +409,248 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Closed manually by web console", "Ročno zaprto iz spletne konzole"),
|
("Closed manually by web console", "Ročno zaprto iz spletne konzole"),
|
||||||
("Local keyboard type", "Lokalna vrsta tipkovnice"),
|
("Local keyboard type", "Lokalna vrsta tipkovnice"),
|
||||||
("Select local keyboard type", "Izberite lokalno vrsto tipkovnice"),
|
("Select local keyboard type", "Izberite lokalno vrsto tipkovnice"),
|
||||||
("software_render_tip", ""),
|
("software_render_tip", "Če na Linuxu uporabljate Nvidino grafično kartico in se oddaljeno okno zapre takoj po vzpostavitvi povezave, lahko pomaga preklop na odprtokodni gonilnik Nouveau in uporaba programskega upodabljanja. Potreben je ponovni zagon programa."),
|
||||||
("Always use software rendering", ""),
|
("Always use software rendering", "Vedno uporabi programsko upodabljanje"),
|
||||||
("config_input", ""),
|
("config_input", "Za nadzor oddaljenega namizja s tipkovnico, rabi RustDesk pravico »Nadzor vnosa«."),
|
||||||
("config_microphone", ""),
|
("config_microphone", "Za zajem zvoka, rabi RustDesk pravico »Snemanje zvoka«."),
|
||||||
("request_elevation_tip", ""),
|
("request_elevation_tip", "Lahko tudi zaprosite za dvig pravic, če je kdo na oddaljeni strani."),
|
||||||
("Wait", ""),
|
("Wait", "Čakaj"),
|
||||||
("Elevation Error", ""),
|
("Elevation Error", "Napaka pri povzdigovanju"),
|
||||||
("Ask the remote user for authentication", ""),
|
("Ask the remote user for authentication", "Vprašaj oddaljenega uporabnika za prijavo"),
|
||||||
("Choose this if the remote account is administrator", ""),
|
("Choose this if the remote account is administrator", "Izberite to, če ima oddaljeni uporabnik skrbniške pravice"),
|
||||||
("Transmit the username and password of administrator", ""),
|
("Transmit the username and password of administrator", "Vnesite poverilnice za skrbnika"),
|
||||||
("still_click_uac_tip", ""),
|
("still_click_uac_tip", "Oddaljeni uporabnik mora klikniti »Da« v oknu za nadzor uporabniškega računa."),
|
||||||
("Request Elevation", ""),
|
("Request Elevation", "Zahtevaj povzdig pravic"),
|
||||||
("wait_accept_uac_tip", ""),
|
("wait_accept_uac_tip", "Počakajte na potrditev oddaljenega uporabnika v oknu za nadzor uporabniškega računa."),
|
||||||
("Elevate successfully", ""),
|
("Elevate successfully", "Povzdig pravic uspešen"),
|
||||||
("uppercase", ""),
|
("uppercase", "velike črke"),
|
||||||
("lowercase", ""),
|
("lowercase", "male črke"),
|
||||||
("digit", ""),
|
("digit", "številke"),
|
||||||
("special character", ""),
|
("special character", "posebni znaki"),
|
||||||
("length>=8", ""),
|
("length>=8", "dolžina>=8"),
|
||||||
("Weak", ""),
|
("Weak", "Šibko"),
|
||||||
("Medium", ""),
|
("Medium", "Srednje"),
|
||||||
("Strong", ""),
|
("Strong", "Močno"),
|
||||||
("Switch Sides", ""),
|
("Switch Sides", "Zamenjaj strani"),
|
||||||
("Please confirm if you want to share your desktop?", ""),
|
("Please confirm if you want to share your desktop?", "Potrdite, če želite deliti vaše namizje"),
|
||||||
("Display", ""),
|
("Display", "Zaslon"),
|
||||||
("Default View Style", ""),
|
("Default View Style", "Privzeti način prikaza"),
|
||||||
("Default Scroll Style", ""),
|
("Default Scroll Style", "Privzeti način drsenja"),
|
||||||
("Default Image Quality", ""),
|
("Default Image Quality", "Privzeta kakovost slike"),
|
||||||
("Default Codec", ""),
|
("Default Codec", "Privzeti kodek"),
|
||||||
("Bitrate", ""),
|
("Bitrate", "Bitna hitrost"),
|
||||||
("FPS", ""),
|
("FPS", "Sličice/sekundo"),
|
||||||
("Auto", ""),
|
("Auto", "Samodejno"),
|
||||||
("Other Default Options", ""),
|
("Other Default Options", "Ostale privzete možnosti"),
|
||||||
("Voice call", ""),
|
("Voice call", "Glasovni klic"),
|
||||||
("Text chat", ""),
|
("Text chat", "Besedilni klepet"),
|
||||||
("Stop voice call", ""),
|
("Stop voice call", "Prekini glasovni klic"),
|
||||||
("relay_hint_tip", ""),
|
("relay_hint_tip", "Morda neposredna povezava ni možna; lahko se poikusite povezati preko posrednika. Če želite uporabiti posrednika ob prvem poizkusu vzpotavljanja povezave, lahko na konec IDja dodate »/r«, ali pa izberete možnost »Vedno poveži preko posrednika« v kartici nedavnih sej, če le-ta obstja."),
|
||||||
("Reconnect", ""),
|
("Reconnect", "Ponovna povezava"),
|
||||||
("Codec", ""),
|
("Codec", "Kodek"),
|
||||||
("Resolution", ""),
|
("Resolution", "Ločljivost"),
|
||||||
("No transfers in progress", ""),
|
("No transfers in progress", "Trenutno ni prenosov"),
|
||||||
("Set one-time password length", ""),
|
("Set one-time password length", "Nastavi dolžino enkratnega gesla"),
|
||||||
("RDP Settings", ""),
|
("RDP Settings", "Nastavitve za RDP"),
|
||||||
("Sort by", ""),
|
("Sort by", "Razvrsti po"),
|
||||||
("New Connection", ""),
|
("New Connection", "Nova povezava"),
|
||||||
("Restore", ""),
|
("Restore", "Obnovi"),
|
||||||
("Minimize", ""),
|
("Minimize", "Minimiziraj"),
|
||||||
("Maximize", ""),
|
("Maximize", "Maksimiziraj"),
|
||||||
("Your Device", ""),
|
("Your Device", "Vaša naprava"),
|
||||||
("empty_recent_tip", ""),
|
("empty_recent_tip", "Oops, ni nedavnih sej.\nPripravite novo."),
|
||||||
("empty_favorite_tip", ""),
|
("empty_favorite_tip", "Nimate še priljubljenih partnerjev?\nVzpostavite povezavo, in jo dodajte med priljubljene."),
|
||||||
("empty_lan_tip", ""),
|
("empty_lan_tip", "Nismo našli še nobenih partnerjev."),
|
||||||
("empty_address_book_tip", ""),
|
("empty_address_book_tip", "Vaš adresar je prazen."),
|
||||||
("eg: admin", ""),
|
("eg: admin", "npr. admin"),
|
||||||
("Empty Username", ""),
|
("Empty Username", "Prazno uporabniško ime"),
|
||||||
("Empty Password", ""),
|
("Empty Password", "Prazno geslo"),
|
||||||
("Me", ""),
|
("Me", "Jaz"),
|
||||||
("identical_file_tip", ""),
|
("identical_file_tip", "Datoteka je enaka partnerjevi"),
|
||||||
("show_monitors_tip", ""),
|
("show_monitors_tip", "Prikaži monitorje v orodni vrstici"),
|
||||||
("View Mode", ""),
|
("View Mode", "Način prikazovanja"),
|
||||||
("login_linux_tip", ""),
|
("login_linux_tip", "Prijaviti se morate v oddaljeni Linux račun in omogočiti namizno sejo X."),
|
||||||
("verify_rustdesk_password_tip", ""),
|
("verify_rustdesk_password_tip", "Preveri geslo za RustDesk"),
|
||||||
("remember_account_tip", ""),
|
("remember_account_tip", "Zapomni si ta račun"),
|
||||||
("os_account_desk_tip", ""),
|
("os_account_desk_tip", "Ta račun se uporabi za prijavo v oddaljeni sistem in omogči namizno sejo v napravi brez monitorja."),
|
||||||
("OS Account", ""),
|
("OS Account", "Račun operacijskega sistema"),
|
||||||
("another_user_login_title_tip", ""),
|
("another_user_login_title_tip", "Prijavljen je že drug uporabnik"),
|
||||||
("another_user_login_text_tip", ""),
|
("another_user_login_text_tip", "Prekini"),
|
||||||
("xorg_not_found_title_tip", ""),
|
("xorg_not_found_title_tip", "Xorg ni najden"),
|
||||||
("xorg_not_found_text_tip", ""),
|
("xorg_not_found_text_tip", "Namestite Xorg"),
|
||||||
("no_desktop_title_tip", ""),
|
("no_desktop_title_tip", "Namizno okolje ni na voljo"),
|
||||||
("no_desktop_text_tip", ""),
|
("no_desktop_text_tip", "Namestite GNOME"),
|
||||||
("No need to elevate", ""),
|
("No need to elevate", "Povzdig pravic ni potreben"),
|
||||||
("System Sound", ""),
|
("System Sound", "Sistemski zvok"),
|
||||||
("Default", ""),
|
("Default", "Privzeto"),
|
||||||
("New RDP", ""),
|
("New RDP", "Nova RDP povezava"),
|
||||||
("Fingerprint", ""),
|
("Fingerprint", "Prstni odtis"),
|
||||||
("Copy Fingerprint", ""),
|
("Copy Fingerprint", "Kopiraj prstni odtis"),
|
||||||
("no fingerprints", ""),
|
("no fingerprints", "ni prstnega odtisa"),
|
||||||
("Select a peer", ""),
|
("Select a peer", "Izberite partnerja"),
|
||||||
("Select peers", ""),
|
("Select peers", "Izberite partnerje"),
|
||||||
("Plugins", ""),
|
("Plugins", "Vključki"),
|
||||||
("Uninstall", ""),
|
("Uninstall", "Odstrani"),
|
||||||
("Update", ""),
|
("Update", "Posodobi"),
|
||||||
("Enable", ""),
|
("Enable", "Omogoči"),
|
||||||
("Disable", ""),
|
("Disable", "Onemogoči"),
|
||||||
("Options", ""),
|
("Options", "Možnosti"),
|
||||||
("resolution_original_tip", ""),
|
("resolution_original_tip", "Izvirna ločljivost"),
|
||||||
("resolution_fit_local_tip", ""),
|
("resolution_fit_local_tip", "Prilagodi lokalni ločljivosti"),
|
||||||
("resolution_custom_tip", ""),
|
("resolution_custom_tip", "Ločljivost po meri"),
|
||||||
("Collapse toolbar", ""),
|
("Collapse toolbar", "Strni orodno vrstico"),
|
||||||
("Accept and Elevate", ""),
|
("Accept and Elevate", "Sprejmi in povzdigni pravice"),
|
||||||
("accept_and_elevate_btn_tooltip", ""),
|
("accept_and_elevate_btn_tooltip", "Sprejmi povezavo in preko nadzora uporabniškera računa povišaj pravice"),
|
||||||
("clipboard_wait_response_timeout_tip", ""),
|
("clipboard_wait_response_timeout_tip", "Časovna omejitev pri kopiranju je potekla"),
|
||||||
("Incoming connection", ""),
|
("Incoming connection", "Dohodna povezava"),
|
||||||
("Outgoing connection", ""),
|
("Outgoing connection", "Odhodna povezava"),
|
||||||
("Exit", ""),
|
("Exit", "Izhod"),
|
||||||
("Open", ""),
|
("Open", "Odpri"),
|
||||||
("logout_tip", ""),
|
("logout_tip", "Ali ste prepričani, da se želite odjaviti?"),
|
||||||
("Service", ""),
|
("Service", "Storitev"),
|
||||||
("Start", ""),
|
("Start", "Zaženi"),
|
||||||
("Stop", ""),
|
("Stop", "Ustavi"),
|
||||||
("exceed_max_devices", ""),
|
("exceed_max_devices", "Dosegli ste največje dovoljeno število upravljanih naprav."),
|
||||||
("Sync with recent sessions", ""),
|
("Sync with recent sessions", "Sinhroniziraj z nedavnimi sejami"),
|
||||||
("Sort tags", ""),
|
("Sort tags", "Uredi oznake"),
|
||||||
("Open connection in new tab", ""),
|
("Open connection in new tab", "Odpri povezavo na novem zavihku"),
|
||||||
("Move tab to new window", ""),
|
("Move tab to new window", "Premakni zavihek v novo okno"),
|
||||||
("Can not be empty", ""),
|
("Can not be empty", "Ne more biti prazno"),
|
||||||
("Already exists", ""),
|
("Already exists", "Že obstaja"),
|
||||||
("Change Password", ""),
|
("Change Password", "Spremeni geslo"),
|
||||||
("Refresh Password", ""),
|
("Refresh Password", "Osveži geslo"),
|
||||||
("ID", ""),
|
("ID", "ID"),
|
||||||
("Grid View", ""),
|
("Grid View", "Mrežni pogled"),
|
||||||
("List View", ""),
|
("List View", "Pogled seznama"),
|
||||||
("Select", ""),
|
("Select", "Izberi"),
|
||||||
("Toggle Tags", ""),
|
("Toggle Tags", "Preklopi oznake"),
|
||||||
("pull_ab_failed_tip", ""),
|
("pull_ab_failed_tip", "Adresarja ni bilo mogoče osvežiti"),
|
||||||
("push_ab_failed_tip", ""),
|
("push_ab_failed_tip", "Adresarja ni bilo mogoče poslati na strežnik"),
|
||||||
("synced_peer_readded_tip", ""),
|
("synced_peer_readded_tip", "Naprave, ki so bile prisotne v nedavnih sejah bodo sinhronizirane z adresarjem."),
|
||||||
("Change Color", ""),
|
("Change Color", "Spremeni barvo"),
|
||||||
("Primary Color", ""),
|
("Primary Color", "Osnovne barve"),
|
||||||
("HSV Color", ""),
|
("HSV Color", "Barve HSV"),
|
||||||
("Installation Successful!", ""),
|
("Installation Successful!", "Namestitev uspešna"),
|
||||||
("Installation failed!", ""),
|
("Installation failed!", "Namestitev ni uspela"),
|
||||||
("Reverse mouse wheel", ""),
|
("Reverse mouse wheel", "Obrni smer drsenja miškinega kolesca"),
|
||||||
("{} sessions", ""),
|
("{} sessions", "{} sej"),
|
||||||
("scam_title", ""),
|
("scam_title", "Lahko gre za prevaro!"),
|
||||||
("scam_text1", ""),
|
("scam_text1", "V primeru, da vas je nekdo, ki ga ne poznate in mu zaupate prosil, da uporabite RustDesk, prekinite klic in program zaprite."),
|
||||||
("scam_text2", ""),
|
("scam_text2", "RustDesk omogoča popoln nadzor nad vašim računalnikom in telefonom, in se lahko uporabi za krajo vašega denarja ali pa zasebnih podatkov."),
|
||||||
("Don't show again", ""),
|
("Don't show again", "Ne prikaži znova"),
|
||||||
("I Agree", ""),
|
("I Agree", "Strinjam se"),
|
||||||
("Decline", ""),
|
("Decline", "Zavrni"),
|
||||||
("Timeout in minutes", ""),
|
("Timeout in minutes", "Časovna omejitev v minutah"),
|
||||||
("auto_disconnect_option_tip", ""),
|
("auto_disconnect_option_tip", "Samodejno prekini neaktivne seje"),
|
||||||
("Connection failed due to inactivity", ""),
|
("Connection failed due to inactivity", "Povezava je bila prekinjena zaradi neaktivnosti"),
|
||||||
("Check for software update on startup", ""),
|
("Check for software update on startup", "Preveri za posodobitve ob zagonu"),
|
||||||
("upgrade_rustdesk_server_pro_to_{}_tip", ""),
|
("upgrade_rustdesk_server_pro_to_{}_tip", "Prosimo, nadgradite RustDesk Server Pro na različico {} ali novejšo."),
|
||||||
("pull_group_failed_tip", ""),
|
("pull_group_failed_tip", "Osveževanje skupine ni uspelo"),
|
||||||
("Filter by intersection", ""),
|
("Filter by intersection", "Filtriraj po preseku"),
|
||||||
("Remove wallpaper during incoming sessions", ""),
|
("Remove wallpaper during incoming sessions", "Odstrani sliko ozadja ob dohodnih povezavah"),
|
||||||
("Test", ""),
|
("Test", "Test"),
|
||||||
("display_is_plugged_out_msg", ""),
|
("display_is_plugged_out_msg", "Zaslon je bil odklopljen, preklop na primarni zaslon."),
|
||||||
("No displays", ""),
|
("No displays", "Ni zaslonov"),
|
||||||
("Open in new window", ""),
|
("Open in new window", "Odpri v novem oknu"),
|
||||||
("Show displays as individual windows", ""),
|
("Show displays as individual windows", "Prikaži zaslone kot ločena okna"),
|
||||||
("Use all my displays for the remote session", ""),
|
("Use all my displays for the remote session", "Uporabi vse zaslone za oddaljeno sejo"),
|
||||||
("selinux_tip", ""),
|
("selinux_tip", "Na vaši napravi je omogčen SELinux, kar lahko povzroča težave pri oddaljenem nadzoru"),
|
||||||
("Change view", ""),
|
("Change view", "Spremeni pogled"),
|
||||||
("Big tiles", ""),
|
("Big tiles", "Velike ploščice"),
|
||||||
("Small tiles", ""),
|
("Small tiles", "Majhne ploščice"),
|
||||||
("List", ""),
|
("List", "Seznam"),
|
||||||
("Virtual display", ""),
|
("Virtual display", "Navidezni zaslon"),
|
||||||
("Plug out all", ""),
|
("Plug out all", "Odklopi vse"),
|
||||||
("True color (4:4:4)", ""),
|
("True color (4:4:4)", "Popolne barve (4:4:4)"),
|
||||||
("Enable blocking user input", ""),
|
("Enable blocking user input", "Omogoči blokiranje vnosa"),
|
||||||
("id_input_tip", ""),
|
("id_input_tip", "Vnesete lahko ID, neposredni IP naslov, ali pa domeno in vrata (<domena>:<vrata>)\nČe želite dostopati do naprave na drugem strežniku, pripnite naslov strežnika (<id>@<naslov_strežnika>?key=<ključ>), npr. 9123456234@192.168.16.1:21117?key=5Qbwsde3unUcJBtrx9ZkvUmwFNoExHzpryHuPUdqlWM=.\nČe želite dostopati do naprave na javnem strežniku, vnesite »<id>@public«; ključ za javni strežnik ni potreben.\nČe želite vsiliti povezavo preko posrednika, pripnite »/r« na konec IDja, npr. »9123456234/r«."),
|
||||||
("privacy_mode_impl_mag_tip", ""),
|
("privacy_mode_impl_mag_tip", "Način 1"),
|
||||||
("privacy_mode_impl_virtual_display_tip", ""),
|
("privacy_mode_impl_virtual_display_tip", "Način 2"),
|
||||||
("Enter privacy mode", ""),
|
("Enter privacy mode", "Vstopi v zasebni način"),
|
||||||
("Exit privacy mode", ""),
|
("Exit privacy mode", "Izstopi iz zasebnega načina"),
|
||||||
("idd_not_support_under_win10_2004_tip", ""),
|
("idd_not_support_under_win10_2004_tip", "Posredni gonilnik ni podprt. Za uporabo rabite Windows 10 2004 ali novejšo različico."),
|
||||||
("input_source_1_tip", ""),
|
("input_source_1_tip", "Vir vnosa 1"),
|
||||||
("input_source_2_tip", ""),
|
("input_source_2_tip", "Vir vnosa 2"),
|
||||||
("Swap control-command key", ""),
|
("Swap control-command key", "Zamenjaj tipki Ctrl-Command"),
|
||||||
("swap-left-right-mouse", ""),
|
("swap-left-right-mouse", "Zamenjaj levo in desno tipko miške"),
|
||||||
("2FA code", ""),
|
("2FA code", "Koda za dvostopenjsko preverjanje"),
|
||||||
("More", ""),
|
("More", "Več"),
|
||||||
("enable-2fa-title", ""),
|
("enable-2fa-title", "Omogoči dvostopenjsko preverjanje"),
|
||||||
("enable-2fa-desc", ""),
|
("enable-2fa-desc", "Pripravite vaš TOTP avtentikator. Uporabite lahko programe kot so Authy, Microsoft ali Google Authenticator, na vašem telefonu ali računalniku.\n\nZa omogočanje dvostopenjskega preverjanja, skenirajte QR kodo in vnesite kodo, ki jo prikaže aplikacija."),
|
||||||
("wrong-2fa-code", ""),
|
("wrong-2fa-code", "Kode ni bilo mogoče preveriti. Preverite, da je koda pravilna, in da je nastavitev ure točna."),
|
||||||
("enter-2fa-title", ""),
|
("enter-2fa-title", "Dvostopenjsko preverjanje"),
|
||||||
("Email verification code must be 6 characters.", ""),
|
("Email verification code must be 6 characters.", "E-poštna koda za preverjanje mora imeti 6 znakov."),
|
||||||
("2FA code must be 6 digits.", ""),
|
("2FA code must be 6 digits.", "Koda za dvostopenjsko preverjanje mora imeti 6 znakov."),
|
||||||
("Multiple Windows sessions found", ""),
|
("Multiple Windows sessions found", "Najdenih je bilo več Windows sej"),
|
||||||
("Please select the session you want to connect to", ""),
|
("Please select the session you want to connect to", "Izberite sejo, v katero se želite povezati"),
|
||||||
("powered_by_me", ""),
|
("powered_by_me", "Uporablja tehnologijo RustDesk"),
|
||||||
("outgoing_only_desk_tip", ""),
|
("outgoing_only_desk_tip", "To je prilagojena različica.\nLahko se povežete na druge naprave, druge naprave pa se k vam ne morejo povezati."),
|
||||||
("preset_password_warning", ""),
|
("preset_password_warning", "Ta prilagojena različica ima prednastavljeno geslo. Kdorkoli, ki pozna to geslo, lahko prevzame popoln nadzor nad vašim računalnikom. Če tega niste pričakovali, takoj odstranite program."),
|
||||||
("Security Alert", ""),
|
("Security Alert", "Varnostno opozorilo"),
|
||||||
("My address book", ""),
|
("My address book", "Moj adresar"),
|
||||||
("Personal", ""),
|
("Personal", "Osebni"),
|
||||||
("Owner", ""),
|
("Owner", "Lastnik"),
|
||||||
("Set shared password", ""),
|
("Set shared password", "Nastavi deljeno geslo"),
|
||||||
("Exist in", ""),
|
("Exist in", "Obstaja v"),
|
||||||
("Read-only", ""),
|
("Read-only", "Samo za branje"),
|
||||||
("Read/Write", ""),
|
("Read/Write", "Branje/pisanje"),
|
||||||
("Full Control", ""),
|
("Full Control", "Popoln nadzor"),
|
||||||
("share_warning_tip", ""),
|
("share_warning_tip", "Zgornja polja so deljena, in vidna vsem"),
|
||||||
("Everyone", ""),
|
("Everyone", "Vsi"),
|
||||||
("ab_web_console_tip", ""),
|
("ab_web_console_tip", "Več na spletni konzoli"),
|
||||||
("allow-only-conn-window-open-tip", ""),
|
("allow-only-conn-window-open-tip", "Dovoli povezavo samo če je okno RustDeska odprto"),
|
||||||
("no_need_privacy_mode_no_physical_displays_tip", ""),
|
("no_need_privacy_mode_no_physical_displays_tip", "Ni fizičnih zaslonov, zasebni način ni potreben"),
|
||||||
("Follow remote cursor", ""),
|
("Follow remote cursor", "Sledi oddaljenemu kazalcu"),
|
||||||
("Follow remote window focus", ""),
|
("Follow remote window focus", "Sledi oddaljenemu fokusu"),
|
||||||
("default_proxy_tip", ""),
|
("default_proxy_tip", "Privzeti protokol je Socks5 na vratih 1080"),
|
||||||
("no_audio_input_device_tip", ""),
|
("no_audio_input_device_tip", "Ni bilo možno najti vhodne zvočne naprave"),
|
||||||
("Incoming", ""),
|
("Incoming", "Dohodno"),
|
||||||
("Outgoing", ""),
|
("Outgoing", "Odhodno"),
|
||||||
("Clear Wayland screen selection", ""),
|
("Clear Wayland screen selection", "Počisti izbiro Wayland zaslona"),
|
||||||
("clear_Wayland_screen_selection_tip", ""),
|
("clear_Wayland_screen_selection_tip", "Po čiščenju izbire Wayland zaslona lahko ponovno izberete zaslon za delitev"),
|
||||||
("confirm_clear_Wayland_screen_selection_tip", ""),
|
("confirm_clear_Wayland_screen_selection_tip", "Ali res želite počistiti izbiro Wayland zaslona?"),
|
||||||
("android_new_voice_call_tip", ""),
|
("android_new_voice_call_tip", "Prejeli ste prošnjo za nov glasovni klic. Če sprejmete, bo zvok preklopljen na glasovno komunikacijo."),
|
||||||
("texture_render_tip", ""),
|
("texture_render_tip", "Uporabi upodabljanje tekstur, za gladkejše slike. Izklopite, če imate težave pri upodabljanju."),
|
||||||
("Use texture rendering", ""),
|
("Use texture rendering", "Uporabi upodabljanje tekstur"),
|
||||||
("Floating window", ""),
|
("Floating window", "Plavajoče okno"),
|
||||||
("floating_window_tip", ""),
|
("floating_window_tip", "Pomaga pri RustDesk storitvi v ozadju"),
|
||||||
("Keep screen on", ""),
|
("Keep screen on", "Ohranite zaslon prižgan"),
|
||||||
("Never", ""),
|
("Never", "Nikoli"),
|
||||||
("During controlled", ""),
|
("During controlled", "Med nadzorom"),
|
||||||
("During service is on", ""),
|
("During service is on", "Med vklopljeno storitvijo"),
|
||||||
("Capture screen using DirectX", ""),
|
("Capture screen using DirectX", "Uporabi DirectX za zajem zaslona"),
|
||||||
("Back", ""),
|
("Back", "Nazaj"),
|
||||||
("Apps", ""),
|
("Apps", "Aplikacije"),
|
||||||
("Volume up", ""),
|
("Volume up", "Glasneje"),
|
||||||
("Volume down", ""),
|
("Volume down", "Tišje"),
|
||||||
("Power", ""),
|
("Power", "Vklop/izklop"),
|
||||||
("Telegram bot", ""),
|
("Telegram bot", "Telegram bot"),
|
||||||
("enable-bot-tip", ""),
|
("enable-bot-tip", "Če vklopite to možnost, lahko dobite kodo za dvostopenjsko preverjanje od bota. Lahko se uporabi tudi za obveščanje o povezavi."),
|
||||||
("enable-bot-desc", ""),
|
("enable-bot-desc", "1. Odprite pogovor z @BotFather.\n2. Pošljite ukaz »/newbot« in prejeli boste žeton.\n3. Začnite pogovor z na novo narejenim botom. Pošljite sporočilo z desno poševnico (/) kot npr. »/hello« za aktivacijo."),
|
||||||
("cancel-2fa-confirm-tip", ""),
|
("cancel-2fa-confirm-tip", "Ali ste prepričani, da želite ukiniti dvostopenjsko preverjanje?"),
|
||||||
("cancel-bot-confirm-tip", ""),
|
("cancel-bot-confirm-tip", "Ali ste prepričani, da želite ukiniti Telegram bota?"),
|
||||||
("About RustDesk", ""),
|
("About RustDesk", "O RustDesku"),
|
||||||
("Send clipboard keystrokes", ""),
|
("Send clipboard keystrokes", "Vtipkaj vsebino odložišča"),
|
||||||
("network_error_tip", ""),
|
("network_error_tip", "Preverite vašo mrežno povezavo, nato kliknite Ponovi."),
|
||||||
("Unlock with PIN", ""),
|
("Unlock with PIN", "Odkleni s PINom"),
|
||||||
("Requires at least {} characters", ""),
|
("Requires at least {} characters", "Potrebuje vsaj {} znakov."),
|
||||||
("Wrong PIN", ""),
|
("Wrong PIN", "Napačen PIN"),
|
||||||
("Set PIN", ""),
|
("Set PIN", "Nastavi PIN"),
|
||||||
("Enable trusted devices", ""),
|
("Enable trusted devices", "Omogoči zaupanja vredne naprave"),
|
||||||
("Manage trusted devices", ""),
|
("Manage trusted devices", "Upravljaj zaupanja vredne naprave"),
|
||||||
("Platform", ""),
|
("Platform", "Platforma"),
|
||||||
("Days remaining", ""),
|
("Days remaining", "Preostane dni"),
|
||||||
("enable-trusted-devices-tip", ""),
|
("enable-trusted-devices-tip", "Na zaupanja vrednih napravah ni potrebno dvostopenjsko preverjanje"),
|
||||||
("Parent directory", ""),
|
("Parent directory", "Nadrejena mapa"),
|
||||||
("Resume", ""),
|
("Resume", "Nadaljuj"),
|
||||||
("Invalid file name", ""),
|
("Invalid file name", "Neveljavno ime datoteke"),
|
||||||
("one-way-file-transfer-tip", ""),
|
("one-way-file-transfer-tip", "Enosmerni prenos datotek je omogočen na nadzorovani strani"),
|
||||||
("Authentication Required", ""),
|
("Authentication Required", "Potrebno je preverjanje pristnosti"),
|
||||||
("Authenticate", ""),
|
("Authenticate", "Preverjanje pristnosti"),
|
||||||
|
("web_id_input_tip", "Vnesete lahko ID iz istega strežnika, neposredni dostop preko IP naslova v spletnem odjemalcu ni podprt.\nČe želite dostopati do naprave na drugem strežniku, pripnite naslov strežnika (<id>@<naslov_strežnika>?key=<ključ>), npr. 9123456234@192.168.16.1:21117?key=5Qbwsde3unUcJBtrx9ZkvUmwFNoExHzpryHuPUdqlWM=.\nČe želite dostopati do naprave na javnem strežniku, vnesite »<id>@public«; ključ za javni strežnik ni potreben."),
|
||||||
|
("Download", ""),
|
||||||
|
("Upload folder", ""),
|
||||||
|
("Upload files", ""),
|
||||||
|
("Clipboard is synchronized", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -647,5 +647,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("one-way-file-transfer-tip", ""),
|
("one-way-file-transfer-tip", ""),
|
||||||
("Authentication Required", ""),
|
("Authentication Required", ""),
|
||||||
("Authenticate", ""),
|
("Authenticate", ""),
|
||||||
|
("web_id_input_tip", ""),
|
||||||
|
("Download", ""),
|
||||||
|
("Upload folder", ""),
|
||||||
|
("Upload files", ""),
|
||||||
|
("Clipboard is synchronized", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -647,5 +647,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("one-way-file-transfer-tip", ""),
|
("one-way-file-transfer-tip", ""),
|
||||||
("Authentication Required", ""),
|
("Authentication Required", ""),
|
||||||
("Authenticate", ""),
|
("Authenticate", ""),
|
||||||
|
("web_id_input_tip", ""),
|
||||||
|
("Download", ""),
|
||||||
|
("Upload folder", ""),
|
||||||
|
("Upload files", ""),
|
||||||
|
("Clipboard is synchronized", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -647,5 +647,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("one-way-file-transfer-tip", ""),
|
("one-way-file-transfer-tip", ""),
|
||||||
("Authentication Required", ""),
|
("Authentication Required", ""),
|
||||||
("Authenticate", ""),
|
("Authenticate", ""),
|
||||||
|
("web_id_input_tip", ""),
|
||||||
|
("Download", ""),
|
||||||
|
("Upload folder", ""),
|
||||||
|
("Upload files", ""),
|
||||||
|
("Clipboard is synchronized", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -647,5 +647,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("one-way-file-transfer-tip", ""),
|
("one-way-file-transfer-tip", ""),
|
||||||
("Authentication Required", ""),
|
("Authentication Required", ""),
|
||||||
("Authenticate", ""),
|
("Authenticate", ""),
|
||||||
|
("web_id_input_tip", ""),
|
||||||
|
("Download", ""),
|
||||||
|
("Upload folder", ""),
|
||||||
|
("Upload files", ""),
|
||||||
|
("Clipboard is synchronized", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -647,5 +647,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("one-way-file-transfer-tip", ""),
|
("one-way-file-transfer-tip", ""),
|
||||||
("Authentication Required", ""),
|
("Authentication Required", ""),
|
||||||
("Authenticate", ""),
|
("Authenticate", ""),
|
||||||
|
("web_id_input_tip", ""),
|
||||||
|
("Download", ""),
|
||||||
|
("Upload folder", ""),
|
||||||
|
("Upload files", ""),
|
||||||
|
("Clipboard is synchronized", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -647,5 +647,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("one-way-file-transfer-tip", ""),
|
("one-way-file-transfer-tip", ""),
|
||||||
("Authentication Required", ""),
|
("Authentication Required", ""),
|
||||||
("Authenticate", ""),
|
("Authenticate", ""),
|
||||||
|
("web_id_input_tip", ""),
|
||||||
|
("Download", ""),
|
||||||
|
("Upload folder", ""),
|
||||||
|
("Upload files", ""),
|
||||||
|
("Clipboard is synchronized", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -310,7 +310,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Start the screen sharing service on boot, requires special permissions", "開機時啟動螢幕分享服務,需要特殊權限。"),
|
("Start the screen sharing service on boot, requires special permissions", "開機時啟動螢幕分享服務,需要特殊權限。"),
|
||||||
("Connection not allowed", "不允許連線"),
|
("Connection not allowed", "不允許連線"),
|
||||||
("Legacy mode", "傳統模式"),
|
("Legacy mode", "傳統模式"),
|
||||||
("Map mode", "1:1 傳輸模式"),
|
("Map mode", "1:1 傳輸模式"),
|
||||||
("Translate mode", "翻譯模式"),
|
("Translate mode", "翻譯模式"),
|
||||||
("Use permanent password", "使用固定密碼"),
|
("Use permanent password", "使用固定密碼"),
|
||||||
("Use both passwords", "同時使用兩種密碼"),
|
("Use both passwords", "同時使用兩種密碼"),
|
||||||
@@ -563,7 +563,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Plug out all", "拔出所有"),
|
("Plug out all", "拔出所有"),
|
||||||
("True color (4:4:4)", "全彩模式(4:4:4)"),
|
("True color (4:4:4)", "全彩模式(4:4:4)"),
|
||||||
("Enable blocking user input", "允許封鎖使用者輸入"),
|
("Enable blocking user input", "允許封鎖使用者輸入"),
|
||||||
("id_input_tip", "您可以輸入 ID、IP、或網域名稱+端口號(<網域名稱>:<端口號>)。\n如果您要存取位於其他伺服器上的設備,請在ID之後添加伺服器地址(<ID>@<伺服器地址>?key=<金鑰>)\n例如:9123456234@192.168.16.1:21117?key=5Qbwsde3unUcJBtrx9ZkvUmwFNoExHzpryHuPUdqlWM=\n要存取公共伺服器上的設備,請輸入\"<id>@public\",不需輸入金鑰。\n\n如果您想要在第一次連線時,強制使用中繼連接,請在 ID 的末尾添加 \"/r\",例如,\"9123456234/r\"。"),
|
("id_input_tip", "您可以輸入 ID、IP、或網域名稱+通訊埠號(<網域名稱>:<通訊埠號>)。\n如果您要存取位於其他伺服器上的設備,請在 ID 之後添加伺服器地址(<ID>@<伺服器地址>?key=<金鑰>)\n例如:9123456234@192.168.16.1:21117?key=5Qbwsde3unUcJBtrx9ZkvUmwFNoExHzpryHuPUdqlWM=\n要存取公共伺服器上的設備,請輸入\"<id>@public\",不需輸入金鑰。\n\n如果您想要在第一次連線時,強制使用中繼連接,請在 ID 的末尾添加 \"/r\",例如,\"9123456234/r\"。"),
|
||||||
("privacy_mode_impl_mag_tip", "模式 1"),
|
("privacy_mode_impl_mag_tip", "模式 1"),
|
||||||
("privacy_mode_impl_virtual_display_tip", "模式 2"),
|
("privacy_mode_impl_virtual_display_tip", "模式 2"),
|
||||||
("Enter privacy mode", "進入隱私模式"),
|
("Enter privacy mode", "進入隱私模式"),
|
||||||
@@ -602,7 +602,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("no_need_privacy_mode_no_physical_displays_tip", "沒有物理螢幕,沒必要使用隱私模式。"),
|
("no_need_privacy_mode_no_physical_displays_tip", "沒有物理螢幕,沒必要使用隱私模式。"),
|
||||||
("Follow remote cursor", "跟隨遠端游標"),
|
("Follow remote cursor", "跟隨遠端游標"),
|
||||||
("Follow remote window focus", "跟隨遠端視窗焦點"),
|
("Follow remote window focus", "跟隨遠端視窗焦點"),
|
||||||
("default_proxy_tip", "預設代理協定及端口為 Socks5 和 1080"),
|
("default_proxy_tip", "預設代理協定及通訊埠為 Socks5 和 1080"),
|
||||||
("no_audio_input_device_tip", "未找到音訊輸入裝置"),
|
("no_audio_input_device_tip", "未找到音訊輸入裝置"),
|
||||||
("Incoming", "連入"),
|
("Incoming", "連入"),
|
||||||
("Outgoing", "連出"),
|
("Outgoing", "連出"),
|
||||||
@@ -647,5 +647,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("one-way-file-transfer-tip", "被控端啟用了單向文件傳輸"),
|
("one-way-file-transfer-tip", "被控端啟用了單向文件傳輸"),
|
||||||
("Authentication Required", "需要身分驗證"),
|
("Authentication Required", "需要身分驗證"),
|
||||||
("Authenticate", "認證"),
|
("Authenticate", "認證"),
|
||||||
|
("web_id_input_tip", "您可以輸入同一個伺服器內的 ID,Web 客戶端不支援直接 IP 存取。\n如果您要存取位於其他伺服器上的設備,請在 ID 之後添加伺服器地址(<ID>@<伺服器地址>?key=<金鑰>)\n例如:9123456234@192.168.16.1:21117?key=5Qbwsde3unUcJBtrx9ZkvUmwFNoExHzpryHuPUdqlWM=\n要存取公共伺服器上的設備,請輸入\"<id>@public\",不需輸入金鑰。"),
|
||||||
|
("Download", "下載"),
|
||||||
|
("Upload folder", "上傳資料夾"),
|
||||||
|
("Upload files", "上傳檔案"),
|
||||||
|
("Clipboard is synchronized", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -351,7 +351,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Enable audio", "Увімкнути аудіо"),
|
("Enable audio", "Увімкнути аудіо"),
|
||||||
("Unlock Network Settings", "Розблокувати мережеві налаштування"),
|
("Unlock Network Settings", "Розблокувати мережеві налаштування"),
|
||||||
("Server", "Сервер"),
|
("Server", "Сервер"),
|
||||||
("Direct IP Access", "Прямий IP доступ"),
|
("Direct IP Access", "Прямий IP-доступ"),
|
||||||
("Proxy", "Проксі"),
|
("Proxy", "Проксі"),
|
||||||
("Apply", "Застосувати"),
|
("Apply", "Застосувати"),
|
||||||
("Disconnect all devices?", "Відʼєднати всі прилади?"),
|
("Disconnect all devices?", "Відʼєднати всі прилади?"),
|
||||||
@@ -469,12 +469,12 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("identical_file_tip", "Цей файл ідентичний з тим, що на вузлі"),
|
("identical_file_tip", "Цей файл ідентичний з тим, що на вузлі"),
|
||||||
("show_monitors_tip", "Показувати монітори на панелі інструментів"),
|
("show_monitors_tip", "Показувати монітори на панелі інструментів"),
|
||||||
("View Mode", "Режим перегляду"),
|
("View Mode", "Режим перегляду"),
|
||||||
("login_linux_tip", "Вам необхідно залогуватися у віддалений обліковий запис Linux, щоб увімкнути стільничний сеанс X"),
|
("login_linux_tip", "Вам необхідно увійти у віддалений обліковий запис Linux, щоб увімкнути стільничний сеанс X"),
|
||||||
("verify_rustdesk_password_tip", "Перевірте пароль RustDesk"),
|
("verify_rustdesk_password_tip", "Перевірте пароль RustDesk"),
|
||||||
("remember_account_tip", "Запамʼятати цей обліковий запис"),
|
("remember_account_tip", "Запамʼятати цей обліковий запис"),
|
||||||
("os_account_desk_tip", "Цей обліковий запис використовується для входу до віддаленої ОС та вмикання сеансу стільниці в неграфічному режимі"),
|
("os_account_desk_tip", "Цей обліковий запис використовується для входу до віддаленої ОС та вмикання сеансу стільниці в режимі без графічного інтерфейсу"),
|
||||||
("OS Account", "Користувач ОС"),
|
("OS Account", "Користувач ОС"),
|
||||||
("another_user_login_title_tip", "Інший користувач вже залогований"),
|
("another_user_login_title_tip", "Інший користувач вже в системі"),
|
||||||
("another_user_login_text_tip", "Відʼєднатися"),
|
("another_user_login_text_tip", "Відʼєднатися"),
|
||||||
("xorg_not_found_title_tip", "Xorg не знайдено"),
|
("xorg_not_found_title_tip", "Xorg не знайдено"),
|
||||||
("xorg_not_found_text_tip", "Будь ласка, встановіть Xorg"),
|
("xorg_not_found_text_tip", "Будь ласка, встановіть Xorg"),
|
||||||
@@ -506,7 +506,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Outgoing connection", "Вихідне підключення"),
|
("Outgoing connection", "Вихідне підключення"),
|
||||||
("Exit", "Вийти"),
|
("Exit", "Вийти"),
|
||||||
("Open", "Відкрити"),
|
("Open", "Відкрити"),
|
||||||
("logout_tip", "Ви впевнені, що хочете вилогуватися?"),
|
("logout_tip", "Ви впевнені, що хочете вийти з системи?"),
|
||||||
("Service", "Служба"),
|
("Service", "Служба"),
|
||||||
("Start", "Запустити"),
|
("Start", "Запустити"),
|
||||||
("Stop", "Зупинити"),
|
("Stop", "Зупинити"),
|
||||||
@@ -563,7 +563,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Plug out all", "Відключити все"),
|
("Plug out all", "Відключити все"),
|
||||||
("True color (4:4:4)", "Справжній колір (4:4:4)"),
|
("True color (4:4:4)", "Справжній колір (4:4:4)"),
|
||||||
("Enable blocking user input", "Блокувати введення для користувача"),
|
("Enable blocking user input", "Блокувати введення для користувача"),
|
||||||
("id_input_tip", "Ви можете ввести ID, безпосередню IP, або ж домен з портом (<домен>:<порт>).\nЯкщо ви хочете отримати доступ до пристрою на іншому сервері, будь ласка, додайте адресу сервера (<id>@<адреса_сервера>?key=<значення_ключа>), наприклад,\n9123456234@192.168.16.1:21117?key=5Qbwsde3unUcJBtrx9ZkvUmwFNoExHzpryHuPUdqlWM=.\nЯкщо ви хочете отримати доступ до пристрою на публічному сервері, будь ласка, введіть \"<id>@public\", ключ для публічного сервера не потрібен."),
|
("id_input_tip", "Ви можете ввести ID, безпосередню IP, або ж домен з портом (<домен>:<порт>).\nЯкщо ви хочете отримати доступ до пристрою на іншому сервері, будь ласка, додайте адресу сервера (<id>@<адреса_сервера>?key=<значення_ключа>), наприклад,\n9123456234@192.168.16.1:21117?key=5Qbwsde3unUcJBtrx9ZkvUmwFNoExHzpryHuPUdqlWM=.\nЯкщо ви хочете отримати доступ до пристрою на публічному сервері, будь ласка, введіть \"<id>@public\", для публічного сервера ключ не потрібен."),
|
||||||
("privacy_mode_impl_mag_tip", "Режим 1"),
|
("privacy_mode_impl_mag_tip", "Режим 1"),
|
||||||
("privacy_mode_impl_virtual_display_tip", "Режим 2"),
|
("privacy_mode_impl_virtual_display_tip", "Режим 2"),
|
||||||
("Enter privacy mode", "Увійти в режим конфіденційності"),
|
("Enter privacy mode", "Увійти в режим конфіденційності"),
|
||||||
@@ -631,7 +631,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("cancel-bot-confirm-tip", "Ви впевнені, що хочете скасувати Telegram бота?"),
|
("cancel-bot-confirm-tip", "Ви впевнені, що хочете скасувати Telegram бота?"),
|
||||||
("About RustDesk", "Про Rustdesk"),
|
("About RustDesk", "Про Rustdesk"),
|
||||||
("Send clipboard keystrokes", "Надіслати вміст буфера обміну"),
|
("Send clipboard keystrokes", "Надіслати вміст буфера обміну"),
|
||||||
("network_error_tip", "Будь ласка, перевірте ваше підключення до мережі та натисність \"Повторити\""),
|
("network_error_tip", "Будь ласка, перевірте ваше підключення до мережі та натисніть \"Повторити\""),
|
||||||
("Unlock with PIN", "Розблокування PIN-кодом"),
|
("Unlock with PIN", "Розблокування PIN-кодом"),
|
||||||
("Requires at least {} characters", "Потрібно щонайменше {} символів"),
|
("Requires at least {} characters", "Потрібно щонайменше {} символів"),
|
||||||
("Wrong PIN", "Неправильний PIN-код"),
|
("Wrong PIN", "Неправильний PIN-код"),
|
||||||
@@ -640,12 +640,17 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Manage trusted devices", "Керувати довіреними пристроями"),
|
("Manage trusted devices", "Керувати довіреними пристроями"),
|
||||||
("Platform", "Платформа"),
|
("Platform", "Платформа"),
|
||||||
("Days remaining", "Залишилося днів"),
|
("Days remaining", "Залишилося днів"),
|
||||||
("enable-trusted-devices-tip", "Дозволити довіреним пристроям пропускати двофакторну автентифікацію?"),
|
("enable-trusted-devices-tip", "Пропускати двофакторну автентифікацію на довірених пристроях"),
|
||||||
("Parent directory", "Батьківський каталог"),
|
("Parent directory", "Батьківський каталог"),
|
||||||
("Resume", "Продовжити"),
|
("Resume", "Продовжити"),
|
||||||
("Invalid file name", "Неправильне ім'я файлу"),
|
("Invalid file name", "Неправильна назва файлу"),
|
||||||
("one-way-file-transfer-tip", "На керованій стороні ввімкнено одностороннє передавання файлів."),
|
("one-way-file-transfer-tip", "На стороні, що керується, увімкнено односторонню передачу файлів."),
|
||||||
("Authentication Required", "Потрібна автентифікація"),
|
("Authentication Required", "Потрібна автентифікація"),
|
||||||
("Authenticate", "Автентифікувати"),
|
("Authenticate", "Автентифікувати"),
|
||||||
|
("web_id_input_tip", "Ви можете ввести ID з того самого серверу, прямий IP-доступ у веб-клієнті не підтримується.\nЯкщо ви хочете отримати доступ до пристрою на іншому сервері, будь ласка, додайте адресу сервера (<id>@<адреса_сервера>?key=<значення_ключа>), наприклад,\n9123456234@192.168.16.1:21117?key=5Qbwsde3unUcJBtrx9ZkvUmwFNoExHzpryHuPUdqlWM=.\nЯкщо ви хочете отримати доступ до пристрою на публічному сервері, будь ласка, введіть \"<id>@public\", для публічного сервера ключ не потрібен."),
|
||||||
|
("Download", ""),
|
||||||
|
("Upload folder", ""),
|
||||||
|
("Upload files", ""),
|
||||||
|
("Clipboard is synchronized", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -647,5 +647,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("one-way-file-transfer-tip", ""),
|
("one-way-file-transfer-tip", ""),
|
||||||
("Authentication Required", ""),
|
("Authentication Required", ""),
|
||||||
("Authenticate", ""),
|
("Authenticate", ""),
|
||||||
|
("web_id_input_tip", ""),
|
||||||
|
("Download", ""),
|
||||||
|
("Upload folder", ""),
|
||||||
|
("Upload files", ""),
|
||||||
|
("Clipboard is synchronized", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -505,7 +505,7 @@ fn child(su_user: Option<String>, args: Vec<String>) -> ResultType<()> {
|
|||||||
command = format!("'{}'", quote_shell_arg(&command, false));
|
command = format!("'{}'", quote_shell_arg(&command, false));
|
||||||
}
|
}
|
||||||
params.push(command);
|
params.push(command);
|
||||||
std::env::set_var("LC_ALL", "C.UTF-8");
|
std::env::set_var("LC_ALL", "C");
|
||||||
|
|
||||||
if let Some(user) = &su_user {
|
if let Some(user) = &su_user {
|
||||||
let su_subcommand = params
|
let su_subcommand = params
|
||||||
|
|||||||
@@ -610,8 +610,15 @@ pub fn get_env_var(k: &str) -> String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_flatpak() -> bool {
|
||||||
|
std::path::PathBuf::from("/.flatpak-info").exists()
|
||||||
|
}
|
||||||
|
|
||||||
// Headless is enabled, always return true.
|
// Headless is enabled, always return true.
|
||||||
pub fn is_prelogin() -> bool {
|
pub fn is_prelogin() -> bool {
|
||||||
|
if is_flatpak() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
let n = get_active_userid().len();
|
let n = get_active_userid().len();
|
||||||
n < 4 && n > 1
|
n < 4 && n > 1
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -117,6 +117,7 @@ impl Handler {
|
|||||||
format: ClipboardFormat::from_i32(c.format)
|
format: ClipboardFormat::from_i32(c.format)
|
||||||
.unwrap_or(ClipboardFormat::Text)
|
.unwrap_or(ClipboardFormat::Text)
|
||||||
.into(),
|
.into(),
|
||||||
|
special_name: c.special_name,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
|
|||||||
@@ -175,6 +175,22 @@ impl LockModesHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
fn sleep_to_ensure_locked(v: bool, k: enigo::Key, en: &mut Enigo) {
|
||||||
|
if wayland_use_uinput() {
|
||||||
|
// Sleep at most 500ms to ensure the lock state is applied.
|
||||||
|
for _ in 0..50 {
|
||||||
|
std::thread::sleep(std::time::Duration::from_millis(10));
|
||||||
|
if en.get_key_state(k) == v {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if wayland_use_rdp_input() {
|
||||||
|
// We can't call `en.get_key_state(k)` because there's no api for this.
|
||||||
|
std::thread::sleep(std::time::Duration::from_millis(50));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(any(target_os = "windows", target_os = "linux"))]
|
#[cfg(any(target_os = "windows", target_os = "linux"))]
|
||||||
fn new(key_event: &KeyEvent, is_numpad_key: bool) -> Self {
|
fn new(key_event: &KeyEvent, is_numpad_key: bool) -> Self {
|
||||||
let mut en = ENIGO.lock().unwrap();
|
let mut en = ENIGO.lock().unwrap();
|
||||||
@@ -183,12 +199,15 @@ impl LockModesHandler {
|
|||||||
let caps_lock_changed = event_caps_enabled != local_caps_enabled;
|
let caps_lock_changed = event_caps_enabled != local_caps_enabled;
|
||||||
if caps_lock_changed {
|
if caps_lock_changed {
|
||||||
en.key_click(enigo::Key::CapsLock);
|
en.key_click(enigo::Key::CapsLock);
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
Self::sleep_to_ensure_locked(event_caps_enabled, enigo::Key::CapsLock, &mut en);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut num_lock_changed = false;
|
let mut num_lock_changed = false;
|
||||||
|
let mut event_num_enabled = false;
|
||||||
if is_numpad_key {
|
if is_numpad_key {
|
||||||
let local_num_enabled = en.get_key_state(enigo::Key::NumLock);
|
let local_num_enabled = en.get_key_state(enigo::Key::NumLock);
|
||||||
let event_num_enabled = Self::is_modifier_enabled(key_event, ControlKey::NumLock);
|
event_num_enabled = Self::is_modifier_enabled(key_event, ControlKey::NumLock);
|
||||||
num_lock_changed = event_num_enabled != local_num_enabled;
|
num_lock_changed = event_num_enabled != local_num_enabled;
|
||||||
} else if is_legacy_mode(key_event) {
|
} else if is_legacy_mode(key_event) {
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
@@ -199,6 +218,8 @@ impl LockModesHandler {
|
|||||||
}
|
}
|
||||||
if num_lock_changed {
|
if num_lock_changed {
|
||||||
en.key_click(enigo::Key::NumLock);
|
en.key_click(enigo::Key::NumLock);
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
Self::sleep_to_ensure_locked(event_num_enabled, enigo::Key::NumLock, &mut en);
|
||||||
}
|
}
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
@@ -236,6 +257,14 @@ impl LockModesHandler {
|
|||||||
#[cfg(any(target_os = "windows", target_os = "linux"))]
|
#[cfg(any(target_os = "windows", target_os = "linux"))]
|
||||||
impl Drop for LockModesHandler {
|
impl Drop for LockModesHandler {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
|
// Do not change led state if is Wayland uinput.
|
||||||
|
// Because there must be a delay to ensure the lock state is applied on Wayland uinput,
|
||||||
|
// which may affect the user experience.
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
if wayland_use_uinput() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let mut en = ENIGO.lock().unwrap();
|
let mut en = ENIGO.lock().unwrap();
|
||||||
if self.caps_lock_changed {
|
if self.caps_lock_changed {
|
||||||
en.key_click(enigo::Key::CapsLock);
|
en.key_click(enigo::Key::CapsLock);
|
||||||
@@ -1633,12 +1662,13 @@ pub fn handle_key_(evt: &KeyEvent) {
|
|||||||
let is_numpad_key = false;
|
let is_numpad_key = false;
|
||||||
#[cfg(any(target_os = "windows", target_os = "linux"))]
|
#[cfg(any(target_os = "windows", target_os = "linux"))]
|
||||||
let is_numpad_key = crate::keyboard::is_numpad_rdev_key(&key);
|
let is_numpad_key = crate::keyboard::is_numpad_rdev_key(&key);
|
||||||
_lock_mode_handler = Some(LockModesHandler::new_handler(evt, is_numpad_key));
|
_lock_mode_handler =
|
||||||
|
Some(LockModesHandler::new_handler(evt, is_numpad_key));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
};
|
}
|
||||||
|
|
||||||
match evt.mode.enum_value() {
|
match evt.mode.enum_value() {
|
||||||
Ok(KeyboardMode::Map) => {
|
Ok(KeyboardMode::Map) => {
|
||||||
|
|||||||
@@ -431,8 +431,8 @@ pub mod service {
|
|||||||
allow_err!(keyboard.emit(&[down_event]));
|
allow_err!(keyboard.emit(&[down_event]));
|
||||||
}
|
}
|
||||||
DataKeyboard::KeyUp(enigo::Key::Raw(code)) => {
|
DataKeyboard::KeyUp(enigo::Key::Raw(code)) => {
|
||||||
let down_event = InputEvent::new(EventType::KEY, *code - 8, 0);
|
let up_event = InputEvent::new(EventType::KEY, *code - 8, 0);
|
||||||
allow_err!(keyboard.emit(&[down_event]));
|
allow_err!(keyboard.emit(&[up_event]));
|
||||||
}
|
}
|
||||||
DataKeyboard::KeyDown(key) => {
|
DataKeyboard::KeyDown(key) => {
|
||||||
if let Ok((k, is_shift)) = map_key(key) {
|
if let Ok((k, is_shift)) = map_key(key) {
|
||||||
|
|||||||
@@ -446,7 +446,7 @@ function handle_custom_image_quality() {
|
|||||||
var extendedBitrate = bitrate > 100;
|
var extendedBitrate = bitrate > 100;
|
||||||
var maxRate = extendedBitrate ? 2000 : 100;
|
var maxRate = extendedBitrate ? 2000 : 100;
|
||||||
msgbox("custom-image-quality", "Custom Image Quality", "<div .form> \
|
msgbox("custom-image-quality", "Custom Image Quality", "<div .form> \
|
||||||
<div><input #bitrate-slider type=\"hslider\" style=\"width: 50%\" name=\"bitrate\" max=\"" + maxRate + "\" min=\"10\" value=\"" + bitrate + "\"/ buddy=\"bitrate-buddy\"><b #bitrate-buddy>x</b>% Bitrate <button|checkbox #extended-slider .custom-event " + (extendedBitrate ? "checked" : "") + ">More</button></div> \
|
<div><input #bitrate-slider type=\"hslider\" style=\"width: 50%\" name=\"bitrate\" max=\"" + maxRate + "\" min=\"5\" value=\"" + bitrate + "\"/ buddy=\"bitrate-buddy\"><b #bitrate-buddy>x</b>% Bitrate <button|checkbox #extended-slider .custom-event " + (extendedBitrate ? "checked" : "") + ">More</button></div> \
|
||||||
</div>", "", function(res=null) {
|
</div>", "", function(res=null) {
|
||||||
if (!res) return;
|
if (!res) return;
|
||||||
if (res.id === "extended-slider") {
|
if (res.id === "extended-slider") {
|
||||||
|
|||||||
@@ -512,6 +512,7 @@ impl<T: InvokeUiCM> IpcTaskRunner<T> {
|
|||||||
width: c.width,
|
width: c.width,
|
||||||
height: c.height,
|
height: c.height,
|
||||||
format: c.format.value(),
|
format: c.format.value(),
|
||||||
|
special_name: c.special_name,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
allow_err!(self.stream.send(&Data::ClipboardNonFile(Some(("".to_owned(), main_data)))).await);
|
allow_err!(self.stream.send(&Data::ClipboardNonFile(Some(("".to_owned(), main_data)))).await);
|
||||||
|
|||||||
Reference in New Issue
Block a user