diff --git a/.dart_tool/flutter_gen/gen_l10n/l10n.dart b/.dart_tool/flutter_gen/gen_l10n/l10n.dart index 2e47649f..85b2d07a 100644 --- a/.dart_tool/flutter_gen/gen_l10n/l10n.dart +++ b/.dart_tool/flutter_gen/gen_l10n/l10n.dart @@ -741,6 +741,12 @@ abstract class S { /// **'Open'** String get open; + /// No description provided for @paste. + /// + /// In en, this message translates to: + /// **'Paste'** + String get paste; + /// No description provided for @path. /// /// In en, this message translates to: diff --git a/.dart_tool/flutter_gen/gen_l10n/l10n_en.dart b/.dart_tool/flutter_gen/gen_l10n/l10n_en.dart index aead5bc5..026d9050 100644 --- a/.dart_tool/flutter_gen/gen_l10n/l10n_en.dart +++ b/.dart_tool/flutter_gen/gen_l10n/l10n_en.dart @@ -350,6 +350,9 @@ class SEn extends S { @override String get open => 'Open'; + @override + String get paste => 'Paste'; + @override String get path => 'Path'; diff --git a/.dart_tool/flutter_gen/gen_l10n/l10n_zh.dart b/.dart_tool/flutter_gen/gen_l10n/l10n_zh.dart index 4ed3569a..b2e96e33 100644 --- a/.dart_tool/flutter_gen/gen_l10n/l10n_zh.dart +++ b/.dart_tool/flutter_gen/gen_l10n/l10n_zh.dart @@ -350,6 +350,9 @@ class SZh extends S { @override String get open => '打开'; + @override + String get paste => '粘贴'; + @override String get path => '路径'; diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index ba9bd2d4..532de3bd 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -359,7 +359,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 255; + CURRENT_PROJECT_VERSION = 256; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -367,7 +367,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.255; + MARKETING_VERSION = 1.0.256; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -490,7 +490,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 255; + CURRENT_PROJECT_VERSION = 256; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -498,7 +498,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.255; + MARKETING_VERSION = 1.0.256; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -515,7 +515,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 255; + CURRENT_PROJECT_VERSION = 256; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -523,7 +523,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.255; + MARKETING_VERSION = 1.0.256; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; diff --git a/lib/data/model/app/backup.dart b/lib/data/model/app/backup.dart index 96edb680..98da112d 100644 --- a/lib/data/model/app/backup.dart +++ b/lib/data/model/app/backup.dart @@ -31,7 +31,7 @@ class Backup { keys = (json['keys'] as List) .map((e) => PrivateKeyInfo.fromJson(e)) .toList(), - dockerHosts = json['dockerHosts']; + dockerHosts = json['dockerHosts'] ?? {}; Map toJson() => { 'version': version, diff --git a/lib/data/model/ssh/virtual_key.dart b/lib/data/model/ssh/virtual_key.dart index 3dd552f9..a7a2df58 100644 --- a/lib/data/model/ssh/virtual_key.dart +++ b/lib/data/model/ssh/virtual_key.dart @@ -12,4 +12,4 @@ class VirtualKey { {this.key, this.toggleable = false, this.icon, this.func}); } -enum VirtualKeyFunc { toggleIME, backspace, copy, paste } +enum VirtualKeyFunc { toggleIME, backspace, copy, paste, snippet } diff --git a/lib/data/res/build_data.dart b/lib/data/res/build_data.dart index 6d27a629..b10df114 100644 --- a/lib/data/res/build_data.dart +++ b/lib/data/res/build_data.dart @@ -2,8 +2,9 @@ class BuildData { static const String name = "ServerBox"; - static const int build = 255; - static const String engine = "Flutter 3.7.7 • channel stable • https://github.com/flutter/flutter.git\nFramework • revision 2ad6cd72c0 (4 weeks ago) • 2023-03-08 09:41:59 -0800\nEngine • revision 1837b5be5f\nTools • Dart 2.19.4 • DevTools 2.20.1\n"; - static const String buildAt = "2023-04-05 15:03:38.565037"; + static const int build = 256; + static const String engine = + "Flutter 3.7.7 • channel stable • https://github.com/flutter/flutter.git\nFramework • revision 2ad6cd72c0 (4 weeks ago) • 2023-03-08 09:41:59 -0800\nEngine • revision 1837b5be5f\nTools • Dart 2.19.4 • DevTools 2.20.1\n"; + static const String buildAt = "2023-04-05 15:16:00.949501"; static const int modifications = 2; } diff --git a/lib/data/res/virtual_key.dart b/lib/data/res/virtual_key.dart index fe326444..d7e8b282 100644 --- a/lib/data/res/virtual_key.dart +++ b/lib/data/res/virtual_key.dart @@ -13,7 +13,8 @@ var virtualKeys = [ // 'Del', // key: TerminalKey.delete, // ), - VirtualKey('Paste', func: VirtualKeyFunc.paste, icon: Icons.paste), + //VirtualKey('Paste', func: VirtualKeyFunc.paste, icon: Icons.paste), + VirtualKey('Snippet', func: VirtualKeyFunc.snippet, icon: Icons.code), VirtualKey('Tab', key: TerminalKey.tab), VirtualKey('Ctrl', key: TerminalKey.control, toggleable: true), VirtualKey('Left', key: TerminalKey.arrowLeft, icon: Icons.arrow_back), diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 674c284e..0cd4b1e6 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -107,6 +107,7 @@ "onServerDetailPage": "On server detail page", "onlyIOS": "Only valid on iOS", "open": "Open", + "paste": "Paste", "path": "Path", "pickFile": "Pick file", "ping": "Ping", diff --git a/lib/l10n/app_zh.arb b/lib/l10n/app_zh.arb index 0e72148d..bab38993 100644 --- a/lib/l10n/app_zh.arb +++ b/lib/l10n/app_zh.arb @@ -107,6 +107,7 @@ "onServerDetailPage": "在服务器详情页", "onlyIOS": "仅在iOS上有效", "open": "打开", + "paste": "粘贴", "path": "路径", "pickFile": "选择文件", "ping": "Ping", diff --git a/lib/view/page/backup.dart b/lib/view/page/backup.dart index 7ff07093..5d28c729 100644 --- a/lib/view/page/backup.dart +++ b/lib/view/page/backup.dart @@ -5,6 +5,7 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:toolbox/core/utils/misc.dart'; import '../../core/extension/colorx.dart'; import '../../core/utils/ui.dart'; @@ -196,14 +197,19 @@ class BackupPage extends StatelessWidget { _dockerHosts.setDockerHost(k, backup.dockerHosts[k]!); } Navigator.of(context).pop(); - showSnackBar(context, Text(s.restoreSuccess)); + showSnackBarWithAction( + context, + s.restoreSuccess, + s.restart, + () => rebuildAll(context), + ); }, child: Text(s.ok), ), ], ); } catch (e) { - showSnackBar(context, Text(s.invalidJson)); + showSnackBar(context, Text(e.toString())); return; } } diff --git a/lib/view/page/ssh.dart b/lib/view/page/ssh.dart index ced5c8b0..2a32b929 100644 --- a/lib/view/page/ssh.dart +++ b/lib/view/page/ssh.dart @@ -274,6 +274,10 @@ class _SSHPageState extends State { case VirtualKeyFunc.copy: copy(terminalSelected); break; + case VirtualKeyFunc.snippet: + // TODO: Handle this case. + // _showSnippet(); + break; } } @@ -300,27 +304,27 @@ class _SSHPageState extends State { } final selected = terminalSelected; if (selected.trim().isEmpty) { - // _menuController.show( - // context: context, - // contextMenuBuilder: (context) { - // return TextSelectionToolbar( - // anchorAbove: detail.globalPosition, - // anchorBelow: detail.globalPosition, - // children: [ - // TextButton( - // child: Text( - // 'Paste', - // style: _menuTextStyle, - // ), - // onPressed: () async { - // _paste(); - // _menuController.remove(); - // }, - // ) - // ], - // ); - // }, - // ); + _menuController.show( + context: context, + contextMenuBuilder: (context) { + return TextSelectionToolbar( + anchorAbove: details.globalPosition, + anchorBelow: details.globalPosition, + children: [ + TextButton( + child: Text( + _s.paste, + style: _menuTextStyle, + ), + onPressed: () async { + _paste(); + _menuController.remove(); + }, + ) + ], + ); + }, + ); return; } _menuController.show( diff --git a/lib/view/widget/picker.dart b/lib/view/widget/picker.dart index b83e81be..9bfef1de 100644 --- a/lib/view/widget/picker.dart +++ b/lib/view/widget/picker.dart @@ -25,10 +25,11 @@ Widget buildPicker(List items, Function(int idx) onSelected) { onSelectedItemChanged: (idx) => onSelected(idx), physics: const FixedExtentScrollPhysics(), childDelegate: ListWheelChildBuilderDelegate( - builder: (context, index) => Center( - child: items[index], - ), - childCount: items.length), + builder: (context, index) => Center( + child: items[index], + ), + childCount: items.length, + ), ) ], ),