diff --git a/flutter/lib/common/widgets/api_server_warning.dart b/flutter/lib/common/widgets/api_server_warning.dart new file mode 100644 index 000000000..a3ad494cf --- /dev/null +++ b/flutter/lib/common/widgets/api_server_warning.dart @@ -0,0 +1,72 @@ +import 'dart:convert'; + +import 'package:flutter/material.dart'; +import 'package:flutter_hbb/models/platform_model.dart'; + +String _resolveApiServer({required String api, required String custom}) { + final key = 'resolve-api-server:${jsonEncode([api, custom])}'; + final response = jsonDecode(bind.mainGetCommonSync(key: key)); + if (response['error'] != null) { + throw FormatException('Failed to resolve API server: ${response['error']}'); + } + return response['url'] as String; +} + +bool shouldWarnApiServer(String? apiServer) { + final uri = Uri.tryParse(apiServer?.trim() ?? ''); + if (uri == null || uri.host.isEmpty || uri.scheme != 'http') { + return false; + } + return !const {'localhost', '127.0.0.1', '::1'}.contains(uri.host); +} + +class ApiServerWarning extends StatelessWidget { + final TextEditingController controller; + final TextEditingController idController; + final String message; + final String emptyMessage; + final String Function({required String api, required String custom}) + resolveApiServer; + + const ApiServerWarning({ + super.key, + required this.controller, + required this.idController, + required this.message, + required this.emptyMessage, + this.resolveApiServer = _resolveApiServer, + }); + + @override + Widget build(BuildContext context) { + return ListenableBuilder( + listenable: Listenable.merge([controller, idController]), + builder: (context, child) { + final apiServer = controller.text; + final idServer = idController.text; + final String effectiveApiServer; + try { + effectiveApiServer = + resolveApiServer(api: apiServer.trim(), custom: idServer.trim()); + } catch (error, stack) { + FlutterError.reportError(FlutterErrorDetails( + exception: error, + stack: stack, + context: ErrorDescription('while resolving the API server warning'), + )); + return const SizedBox.shrink(); + } + if (!shouldWarnApiServer(effectiveApiServer)) { + return const SizedBox.shrink(); + } + return Align( + alignment: AlignmentDirectional.centerStart, + child: Text( + controller.text.trim().isEmpty ? emptyMessage : message, + style: TextStyle(color: Colors.orange.shade700), + ), + ); + }, + ); + } +} diff --git a/flutter/lib/mobile/widgets/dialog.dart b/flutter/lib/mobile/widgets/dialog.dart index f1ff8550f..4e8179e8f 100644 --- a/flutter/lib/mobile/widgets/dialog.dart +++ b/flutter/lib/mobile/widgets/dialog.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'dart:convert'; import 'package:flutter/material.dart'; +import 'package:flutter_hbb/common/widgets/api_server_warning.dart'; import 'package:flutter_hbb/common/widgets/setting_widgets.dart'; import 'package:flutter_hbb/common/widgets/toolbar.dart'; import 'package:get/get.dart'; @@ -69,6 +70,8 @@ void showServerSettingsWithValue( ServerConfig serverConfig, OverlayDialogManager dialogManager, void Function(VoidCallback)? upSetState) async { + const labelWidth = 120.0; + const labelSpacing = 8.0; var isInProgress = false; final idCtrl = TextEditingController(text: serverConfig.idServer); final relayCtrl = TextEditingController(text: serverConfig.relayServer); @@ -112,10 +115,10 @@ void showServerSettingsWithValue( return Row( children: [ SizedBox( - width: 120, + width: labelWidth, child: Text(label), ), - SizedBox(width: 8), + SizedBox(width: labelSpacing), Expanded( child: serverSettingsTextFormField( label: label, @@ -175,6 +178,17 @@ void showServerSettingsWithValue( return null; }, ), + Padding( + padding: EdgeInsetsDirectional.only( + start: isDesktop || isWeb ? labelWidth + labelSpacing : 0, + ), + child: ApiServerWarning( + controller: apiCtrl, + idController: idCtrl, + message: translate('api_server_connection_tip'), + emptyMessage: translate('api_server_empty_tip'), + ), + ), SizedBox(height: 8), buildField('Key', keyCtrl, ''), if (isInProgress) diff --git a/flutter/lib/web/bridge.dart b/flutter/lib/web/bridge.dart index a8b1f21e2..f82672d10 100644 --- a/flutter/lib/web/bridge.dart +++ b/flutter/lib/web/bridge.dart @@ -1928,6 +1928,11 @@ class RustdeskImpl { } String mainGetCommonSync({required String key, dynamic hint}) { + const prefix = 'resolve-api-server:'; + if (key.startsWith(prefix)) { + return js.context + .callMethod('getByName', ['api_server', key.substring(prefix.length)]); + } throw UnimplementedError("mainGetCommonSync"); } diff --git a/flutter/test/api_server_warning_test.dart b/flutter/test/api_server_warning_test.dart new file mode 100644 index 000000000..d93f043b5 --- /dev/null +++ b/flutter/test/api_server_warning_test.dart @@ -0,0 +1,80 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:flutter_hbb/common/widgets/api_server_warning.dart'; + +void main() { + test('warns only for remote HTTP endpoints', () { + final cases = { + null: false, + '': false, + 'https://api.example.com': false, + 'http://api.example.com': true, + 'http://192.168.1.13:13000': true, + 'http://localhost:21114': false, + 'http://127.0.0.1:21114': false, + 'http://[::1]:21114': false, + }; + for (final entry in cases.entries) { + expect(shouldWarnApiServer(entry.key), entry.value, reason: entry.key); + } + }); + + testWidgets('warning follows API and ID changes using the resolved endpoint', + (tester) async { + final api = TextEditingController(); + final id = TextEditingController(text: 'id.example.com'); + addTearDown(api.dispose); + addTearDown(id.dispose); + await tester.pumpWidget(MaterialApp( + home: ApiServerWarning( + controller: api, + idController: id, + message: 'HTTP warning', + emptyMessage: 'Default HTTP warning', + resolveApiServer: ({required api, required custom}) => + api.isNotEmpty ? api : 'http://$custom', + ), + )); + expect(find.text('Default HTTP warning'), findsOneWidget); + + id.text = 'localhost'; + await tester.pump(); + expect(find.text('Default HTTP warning'), findsNothing); + + api.text = 'http://api.example.com'; + await tester.pump(); + expect(find.text('HTTP warning'), findsOneWidget); + + api.text = 'https://api.example.com'; + await tester.pump(); + expect(find.text('HTTP warning'), findsNothing); + }); + + testWidgets('resolver failures are reported without breaking the server form', + (tester) async { + final api = TextEditingController(); + final id = TextEditingController(); + addTearDown(api.dispose); + addTearDown(id.dispose); + await tester.pumpWidget(MaterialApp( + home: Scaffold( + body: Column(children: [ + TextField(controller: api), + Expanded( + child: ApiServerWarning( + controller: api, + idController: id, + message: 'HTTP warning', + emptyMessage: 'Default HTTP warning', + resolveApiServer: ({required api, required custom}) => + throw const FormatException('API preview failed'), + )), + ]), + ), + )); + expect(tester.takeException(), isA()); + expect(find.byType(ErrorWidget), findsNothing); + expect(find.text('Default HTTP warning'), findsNothing); + expect(find.byType(TextField), findsOneWidget); + }); +} diff --git a/src/flutter_ffi.rs b/src/flutter_ffi.rs index 7d7eb007f..db20e6084 100644 --- a/src/flutter_ffi.rs +++ b/src/flutter_ffi.rs @@ -2763,6 +2763,16 @@ pub fn main_get_common(key: String) -> String { } pub fn main_get_common_sync(key: String) -> SyncReturn { + if let Some(args) = key.strip_prefix("resolve-api-server:") { + let response = match serde_json::from_str::<(String, String)>(args) { + Ok((api, custom)) => serde_json::json!({"url": crate::get_api_server(api, custom)}), + Err(err) => { + log::trace!("Invalid API server preview arguments: {err}"); + serde_json::json!({"error": err.to_string()}) + } + }; + return SyncReturn(response.to_string()); + } // Metadata verification performs blocking network requests. Keep this key on // the asynchronous FFI path to avoid blocking the calling Flutter isolate. if key.starts_with("verified-download-url-") { diff --git a/src/lang/ar.rs b/src/lang/ar.rs index 67a38764a..172ba0405 100644 --- a/src/lang/ar.rs +++ b/src/lang/ar.rs @@ -813,5 +813,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-key-not-supported", ""), ("On", ""), ("Off", ""), + ("api_server_connection_tip", ""), + ("api_server_empty_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/az.rs b/src/lang/az.rs index 6811021d6..ecacc1aad 100644 --- a/src/lang/az.rs +++ b/src/lang/az.rs @@ -813,5 +813,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-key-not-supported", ""), ("On", ""), ("Off", ""), + ("api_server_connection_tip", ""), + ("api_server_empty_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/be.rs b/src/lang/be.rs index cec7de809..134132154 100644 --- a/src/lang/be.rs +++ b/src/lang/be.rs @@ -813,5 +813,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-key-not-supported", ""), ("On", ""), ("Off", ""), + ("api_server_connection_tip", ""), + ("api_server_empty_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/bg.rs b/src/lang/bg.rs index 98836b209..674208ac4 100644 --- a/src/lang/bg.rs +++ b/src/lang/bg.rs @@ -813,5 +813,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-key-not-supported", ""), ("On", ""), ("Off", ""), + ("api_server_connection_tip", ""), + ("api_server_empty_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ca.rs b/src/lang/ca.rs index 55ff85020..b936e9a2e 100644 --- a/src/lang/ca.rs +++ b/src/lang/ca.rs @@ -813,5 +813,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-key-not-supported", ""), ("On", ""), ("Off", ""), + ("api_server_connection_tip", ""), + ("api_server_empty_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/cn.rs b/src/lang/cn.rs index bf277975d..b87d47176 100644 --- a/src/lang/cn.rs +++ b/src/lang/cn.rs @@ -813,5 +813,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-key-not-supported", "“{}” 不能用作快捷键。"), ("On", "开"), ("Off", "关"), + ("api_server_connection_tip", "自定义服务器正在使用未加密的 HTTP。请联系管理员启用 HTTPS。"), + ("api_server_empty_tip", "API 服务器留空时,自定义服务器默认使用 HTTP。请联系管理员启用 HTTPS。"), ].iter().cloned().collect(); } diff --git a/src/lang/cs.rs b/src/lang/cs.rs index 635b2d7c6..fb0bd330b 100644 --- a/src/lang/cs.rs +++ b/src/lang/cs.rs @@ -813,5 +813,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-key-not-supported", ""), ("On", ""), ("Off", ""), + ("api_server_connection_tip", ""), + ("api_server_empty_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/da.rs b/src/lang/da.rs index 926b0c5b4..cf2fc7c35 100644 --- a/src/lang/da.rs +++ b/src/lang/da.rs @@ -813,5 +813,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-key-not-supported", ""), ("On", ""), ("Off", ""), + ("api_server_connection_tip", ""), + ("api_server_empty_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/de.rs b/src/lang/de.rs index 2c7bdad39..a4bb78fca 100644 --- a/src/lang/de.rs +++ b/src/lang/de.rs @@ -813,5 +813,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-key-not-supported", ""), ("On", ""), ("Off", ""), + ("api_server_connection_tip", ""), + ("api_server_empty_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/el.rs b/src/lang/el.rs index 2ad67b754..980450aa2 100644 --- a/src/lang/el.rs +++ b/src/lang/el.rs @@ -813,5 +813,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-key-not-supported", ""), ("On", ""), ("Off", ""), + ("api_server_connection_tip", ""), + ("api_server_empty_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/en.rs b/src/lang/en.rs index 98010d877..4709a0d0b 100644 --- a/src/lang/en.rs +++ b/src/lang/en.rs @@ -288,5 +288,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-already-bound-to", "Already bound to"), ("shortcut-mobile-physical-keyboard-tip", "Recording requires a physical keyboard. Soft keyboards are not supported."), ("shortcut-key-not-supported", "\"{}\" can't be used as a shortcut."), + ("api_server_connection_tip", "Your custom server uses unencrypted HTTP. Contact your administrator to enable HTTPS."), + ("api_server_empty_tip", "With API Server empty, your custom server defaults to HTTP. Contact your administrator to enable HTTPS."), ].iter().cloned().collect(); } diff --git a/src/lang/eo.rs b/src/lang/eo.rs index edf05091b..d550e3000 100644 --- a/src/lang/eo.rs +++ b/src/lang/eo.rs @@ -813,5 +813,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-key-not-supported", ""), ("On", ""), ("Off", ""), + ("api_server_connection_tip", ""), + ("api_server_empty_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/es.rs b/src/lang/es.rs index efc91b9b8..f2670cee1 100644 --- a/src/lang/es.rs +++ b/src/lang/es.rs @@ -813,5 +813,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-key-not-supported", ""), ("On", ""), ("Off", ""), + ("api_server_connection_tip", ""), + ("api_server_empty_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/et.rs b/src/lang/et.rs index edaee1c05..d32b6116c 100644 --- a/src/lang/et.rs +++ b/src/lang/et.rs @@ -813,5 +813,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-key-not-supported", ""), ("On", ""), ("Off", ""), + ("api_server_connection_tip", ""), + ("api_server_empty_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/eu.rs b/src/lang/eu.rs index 5a2ae9f05..6c292d027 100644 --- a/src/lang/eu.rs +++ b/src/lang/eu.rs @@ -813,5 +813,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-key-not-supported", ""), ("On", ""), ("Off", ""), + ("api_server_connection_tip", ""), + ("api_server_empty_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/fa.rs b/src/lang/fa.rs index 17b1b7717..dbc306a58 100644 --- a/src/lang/fa.rs +++ b/src/lang/fa.rs @@ -813,5 +813,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-key-not-supported", ""), ("On", ""), ("Off", ""), + ("api_server_connection_tip", ""), + ("api_server_empty_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/fi.rs b/src/lang/fi.rs index cfc05abed..b46c5e54e 100644 --- a/src/lang/fi.rs +++ b/src/lang/fi.rs @@ -813,5 +813,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-key-not-supported", ""), ("On", ""), ("Off", ""), + ("api_server_connection_tip", ""), + ("api_server_empty_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/fr.rs b/src/lang/fr.rs index df9ce68c4..1a320bee7 100644 --- a/src/lang/fr.rs +++ b/src/lang/fr.rs @@ -813,5 +813,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-key-not-supported", ""), ("On", ""), ("Off", ""), + ("api_server_connection_tip", ""), + ("api_server_empty_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ge.rs b/src/lang/ge.rs index 78dd11b8e..16beeede9 100644 --- a/src/lang/ge.rs +++ b/src/lang/ge.rs @@ -813,5 +813,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-key-not-supported", ""), ("On", ""), ("Off", ""), + ("api_server_connection_tip", ""), + ("api_server_empty_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/gl.rs b/src/lang/gl.rs index 2868ffbc6..3624d4d81 100644 --- a/src/lang/gl.rs +++ b/src/lang/gl.rs @@ -813,5 +813,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-key-not-supported", ""), ("On", ""), ("Off", ""), + ("api_server_connection_tip", ""), + ("api_server_empty_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/gu.rs b/src/lang/gu.rs index 128f47516..72ca26833 100644 --- a/src/lang/gu.rs +++ b/src/lang/gu.rs @@ -813,5 +813,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-key-not-supported", ""), ("On", ""), ("Off", ""), + ("api_server_connection_tip", ""), + ("api_server_empty_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/he.rs b/src/lang/he.rs index 0d6d7e7d0..da6ee7b36 100644 --- a/src/lang/he.rs +++ b/src/lang/he.rs @@ -813,5 +813,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-key-not-supported", ""), ("On", ""), ("Off", ""), + ("api_server_connection_tip", ""), + ("api_server_empty_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/hi.rs b/src/lang/hi.rs index 3c35d9c05..68357b3ce 100644 --- a/src/lang/hi.rs +++ b/src/lang/hi.rs @@ -813,5 +813,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-key-not-supported", ""), ("On", ""), ("Off", ""), + ("api_server_connection_tip", ""), + ("api_server_empty_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/hr.rs b/src/lang/hr.rs index 17f28791e..a13796f7b 100644 --- a/src/lang/hr.rs +++ b/src/lang/hr.rs @@ -813,5 +813,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-key-not-supported", ""), ("On", ""), ("Off", ""), + ("api_server_connection_tip", ""), + ("api_server_empty_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/hu.rs b/src/lang/hu.rs index 6a2449bf5..3dcf4031a 100644 --- a/src/lang/hu.rs +++ b/src/lang/hu.rs @@ -813,5 +813,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-key-not-supported", ""), ("On", ""), ("Off", ""), + ("api_server_connection_tip", ""), + ("api_server_empty_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/id.rs b/src/lang/id.rs index 99e96c47f..bebf2a402 100644 --- a/src/lang/id.rs +++ b/src/lang/id.rs @@ -813,5 +813,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-key-not-supported", ""), ("On", ""), ("Off", ""), + ("api_server_connection_tip", ""), + ("api_server_empty_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/it.rs b/src/lang/it.rs index 460dcb7e9..4a518f032 100644 --- a/src/lang/it.rs +++ b/src/lang/it.rs @@ -813,5 +813,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-key-not-supported", "'{}' non può essere usato come scorciatoia."), ("On", "ON"), ("Off", "OFF"), + ("api_server_connection_tip", ""), + ("api_server_empty_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ja.rs b/src/lang/ja.rs index 32ec2df45..e1661feb8 100644 --- a/src/lang/ja.rs +++ b/src/lang/ja.rs @@ -813,5 +813,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-key-not-supported", ""), ("On", ""), ("Off", ""), + ("api_server_connection_tip", ""), + ("api_server_empty_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ko.rs b/src/lang/ko.rs index 7eaafbab7..8c68bea9b 100644 --- a/src/lang/ko.rs +++ b/src/lang/ko.rs @@ -813,5 +813,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-key-not-supported", ""), ("On", ""), ("Off", ""), + ("api_server_connection_tip", ""), + ("api_server_empty_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/kz.rs b/src/lang/kz.rs index 3a83f9a35..1f02923cd 100644 --- a/src/lang/kz.rs +++ b/src/lang/kz.rs @@ -813,5 +813,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-key-not-supported", ""), ("On", ""), ("Off", ""), + ("api_server_connection_tip", ""), + ("api_server_empty_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/lt.rs b/src/lang/lt.rs index e7c387cba..6d71fe793 100644 --- a/src/lang/lt.rs +++ b/src/lang/lt.rs @@ -813,5 +813,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-key-not-supported", ""), ("On", ""), ("Off", ""), + ("api_server_connection_tip", ""), + ("api_server_empty_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/lv.rs b/src/lang/lv.rs index 16690dbf8..0b62990f8 100644 --- a/src/lang/lv.rs +++ b/src/lang/lv.rs @@ -813,5 +813,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-key-not-supported", ""), ("On", ""), ("Off", ""), + ("api_server_connection_tip", ""), + ("api_server_empty_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ml.rs b/src/lang/ml.rs index 076f2628f..1dcfe3068 100644 --- a/src/lang/ml.rs +++ b/src/lang/ml.rs @@ -813,5 +813,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-key-not-supported", ""), ("On", ""), ("Off", ""), + ("api_server_connection_tip", ""), + ("api_server_empty_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/nb.rs b/src/lang/nb.rs index fda6f66c5..a080248d8 100644 --- a/src/lang/nb.rs +++ b/src/lang/nb.rs @@ -813,5 +813,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-key-not-supported", ""), ("On", ""), ("Off", ""), + ("api_server_connection_tip", ""), + ("api_server_empty_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/nl.rs b/src/lang/nl.rs index 4eb6d83e1..19131b4ca 100644 --- a/src/lang/nl.rs +++ b/src/lang/nl.rs @@ -813,5 +813,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-key-not-supported", "Sneltoets wordt niet ondersteund"), ("On", "Aan"), ("Off", "Uit"), + ("api_server_connection_tip", ""), + ("api_server_empty_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/pl.rs b/src/lang/pl.rs index c66ff09c4..1cefd6021 100644 --- a/src/lang/pl.rs +++ b/src/lang/pl.rs @@ -813,5 +813,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-key-not-supported", ""), ("On", ""), ("Off", ""), + ("api_server_connection_tip", ""), + ("api_server_empty_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/pt_BR.rs b/src/lang/pt_BR.rs index b32fca6d7..250a947d0 100644 --- a/src/lang/pt_BR.rs +++ b/src/lang/pt_BR.rs @@ -813,5 +813,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-key-not-supported", "Não é possível usar \"{}\" como atalho."), ("On", "Ativado"), ("Off", "Desativado"), + ("api_server_connection_tip", ""), + ("api_server_empty_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/pt_PT.rs b/src/lang/pt_PT.rs index f741573c9..4570cfae2 100644 --- a/src/lang/pt_PT.rs +++ b/src/lang/pt_PT.rs @@ -813,5 +813,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-key-not-supported", ""), ("On", ""), ("Off", ""), + ("api_server_connection_tip", ""), + ("api_server_empty_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ro.rs b/src/lang/ro.rs index 2458acf6b..8a190c6de 100644 --- a/src/lang/ro.rs +++ b/src/lang/ro.rs @@ -813,5 +813,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-key-not-supported", ""), ("On", ""), ("Off", ""), + ("api_server_connection_tip", ""), + ("api_server_empty_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ru.rs b/src/lang/ru.rs index 05856cbe2..7e78de3ff 100644 --- a/src/lang/ru.rs +++ b/src/lang/ru.rs @@ -813,5 +813,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-key-not-supported", "\"{}\" невозможно использовать как сочетание клавиш."), ("On", "вкл"), ("Off", "откл"), + ("api_server_connection_tip", ""), + ("api_server_empty_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sc.rs b/src/lang/sc.rs index 6791db5e4..3305991a7 100644 --- a/src/lang/sc.rs +++ b/src/lang/sc.rs @@ -813,5 +813,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-key-not-supported", ""), ("On", ""), ("Off", ""), + ("api_server_connection_tip", ""), + ("api_server_empty_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sk.rs b/src/lang/sk.rs index a1f424116..b6361ec56 100644 --- a/src/lang/sk.rs +++ b/src/lang/sk.rs @@ -813,5 +813,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-key-not-supported", ""), ("On", ""), ("Off", ""), + ("api_server_connection_tip", ""), + ("api_server_empty_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sl.rs b/src/lang/sl.rs index 910c7fea4..68346a40e 100644 --- a/src/lang/sl.rs +++ b/src/lang/sl.rs @@ -813,5 +813,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-key-not-supported", ""), ("On", ""), ("Off", ""), + ("api_server_connection_tip", ""), + ("api_server_empty_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sq.rs b/src/lang/sq.rs index b2d1688f0..057f51ff7 100644 --- a/src/lang/sq.rs +++ b/src/lang/sq.rs @@ -813,5 +813,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-key-not-supported", ""), ("On", ""), ("Off", ""), + ("api_server_connection_tip", ""), + ("api_server_empty_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sr.rs b/src/lang/sr.rs index 4992a2518..b09289399 100644 --- a/src/lang/sr.rs +++ b/src/lang/sr.rs @@ -813,5 +813,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-key-not-supported", ""), ("On", ""), ("Off", ""), + ("api_server_connection_tip", ""), + ("api_server_empty_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sv.rs b/src/lang/sv.rs index 0aab13b68..69ef3cd78 100644 --- a/src/lang/sv.rs +++ b/src/lang/sv.rs @@ -813,5 +813,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-key-not-supported", ""), ("On", ""), ("Off", ""), + ("api_server_connection_tip", ""), + ("api_server_empty_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ta.rs b/src/lang/ta.rs index 2f0b37069..fc967030a 100644 --- a/src/lang/ta.rs +++ b/src/lang/ta.rs @@ -813,5 +813,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-key-not-supported", ""), ("On", ""), ("Off", ""), + ("api_server_connection_tip", ""), + ("api_server_empty_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/template.rs b/src/lang/template.rs index 70b737117..d0fe5079a 100644 --- a/src/lang/template.rs +++ b/src/lang/template.rs @@ -813,5 +813,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-key-not-supported", ""), ("On", ""), ("Off", ""), + ("api_server_connection_tip", ""), + ("api_server_empty_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/th.rs b/src/lang/th.rs index a7baf3b9c..cd989476d 100644 --- a/src/lang/th.rs +++ b/src/lang/th.rs @@ -813,5 +813,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-key-not-supported", ""), ("On", ""), ("Off", ""), + ("api_server_connection_tip", ""), + ("api_server_empty_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/tr.rs b/src/lang/tr.rs index 792d968f3..cef0fb674 100644 --- a/src/lang/tr.rs +++ b/src/lang/tr.rs @@ -813,5 +813,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-key-not-supported", ""), ("On", ""), ("Off", ""), + ("api_server_connection_tip", ""), + ("api_server_empty_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/tw.rs b/src/lang/tw.rs index 8c42d8eae..375fbabb5 100644 --- a/src/lang/tw.rs +++ b/src/lang/tw.rs @@ -813,5 +813,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-key-not-supported", ""), ("On", ""), ("Off", ""), + ("api_server_connection_tip", "自訂伺服器正在使用未加密的 HTTP。請聯絡管理員啟用 HTTPS。"), + ("api_server_empty_tip", "API 伺服器留空時,自訂伺服器預設使用 HTTP。請聯絡管理員啟用 HTTPS。"), ].iter().cloned().collect(); } diff --git a/src/lang/uk.rs b/src/lang/uk.rs index caece340a..304a9075f 100644 --- a/src/lang/uk.rs +++ b/src/lang/uk.rs @@ -813,5 +813,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-key-not-supported", ""), ("On", ""), ("Off", ""), + ("api_server_connection_tip", ""), + ("api_server_empty_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ur.rs b/src/lang/ur.rs index f43d89ef4..0c589d720 100644 --- a/src/lang/ur.rs +++ b/src/lang/ur.rs @@ -813,6 +813,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-key-not-supported", ""), ("On", ""), ("Off", ""), + ("api_server_connection_tip", ""), + ("api_server_empty_tip", ""), ].iter().cloned().collect(); } diff --git a/src/lang/vi.rs b/src/lang/vi.rs index 3427c1903..25580d4a4 100644 --- a/src/lang/vi.rs +++ b/src/lang/vi.rs @@ -813,5 +813,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("shortcut-key-not-supported", ""), ("On", ""), ("Off", ""), + ("api_server_connection_tip", ""), + ("api_server_empty_tip", ""), ].iter().cloned().collect(); }