more zh, for configuration and installation and upgrade, and flutter,
not test yet
This commit is contained in:
parent
0c35437531
commit
6b6ffb3f17
@ -2,6 +2,73 @@ import 'package:flutter/material.dart';
|
||||
import 'dart:async';
|
||||
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
||||
import 'package:tuple/tuple.dart';
|
||||
import 'dart:io';
|
||||
|
||||
final bool isZh = Platform.localeName == "zh_CN";
|
||||
|
||||
final langs = <String, Map<String, String>>{
|
||||
'zh': <String, String>{
|
||||
'Remote ID': '远程',
|
||||
'ID/Relay Server': 'ID/中继服务器',
|
||||
'About': '关于',
|
||||
'Mute': '静音',
|
||||
'ID Server': 'ID服务器',
|
||||
'Relay Server': '中继服务器',
|
||||
'Invalid IP': '无效IP',
|
||||
'Invalid format': '无效格式',
|
||||
'Cancel': '取消',
|
||||
'Close': '关闭',
|
||||
'Retry': '再试',
|
||||
'OK': '确认',
|
||||
'Password Required': '需要密码',
|
||||
'Please enter your password': '请输入密码',
|
||||
'Remember password': '记住密码',
|
||||
'Wrong Password': '密码错误',
|
||||
'Do you want to enter again?': '还想输入一次吗?',
|
||||
'Connection Error': '连接错误',
|
||||
'Error': '错误',
|
||||
'Reset by the peer': '连接被对方关闭',
|
||||
'Connecting...': '正在连接...',
|
||||
'Connection in progress. Please wait.': '连接进行中,请稍等。',
|
||||
'Please try 1 minute later': '一分钟后再试',
|
||||
'Login Error': '登录错误',
|
||||
'Successful': '成功',
|
||||
'Connected, waiting for image...': '已连接,等待画面传输...',
|
||||
'Custom Image Quality': '设置画面质量',
|
||||
'Privacy mode': '隐私模式',
|
||||
'Remove': '删除',
|
||||
'Adjust Window': '调节窗口',
|
||||
'Good image quality': '好画质',
|
||||
'Balanced': '一般画质',
|
||||
'Optimize reaction time': '优化反应时间',
|
||||
'Custom': '自定义画质',
|
||||
'Show remote cursor': '显示远程光标',
|
||||
'Disable clipboard': '禁止剪贴板',
|
||||
'Lock after session end': '断开后锁定远程电脑',
|
||||
'Insert': '插入',
|
||||
'Insert Lock': '锁定远程电脑',
|
||||
'Refresh': '刷新画面',
|
||||
'ID not exist': 'ID不存在',
|
||||
'Failed to connect to rendezvous server': '连接服务器失败',
|
||||
'Remote desktop is offline': '远程电脑不在线',
|
||||
'Key mismatch': 'Key不匹配',
|
||||
'Timeout': '连接超时',
|
||||
'Failed to connect to relay server': '无法连接到中继服务器',
|
||||
'Failed to connect via rendezvous server': '无法通过服务器建立连接',
|
||||
'Failed to make direct connection to remote desktop': '无法建立直接连接',
|
||||
'OS Password': '操作系统密码',
|
||||
'Paste': '粘贴',
|
||||
'Logging in...': '正在登录...',
|
||||
'Are you sure to close the connection?': '是否确认关闭连接?',
|
||||
},
|
||||
'en': <String, String>{}
|
||||
};
|
||||
|
||||
String translate(name) {
|
||||
final tmp = isZh ? langs['zh'] : langs['en'];
|
||||
final v = tmp[name];
|
||||
return v != null ? v : name;
|
||||
}
|
||||
|
||||
class MyTheme {
|
||||
MyTheme._();
|
||||
@ -83,7 +150,7 @@ void msgbox(String type, String title, String text, BuildContext context,
|
||||
}
|
||||
final buttons = [
|
||||
Expanded(child: Container()),
|
||||
wrap('OK', () {
|
||||
wrap(translate('OK'), () {
|
||||
dismissLoading();
|
||||
Navigator.pop(context);
|
||||
})
|
||||
@ -94,7 +161,7 @@ void msgbox(String type, String title, String text, BuildContext context,
|
||||
if (hasCancel) {
|
||||
buttons.insert(
|
||||
1,
|
||||
wrap('Cancel', () {
|
||||
wrap(translate('Cancel'), () {
|
||||
dismissLoading();
|
||||
}));
|
||||
}
|
||||
@ -102,9 +169,9 @@ void msgbox(String type, String title, String text, BuildContext context,
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(title, style: TextStyle(fontSize: 21)),
|
||||
Text(translate(title), style: TextStyle(fontSize: 21)),
|
||||
SizedBox(height: 20),
|
||||
Text(text, style: TextStyle(fontSize: 15)),
|
||||
Text(translate(text), style: TextStyle(fontSize: 15)),
|
||||
SizedBox(height: 20),
|
||||
Row(
|
||||
children: buttons,
|
||||
|
@ -49,9 +49,11 @@ class _HomePageState extends State<HomePage> {
|
||||
position: RelativeRect.fromLTRB(3000, 70, 3000, 70),
|
||||
items: [
|
||||
PopupMenuItem<String>(
|
||||
child: Text('ID/Relay Server'), value: 'server'),
|
||||
child: Text(translate('ID/Relay Server')),
|
||||
value: 'server'),
|
||||
PopupMenuItem<String>(
|
||||
child: Text('About RustDesk'), value: 'about'),
|
||||
child: Text(translate('About') + ' RustDesk'),
|
||||
value: 'about'),
|
||||
],
|
||||
elevation: 8,
|
||||
);
|
||||
@ -154,7 +156,7 @@ class _HomePageState extends State<HomePage> {
|
||||
color: Color(0xFF00B6F0),
|
||||
),
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Remote ID',
|
||||
labelText: translate('Remote ID'),
|
||||
// hintText: 'Enter your remote ID',
|
||||
border: InputBorder.none,
|
||||
helperStyle: TextStyle(
|
||||
@ -227,7 +229,8 @@ class _HomePageState extends State<HomePage> {
|
||||
position: RelativeRect.fromLTRB(x, y, x, y),
|
||||
items: [
|
||||
PopupMenuItem<String>(
|
||||
child: Text('Remove'), value: 'remove'),
|
||||
child: Text(translate('Remove')),
|
||||
value: 'remove'),
|
||||
],
|
||||
elevation: 8,
|
||||
);
|
||||
@ -260,7 +263,7 @@ void showServer(BuildContext context) {
|
||||
showAlertDialog(
|
||||
context,
|
||||
(setState) => Tuple3(
|
||||
Text('ID/Relay Server'),
|
||||
Text(translate('ID/Relay Server')),
|
||||
Form(
|
||||
key: formKey,
|
||||
child:
|
||||
@ -268,7 +271,7 @@ void showServer(BuildContext context) {
|
||||
TextFormField(
|
||||
initialValue: id0,
|
||||
decoration: InputDecoration(
|
||||
labelText: 'ID Server',
|
||||
labelText: translate('ID Server'),
|
||||
),
|
||||
validator: validate,
|
||||
onSaved: (String value) {
|
||||
@ -278,7 +281,7 @@ void showServer(BuildContext context) {
|
||||
TextFormField(
|
||||
initialValue: relay0,
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Relay Server',
|
||||
labelText: translate('Relay Server'),
|
||||
),
|
||||
validator: validate,
|
||||
onSaved: (String value) {
|
||||
@ -316,7 +319,7 @@ void showServer(BuildContext context) {
|
||||
Navigator.pop(context);
|
||||
}
|
||||
},
|
||||
child: Text('OK'),
|
||||
child: Text(translate('OK')),
|
||||
),
|
||||
],
|
||||
));
|
||||
|
@ -179,7 +179,7 @@ class FfiModel with ChangeNotifier {
|
||||
_pi.sasEnabled = evt['sas_enabled'] == "true";
|
||||
_pi.currentDisplay = int.parse(evt['current_display']);
|
||||
List<dynamic> displays = json.decode(evt['displays']);
|
||||
_pi.displays = List<Display>();
|
||||
_pi.displays = [];
|
||||
for (int i = 0; i < displays.length; ++i) {
|
||||
Map<String, dynamic> d0 = displays[i];
|
||||
var d = Display();
|
||||
|
@ -47,7 +47,7 @@ class _RemotePageState extends State<RemotePage> {
|
||||
FFI.connect(widget.id);
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
SystemChrome.setEnabledSystemUIOverlays([]);
|
||||
showLoading('Connecting...', context);
|
||||
showLoading(translate('Connecting...'), context);
|
||||
_interval =
|
||||
Timer.periodic(Duration(milliseconds: 30), (timer) => interval());
|
||||
});
|
||||
@ -113,7 +113,7 @@ class _RemotePageState extends State<RemotePage> {
|
||||
_timer?.cancel();
|
||||
_timer = Timer(Duration(seconds: _reconnects), () {
|
||||
FFI.reconnect();
|
||||
showLoading('Connecting...', context);
|
||||
showLoading(translate('Connecting...'), context);
|
||||
});
|
||||
_reconnects *= 2;
|
||||
} else {
|
||||
@ -579,7 +579,7 @@ void enterPasswordDialog(String id, BuildContext context) {
|
||||
showAlertDialog(
|
||||
context,
|
||||
(setState) => Tuple3(
|
||||
Text('Password required'),
|
||||
Text(translate('Password required')),
|
||||
Column(mainAxisSize: MainAxisSize.min, children: [
|
||||
PasswordWidget(controller: controller),
|
||||
CheckboxListTile(
|
||||
@ -587,7 +587,7 @@ void enterPasswordDialog(String id, BuildContext context) {
|
||||
dense: true,
|
||||
controlAffinity: ListTileControlAffinity.leading,
|
||||
title: Text(
|
||||
'Remember password',
|
||||
translate('Remember password'),
|
||||
),
|
||||
value: remember,
|
||||
onChanged: (v) {
|
||||
@ -602,7 +602,7 @@ void enterPasswordDialog(String id, BuildContext context) {
|
||||
Navigator.pop(context);
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: Text('Cancel'),
|
||||
child: Text(translate('Cancel')),
|
||||
),
|
||||
FlatButton(
|
||||
textColor: MyTheme.accent,
|
||||
@ -610,10 +610,10 @@ void enterPasswordDialog(String id, BuildContext context) {
|
||||
var text = controller.text.trim();
|
||||
if (text == '') return;
|
||||
FFI.login(text, remember);
|
||||
showLoading('Logging in...', null);
|
||||
showLoading(translate('Logging in...'), null);
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: Text('OK'),
|
||||
child: Text(translate('OK')),
|
||||
),
|
||||
],
|
||||
));
|
||||
@ -622,22 +622,22 @@ void enterPasswordDialog(String id, BuildContext context) {
|
||||
void wrongPasswordDialog(String id, BuildContext context) {
|
||||
showAlertDialog(
|
||||
context,
|
||||
(_) =>
|
||||
Tuple3(Text('Wrong Password'), Text('Do you want to enter again?'), [
|
||||
(_) => Tuple3(Text(translate('Wrong Password')),
|
||||
Text(translate('Do you want to enter again?')), [
|
||||
FlatButton(
|
||||
textColor: MyTheme.accent,
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: Text('Cancel'),
|
||||
child: Text(translate('Cancel')),
|
||||
),
|
||||
FlatButton(
|
||||
textColor: MyTheme.accent,
|
||||
onPressed: () {
|
||||
enterPasswordDialog(id, context);
|
||||
},
|
||||
child: Text('Retry'),
|
||||
child: Text(translate('Retry')),
|
||||
),
|
||||
]));
|
||||
}
|
||||
@ -691,7 +691,7 @@ void showOptions(BuildContext context) {
|
||||
FFI.setByName('toggle_option', 'disable-audio');
|
||||
});
|
||||
},
|
||||
title: Text('Mute')));
|
||||
title: Text(translate('Mute'))));
|
||||
}
|
||||
if (FFI.ffiModel.permissions['keyboard'] != false) {
|
||||
more.add(CheckboxListTile(
|
||||
@ -702,7 +702,7 @@ void showOptions(BuildContext context) {
|
||||
FFI.setByName('toggle_option', 'lock-after-session-end');
|
||||
});
|
||||
},
|
||||
title: Text('Lock after session end')));
|
||||
title: Text(translate('Lock after session end'))));
|
||||
}
|
||||
return Tuple3(
|
||||
null,
|
||||
@ -712,7 +712,7 @@ void showOptions(BuildContext context) {
|
||||
<Widget>[
|
||||
RadioListTile<String>(
|
||||
controlAffinity: ListTileControlAffinity.trailing,
|
||||
title: const Text('Good image quality'),
|
||||
title: Text(translate('Good image quality')),
|
||||
value: 'best',
|
||||
groupValue: quality,
|
||||
onChanged: (String value) {
|
||||
@ -724,7 +724,7 @@ void showOptions(BuildContext context) {
|
||||
),
|
||||
RadioListTile<String>(
|
||||
controlAffinity: ListTileControlAffinity.trailing,
|
||||
title: const Text('Balanced'),
|
||||
title: Text(translate('Balanced')),
|
||||
value: 'balanced',
|
||||
groupValue: quality,
|
||||
onChanged: (String value) {
|
||||
@ -736,7 +736,7 @@ void showOptions(BuildContext context) {
|
||||
),
|
||||
RadioListTile<String>(
|
||||
controlAffinity: ListTileControlAffinity.trailing,
|
||||
title: const Text('Optimize reaction time'),
|
||||
title: Text(translate('Optimize reaction time')),
|
||||
value: 'low',
|
||||
groupValue: quality,
|
||||
onChanged: (String value) {
|
||||
@ -756,7 +756,7 @@ void showOptions(BuildContext context) {
|
||||
FFI.setByName('toggle_option', 'show-remote-cursor');
|
||||
});
|
||||
},
|
||||
title: Text('Show remote cursor')),
|
||||
title: Text(translate('Show remote cursor'))),
|
||||
] +
|
||||
more),
|
||||
null);
|
||||
@ -769,11 +769,13 @@ void showActions(BuildContext context) {
|
||||
final y = size.height;
|
||||
final more = <PopupMenuItem<String>>[];
|
||||
if (FFI.ffiModel.pi.version.isNotEmpty) {
|
||||
more.add(PopupMenuItem<String>(child: Text('Refresh'), value: 'refresh'));
|
||||
more.add(PopupMenuItem<String>(
|
||||
child: Text(translate('Refresh')), value: 'refresh'));
|
||||
}
|
||||
if (FFI.ffiModel.permissions['keyboard'] != false &&
|
||||
FFI.ffiModel.permissions['clipboard'] != false) {
|
||||
more.add(PopupMenuItem<String>(child: Text('Paste'), value: 'paste'));
|
||||
more.add(
|
||||
PopupMenuItem<String>(child: Text(translate('Paste')), value: 'paste'));
|
||||
}
|
||||
more.add(PopupMenuItem<String>(
|
||||
child: Row(
|
||||
@ -795,8 +797,10 @@ void showActions(BuildContext context) {
|
||||
position: RelativeRect.fromLTRB(x, y, x, y),
|
||||
items: [
|
||||
PopupMenuItem<String>(
|
||||
child: Text('Insert Ctrl + Alt + Del'), value: 'cad'),
|
||||
PopupMenuItem<String>(child: Text('Insert Lock'), value: 'lock'),
|
||||
child: Text(translate('Insert') + ' Ctrl + Alt + Del'),
|
||||
value: 'cad'),
|
||||
PopupMenuItem<String>(
|
||||
child: Text(translate('Insert Lock')), value: 'lock'),
|
||||
] +
|
||||
more,
|
||||
elevation: 8,
|
||||
@ -841,7 +845,7 @@ void showSetOSPassword(BuildContext context) async {
|
||||
showAlertDialog(
|
||||
context,
|
||||
(setState) => Tuple3(
|
||||
Text('Password required'),
|
||||
Text(translate('Password required')),
|
||||
Column(mainAxisSize: MainAxisSize.min, children: [
|
||||
PasswordWidget(controller: controller),
|
||||
]),
|
||||
@ -851,7 +855,7 @@ void showSetOSPassword(BuildContext context) async {
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: Text('Cancel'),
|
||||
child: Text(translate('Cancel')),
|
||||
),
|
||||
FlatButton(
|
||||
textColor: MyTheme.accent,
|
||||
@ -860,7 +864,7 @@ void showSetOSPassword(BuildContext context) async {
|
||||
savePassword(FFI.id, text);
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: Text('OK'),
|
||||
child: Text(translate('OK')),
|
||||
),
|
||||
],
|
||||
));
|
||||
|
Loading…
x
Reference in New Issue
Block a user