#73 opt.: reorderable

This commit is contained in:
lollipopkit
2023-07-21 15:05:09 +08:00
parent aac556f769
commit 262b4486e4
4 changed files with 99 additions and 83 deletions

View File

@@ -4,9 +4,6 @@ import 'package:nil/nil.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:toolbox/core/extension/order.dart'; import 'package:toolbox/core/extension/order.dart';
import 'package:toolbox/data/model/server/cpu.dart'; import 'package:toolbox/data/model/server/cpu.dart';
import 'package:toolbox/data/model/server/disk.dart';
import 'package:toolbox/data/model/server/memory.dart';
import 'package:toolbox/data/model/server/temp.dart';
import '../../../core/extension/numx.dart'; import '../../../core/extension/numx.dart';
import '../../../data/model/server/net_speed.dart'; import '../../../data/model/server/net_speed.dart';
@@ -51,6 +48,18 @@ class _ServerDetailPageState extends State<ServerDetailPage>
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final map = Map.fromIterables(
defaultDetailCardOrder,
[
_buildUpTimeAndSys,
_buildCPUView,
_buildMemView,
_buildSwapView,
_buildDiskView,
_buildNetView,
_buildTemperature,
],
);
return Consumer<ServerProvider>(builder: (_, provider, __) { return Consumer<ServerProvider>(builder: (_, provider, __) {
final s = provider.servers[widget.id]; final s = provider.servers[widget.id];
if (s == null) { if (s == null) {
@@ -60,16 +69,19 @@ class _ServerDetailPageState extends State<ServerDetailPage>
), ),
); );
} }
return _buildMainPage(s); return _buildMainPage(s, map);
}); });
} }
Widget _buildMainPage(Server si) { Widget _buildMainPage(
Server si,
Map<String, Widget Function(ServerStatus)> map,
) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: Text(si.spi.name, style: textSize18), title: Text(si.spi.name, style: textSize18),
), ),
body: ReorderableListView( body: ReorderableListView.builder(
padding: EdgeInsets.only( padding: EdgeInsets.only(
left: 13, right: 13, top: 13, bottom: _media.padding.bottom), left: 13, right: 13, top: 13, bottom: _media.padding.bottom),
onReorder: (int oldIndex, int newIndex) { onReorder: (int oldIndex, int newIndex) {
@@ -82,30 +94,18 @@ class _ServerDetailPageState extends State<ServerDetailPage>
}); });
}, },
footer: height13, footer: height13,
children: _buildMainList(si.status), itemCount: _cardsOrder.length,
buildDefaultDragHandles: false,
itemBuilder: (context, index) => ReorderableDelayedDragStartListener(
key: ValueKey(index),
index: index,
child: map[_cardsOrder[index]]?.call(si.status) ?? nil,
),
), ),
); );
} }
List<Widget> _buildMainList(ServerStatus ss) { Widget _buildCPUView(ServerStatus ss) {
final map = Map.fromIterables(
defaultDetailCardOrder,
[
_buildUpTimeAndSys(ss.sysVer, ss.uptime),
_buildCPUView(ss.cpu),
_buildMemView(ss.mem),
_buildSwapView(ss.swap),
_buildDiskView(ss.disk),
_buildNetView(ss.netSpeed),
_buildTemperature(ss.temps),
],
);
return _cardsOrder
.map((e) => SizedBox(key: ValueKey(e), child: map[e]))
.toList();
}
Widget _buildCPUView(Cpus cs) {
return RoundRectCard( return RoundRectCard(
Padding( Padding(
padding: roundRectCardPadding, padding: roundRectCardPadding,
@@ -114,25 +114,25 @@ class _ServerDetailPageState extends State<ServerDetailPage>
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text( Text(
'${cs.usedPercent(coreIdx: 0).toInt()}%', '${ss.cpu.usedPercent(coreIdx: 0).toInt()}%',
style: textSize27, style: textSize27,
textScaleFactor: 1.0, textScaleFactor: 1.0,
), ),
Row( Row(
children: [ children: [
_buildDetailPercent(cs.user, 'user'), _buildDetailPercent(ss.cpu.user, 'user'),
width13, width13,
_buildDetailPercent(cs.sys, 'sys'), _buildDetailPercent(ss.cpu.sys, 'sys'),
width13, width13,
_buildDetailPercent(cs.iowait, 'io'), _buildDetailPercent(ss.cpu.iowait, 'io'),
width13, width13,
_buildDetailPercent(cs.idle, 'idle') _buildDetailPercent(ss.cpu.idle, 'idle')
], ],
) )
], ],
), ),
height13, height13,
_buildCPUProgress(cs) _buildCPUProgress(ss.cpu)
]), ]),
), ),
); );
@@ -183,16 +183,16 @@ class _ServerDetailPageState extends State<ServerDetailPage>
); );
} }
Widget _buildUpTimeAndSys(String sysVer, String uptime) { Widget _buildUpTimeAndSys(ServerStatus ss) {
return RoundRectCard( return RoundRectCard(
Padding( Padding(
padding: roundRectCardPadding, padding: roundRectCardPadding,
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text(sysVer, style: textSize11, textScaleFactor: 1.0), Text(ss.sysVer, style: textSize11, textScaleFactor: 1.0),
Text( Text(
uptime, ss.uptime,
style: textSize11, style: textSize11,
textScaleFactor: 1.0, textScaleFactor: 1.0,
), ),
@@ -202,10 +202,10 @@ class _ServerDetailPageState extends State<ServerDetailPage>
); );
} }
Widget _buildMemView(Memory mem) { Widget _buildMemView(ServerStatus ss) {
final free = mem.free / mem.total * 100; final free = ss.mem.free / ss.mem.total * 100;
final avail = mem.availPercent * 100; final avail = ss.mem.availPercent * 100;
final used = mem.usedPercent * 100; final used = ss.mem.usedPercent * 100;
return RoundRectCard( return RoundRectCard(
Padding( Padding(
@@ -221,7 +221,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
children: [ children: [
Text('${used.toStringAsFixed(0)}%', style: textSize27), Text('${used.toStringAsFixed(0)}%', style: textSize27),
width7, width7,
Text('of ${(mem.total * 1024).convertBytes}', Text('of ${(ss.mem.total * 1024).convertBytes}',
style: textSize13Grey) style: textSize13Grey)
], ],
), ),
@@ -242,10 +242,10 @@ class _ServerDetailPageState extends State<ServerDetailPage>
); );
} }
Widget _buildSwapView(Swap swap) { Widget _buildSwapView(ServerStatus ss) {
if (swap.total == 0) return nil; if (ss.swap.total == 0) return nil;
final used = swap.usedPercent * 100; final used = ss.swap.usedPercent * 100;
final cached = swap.cached / swap.total * 100; final cached = ss.swap.cached / ss.swap.total * 100;
return RoundRectCard( return RoundRectCard(
Padding( Padding(
padding: roundRectCardPadding, padding: roundRectCardPadding,
@@ -260,7 +260,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
children: [ children: [
Text('${used.toStringAsFixed(0)}%', style: textSize27), Text('${used.toStringAsFixed(0)}%', style: textSize27),
width7, width7,
Text('of ${(swap.total * 1024).convertBytes} ', Text('of ${(ss.swap.total * 1024).convertBytes} ',
style: textSize13Grey) style: textSize13Grey)
], ],
), ),
@@ -275,7 +275,8 @@ class _ServerDetailPageState extends State<ServerDetailPage>
); );
} }
Widget _buildDiskView(List<Disk> disk) { Widget _buildDiskView(ServerStatus ss) {
final disk = ss.disk;
disk.removeWhere((e) { disk.removeWhere((e) {
for (final ingorePath in _setting.diskIgnorePath.fetch()!) { for (final ingorePath in _setting.diskIgnorePath.fetch()!) {
if (e.path.startsWith(ingorePath)) return true; if (e.path.startsWith(ingorePath)) return true;
@@ -315,7 +316,8 @@ class _ServerDetailPageState extends State<ServerDetailPage>
); );
} }
Widget _buildNetView(NetSpeed ns) { Widget _buildNetView(ServerStatus ss) {
final ns = ss.netSpeed;
final children = <Widget>[ final children = <Widget>[
_buildNetSpeedTop(), _buildNetSpeedTop(),
const Divider( const Divider(
@@ -397,7 +399,8 @@ class _ServerDetailPageState extends State<ServerDetailPage>
); );
} }
Widget _buildTemperature(Temperatures temps) { Widget _buildTemperature(ServerStatus ss) {
final temps = ss.temps;
if (temps.isEmpty) { if (temps.isEmpty) {
return nil; return nil;
} }

View File

@@ -11,7 +11,6 @@ import 'package:toolbox/data/model/app/net_view.dart';
import 'package:toolbox/data/model/server/snippet.dart'; import 'package:toolbox/data/model/server/snippet.dart';
import 'package:toolbox/data/provider/snippet.dart'; import 'package:toolbox/data/provider/snippet.dart';
import 'package:toolbox/view/page/process.dart'; import 'package:toolbox/view/page/process.dart';
import 'package:toolbox/view/widget/fade_in.dart';
import 'package:toolbox/view/widget/tag/picker.dart'; import 'package:toolbox/view/widget/tag/picker.dart';
import 'package:toolbox/view/widget/tag/switcher.dart'; import 'package:toolbox/view/widget/tag/switcher.dart';
@@ -126,8 +125,10 @@ class _ServerPageState extends State<ServerPage>
property: _settingStore.serverOrder, property: _settingStore.serverOrder,
); );
}), }),
itemBuilder: (_, index) => FadeIn( buildDefaultDragHandles: false,
itemBuilder: (_, index) => ReorderableDelayedDragStartListener(
key: ValueKey('$_tag${filtered[index]}'), key: ValueKey('$_tag${filtered[index]}'),
index: index,
child: _buildEachServerCard(pro.servers[filtered[index]]), child: _buildEachServerCard(pro.servers[filtered[index]]),
), ),
itemCount: filtered.length, itemCount: filtered.length,

View File

@@ -88,40 +88,13 @@ class _SnippetListPageState extends State<SnippetListPage> {
all: _s.all, all: _s.all,
width: _media.size.width, width: _media.size.width,
), ),
buildDefaultDragHandles: false,
itemBuilder: (context, idx) { itemBuilder: (context, idx) {
final snippet = filtered.elementAt(idx); final snippet = filtered.elementAt(idx);
return RoundRectCard( return ReorderableDelayedDragStartListener(
ListTile(
contentPadding: const EdgeInsets.only(left: 23, right: 17),
title: Text(
snippet.name,
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
subtitle: Text(
snippet.script,
overflow: TextOverflow.ellipsis,
maxLines: 1,
style: grey,
),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(
onPressed: () => AppRoute(
SnippetEditPage(snippet: snippet),
'snippet edit page',
).go(context),
icon: const Icon(Icons.edit),
),
IconButton(
onPressed: () => _runSnippet(snippet),
icon: const Icon(Icons.play_arrow),
),
],
),
),
key: ValueKey(snippet.name), key: ValueKey(snippet.name),
index: idx,
child: _buildSnippetItem(snippet),
); );
}, },
); );
@@ -129,6 +102,41 @@ class _SnippetListPageState extends State<SnippetListPage> {
); );
} }
Widget _buildSnippetItem(Snippet snippet) {
return RoundRectCard(
ListTile(
contentPadding: const EdgeInsets.only(left: 23, right: 17),
title: Text(
snippet.name,
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
subtitle: Text(
snippet.script,
overflow: TextOverflow.ellipsis,
maxLines: 1,
style: grey,
),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(
onPressed: () => AppRoute(
SnippetEditPage(snippet: snippet),
'snippet edit page',
).go(context),
icon: const Icon(Icons.edit),
),
IconButton(
onPressed: () => _runSnippet(snippet),
icon: const Icon(Icons.play_arrow),
),
],
),
),
);
}
Future<void> _runSnippet(Snippet snippet) async { Future<void> _runSnippet(Snippet snippet) async {
final provider = locator<ServerProvider>(); final provider = locator<ServerProvider>();
final servers = await showDialog<List<Server>>( final servers = await showDialog<List<Server>>(

View File

@@ -1,6 +1,8 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:nil/nil.dart';
import 'package:toolbox/core/extension/order.dart'; import 'package:toolbox/core/extension/order.dart';
import 'package:toolbox/core/utils/platform.dart';
import 'package:toolbox/core/utils/ui.dart'; import 'package:toolbox/core/utils/ui.dart';
import 'package:toolbox/data/model/ssh/virtual_key.dart'; import 'package:toolbox/data/model/ssh/virtual_key.dart';
import 'package:toolbox/data/store/setting.dart'; import 'package:toolbox/data/store/setting.dart';
@@ -48,8 +50,10 @@ class _SSHVirtKeySettingPageState extends State<SSHVirtKeySettingPage> {
return ListTile( return ListTile(
key: ValueKey(idx), key: ValueKey(idx),
title: _buildTitle(key), title: _buildTitle(key),
leading: const Icon(Icons.drag_handle, color: Colors.grey), leading: _buildCheckBox(keys, key, idx, idx < keys.length),
trailing: _buildCheckBox(keys, key, idx, idx < keys.length), trailing: isDesktop
? nil
: const Icon(Icons.drag_handle, color: Colors.grey),
); );
}, },
itemCount: allKeys.length, itemCount: allKeys.length,