diff --git a/.dart_tool/flutter_gen/gen_l10n/l10n.dart b/.dart_tool/flutter_gen/gen_l10n/l10n.dart index 5589a5ae..95abe9ee 100644 --- a/.dart_tool/flutter_gen/gen_l10n/l10n.dart +++ b/.dart_tool/flutter_gen/gen_l10n/l10n.dart @@ -144,6 +144,12 @@ abstract class S { /// **'Already in last directory.'** String get alreadyLastDir; + /// No description provided for @alterHost. + /// + /// In en, this message translates to: + /// **'Alter host'** + String get alterHost; + /// No description provided for @attention. /// /// In en, this message translates to: diff --git a/.dart_tool/flutter_gen/gen_l10n/l10n_de.dart b/.dart_tool/flutter_gen/gen_l10n/l10n_de.dart index a139cfd9..10cbc63b 100644 --- a/.dart_tool/flutter_gen/gen_l10n/l10n_de.dart +++ b/.dart_tool/flutter_gen/gen_l10n/l10n_de.dart @@ -28,6 +28,9 @@ class SDe extends S { @override String get alreadyLastDir => 'Bereits im letzten Verzeichnis.'; + @override + String get alterHost => 'Alternative Gastgeber'; + @override String get attention => 'Achtung'; diff --git a/.dart_tool/flutter_gen/gen_l10n/l10n_en.dart b/.dart_tool/flutter_gen/gen_l10n/l10n_en.dart index 331264d6..db400d6f 100644 --- a/.dart_tool/flutter_gen/gen_l10n/l10n_en.dart +++ b/.dart_tool/flutter_gen/gen_l10n/l10n_en.dart @@ -28,6 +28,9 @@ class SEn extends S { @override String get alreadyLastDir => 'Already in last directory.'; + @override + String get alterHost => 'Alter host'; + @override String get attention => 'Attention'; diff --git a/.dart_tool/flutter_gen/gen_l10n/l10n_zh.dart b/.dart_tool/flutter_gen/gen_l10n/l10n_zh.dart index c41b7ff4..3bff4e9a 100644 --- a/.dart_tool/flutter_gen/gen_l10n/l10n_zh.dart +++ b/.dart_tool/flutter_gen/gen_l10n/l10n_zh.dart @@ -28,6 +28,9 @@ class SZh extends S { @override String get alreadyLastDir => '已经是最上层目录了'; + @override + String get alterHost => '备选主机'; + @override String get attention => '注意'; @@ -701,6 +704,9 @@ class SZhTw extends SZh { @override String get alreadyLastDir => '已經是最上層目錄了'; + @override + String get alterHost => '備選主機'; + @override String get attention => '注意'; diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 19d4820e..cd4529d6 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -470,7 +470,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 388; + CURRENT_PROJECT_VERSION = 389; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -478,7 +478,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.388; + MARKETING_VERSION = 1.0.389; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -602,7 +602,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 388; + CURRENT_PROJECT_VERSION = 389; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -610,7 +610,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.388; + MARKETING_VERSION = 1.0.389; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -628,7 +628,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 388; + CURRENT_PROJECT_VERSION = 389; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -636,7 +636,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.388; + MARKETING_VERSION = 1.0.389; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -657,7 +657,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 388; + CURRENT_PROJECT_VERSION = 389; DEVELOPMENT_TEAM = BA88US33G6; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -670,7 +670,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 1.0.388; + MARKETING_VERSION = 1.0.389; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; @@ -696,7 +696,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 388; + CURRENT_PROJECT_VERSION = 389; DEVELOPMENT_TEAM = BA88US33G6; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -709,7 +709,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 1.0.388; + MARKETING_VERSION = 1.0.389; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -732,7 +732,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 388; + CURRENT_PROJECT_VERSION = 389; DEVELOPMENT_TEAM = BA88US33G6; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -745,7 +745,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 1.0.388; + MARKETING_VERSION = 1.0.389; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; PRODUCT_NAME = "$(TARGET_NAME)"; diff --git a/lib/core/utils/server.dart b/lib/core/utils/server.dart index 72bb4076..eb9676ed 100644 --- a/lib/core/utils/server.dart +++ b/lib/core/utils/server.dart @@ -35,15 +35,31 @@ Future genClient( ServerPrivateInfo spi, { void Function(GenSSHClientStatus)? onStatus, }) async { - final onStatus_ = onStatus ?? (_) {}; - onStatus_(GenSSHClientStatus.socket); - final socket = await SSHSocket.connect( - spi.ip, - spi.port, - timeout: const Duration(seconds: 5), - ); + onStatus?.call(GenSSHClientStatus.socket); + late SSHSocket socket; + try { + socket = await SSHSocket.connect( + spi.ip, + spi.port, + timeout: const Duration(seconds: 5), + ); + } catch (e) { + try { + socket = await SSHSocket.connect( + spi.alterHost!, + spi.port, + timeout: const Duration(seconds: 5), + ); + } catch (e) { + throw SSHErr( + type: SSHErrType.connect, + message: e.toString(), + ); + } + } + if (spi.pubKeyId == null) { - onStatus_(GenSSHClientStatus.pwd); + onStatus?.call(GenSSHClientStatus.pwd); return SSHClient( socket, username: spi.user, @@ -57,7 +73,7 @@ Future genClient( message: 'key [${spi.pubKeyId}] not found', ); } - onStatus_(GenSSHClientStatus.key); + onStatus?.call(GenSSHClientStatus.key); return SSHClient( socket, username: spi.user, diff --git a/lib/data/model/app/error.dart b/lib/data/model/app/error.dart index d2d01906..11b23555 100644 --- a/lib/data/model/app/error.dart +++ b/lib/data/model/app/error.dart @@ -17,6 +17,7 @@ abstract class Err { enum SSHErrType { unknown, + connect, noPrivateKey; } diff --git a/lib/data/model/server/server_private_info.dart b/lib/data/model/server/server_private_info.dart index a6b44268..a27e5f1e 100644 --- a/lib/data/model/server/server_private_info.dart +++ b/lib/data/model/server/server_private_info.dart @@ -18,6 +18,8 @@ class ServerPrivateInfo { String? pubKeyId; @HiveField(6) List? tags; + @HiveField(7) + String? alterHost; late String id; @@ -29,6 +31,7 @@ class ServerPrivateInfo { required this.pwd, this.pubKeyId, this.tags, + this.alterHost, }) : id = '$user@$ip:$port'; ServerPrivateInfo.fromJson(Map json) { @@ -40,6 +43,7 @@ class ServerPrivateInfo { pubKeyId = json["pubKeyId"]?.toString(); id = '$user@$ip:$port'; tags = json["tags"]?.cast(); + alterHost = json["alterHost"]?.toString(); } Map toJson() { @@ -51,11 +55,15 @@ class ServerPrivateInfo { data["authorization"] = pwd; data["pubKeyId"] = pubKeyId; data["tags"] = tags; + data["alterHost"] = alterHost; return data; } bool shouldReconnect(ServerPrivateInfo old) { - return id != old.id || pwd != old.pwd || pubKeyId != old.pubKeyId; + return id != old.id || + pwd != old.pwd || + pubKeyId != old.pubKeyId || + alterHost != old.alterHost; } @override diff --git a/lib/data/model/server/server_private_info.g.dart b/lib/data/model/server/server_private_info.g.dart index 5ed90420..4a08e47c 100644 --- a/lib/data/model/server/server_private_info.g.dart +++ b/lib/data/model/server/server_private_info.g.dart @@ -24,13 +24,14 @@ class ServerPrivateInfoAdapter extends TypeAdapter { pwd: fields[4] as String, pubKeyId: fields[5] as String?, tags: (fields[6] as List?)?.cast(), + alterHost: fields[7] as String?, ); } @override void write(BinaryWriter writer, ServerPrivateInfo obj) { writer - ..writeByte(7) + ..writeByte(8) ..writeByte(0) ..write(obj.name) ..writeByte(1) @@ -44,7 +45,9 @@ class ServerPrivateInfoAdapter extends TypeAdapter { ..writeByte(5) ..write(obj.pubKeyId) ..writeByte(6) - ..write(obj.tags); + ..write(obj.tags) + ..writeByte(7) + ..write(obj.alterHost); } @override diff --git a/lib/data/res/build_data.dart b/lib/data/res/build_data.dart index eeeb3dc5..fc56292c 100644 --- a/lib/data/res/build_data.dart +++ b/lib/data/res/build_data.dart @@ -2,8 +2,8 @@ class BuildData { static const String name = "ServerBox"; - static const int build = 388; + static const int build = 389; static const String engine = "3.10.6"; - static const String buildAt = "2023-07-27 13:03:33.193528"; - static const int modifications = 16; + static const String buildAt = "2023-07-28 13:50:35.251988"; + static const int modifications = 17; } diff --git a/lib/data/res/url.dart b/lib/data/res/url.dart index 0874c111..72741a51 100644 --- a/lib/data/res/url.dart +++ b/lib/data/res/url.dart @@ -14,4 +14,5 @@ const thanksMap = { 'wxdjs': 'https://github.com/wxdjs', 'Aeorq': 'https://github.com/Aeorq', 'jaychoubaby': 'https://github.com/jaychoubaby', + 'allonmymind': 'https://github.com/allonmymind', }; diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index a18cf3fe..97f6dec3 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -8,6 +8,7 @@ "added2List": "Zur Aufgabenliste hinzugefügt", "all": "Alle", "alreadyLastDir": "Bereits im letzten Verzeichnis.", + "alterHost": "Alternative Gastgeber", "attention": "Achtung", "auto": "System folgen", "autoUpdateHomeWidget": "Home-Widget automatisch aktualisieren", diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index f833d41d..aaa37858 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -8,6 +8,7 @@ "added2List": "Added to task list", "all": "All", "alreadyLastDir": "Already in last directory.", + "alterHost": "Alter host", "attention": "Attention", "auto": "Auto", "autoUpdateHomeWidget": "Auto update home widget", diff --git a/lib/l10n/app_zh.arb b/lib/l10n/app_zh.arb index 2a0c5927..4dbf165b 100644 --- a/lib/l10n/app_zh.arb +++ b/lib/l10n/app_zh.arb @@ -8,6 +8,7 @@ "added2List": "已添加至任务列表", "all": "所有", "alreadyLastDir": "已经是最上层目录了", + "alterHost": "备选主机", "attention": "注意", "auto": "自动", "autoUpdateHomeWidget": "自动更新桌面小部件", diff --git a/lib/l10n/app_zh_tw.arb b/lib/l10n/app_zh_tw.arb index 44a5ee86..5194bda3 100644 --- a/lib/l10n/app_zh_tw.arb +++ b/lib/l10n/app_zh_tw.arb @@ -8,6 +8,7 @@ "added2List": "已添加至任務列表", "all": "所有", "alreadyLastDir": "已經是最上層目錄了", + "alterHost": "備選主機", "attention": "注意", "auto": "自動", "autoUpdateHomeWidget": "自動更新桌面小部件", diff --git a/lib/view/page/server/edit.dart b/lib/view/page/server/edit.dart index 10a9348f..e23842f2 100644 --- a/lib/view/page/server/edit.dart +++ b/lib/view/page/server/edit.dart @@ -30,11 +30,13 @@ class ServerEditPage extends StatefulWidget { class _ServerEditPageState extends State with AfterLayoutMixin { final _nameController = TextEditingController(); final _ipController = TextEditingController(); + final _alterHostController = TextEditingController(); final _portController = TextEditingController(); final _usernameController = TextEditingController(); final _passwordController = TextEditingController(); final _nameFocus = FocusNode(); final _ipFocus = FocusNode(); + final _alterHostFocus = FocusNode(); final _portFocus = FocusNode(); final _usernameFocus = FocusNode(); @@ -118,12 +120,20 @@ class _ServerEditPageState extends State with AfterLayoutMixin { Input( controller: _ipController, type: TextInputType.text, - onSubmitted: (_) => _focusScope.requestFocus(_portFocus), + onSubmitted: (_) => _focusScope.requestFocus(_alterHostFocus), node: _ipFocus, label: _s.host, - icon: Icons.storage, + icon: Icons.computer, hint: 'example.com', ), + Input( + controller: _alterHostController, + type: TextInputType.text, + node: _alterHostFocus, + onSubmitted: (_) => _focusScope.requestFocus(_portFocus), + label: _s.alterHost, + icon: Icons.computer, + ), Input( controller: _portController, type: TextInputType.number, @@ -280,6 +290,9 @@ class _ServerEditPageState extends State with AfterLayoutMixin { pwd: authorization, pubKeyId: usePublicKey ? _keyInfo!.id : null, tags: _tags, + alterHost: _alterHostController.text == '' + ? null + : _alterHostController.text, ); if (widget.spi == null) { @@ -321,6 +334,7 @@ class _ServerEditPageState extends State with AfterLayoutMixin { if (widget.spi?.tags != null) { _tags = widget.spi!.tags!; } + _alterHostController.text = widget.spi?.alterHost ?? ''; setState(() {}); } } diff --git a/lib/view/page/setting.dart b/lib/view/page/setting.dart index ad96fd21..145f0cea 100644 --- a/lib/view/page/setting.dart +++ b/lib/view/page/setting.dart @@ -869,7 +869,7 @@ class _SettingPageState extends State { Widget _buildAndroidWidgetSharedPreference() { return ListTile( title: Text(_s.homeWidgetUrlConfig), - trailing: const Icon(Icons.arrow_forward_ios, size: 13), + trailing: const Icon(Icons.keyboard_arrow_right), onTap: () { final data = {}; _sp.getKeys().forEach((key) { diff --git a/macos/Runner.xcodeproj/project.pbxproj b/macos/Runner.xcodeproj/project.pbxproj index 8740a389..4da5ebed 100644 --- a/macos/Runner.xcodeproj/project.pbxproj +++ b/macos/Runner.xcodeproj/project.pbxproj @@ -475,9 +475,9 @@ baseConfigurationReference = C1C758C41C4E208965A68933 /* Pods-RunnerTests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; - CURRENT_PROJECT_VERSION = 388; + CURRENT_PROJECT_VERSION = 389; GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0.388; + MARKETING_VERSION = 1.0.389; PRODUCT_BUNDLE_IDENTIFIER = tech.lolli.serverBox.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; @@ -490,9 +490,9 @@ baseConfigurationReference = 15AF97DF993E8968098D6EBE /* Pods-RunnerTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; - CURRENT_PROJECT_VERSION = 388; + CURRENT_PROJECT_VERSION = 389; GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0.388; + MARKETING_VERSION = 1.0.389; PRODUCT_BUNDLE_IDENTIFIER = tech.lolli.serverBox.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; @@ -505,9 +505,9 @@ baseConfigurationReference = 7CFA7DE7FABA75685DFB6948 /* Pods-RunnerTests.profile.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; - CURRENT_PROJECT_VERSION = 388; + CURRENT_PROJECT_VERSION = 389; GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0.388; + MARKETING_VERSION = 1.0.389; PRODUCT_BUNDLE_IDENTIFIER = tech.lolli.serverBox.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0;