diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index b358ee178..e59e70fe0 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -586,7 +586,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 770; + CURRENT_PROJECT_VERSION = 771; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -596,7 +596,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.770; + MARKETING_VERSION = 1.0.771; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -720,7 +720,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 770; + CURRENT_PROJECT_VERSION = 771; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -730,7 +730,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.770; + MARKETING_VERSION = 1.0.771; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -748,7 +748,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 770; + CURRENT_PROJECT_VERSION = 771; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -758,7 +758,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.770; + MARKETING_VERSION = 1.0.771; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -779,7 +779,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 770; + CURRENT_PROJECT_VERSION = 771; DEVELOPMENT_TEAM = BA88US33G6; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -792,7 +792,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 1.0.770; + MARKETING_VERSION = 1.0.771; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; @@ -818,7 +818,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 770; + CURRENT_PROJECT_VERSION = 771; DEVELOPMENT_TEAM = BA88US33G6; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -831,7 +831,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 1.0.770; + MARKETING_VERSION = 1.0.771; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -854,7 +854,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 770; + CURRENT_PROJECT_VERSION = 771; DEVELOPMENT_TEAM = BA88US33G6; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -867,7 +867,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 1.0.770; + MARKETING_VERSION = 1.0.771; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -890,7 +890,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 770; + CURRENT_PROJECT_VERSION = 771; DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_PREVIEWS = YES; @@ -902,7 +902,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.770; + MARKETING_VERSION = 1.0.771; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd; @@ -931,7 +931,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 770; + CURRENT_PROJECT_VERSION = 771; DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_PREVIEWS = YES; @@ -943,7 +943,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.770; + MARKETING_VERSION = 1.0.771; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd; PRODUCT_NAME = ServerBox; @@ -969,7 +969,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 770; + CURRENT_PROJECT_VERSION = 771; DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_PREVIEWS = YES; @@ -981,7 +981,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.770; + MARKETING_VERSION = 1.0.771; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd; PRODUCT_NAME = ServerBox; diff --git a/lib/core/extension/context/dialog.dart b/lib/core/extension/context/dialog.dart index 73448ed95..5c905e877 100644 --- a/lib/core/extension/context/dialog.dart +++ b/lib/core/extension/context/dialog.dart @@ -3,6 +3,7 @@ import 'package:flutter/material.dart'; import 'package:toolbox/core/extension/context/common.dart'; import 'package:toolbox/core/extension/context/locale.dart'; import 'package:toolbox/view/widget/choice_chip.dart'; +import 'package:toolbox/view/widget/tag.dart'; import '../../../data/res/ui.dart'; import '../../../view/widget/input_field.dart'; @@ -119,4 +120,77 @@ extension DialogX on BuildContext { } return null; } + + Future?> showPickWithTagDialog({ + required List Function(String? tag) itemsBuilder, + required ValueNotifier> tags, + String Function(T)? name, + List? initial, + bool clearable = false, + bool multi = false, + List? actions, + }) async { + var vals = initial ?? []; + final tag = ValueNotifier(null); + final sure = await showRoundDialog( + title: Text(l10n.choose), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ListenableBuilder( + listenable: tag, + builder: (_, __) => TagSwitcher( + tags: tags, + width: 300, + initTag: tag.value, + onTagChanged: (e) => tag.value = e, + ), + ), + const Divider(), + SingleChildScrollView( + child: ValueListenableBuilder( + valueListenable: tag, + builder: (_, val, __) { + final items = itemsBuilder(val); + return Choice( + onChanged: (value) => vals = value, + multiple: multi, + clearable: clearable, + value: vals, + builder: (state, _) { + return Wrap( + children: List.generate( + items.length, + (index) { + final item = items[index]; + if (item == null) return UIs.placeholder; + return ChoiceChipX( + label: name?.call(item) ?? item.toString(), + state: state, + value: item, + ); + }, + ), + ); + }, + ); + }, + ), + ) + ], + ), + actions: [ + if (actions != null) ...actions, + TextButton( + onPressed: () => pop(true), + child: Text(l10n.ok), + ), + ], + ); + if (sure == true && vals.isNotEmpty) { + return vals; + } + return null; + } } diff --git a/lib/data/res/build_data.dart b/lib/data/res/build_data.dart index 7581ddae9..7284372af 100644 --- a/lib/data/res/build_data.dart +++ b/lib/data/res/build_data.dart @@ -2,9 +2,9 @@ class BuildData { static const String name = "ServerBox"; - static const int build = 770; + static const int build = 771; static const String engine = "3.19.0"; - static const String buildAt = "2024-02-20 15:34:30"; - static const int modifications = 10; + static const String buildAt = "2024-02-20 16:12:21"; + static const int modifications = 8; static const int script = 38; } diff --git a/lib/view/page/server/tab.dart b/lib/view/page/server/tab.dart index 0b91e8e6c..1a5d087c5 100644 --- a/lib/view/page/server/tab.dart +++ b/lib/view/page/server/tab.dart @@ -120,7 +120,6 @@ class _ServerPageState extends State _tag = p0; }), initTag: _tag, - all: l10n.all, ); } diff --git a/lib/view/page/snippet/list.dart b/lib/view/page/snippet/list.dart index 651a5adf8..be73cc6f3 100644 --- a/lib/view/page/snippet/list.dart +++ b/lib/view/page/snippet/list.dart @@ -71,7 +71,6 @@ class _SnippetListPageState extends State { tags: provider.tags, onTagChanged: (tag) => setState(() => _tag = tag), initTag: _tag, - all: l10n.all, width: _media.size.width, ), footer: UIs.height77, diff --git a/lib/view/page/ssh/page.dart b/lib/view/page/ssh/page.dart index 73480720b..4f8c182ae 100644 --- a/lib/view/page/ssh/page.dart +++ b/lib/view/page/ssh/page.dart @@ -275,12 +275,20 @@ class _SSHPageState extends State with AutomaticKeepAliveClientMixin { } break; case VirtualKeyFunc.snippet: - final s = await context.showPickSingleDialog( - items: Pros.snippet.snippets, - name: (p0) => p0.name, + final snippets = await context.showPickWithTagDialog( + tags: Pros.snippet.tags, + itemsBuilder: (e) { + if (e == null) return Pros.snippet.snippets; + return Pros.snippet.snippets + .where((element) => element.tags?.contains(e) ?? false) + .toList(); + }, + name: (e) => e.name, ); - if (s == null) return; - _terminal.textInput(s.script); + if (snippets == null || snippets.isEmpty) return; + + final snippet = snippets.first; + _terminal.textInput(snippet.script); _terminal.keyInput(TerminalKey.enter); break; case VirtualKeyFunc.file: diff --git a/lib/view/widget/server_func_btns.dart b/lib/view/widget/server_func_btns.dart index 0b8f5c84e..c63370f9c 100644 --- a/lib/view/widget/server_func_btns.dart +++ b/lib/view/widget/server_func_btns.dart @@ -122,11 +122,18 @@ void _onTapMoreBtns( ); break; case ServerFuncBtn.snippet: - final snippet = await context.showPickSingleDialog( - items: Pros.snippet.snippets, + final snippets = await context.showPickWithTagDialog( + tags: Pros.snippet.tags, + itemsBuilder: (e) { + if (e == null) return Pros.snippet.snippets; + return Pros.snippet.snippets + .where((element) => element.tags?.contains(e) ?? false) + .toList(); + }, name: (e) => e.name, ); - if (snippet == null) return; + if (snippets == null || snippets.isEmpty) return; + final snippet = snippets.first; AppRoute.ssh(spi: spi, initCmd: snippet.fmtWith(spi)).checkGo( context: context, diff --git a/lib/view/widget/tag.dart b/lib/view/widget/tag.dart index aa2a877f4..9b499125d 100644 --- a/lib/view/widget/tag.dart +++ b/lib/view/widget/tag.dart @@ -184,14 +184,12 @@ class TagSwitcher extends StatelessWidget implements PreferredSizeWidget { final double width; final void Function(String?) onTagChanged; final String? initTag; - final String all; const TagSwitcher({ super.key, required this.tags, required this.width, required this.onTagChanged, - required this.all, this.initTag, }); @@ -213,7 +211,7 @@ class TagSwitcher extends StatelessWidget implements PreferredSizeWidget { itemBuilder: (context, index) { final item = items[index]; return TagBtn( - content: item == null ? all : '#$item', + content: item == null ? l10n.all : '#$item', isEnable: initTag == item, onTap: () => onTagChanged(item), ); diff --git a/macos/Runner.xcodeproj/project.pbxproj b/macos/Runner.xcodeproj/project.pbxproj index 89adb978c..29eb1ab84 100644 --- a/macos/Runner.xcodeproj/project.pbxproj +++ b/macos/Runner.xcodeproj/project.pbxproj @@ -439,7 +439,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 770; + CURRENT_PROJECT_VERSION = 771; DEVELOPMENT_TEAM = BA88US33G6; INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = "Server Box"; @@ -449,7 +449,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.15; - MARKETING_VERSION = 1.0.770; + MARKETING_VERSION = 1.0.771; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "Server Box"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -574,7 +574,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 770; + CURRENT_PROJECT_VERSION = 771; DEVELOPMENT_TEAM = BA88US33G6; INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = "Server Box"; @@ -584,7 +584,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.15; - MARKETING_VERSION = 1.0.770; + MARKETING_VERSION = 1.0.771; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "Server Box"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -604,7 +604,7 @@ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "3rd Party Mac Developer Application"; CODE_SIGN_STYLE = Manual; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 770; + CURRENT_PROJECT_VERSION = 771; DEVELOPMENT_TEAM = ""; "DEVELOPMENT_TEAM[sdk=macosx*]" = BA88US33G6; INFOPLIST_FILE = Runner/Info.plist; @@ -615,7 +615,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.15; - MARKETING_VERSION = 1.0.770; + MARKETING_VERSION = 1.0.771; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "Server Box"; PROVISIONING_PROFILE_SPECIFIER = "";