diff --git a/lib/view/page/server/detail.dart b/lib/view/page/server/detail.dart index 87bd2d6e..470db3b9 100644 --- a/lib/view/page/server/detail.dart +++ b/lib/view/page/server/detail.dart @@ -99,7 +99,6 @@ class _ServerDetailPageState extends State padding: EdgeInsets.only( left: 13, right: 13, - top: 13, bottom: _media.padding.bottom + 77, ), itemCount: buildFuncs ? _cardsOrder.length + 1 : _cardsOrder.length, diff --git a/lib/view/page/server/edit.dart b/lib/view/page/server/edit.dart index 9d516e0f..1736d251 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/editor.dart'; +import '../../widget/tag/btn.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 222a131c..e74b8255 100644 --- a/lib/view/page/server/tab.dart +++ b/lib/view/page/server/tab.dart @@ -127,7 +127,7 @@ class _ServerPageState extends State Widget _buildBodySmall({ required ServerProvider provider, required List filtered, - EdgeInsets? padding = const EdgeInsets.fromLTRB(7, 10, 7, 7), + EdgeInsets? padding = const EdgeInsets.fromLTRB(7, 0, 7, 7), bool buildTags = true, }) { final count = buildTags ? filtered.length + 2 : filtered.length + 1; @@ -164,7 +164,7 @@ class _ServerPageState extends State child: _buildBodySmall( provider: pro, filtered: left, - padding: const EdgeInsets.fromLTRB(7, 10, 0, 7), + padding: const EdgeInsets.fromLTRB(7, 0, 0, 7), buildTags: false, ), ), @@ -172,7 +172,7 @@ class _ServerPageState extends State child: _buildBodySmall( provider: pro, filtered: right, - padding: const EdgeInsets.fromLTRB(0, 10, 7, 7), + padding: const EdgeInsets.fromLTRB(0, 0, 7, 7), buildTags: false, ), ), diff --git a/lib/view/page/snippet/edit.dart b/lib/view/page/snippet/edit.dart index 757558bd..dc0f3a44 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/editor.dart'; +import '../../widget/tag/btn.dart'; class SnippetEditPage extends StatefulWidget { const SnippetEditPage({Key? key, this.snippet}) : super(key: key); diff --git a/lib/view/widget/tag/btn.dart b/lib/view/widget/tag/btn.dart index 706889be..ce55997b 100644 --- a/lib/view/widget/tag/btn.dart +++ b/lib/view/widget/tag/btn.dart @@ -1,5 +1,11 @@ import 'package:flutter/material.dart'; +import 'package:toolbox/core/extension/navigator.dart'; +import 'package:toolbox/data/res/ui.dart'; +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'; class TagBtn extends StatelessWidget { @@ -16,28 +22,174 @@ class TagBtn extends StatelessWidget { @override Widget build(BuildContext context) { - return Padding( - padding: const EdgeInsets.only(left: 4, right: 5, bottom: 9), - child: ClipRRect( - borderRadius: const BorderRadius.all(Radius.circular(20.0)), - child: Material( - color: primaryColor.withAlpha(20), - child: InkWell( - onTap: onTap, - child: Padding( - padding: - const EdgeInsets.symmetric(horizontal: 11, vertical: 2.7), - child: Text( - content, - style: TextStyle( - color: isEnable ? null : Colors.grey, - fontSize: 13, - ), - ), - ), - ), + return _wrap( + Text( + content, + textAlign: TextAlign.center, + style: TextStyle( + color: isEnable ? null : Colors.grey, + fontSize: 13, ), ), + onTap: onTap, ); } } + +class TagEditor extends StatelessWidget { + final List tags; + final S s; + final void Function(List)? onChanged; + final void Function(String old, String new_)? onRenameTag; + final List? tagSuggestions; + + const TagEditor({ + super.key, + required this.tags, + required this.s, + this.onChanged, + this.onRenameTag, + this.tagSuggestions, + }); + + @override + Widget build(BuildContext context) { + return RoundRectCard(ListTile( + leading: const Icon(Icons.tag), + title: _buildTags(context, tags), + trailing: InkWell( + child: const Icon(Icons.add), + onTap: () { + _showTagDialog(context, tags, onChanged); + }, + ), + )); + } + + Widget _buildTags(BuildContext context, List tags) { + tagSuggestions?.removeWhere((element) => tags.contains(element)); + final suggestionLen = tagSuggestions?.length ?? 0; + final counts = tags.length + suggestionLen + (suggestionLen == 0 ? 0 : 1); + if (counts == 0) return Text(s.tag); + return ConstrainedBox( + constraints: const BoxConstraints(maxHeight: 27), + child: ListView.builder( + scrollDirection: Axis.horizontal, + itemBuilder: (context, index) { + if (index < tags.length) { + return _buildTagItem(context, tags[index], false); + } else if (index > tags.length) { + return _buildTagItem( + context, + tagSuggestions![index - tags.length - 1], + true, + ); + } + return const VerticalDivider(); + }, + itemCount: counts, + ), + ); + } + + Widget _buildTagItem(BuildContext context, String tag, bool isAdd) { + return _wrap( + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + '#$tag', + textAlign: TextAlign.center, + style: textSize13, + ), + const SizedBox(width: 4.0), + Icon( + isAdd ? Icons.add_circle : Icons.cancel, + size: 13.7, + ), + ], + ), + onTap: () { + if (isAdd) { + tags.add(tag); + } else { + tags.remove(tag); + } + onChanged?.call(tags); + }, + onLongPress: () => _showRenameDialog(context, tag), + ); + } + + void _showTagDialog( + BuildContext context, + List tags, + void Function(List)? onChanged, + ) { + final textEditingController = TextEditingController(); + showRoundDialog( + context: context, + title: Text(s.add), + child: Input( + controller: textEditingController, + hint: s.tag, + ), + actions: [ + TextButton( + onPressed: () { + final tag = textEditingController.text; + tags.add(tag.trim()); + onChanged?.call(tags); + Navigator.pop(context); + }, + child: Text(s.add), + ), + ], + ); + } + + void _showRenameDialog(BuildContext context, String tag) { + final textEditingController = TextEditingController(text: tag); + showRoundDialog( + context: context, + title: Text(s.rename), + child: Input( + controller: textEditingController, + hint: s.tag, + ), + actions: [ + TextButton( + onPressed: () { + final newTag = textEditingController.text.trim(); + if (newTag.isEmpty) return; + onRenameTag?.call(tag, newTag); + context.pop(); + }, + child: Text(s.rename), + ), + ], + ); + } +} + +Widget _wrap(Widget child, {void Function()? onTap, + void Function()? onLongPress,}) { + return Padding( + padding: const EdgeInsets.all(3), + child: ClipRRect( + borderRadius: const BorderRadius.all(Radius.circular(20.0)), + child: Material( + color: primaryColor.withAlpha(20), + child: InkWell( + onTap: onTap, + onLongPress: onLongPress, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 9.7, vertical: 1.7), + child: child, + ), + ), + ), + ), + ); +} diff --git a/lib/view/widget/tag/editor.dart b/lib/view/widget/tag/editor.dart deleted file mode 100644 index b69b9a29..00000000 --- a/lib/view/widget/tag/editor.dart +++ /dev/null @@ -1,154 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:toolbox/core/extension/navigator.dart'; -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'; - -class TagEditor extends StatelessWidget { - final List tags; - final S s; - final void Function(List)? onChanged; - final void Function(String old, String new_)? onRenameTag; - final List? tagSuggestions; - - const TagEditor({ - super.key, - required this.tags, - required this.s, - this.onChanged, - this.onRenameTag, - this.tagSuggestions, - }); - - @override - Widget build(BuildContext context) { - return RoundRectCard(ListTile( - leading: const Icon(Icons.tag), - title: _buildTags(context, tags), - trailing: InkWell( - child: const Icon(Icons.add), - onTap: () { - _showTagDialog(context, tags, onChanged); - }, - ), - )); - } - - Widget _buildTags(BuildContext context, List tags) { - tagSuggestions?.removeWhere((element) => tags.contains(element)); - final suggestionLen = tagSuggestions?.length ?? 0; - final counts = tags.length + suggestionLen + (suggestionLen == 0 ? 0 : 1); - if (counts == 0) return Text(s.tag); - return ConstrainedBox( - constraints: const BoxConstraints(maxHeight: 27), - child: ListView.builder( - scrollDirection: Axis.horizontal, - itemBuilder: (context, index) { - if (index < tags.length) { - return _buildTagItem(context, tags[index], false); - } else if (index > tags.length) { - return _buildTagItem( - context, - tagSuggestions![index - tags.length - 1], - true, - ); - } - return const VerticalDivider(); - }, - itemCount: counts, - ), - ); - } - - Widget _buildTagItem(BuildContext context, String tag, bool isAdd) { - return Padding( - padding: const EdgeInsets.symmetric(horizontal: 3), - child: InkWell( - onTap: () { - if (isAdd) { - tags.add(tag); - } else { - tags.remove(tag); - } - onChanged?.call(tags); - }, - onLongPress: () => _showRenameDialog(context, tag), - child: Container( - decoration: BoxDecoration( - borderRadius: const BorderRadius.all(Radius.circular(20.0)), - color: primaryColor, - ), - padding: const EdgeInsets.symmetric(horizontal: 7, vertical: 3), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - '#$tag', - style: const TextStyle(color: Colors.white), - ), - const SizedBox(width: 4.0), - Icon( - isAdd ? Icons.add_circle : Icons.cancel, - size: 14.0, - color: Colors.white, - ), - ], - ), - ), - ), - ); - } - - void _showTagDialog( - BuildContext context, - List tags, - void Function(List)? onChanged, - ) { - final textEditingController = TextEditingController(); - showRoundDialog( - context: context, - title: Text(s.add), - child: Input( - controller: textEditingController, - hint: s.tag, - ), - actions: [ - TextButton( - onPressed: () { - final tag = textEditingController.text; - tags.add(tag.trim()); - onChanged?.call(tags); - Navigator.pop(context); - }, - child: Text(s.add), - ), - ], - ); - } - - void _showRenameDialog(BuildContext context, String tag) { - final textEditingController = TextEditingController(text: tag); - showRoundDialog( - context: context, - title: Text(s.rename), - child: Input( - controller: textEditingController, - hint: s.tag, - ), - actions: [ - TextButton( - onPressed: () { - final newTag = textEditingController.text.trim(); - if (newTag.isEmpty) return; - onRenameTag?.call(tag, newTag); - context.pop(); - }, - child: Text(s.rename), - ), - ], - ); - } -} diff --git a/lib/view/widget/tag/picker.dart b/lib/view/widget/tag/picker.dart index 89d3dbc0..5cdd713c 100644 --- a/lib/view/widget/tag/picker.dart +++ b/lib/view/widget/tag/picker.dart @@ -2,7 +2,8 @@ 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 'package:toolbox/view/widget/tag/btn.dart'; + +import 'btn.dart'; class TagPicker extends StatefulWidget { final List items; diff --git a/lib/view/widget/tag/switcher.dart b/lib/view/widget/tag/switcher.dart index 551d0dc7..c0f7ba04 100644 --- a/lib/view/widget/tag/switcher.dart +++ b/lib/view/widget/tag/switcher.dart @@ -23,7 +23,7 @@ class TagSwitcher extends StatelessWidget { if (tags.isEmpty) return placeholder; final items = [null, ...tags]; return Container( - height: 37, + height: 31, width: width, alignment: Alignment.center, color: Colors.transparent, diff --git a/lib/view/widget/tag/view.dart b/lib/view/widget/tag/view.dart index c392222f..f090094e 100644 --- a/lib/view/widget/tag/view.dart +++ b/lib/view/widget/tag/view.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:toolbox/view/widget/tag/btn.dart'; + +import 'btn.dart'; class TagView extends StatelessWidget { final void Function(String?) onTap;