mirror of
https://github.com/lollipopkit/flutter_server_box.git
synced 2025-12-17 07:14:28 +01:00
opt.
This commit is contained in:
@@ -99,7 +99,6 @@ class _ServerDetailPageState extends State<ServerDetailPage>
|
||||
padding: EdgeInsets.only(
|
||||
left: 13,
|
||||
right: 13,
|
||||
top: 13,
|
||||
bottom: _media.padding.bottom + 77,
|
||||
),
|
||||
itemCount: buildFuncs ? _cardsOrder.length + 1 : _cardsOrder.length,
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -127,7 +127,7 @@ class _ServerPageState extends State<ServerPage>
|
||||
Widget _buildBodySmall({
|
||||
required ServerProvider provider,
|
||||
required List<String> 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<ServerPage>
|
||||
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<ServerPage>
|
||||
child: _buildBodySmall(
|
||||
provider: pro,
|
||||
filtered: right,
|
||||
padding: const EdgeInsets.fromLTRB(0, 10, 7, 7),
|
||||
padding: const EdgeInsets.fromLTRB(0, 0, 7, 7),
|
||||
buildTags: false,
|
||||
),
|
||||
),
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<String> tags;
|
||||
final S s;
|
||||
final void Function(List<String>)? onChanged;
|
||||
final void Function(String old, String new_)? onRenameTag;
|
||||
final List<String>? 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<String> 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<String> tags,
|
||||
void Function(List<String>)? 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,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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<String> tags;
|
||||
final S s;
|
||||
final void Function(List<String>)? onChanged;
|
||||
final void Function(String old, String new_)? onRenameTag;
|
||||
final List<String>? 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<String> 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<String> tags,
|
||||
void Function(List<String>)? 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),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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<T> extends StatefulWidget {
|
||||
final List<T> items;
|
||||
|
||||
@@ -23,7 +23,7 @@ class TagSwitcher extends StatelessWidget {
|
||||
if (tags.isEmpty) return placeholder;
|
||||
final items = <String?>[null, ...tags];
|
||||
return Container(
|
||||
height: 37,
|
||||
height: 31,
|
||||
width: width,
|
||||
alignment: Alignment.center,
|
||||
color: Colors.transparent,
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user