#140 feat: double columns of servers tab

This commit is contained in:
lollipopkit
2023-08-20 14:01:41 +08:00
parent 35e9ecedd0
commit b5d8b8771e
2 changed files with 92 additions and 73 deletions

View File

@@ -0,0 +1,5 @@
import 'package:flutter/widgets.dart';
extension MideaQueryX on MediaQueryData {
bool get isLarge => size.aspectRatio > 0.87 && size.width > 600;
}

View File

@@ -6,6 +6,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:get_it/get_it.dart'; import 'package:get_it/get_it.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:toolbox/core/extension/media_queryx.dart';
import 'package:toolbox/core/extension/order.dart'; import 'package:toolbox/core/extension/order.dart';
import 'package:toolbox/data/model/app/net_view.dart'; 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';
@@ -54,6 +55,7 @@ class _ServerPageState extends State<ServerPage>
late S _s; late S _s;
String? _tag; String? _tag;
bool _buildGrid = false;
@override @override
void initState() { void initState() {
@@ -66,6 +68,7 @@ class _ServerPageState extends State<ServerPage>
void didChangeDependencies() { void didChangeDependencies() {
super.didChangeDependencies(); super.didChangeDependencies();
_media = MediaQuery.of(context); _media = MediaQuery.of(context);
_buildGrid = _media.isLarge;
_theme = Theme.of(context); _theme = Theme.of(context);
_s = S.of(context)!; _s = S.of(context)!;
} }
@@ -88,58 +91,87 @@ class _ServerPageState extends State<ServerPage>
} }
Widget _buildBody() { Widget _buildBody() {
final child = Consumer<ServerProvider>(
builder: (_, pro, __) {
if (!pro.tags.contains(_tag)) {
_tag = null;
}
if (pro.serverOrder.isEmpty) {
return Center(
child: Text(
_s.serverTabEmpty,
textAlign: TextAlign.center,
),
);
}
final filtered = _filterServers(pro);
if (_buildGrid) {
return _buildBodyMedium(pro);
}
return _buildBodySmall(pro, filtered);
},
);
if (isDesktop) {
return child;
}
return RefreshIndicator( return RefreshIndicator(
onRefresh: () async => onRefresh: () async =>
await _serverProvider.refreshData(onlyFailed: true), await _serverProvider.refreshData(onlyFailed: true),
child: Consumer<ServerProvider>( child: child,
builder: (_, pro, __) { );
if (!pro.tags.contains(_tag)) { }
_tag = null;
} List<String> _filterServers(ServerProvider pro) => pro.serverOrder
if (pro.serverOrder.isEmpty) { .where((e) => pro.servers.containsKey(e))
return Center( .where((e) =>
child: Text( _tag == null || (pro.servers[e]?.spi.tags?.contains(_tag) ?? false))
_s.serverTabEmpty, .toList();
textAlign: TextAlign.center,
), Widget _buildBodySmall(ServerProvider pro, List<String> filtered) {
); return ReorderableListView.builder(
} header: TagSwitcher(
final filtered = pro.serverOrder tags: pro.tags,
.where((e) => pro.servers.containsKey(e)) width: _media.size.width,
.where((e) => onTagChanged: (p0) => setState(() {
_tag == null || _tag = p0;
(pro.servers[e]?.spi.tags?.contains(_tag) ?? false)) }),
.toList(); initTag: _tag,
return ReorderableListView.builder( all: _s.all,
header: TagSwitcher(
tags: pro.tags,
width: _media.size.width,
onTagChanged: (p0) => setState(() {
_tag = p0;
}),
initTag: _tag,
all: _s.all,
),
footer: const SizedBox(height: 77),
padding: const EdgeInsets.fromLTRB(7, 10, 7, 7),
onReorder: (oldIndex, newIndex) => setState(() {
pro.serverOrder.moveByItem(
filtered,
oldIndex,
newIndex,
property: _settingStore.serverOrder,
);
}),
buildDefaultDragHandles: false,
itemBuilder: (_, index) => ReorderableDelayedDragStartListener(
key: ValueKey('$_tag${filtered[index]}'),
index: index,
child: _buildEachServerCard(pro.servers[filtered[index]]),
),
itemCount: filtered.length,
);
},
), ),
footer: const SizedBox(height: 77),
padding: const EdgeInsets.fromLTRB(7, 10, 7, 7),
onReorder: (oldIndex, newIndex) => setState(() {
pro.serverOrder.moveByItem(
filtered,
oldIndex,
newIndex,
property: _settingStore.serverOrder,
);
}),
buildDefaultDragHandles: false,
itemBuilder: (_, index) => ReorderableDelayedDragStartListener(
key: ValueKey('$_tag${filtered[index]}'),
index: index,
child: _buildEachServerCard(pro.servers[filtered[index]]),
),
itemCount: filtered.length,
);
}
Widget _buildBodyMedium(ServerProvider pro) {
final filtered = _filterServers(pro);
final left = filtered.where((e) => filtered.indexOf(e) % 2 == 0).toList();
final right = filtered.where((e) => filtered.indexOf(e) % 2 == 1).toList();
return Row(
children: [
Expanded(
child: _buildBodySmall(pro, left),
),
Expanded(
child: _buildBodySmall(pro, right),
),
],
); );
} }
@@ -147,6 +179,7 @@ class _ServerPageState extends State<ServerPage>
if (si == null) { if (si == null) {
return placeholder; return placeholder;
} }
return GestureDetector( return GestureDetector(
key: Key(si.spi.id + (_tag ?? '')), key: Key(si.spi.id + (_tag ?? '')),
onTap: () { onTap: () {
@@ -184,7 +217,6 @@ class _ServerPageState extends State<ServerPage>
height = 137; height = 137;
children = [ children = [
_buildServerCardTitle(ss, cs, spi), _buildServerCardTitle(ss, cs, spi),
height13,
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceAround, mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [ children: [
@@ -195,16 +227,6 @@ class _ServerPageState extends State<ServerPage>
'Total:\n${rootDisk?.size}', 'Used:\n${rootDisk?.usedPercent}%') 'Total:\n${rootDisk?.size}', 'Used:\n${rootDisk?.usedPercent}%')
], ],
), ),
height13,
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
_buildExplainText('CPU'),
_buildExplainText('Mem'),
_buildExplainText('Net'),
_buildExplainText('Disk'),
],
),
const SizedBox(height: 3), const SizedBox(height: 3),
]; ];
} }
@@ -214,6 +236,7 @@ class _ServerPageState extends State<ServerPage>
curve: Curves.fastEaseInToSlowEaseOut, curve: Curves.fastEaseInToSlowEaseOut,
height: height, height: height,
child: Column( child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: children, children: children,
), ),
@@ -389,15 +412,12 @@ class _ServerPageState extends State<ServerPage>
} }
Widget _buildExplainText(String text) { Widget _buildExplainText(String text) {
return SizedBox( return Text(
width: _media.size.width * 0.2,
child: Text(
text, text,
style: const TextStyle(fontSize: 12), style: const TextStyle(fontSize: 12),
textAlign: TextAlign.center, textAlign: TextAlign.center,
textScaleFactor: 1.0, textScaleFactor: 1.0,
), );
);
} }
String _getTopRightStr( String _getTopRightStr(
@@ -435,9 +455,7 @@ class _ServerPageState extends State<ServerPage>
Widget _buildIOData(String up, String down) { Widget _buildIOData(String up, String down) {
final statusTextStyle = TextStyle( final statusTextStyle = TextStyle(
fontSize: 9, color: _theme.textTheme.bodyLarge!.color!.withAlpha(177)); fontSize: 9, color: _theme.textTheme.bodyLarge!.color!.withAlpha(177));
return SizedBox( return Column(
width: _media.size.width * 0.2,
child: Column(
children: [ children: [
const SizedBox(height: 5), const SizedBox(height: 5),
Text( Text(
@@ -454,16 +472,13 @@ class _ServerPageState extends State<ServerPage>
textScaleFactor: 1.0, textScaleFactor: 1.0,
) )
], ],
), );
);
} }
Widget _buildPercentCircle(double percent) { Widget _buildPercentCircle(double percent) {
if (percent <= 0) percent = 0.01; if (percent <= 0) percent = 0.01;
if (percent >= 100) percent = 99.9; if (percent >= 100) percent = 99.9;
return SizedBox( return Stack(
width: _media.size.width * 0.2,
child: Stack(
children: [ children: [
Center( Center(
child: CircleChart( child: CircleChart(
@@ -485,7 +500,6 @@ class _ServerPageState extends State<ServerPage>
), ),
), ),
], ],
),
); );
} }