new: server tag

This commit is contained in:
lollipopkit
2023-05-30 22:44:45 +08:00
parent 92ffed6541
commit 472a441c8e
23 changed files with 239 additions and 112 deletions

View File

@@ -69,7 +69,6 @@ class _ConvertPageState extends State<ConvertPage>
}
},
tooltip: _s.convert,
heroTag: 'convert fab',
child: const Icon(Icons.send),
),
);

View File

@@ -76,7 +76,6 @@ class _PingPageState extends State<PingPage>
),
),
floatingActionButton: FloatingActionButton(
heroTag: 'ping fab',
onPressed: () {
try {
doPing();

View File

@@ -14,6 +14,7 @@ import '../../../data/provider/server.dart';
import '../../../data/res/ui.dart';
import '../../../data/store/private_key.dart';
import '../../../locator.dart';
import '../../widget/tag.dart';
import '../private_key/edit.dart';
class ServerEditPage extends StatefulWidget {
@@ -43,6 +44,7 @@ class _ServerEditPageState extends State<ServerEditPage> with AfterLayoutMixin {
bool usePublicKey = false;
int? _pubKeyIndex;
PrivateKeyInfo? _keyInfo;
List<String> _tags = [];
@override
void initState() {
@@ -143,6 +145,13 @@ class _ServerEditPageState extends State<ServerEditPage> with AfterLayoutMixin {
icon: Icons.account_box,
hint: 'root',
),
TagEditor(
tags: _tags,
onChanged: (p0) => setState(() {
_tags = p0;
}),
s: _s,
),
width7,
Row(
children: [
@@ -262,6 +271,7 @@ class _ServerEditPageState extends State<ServerEditPage> with AfterLayoutMixin {
user: _usernameController.text,
pwd: authorization,
pubKeyId: usePublicKey ? _keyInfo!.id : null,
tags: _tags,
);
if (widget.spi == null) {
@@ -300,6 +310,9 @@ class _ServerEditPageState extends State<ServerEditPage> with AfterLayoutMixin {
} else {
usePublicKey = true;
}
if (widget.spi?.tags != null) {
_tags = widget.spi!.tags!;
}
setState(() {});
}
}

View File

@@ -7,6 +7,7 @@ import 'package:provider/provider.dart';
import 'package:toolbox/core/extension/navigator.dart';
import 'package:toolbox/core/extension/order.dart';
import 'package:toolbox/core/utils/misc.dart';
import 'package:toolbox/view/widget/fade_in.dart';
import '../../../core/route.dart';
import '../../../core/utils/ui.dart';
@@ -45,6 +46,8 @@ class _ServerPageState extends State<ServerPage>
late SettingStore _settingStore;
late S _s;
String? _tag;
@override
void initState() {
super.initState();
@@ -71,18 +74,65 @@ class _ServerPageState extends State<ServerPage>
'Add server info page',
).go(context),
tooltip: _s.addAServer,
heroTag: 'server page fab',
child: const Icon(Icons.add),
),
);
}
Widget _buildTagsSwitcher(ServerProvider pro) {
if (pro.tags.isEmpty) return placeholder;
final items = <String?>[null, ...pro.tags];
return Container(
height: 37,
width: _media.size.width,
alignment: Alignment.center,
color: Colors.transparent,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) => _buildTagItem(items[index]),
itemCount: items.length,
),
);
}
Widget _buildTagItem(String? tag) {
return Padding(
padding: const EdgeInsets.only(left: 4, right: 5, bottom: 9),
child: GestureDetector(
onTap: () {
setState(() {
_tag = tag;
});
},
child: Container(
decoration: BoxDecoration(
borderRadius: const BorderRadius.all(Radius.circular(20.0)),
color: primaryColor.withAlpha(20),
),
padding: const EdgeInsets.symmetric(horizontal: 11, vertical: 2.7),
child: Center(
child: Text(
tag == null ? _s.all : '#$tag',
style: TextStyle(
color: _tag == tag ? null : _theme.disabledColor,
fontSize: 15,
fontWeight: FontWeight.w500,
),
),
)),
),
);
}
Widget _buildBody() {
return RefreshIndicator(
onRefresh: () async =>
await _serverProvider.refreshData(onlyFailed: true),
child: Consumer<ServerProvider>(
builder: (_, pro, __) {
if (!pro.tags.contains(_tag)) {
_tag = null;
}
if (pro.serverOrder.isEmpty) {
return Center(
child: Text(
@@ -91,21 +141,29 @@ class _ServerPageState extends State<ServerPage>
),
);
}
return ReorderableListView(
padding: const EdgeInsets.fromLTRB(7, 10, 7, 7),
physics: const AlwaysScrollableScrollPhysics(),
onReorder: (oldIndex, newIndex) => setState(() {
pro.serverOrder.move(
oldIndex,
newIndex,
_settingStore.serverOrder,
);
}),
children: pro.serverOrder
.where((e) => pro.servers.containsKey(e))
.map((e) => _buildEachServerCard(pro.servers[e]))
.toList(),
);
final filtered = pro.serverOrder
.where((e) => pro.servers.containsKey(e))
.where((e) =>
_tag == null ||
(pro.servers[e]?.spi.tags?.contains(_tag) ?? false))
.toList();
return FadeIn(
key: ValueKey(_tag),
child: ReorderableListView(
header: _buildTagsSwitcher(pro),
padding: const EdgeInsets.fromLTRB(7, 10, 7, 7),
physics: const AlwaysScrollableScrollPhysics(),
onReorder: (oldIndex, newIndex) => setState(() {
pro.serverOrder.moveById(
filtered[oldIndex],
filtered[newIndex],
_settingStore.serverOrder,
);
}),
children: filtered
.map((e) => _buildEachServerCard(pro.servers[e]))
.toList(),
));
},
),
);

View File

@@ -217,7 +217,7 @@ class _SFTPPageState extends State<SFTPPage> {
_onItemPress(context, file, true);
}
},
onLongPress: () => _onItemPress(context, file, false),
onLongPress: () => _onItemPress(context, file, !isDir),
);
},
),

