mirror of
https://github.com/lollipopkit/flutter_server_box.git
synced 2026-02-23 16:45:27 +01:00
new: server tag
This commit is contained in:
@@ -69,7 +69,6 @@ class _ConvertPageState extends State<ConvertPage>
|
||||
}
|
||||
},
|
||||
tooltip: _s.convert,
|
||||
heroTag: 'convert fab',
|
||||
child: const Icon(Icons.send),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -76,7 +76,6 @@ class _PingPageState extends State<PingPage>
|
||||
),
|
||||
),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
heroTag: 'ping fab',
|
||||
onPressed: () {
|
||||
try {
|
||||
doPing();
|
||||
|
||||
@@ -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(() {});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(),
|
||||
));
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
@@ -217,7 +217,7 @@ class _SFTPPageState extends State<SFTPPage> {
|
||||
_onItemPress(context, file, true);
|
||||
}
|
||||
},
|
||||
onLongPress: () => _onItemPress(context, file, false),
|
||||
onLongPress: () => _onItemPress(context, file, !isDir),
|
||||
);
|
||||
},
|
||||
),
|
||||
|
||||
@@ -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 ?? [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
// import 'package:flutter/material.dart';
|
||||
|
||||
// class SnippetGroupOrderPage extends StatelessWidget {
|
||||
// final
|
||||
// }
|
||||
@@ -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),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user