diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index bb2102b8..a4d3ea0d 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 = 489; + CURRENT_PROJECT_VERSION = 491; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -478,7 +478,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.489; + MARKETING_VERSION = 1.0.491; 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 = 489; + CURRENT_PROJECT_VERSION = 491; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -610,7 +610,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.489; + MARKETING_VERSION = 1.0.491; 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 = 489; + CURRENT_PROJECT_VERSION = 491; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -636,7 +636,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.489; + MARKETING_VERSION = 1.0.491; 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 = 489; + CURRENT_PROJECT_VERSION = 491; 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.489; + MARKETING_VERSION = 1.0.491; 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 = 489; + CURRENT_PROJECT_VERSION = 491; 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.489; + MARKETING_VERSION = 1.0.491; 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 = 489; + CURRENT_PROJECT_VERSION = 491; 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.489; + MARKETING_VERSION = 1.0.491; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; PRODUCT_NAME = "$(TARGET_NAME)"; diff --git a/lib/data/res/build_data.dart b/lib/data/res/build_data.dart index b0fbdc8f..35b9a138 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 = 489; + static const int build = 491; static const String engine = "3.10.6"; - static const String buildAt = "2023-08-20 22:40:51.896334"; - static const int modifications = 3; + static const String buildAt = "2023-08-20 23:32:07.343451"; + static const int modifications = 4; } diff --git a/lib/view/page/server/edit.dart b/lib/view/page/server/edit.dart index 1736d251..c9e9d16a 100644 --- a/lib/view/page/server/edit.dart +++ b/lib/view/page/server/edit.dart @@ -16,7 +16,7 @@ import '../../../data/res/ui.dart'; import '../../../data/store/private_key.dart'; import '../../../locator.dart'; import '../../widget/custom_appbar.dart'; -import '../../widget/tag/btn.dart'; +import '../../widget/tag.dart'; import '../private_key/edit.dart'; class ServerEditPage extends StatefulWidget { diff --git a/lib/view/page/server/tab.dart b/lib/view/page/server/tab.dart index e74b8255..71ac9b84 100644 --- a/lib/view/page/server/tab.dart +++ b/lib/view/page/server/tab.dart @@ -22,7 +22,7 @@ import '../../../data/store/setting.dart'; import '../../../locator.dart'; import '../../widget/round_rect_card.dart'; import '../../widget/server_func_btns.dart'; -import '../../widget/tag/switcher.dart'; +import '../../widget/tag.dart'; import 'edit.dart'; class ServerPage extends StatefulWidget { @@ -425,7 +425,7 @@ class _ServerPageState extends State child: Text( '${percent.toStringAsFixed(1)}%', textAlign: TextAlign.center, - style: textSize11Grey, + style: textSize11, textScaleFactor: 1.0, ), ), diff --git a/lib/view/page/setting/virt_key.dart b/lib/view/page/setting/virt_key.dart index f90f133e..a26518c9 100644 --- a/lib/view/page/setting/virt_key.dart +++ b/lib/view/page/setting/virt_key.dart @@ -52,13 +52,14 @@ class _SSHVirtKeySettingPageState extends State { final key = allKeys[idx]; final help = key.help(_s); return RoundRectCard( - key: ValueKey(idx), - ListTile( - title: _buildTitle(key), - subtitle: help == null ? null : Text(help, style: grey), - leading: _buildCheckBox(keys, key, idx, idx < keys.length), - trailing: isDesktop ? null : const Icon(Icons.drag_handle), - )); + key: ValueKey(idx), + ListTile( + title: _buildTitle(key), + subtitle: help == null ? null : Text(help, style: grey), + leading: _buildCheckBox(keys, key, idx, idx < keys.length), + trailing: isDesktop ? null : const Icon(Icons.drag_handle), + ), + ); }, itemCount: allKeys.length, onReorder: (o, n) { diff --git a/lib/view/page/snippet/edit.dart b/lib/view/page/snippet/edit.dart index dc0f3a44..e1029dcf 100644 --- a/lib/view/page/snippet/edit.dart +++ b/lib/view/page/snippet/edit.dart @@ -10,7 +10,7 @@ import '../../../data/provider/snippet.dart'; import '../../../data/res/ui.dart'; import '../../../locator.dart'; import '../../widget/custom_appbar.dart'; -import '../../widget/tag/btn.dart'; +import '../../widget/tag.dart'; class SnippetEditPage extends StatefulWidget { const SnippetEditPage({Key? key, this.snippet}) : super(key: key); diff --git a/lib/view/page/snippet/list.dart b/lib/view/page/snippet/list.dart index fb4d3bf2..691de285 100644 --- a/lib/view/page/snippet/list.dart +++ b/lib/view/page/snippet/list.dart @@ -2,17 +2,16 @@ import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:provider/provider.dart'; import 'package:toolbox/core/extension/order.dart'; -import 'package:toolbox/data/model/server/server.dart'; -import 'package:toolbox/data/provider/server.dart'; -import 'package:toolbox/data/res/ui.dart'; -import 'package:toolbox/view/widget/tag/switcher.dart'; import '../../../core/utils/misc.dart'; import '../../../core/utils/ui.dart'; +import '../../../data/model/server/server.dart'; import '../../../data/model/server/snippet.dart'; +import '../../../data/provider/server.dart'; +import '../../../data/res/ui.dart'; import '../../../data/store/setting.dart'; import '../../../locator.dart'; -import '../../widget/tag/picker.dart'; +import '../../widget/tag.dart'; import '/core/route.dart'; import '/data/provider/snippet.dart'; import 'edit.dart'; diff --git a/lib/view/widget/server_func_btns.dart b/lib/view/widget/server_func_btns.dart index 640f1982..b11160f9 100644 --- a/lib/view/widget/server_func_btns.dart +++ b/lib/view/widget/server_func_btns.dart @@ -15,7 +15,7 @@ import '../../data/model/server/snippet.dart'; import '../../data/provider/snippet.dart'; import '../../locator.dart'; import '../page/process.dart'; -import 'tag/picker.dart'; +import 'tag.dart'; class ServerFuncBtns extends StatelessWidget { const ServerFuncBtns({ @@ -107,6 +107,7 @@ class ServerFuncBtns extends StatelessWidget { .map((e) => IconButton( onPressed: () => _onTapMoreBtns(e, spi, context), padding: EdgeInsets.zero, + tooltip: e.name, icon: Icon(e.icon, size: iconSize ?? 15), )) .toList(), diff --git a/lib/view/widget/tag/btn.dart b/lib/view/widget/tag.dart similarity index 51% rename from lib/view/widget/tag/btn.dart rename to lib/view/widget/tag.dart index ce55997b..2ffa88b3 100644 --- a/lib/view/widget/tag/btn.dart +++ b/lib/view/widget/tag.dart @@ -5,8 +5,10 @@ import 'package:toolbox/view/widget/input_field.dart'; import 'package:toolbox/view/widget/round_rect_card.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; -import '../../../core/utils/ui.dart'; -import '../../../data/res/color.dart'; +import '../../core/utils/ui.dart'; +import '../../data/res/color.dart'; + +const _kTagBtnHeight = 31.0; class TagBtn extends StatelessWidget { final String content; @@ -26,10 +28,8 @@ class TagBtn extends StatelessWidget { Text( content, textAlign: TextAlign.center, - style: TextStyle( - color: isEnable ? null : Colors.grey, - fontSize: 13, - ), + textScaleFactor: 1.0, + style: isEnable ? textSize13 : textSize13Grey, ), onTap: onTap, ); @@ -102,6 +102,7 @@ class TagEditor extends StatelessWidget { '#$tag', textAlign: TextAlign.center, style: textSize13, + textScaleFactor: 1.0, ), const SizedBox(width: 4.0), Icon( @@ -173,8 +174,171 @@ class TagEditor extends StatelessWidget { } } -Widget _wrap(Widget child, {void Function()? onTap, - void Function()? onLongPress,}) { +class TagPicker extends StatefulWidget { + final List items; + final bool Function(T, String?) containsTag; + final String Function(T) name; + final Set tags; + + const TagPicker({ + Key? key, + required this.items, + required this.containsTag, + required this.name, + required this.tags, + }) : super(key: key); + + @override + _TagPickerState createState() => _TagPickerState(); +} + +class _TagPickerState extends State> { + late S _s; + late MediaQueryData _media; + final List _selected = []; + + @override + void didChangeDependencies() { + super.didChangeDependencies(); + _s = S.of(context)!; + _media = MediaQuery.of(context); + } + + @override + Widget build(BuildContext context) { + final children = []; + if (widget.tags.isNotEmpty) { + children.add(Text(_s.tag)); + children.add(height13); + children.add(SizedBox( + height: _kTagBtnHeight, + width: _media.size.width * 0.7, + child: _buildTags(), + )); + } + if (widget.items.isNotEmpty) { + children.add(Text(_s.all)); + children.add(height13); + children.add(SizedBox( + height: _kTagBtnHeight, + width: _media.size.width * 0.7, + child: _buildItems(), + )); + } + final child = widget.tags.isEmpty && widget.items.isEmpty + ? Text(_s.noOptions) + : Column(mainAxisSize: MainAxisSize.min, children: children); + return AlertDialog( + title: Text(_s.choose), + content: child, + actions: [ + TextButton( + onPressed: () => context.pop(_selected), + child: Text(_s.ok), + ), + ], + ); + } + + Widget _buildTags() { + return ListView.builder( + scrollDirection: Axis.horizontal, + itemCount: widget.tags.length, + itemBuilder: (_, idx) { + final item = widget.tags.elementAt(idx); + final isEnable = + widget.items.where((ele) => widget.containsTag(ele, item)).every( + (element) => _selected.contains(element), + ); + return TagBtn( + isEnable: isEnable, + onTap: () { + if (isEnable) { + _selected.removeWhere( + (element) => widget.containsTag(element, item), + ); + } else { + _selected.addAll(widget.items.where( + (ele) => widget.containsTag(ele, item), + )); + } + setState(() {}); + }, + content: item, + ); + }, + ); + } + + Widget _buildItems() { + return ListView.builder( + scrollDirection: Axis.horizontal, + itemCount: widget.items.length, + itemBuilder: (context, index) { + final e = widget.items[index]; + return TagBtn( + isEnable: _selected.contains(e), + onTap: () { + if (_selected.contains(e)) { + _selected.remove(e); + } else { + _selected.add(e); + } + setState(() {}); + }, + content: widget.name(e), + ); + }, + ); + } +} + +class TagSwitcher extends StatelessWidget { + final List tags; + final double width; + final void Function(String?) onTagChanged; + final String? initTag; + final String all; + + const TagSwitcher({ + Key? key, + required this.tags, + required this.width, + required this.onTagChanged, + required this.all, + this.initTag, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + if (tags.isEmpty) return placeholder; + final items = [null, ...tags]; + return Container( + height: _kTagBtnHeight, + width: width, + alignment: Alignment.center, + color: Colors.transparent, + child: ListView.builder( + scrollDirection: Axis.horizontal, + itemBuilder: (context, index) { + final item = items[index]; + return TagBtn( + content: item == null ? all : '#$item', + isEnable: initTag == item, + onTap: () => onTagChanged(item), + ); + }, + itemCount: items.length, + ), + ); + } +} + +Widget _wrap( + Widget child, { + void Function()? onTap, + void Function()? onLongPress, +}) { return Padding( padding: const EdgeInsets.all(3), child: ClipRRect( @@ -185,7 +349,9 @@ Widget _wrap(Widget child, {void Function()? onTap, onTap: onTap, onLongPress: onLongPress, child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 9.7, vertical: 1.7), + /// Hard coded padding + /// For centering the text + padding: const EdgeInsets.fromLTRB(11.7, 2.7, 11.7, 0), child: child, ), ), diff --git a/lib/view/widget/tag/picker.dart b/lib/view/widget/tag/picker.dart deleted file mode 100644 index 5cdd713c..00000000 --- a/lib/view/widget/tag/picker.dart +++ /dev/null @@ -1,126 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_gen/gen_l10n/l10n.dart'; -import 'package:toolbox/core/extension/navigator.dart'; -import 'package:toolbox/data/res/ui.dart'; - -import 'btn.dart'; - -class TagPicker extends StatefulWidget { - final List items; - final bool Function(T, String?) containsTag; - final String Function(T) name; - final Set tags; - - const TagPicker({ - Key? key, - required this.items, - required this.containsTag, - required this.name, - required this.tags, - }) : super(key: key); - - @override - _TagPickerState createState() => _TagPickerState(); -} - -class _TagPickerState extends State> { - late S _s; - late MediaQueryData _media; - final List _selected = []; - - @override - void didChangeDependencies() { - super.didChangeDependencies(); - _s = S.of(context)!; - _media = MediaQuery.of(context); - } - - @override - Widget build(BuildContext context) { - final child = widget.tags.isEmpty && widget.items.isEmpty - ? Text(_s.noOptions) - : Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text(_s.tag), - height13, - SizedBox( - height: 37, - width: _media.size.width * 0.7, - child: _buildTags(), - ), - Text(_s.all), - height13, - SizedBox( - height: 37, - width: _media.size.width * 0.7, - child: _buildItems(), - ), - ], - ); - return AlertDialog( - title: Text(_s.choose), - content: child, - actions: [ - TextButton( - onPressed: () { - context.pop(_selected); - }, - child: Text(_s.ok), - ), - ], - ); - } - - Widget _buildTags() { - return ListView.builder( - scrollDirection: Axis.horizontal, - itemCount: widget.tags.length, - itemBuilder: (_, idx) { - final item = widget.tags.elementAt(idx); - final isEnable = - widget.items.where((ele) => widget.containsTag(ele, item)).every( - (element) => _selected.contains(element), - ); - return TagBtn( - isEnable: isEnable, - onTap: () { - if (isEnable) { - _selected.removeWhere( - (element) => widget.containsTag(element, item), - ); - } else { - _selected.addAll(widget.items.where( - (ele) => widget.containsTag(ele, item), - )); - } - setState(() {}); - }, - content: item, - ); - }, - ); - } - - Widget _buildItems() { - return ListView.builder( - scrollDirection: Axis.horizontal, - itemCount: widget.items.length, - itemBuilder: (context, index) { - final e = widget.items[index]; - return TagBtn( - isEnable: _selected.contains(e), - onTap: () { - if (_selected.contains(e)) { - _selected.remove(e); - } else { - _selected.add(e); - } - setState(() {}); - }, - content: widget.name(e), - ); - }, - ); - } -} diff --git a/lib/view/widget/tag/switcher.dart b/lib/view/widget/tag/switcher.dart deleted file mode 100644 index c0f7ba04..00000000 --- a/lib/view/widget/tag/switcher.dart +++ /dev/null @@ -1,45 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:toolbox/data/res/ui.dart'; -import 'package:toolbox/view/widget/tag/view.dart'; - -class TagSwitcher extends StatelessWidget { - final List tags; - final double width; - final void Function(String?) onTagChanged; - final String? initTag; - final String all; - - const TagSwitcher({ - Key? key, - required this.tags, - required this.width, - required this.onTagChanged, - required this.all, - this.initTag, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - if (tags.isEmpty) return placeholder; - final items = [null, ...tags]; - return Container( - height: 31, - width: width, - alignment: Alignment.center, - color: Colors.transparent, - child: ListView.builder( - scrollDirection: Axis.horizontal, - itemBuilder: (context, index) { - final item = items[index]; - return TagView( - tag: item, - initTag: initTag, - all: all, - onTap: onTagChanged, - ); - }, - itemCount: items.length, - ), - ); - } -} diff --git a/lib/view/widget/tag/view.dart b/lib/view/widget/tag/view.dart deleted file mode 100644 index f090094e..00000000 --- a/lib/view/widget/tag/view.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'btn.dart'; - -class TagView extends StatelessWidget { - final void Function(String?) onTap; - final String? tag; - final String? initTag; - final String all; - - const TagView({ - super.key, - required this.onTap, - this.tag, - this.initTag, - required this.all, - }); - - @override - Widget build(BuildContext context) { - return TagBtn( - onTap: () => onTap(tag), - isEnable: initTag == tag, - content: tag == null ? all : '#$tag', - ); - } -} diff --git a/macos/Runner.xcodeproj/project.pbxproj b/macos/Runner.xcodeproj/project.pbxproj index 67f133e2..b8486dd0 100644 --- a/macos/Runner.xcodeproj/project.pbxproj +++ b/macos/Runner.xcodeproj/project.pbxproj @@ -474,9 +474,9 @@ baseConfigurationReference = C1C758C41C4E208965A68933 /* Pods-RunnerTests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; - CURRENT_PROJECT_VERSION = 489; + CURRENT_PROJECT_VERSION = 491; GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0.489; + MARKETING_VERSION = 1.0.491; PRODUCT_BUNDLE_IDENTIFIER = tech.lolli.serverBox.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; @@ -489,9 +489,9 @@ baseConfigurationReference = 15AF97DF993E8968098D6EBE /* Pods-RunnerTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; - CURRENT_PROJECT_VERSION = 489; + CURRENT_PROJECT_VERSION = 491; GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0.489; + MARKETING_VERSION = 1.0.491; PRODUCT_BUNDLE_IDENTIFIER = tech.lolli.serverBox.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; @@ -504,9 +504,9 @@ baseConfigurationReference = 7CFA7DE7FABA75685DFB6948 /* Pods-RunnerTests.profile.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; - CURRENT_PROJECT_VERSION = 489; + CURRENT_PROJECT_VERSION = 491; GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0.489; + MARKETING_VERSION = 1.0.491; PRODUCT_BUNDLE_IDENTIFIER = tech.lolli.serverBox.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0;