View File

@@ -3,7 +3,6 @@ import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:toolbox/core/extension/navigator.dart';
import 'package:toolbox/view/widget/input_field.dart';
import 'package:toolbox/view/widget/tag.dart';
import '../../../core/utils/ui.dart';
import '../../../data/model/server/snippet.dart';
@@ -29,8 +28,6 @@ class _SnippetEditPageState extends State<SnippetEditPage>
late SnippetProvider _provider;
late S _s;
var _tags = <String>[];
@override
void initState() {
super.initState();
@@ -76,7 +73,7 @@ class _SnippetEditPageState extends State<SnippetEditPage>
showSnackBar(context, Text(_s.fieldMustNotEmpty));
return;
}
final snippet = Snippet(name, script, tags: _tags);
final snippet = Snippet(name, script);
if (widget.snippet != null) {
_provider.update(widget.snippet!, snippet);
} else {
@@ -107,13 +104,6 @@ class _SnippetEditPageState extends State<SnippetEditPage>
label: _s.snippet,
icon: Icons.code,
),
TagEditor(
tags: widget.snippet?.tags ?? [],
onChanged: (p0) => setState(() {
_tags = p0;
}),
s: _s.tag,
)
],
);
}
@@ -123,7 +113,6 @@ class _SnippetEditPageState extends State<SnippetEditPage>
if (widget.snippet != null) {
_nameController.text = widget.snippet!.name;
_scriptController.text = widget.snippet!.script;
_tags = widget.snippet!.tags ?? [];
}
}
}

View File

@@ -1,5 +0,0 @@
// import 'package:flutter/material.dart';
// class SnippetGroupOrderPage extends StatelessWidget {
// final
// }

View File

@@ -1,16 +1,22 @@
import 'package:flutter/material.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 String s;
final S s;
final void Function(List<String>)? onChanged;
const TagEditor(
{super.key, required this.tags, this.onChanged, required this.s});
const TagEditor({
super.key,
required this.tags,
this.onChanged,
required this.s,
});
@override
Widget build(BuildContext context) {
@@ -38,7 +44,7 @@ class TagEditor extends StatelessWidget {
List<String> tags,
Function(String) onTagDelete,
) {
if (tags.isEmpty) return Text(s);
if (tags.isEmpty) return Text(s.tag);
return SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
@@ -88,28 +94,24 @@ class TagEditor extends StatelessWidget {
void Function(List<String>)? onChanged,
) {
final textEditingController = TextEditingController();
showDialog(
showRoundDialog(
context: context,
builder: (context) {
return AlertDialog(
title: const Text('Add Tag'),
content: Input(
controller: textEditingController,
hint: 'Tag',
),
actions: [
TextButton(
onPressed: () {
final tag = textEditingController.text;
tags.add(tag.trim());
onChanged?.call(tags);
Navigator.pop(context);
},
child: const Text('Add'),
),
],
);
},
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),
),
],
);
}
}