From 8e484a575c338d7b03445156313fbca67a85c5f9 Mon Sep 17 00:00:00 2001 From: lollipopkit Date: Tue, 20 Feb 2024 18:02:08 +0800 Subject: [PATCH] readd: server tab double column (#277) --- lib/core/extension/media_queryx.dart | 8 +- lib/core/extension/widget.dart | 32 ------- lib/data/res/github_id.dart | 2 + lib/data/store/setting.dart | 8 +- lib/main.dart | 1 - lib/view/page/server/detail.dart | 127 ++++++++++++++------------ lib/view/page/server/tab.dart | 87 ++++++++++-------- lib/view/page/setting/entry.dart | 64 +++++-------- lib/view/page/snippet/edit.dart | 16 ++-- lib/view/page/ssh/tab.dart | 8 +- lib/view/widget/server_func_btns.dart | 26 +++--- lib/view/widget/tag.dart | 25 +++-- 12 files changed, 191 insertions(+), 213 deletions(-) delete mode 100644 lib/core/extension/widget.dart diff --git a/lib/core/extension/media_queryx.dart b/lib/core/extension/media_queryx.dart index 393d5bc2..b02c815c 100644 --- a/lib/core/extension/media_queryx.dart +++ b/lib/core/extension/media_queryx.dart @@ -1,5 +1,5 @@ -// import 'package:flutter/widgets.dart'; +import 'package:flutter/widgets.dart'; -// extension MideaQueryX on MediaQueryData { -// bool get useDoubleColumn => size.width > 639; -// } +extension MideaQueryX on MediaQueryData { + bool get useDoubleColumn => size.width > 639; +} diff --git a/lib/core/extension/widget.dart b/lib/core/extension/widget.dart deleted file mode 100644 index e5b3d2b4..00000000 --- a/lib/core/extension/widget.dart +++ /dev/null @@ -1,32 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:toolbox/core/utils/function.dart'; - -extension WidgetX on Widget { - Widget padding(EdgeInsetsGeometry padding) { - return Padding(padding: padding, child: this); - } - - Widget expanded({int flex = 1}) { - return Expanded(flex: flex, child: this); - } - - Widget center() { - return Center(child: this); - } - - Widget tap({ - VoidCallback? onTap, - bool disable = false, - VoidCallback? onLongTap, - VoidCallback? onDoubleTap, - }) { - if (disable) return this; - - return InkWell( - onTap: () => Funcs.throttle(onTap), - onLongPress: onLongTap, - onDoubleTap: onDoubleTap, - child: this, - ); - } -} diff --git a/lib/data/res/github_id.dart b/lib/data/res/github_id.dart index 574f0853..11862f26 100644 --- a/lib/data/res/github_id.dart +++ b/lib/data/res/github_id.dart @@ -59,5 +59,7 @@ abstract final class GithubIds { 'KatharsisKing', 'mervinniu', 'L-Super', + 'Tridays', + 'Nebulosa-Cat', }; } diff --git a/lib/data/store/setting.dart b/lib/data/store/setting.dart index e20b73e2..c03e57f7 100644 --- a/lib/data/store/setting.dart +++ b/lib/data/store/setting.dart @@ -44,10 +44,10 @@ class SettingStore extends PersistentStore { property('diskIgnorePath', Defaults.diskIgnorePath); /// Use double column servers page on Desktop - // late final doubleColumnServersPage = property( - // 'doubleColumnServersPage', - // isDesktop, - // ); + late final doubleColumnServersPage = property( + 'doubleColumnServersPage', + isDesktop, + ); /// Disk view: amount / IO late final serverTabPreferDiskAmount = property( diff --git a/lib/main.dart b/lib/main.dart index c2fdb0e0..5cbff32c 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -137,7 +137,6 @@ Future _initDesktopWindow() async { await CustomAppBar.updateTitlebarHeight(); const windowOptions = WindowOptions( - size: Size(400, 777), center: true, backgroundColor: Colors.transparent, skipTaskbar: false, diff --git a/lib/view/page/server/detail.dart b/lib/view/page/server/detail.dart index c01a095e..b7d880d2 100644 --- a/lib/view/page/server/detail.dart +++ b/lib/view/page/server/detail.dart @@ -5,7 +5,6 @@ import 'package:toolbox/core/extension/context/dialog.dart'; import 'package:toolbox/core/extension/context/locale.dart'; import 'package:toolbox/core/extension/order.dart'; import 'package:toolbox/core/extension/status_cmd_type.dart'; -import 'package:toolbox/core/extension/widget.dart'; import 'package:toolbox/data/model/server/battery.dart'; import 'package:toolbox/data/model/server/cpu.dart'; import 'package:toolbox/data/model/server/disk.dart'; @@ -136,13 +135,16 @@ class _ServerDetailPageState extends State ), children: ss.more.entries .map( - (e) => Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text(e.key.i18n, style: UIs.text13), - Text(e.value, style: UIs.text13Grey) - ], - ).padding(const EdgeInsets.symmetric(vertical: 2)), + (e) => Padding( + padding: const EdgeInsets.symmetric(vertical: 2), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text(e.key.i18n, style: UIs.text13), + Text(e.value, style: UIs.text13Grey) + ], + ), + ), ) .toList(), ), @@ -399,7 +401,7 @@ class _ServerDetailPageState extends State style: UIs.text12Grey, textScaler: _textFactor, ), - trailing: const Icon(Icons.info_outline, size: 17).tap( + trailing: InkWell( onTap: () { context.showRoundDialog( title: SizedBox( @@ -424,6 +426,7 @@ class _ServerDetailPageState extends State ], ); }, + child: const Icon(Icons.info_outline, size: 17), ), ); } @@ -456,44 +459,47 @@ class _ServerDetailPageState extends State if (read == null || write == null) return use; return '$use\n${l10n.read} $read | ${l10n.write} $write'; }(); - return Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - disk.dev, - style: UIs.text12, - textScaler: _textFactor, - ), - Text( - text, - style: UIs.text12Grey, - textScaler: _textFactor, - ) - ], - ), - SizedBox( - height: 41, - width: 41, - child: Stack( - alignment: Alignment.center, + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 17, vertical: 5), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, children: [ - CircularProgressIndicator( - value: disk.usedPercent / 100, - strokeWidth: 5, - backgroundColor: DynamicColors.progress.resolve(context), - color: primaryColor, + Text( + disk.dev, + style: UIs.text12, + textScaler: _textFactor, ), - Text('${disk.usedPercent}%', style: UIs.text12Grey) + Text( + text, + style: UIs.text12Grey, + textScaler: _textFactor, + ) ], ), - ) - ], - ).padding(const EdgeInsets.symmetric(horizontal: 17, vertical: 5)); + SizedBox( + height: 41, + width: 41, + child: Stack( + alignment: Alignment.center, + children: [ + CircularProgressIndicator( + value: disk.usedPercent / 100, + strokeWidth: 5, + backgroundColor: DynamicColors.progress.resolve(context), + color: primaryColor, + ), + Text('${disk.usedPercent}%', style: UIs.text12Grey) + ], + ), + ) + ], + ), + ); } Widget _buildNetView(ServerStatus ss) { @@ -519,23 +525,26 @@ class _ServerDetailPageState extends State UIs.width13, ValueListenableBuilder( valueListenable: _netSortType, - builder: (_, val, __) => AnimatedSwitcher( - duration: const Duration(milliseconds: 377), - transitionBuilder: (child, animation) => FadeTransition( - opacity: animation, - child: child, + builder: (_, val, __) => InkWell( + onTap: () => _netSortType.value = val.next, + child: AnimatedSwitcher( + duration: const Duration(milliseconds: 377), + transitionBuilder: (child, animation) => FadeTransition( + opacity: animation, + child: child, + ), + child: Row( + children: [ + const Icon(Icons.sort, size: 17), + UIs.width7, + Text( + val.name, + style: UIs.text13Grey, + ), + ], + ), ), - child: Row( - children: [ - const Icon(Icons.sort, size: 17), - UIs.width7, - Text( - val.name, - style: UIs.text13Grey, - ), - ], - ), - ).tap(onTap: () => _netSortType.value = val.next), + ), ), ], ), diff --git a/lib/view/page/server/tab.dart b/lib/view/page/server/tab.dart index 1a5d087c..fd33a509 100644 --- a/lib/view/page/server/tab.dart +++ b/lib/view/page/server/tab.dart @@ -6,9 +6,9 @@ import 'package:provider/provider.dart'; import 'package:toolbox/core/extension/context/common.dart'; import 'package:toolbox/core/extension/context/dialog.dart'; import 'package:toolbox/core/extension/context/locale.dart'; +import 'package:toolbox/core/extension/media_queryx.dart'; import 'package:toolbox/core/extension/numx.dart'; import 'package:toolbox/core/extension/ssh_client.dart'; -import 'package:toolbox/core/extension/widget.dart'; import 'package:toolbox/core/utils/platform/base.dart'; import 'package:toolbox/core/utils/share.dart'; import 'package:toolbox/data/model/app/shell_func.dart'; @@ -45,15 +45,13 @@ class _ServerPageState extends State final _cardsStatus = {}; String? _tag; - // bool _useDoubleColumn = false; + bool _useDoubleColumn = false; @override void didChangeDependencies() { super.didChangeDependencies(); _media = MediaQuery.of(context); - // _useDoubleColumn = _media.useDoubleColumn; - _textFactorDouble = Stores.setting.textFactor.fetch(); - _textFactor = TextScaler.linear(_textFactorDouble); + _useDoubleColumn = _media.useDoubleColumn; } @override @@ -94,11 +92,11 @@ class _ServerPageState extends State } final filtered = _filterServers(pro); - // if (_useDoubleColumn && - // Stores.setting.doubleColumnServersPage.fetch()) { - // return _buildBodyMedium(pro: pro, filtered: filtered); - // } - return _buildBodySmall(provider: pro, filtered: filtered); + if (_useDoubleColumn && + Stores.setting.doubleColumnServersPage.fetch()) { + return _buildBodyMedium(pro: pro, filtered: filtered); + } + return _buildBodySmall(pro: pro, filtered: filtered); }, ); @@ -124,7 +122,7 @@ class _ServerPageState extends State } Widget _buildBodySmall({ - required ServerProvider provider, + required ServerProvider pro, required List filtered, EdgeInsets? padding = const EdgeInsets.fromLTRB(7, 0, 7, 7), }) { @@ -135,25 +133,37 @@ class _ServerPageState extends State itemBuilder: (_, index) { // Issue #130 if (index == count - 1) return UIs.height77; - return _buildEachServerCard(provider.pick(id: filtered[index])); + return _buildEachServerCard(pro.pick(id: filtered[index])); }, ); } - // Widget _buildBodyMedium({ - // required ServerProvider pro, - // required List filtered, - // }) { - // return GridView.builder( - // gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( - // crossAxisCount: 2, - // ), - // itemCount: filtered.length, - // itemBuilder: (context, index) { - // return _buildEachServerCard(pro.pick(id: filtered[index])); - // }, - // ); - // } + Widget _buildBodyMedium({ + required ServerProvider pro, + required List filtered, + }) { + final mid = (filtered.length / 2).ceil(); + final filteredLeft = filtered.sublist(0, mid); + final filteredRight = filtered.sublist(mid); + return Row( + children: [ + Expanded( + child: _buildBodySmall( + pro: pro, + filtered: filteredLeft, + padding: const EdgeInsets.only(left: 7), + ), + ), + Expanded( + child: _buildBodySmall( + pro: pro, + filtered: filteredRight, + padding: const EdgeInsets.only(right: 7), + ), + ) + ], + ); + } Widget _buildEachServerCard(Server? srv) { if (srv == null) { @@ -162,7 +172,7 @@ class _ServerPageState extends State return CardX( key: Key(srv.spi.id + (_tag ?? '')), - child: _buildRealServerCard(srv).padding(const EdgeInsets.all(13)).tap( + child: InkWell( onTap: () { if (srv.canViewDetails) { AppRoute.serverDetail(spi: srv.spi).go(context); @@ -170,7 +180,7 @@ class _ServerPageState extends State _showFailReason(srv.status); } }, - onLongTap: () { + onLongPress: () { if (srv.state == ServerState.finished) { final id = srv.spi.id; final cardStatus = _getCardNoti(id); @@ -181,6 +191,10 @@ class _ServerPageState extends State AppRoute.serverEdit(spi: srv.spi).go(context); } }, + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 13, horizontal: 7), + child: _buildRealServerCard(srv), + ), ), ); } @@ -188,8 +202,10 @@ class _ServerPageState extends State /// The child's width mat not equal to 1/4 of the screen width, /// so we need to wrap it with a SizedBox. Widget _wrapWithSizedbox(Widget child, [bool circle = false]) { + var width = (_media.size.width - 74) / (circle ? 4 : 4.3); + if (_useDoubleColumn) width /= 2; return SizedBox( - width: (_media.size.width - 74) / (circle ? 4 : 4.3), + width: width, child: child, ); } @@ -202,16 +218,15 @@ class _ServerPageState extends State return ListenableBuilder( listenable: cardStatus, builder: (_, __) { - late final List children; + final List children = [title]; if (srv.state == ServerState.finished) { if (cardStatus.value.flip) { - children = [title, ..._buildFlippedCard(srv)]; + children.addAll(_buildFlippedCard(srv)); } else { - children = [title, ..._buildNormalCard(srv.status, srv.spi)]; + children.addAll(_buildNormalCard(srv.status, srv.spi)); } - } else { - children = [title]; } + return AnimatedContainer( duration: const Duration(milliseconds: 377), curve: Curves.fastEaseInToSlowEaseOut, @@ -317,7 +332,7 @@ class _ServerPageState extends State ServerState cs, ServerPrivateInfo spi, ) { - Widget? rightCorner; + Widget rightCorner = UIs.placeholder; if (cs == ServerState.failed) { rightCorner = InkWell( onTap: () { @@ -369,7 +384,7 @@ class _ServerPageState extends State Row( children: [ _buildTopRightText(ss, cs), - if (rightCorner != null) rightCorner, + rightCorner, ], ) ], diff --git a/lib/view/page/setting/entry.dart b/lib/view/page/setting/entry.dart index 249d8eee..bb2192aa 100644 --- a/lib/view/page/setting/entry.dart +++ b/lib/view/page/setting/entry.dart @@ -4,7 +4,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_highlight/theme_map.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:provider/provider.dart'; -import 'package:toolbox/core/build_mode.dart'; import 'package:toolbox/core/extension/colorx.dart'; import 'package:toolbox/core/extension/context/common.dart'; import 'package:toolbox/core/extension/context/locale.dart'; @@ -12,7 +11,6 @@ import 'package:toolbox/core/extension/context/snackbar.dart'; import 'package:toolbox/core/extension/locale.dart'; import 'package:toolbox/core/extension/context/dialog.dart'; import 'package:toolbox/core/extension/stringx.dart'; -import 'package:toolbox/core/extension/widget.dart'; import 'package:toolbox/core/utils/function.dart'; import 'package:toolbox/core/utils/platform/base.dart'; import 'package:toolbox/data/res/provider.dart'; @@ -88,48 +86,28 @@ class _SettingPageState extends State { appBar: CustomAppBar( title: Text(l10n.setting), actions: [ - const Icon(Icons.delete) - .tap( - onTap: () => context.showRoundDialog( - title: Text(l10n.attention), - child: Text(l10n.askContinue( - '${l10n.delete}: **${l10n.all}** ${l10n.setting}', - )), - actions: [ - TextButton( - onPressed: () { - _setting.box.deleteAll(_setting.box.keys); - context.pop(); - context.showSnackBar(l10n.success); - }, - child: Text( - l10n.ok, - style: const TextStyle(color: Colors.red), - ), - ), - ], + IconButton( + icon: const Icon(Icons.delete), + onPressed: () => context.showRoundDialog( + title: Text(l10n.attention), + child: Text(l10n.askContinue( + '${l10n.delete}: **${l10n.all}** ${l10n.setting}', + )), + actions: [ + TextButton( + onPressed: () { + _setting.box.deleteAll(_setting.box.keys); + context.pop(); + context.showSnackBar(l10n.success); + }, + child: Text( + l10n.ok, + style: const TextStyle(color: Colors.red), + ), ), - - /// Only for debug, this will cause the app to crash - onDoubleTap: () => context.showRoundDialog( - title: Text(l10n.attention), - child: Text(l10n.askContinue( - 'Delete all data from disk, and exit the app?', - )), - actions: [ - TextButton( - onPressed: () { - if (!BuildMode.isDebug) return; - Stores.all.map((e) => e.box.deleteFromDisk()); - exit(0); - }, - child: Text(l10n.ok, - style: const TextStyle(color: Colors.red)), - ), - ], - ), - ) - .padding(const EdgeInsets.only(right: 17)), + ], + ), + ), ], ), body: ListView( diff --git a/lib/view/page/snippet/edit.dart b/lib/view/page/snippet/edit.dart index 705b19d3..6c60ad43 100644 --- a/lib/view/page/snippet/edit.dart +++ b/lib/view/page/snippet/edit.dart @@ -5,7 +5,6 @@ import 'package:toolbox/core/extension/context/common.dart'; import 'package:toolbox/core/extension/context/dialog.dart'; import 'package:toolbox/core/extension/context/locale.dart'; import 'package:toolbox/core/extension/context/snackbar.dart'; -import 'package:toolbox/core/extension/widget.dart'; import 'package:toolbox/data/res/provider.dart'; import 'package:toolbox/view/widget/cardx.dart'; import 'package:toolbox/view/widget/input_field.dart'; @@ -195,18 +194,21 @@ class _SnippetEditPageState extends State Widget _buildTip() { return CardX( - child: MarkdownBody( - data: ''' + child: Padding( + padding: const EdgeInsets.all(13), + child: MarkdownBody( + data: ''' 📌 ${l10n.supportFmtArgs} ${Snippet.fmtArgs.keys.map((e) => '`$e`').join(', ')} ''', - styleSheet: MarkdownStyleSheet( - codeblockDecoration: const BoxDecoration( - color: Colors.transparent, + styleSheet: MarkdownStyleSheet( + codeblockDecoration: const BoxDecoration( + color: Colors.transparent, + ), ), ), - ).padding(const EdgeInsets.all(13)), + ), ); } diff --git a/lib/view/page/ssh/tab.dart b/lib/view/page/ssh/tab.dart index 9f597559..22ba75d8 100644 --- a/lib/view/page/ssh/tab.dart +++ b/lib/view/page/ssh/tab.dart @@ -3,7 +3,6 @@ import 'package:provider/provider.dart'; import 'package:toolbox/core/extension/context/common.dart'; import 'package:toolbox/core/extension/context/dialog.dart'; import 'package:toolbox/core/extension/context/locale.dart'; -import 'package:toolbox/core/extension/widget.dart'; import 'package:toolbox/data/provider/server.dart'; import 'package:toolbox/data/res/ui.dart'; import 'package:toolbox/view/page/ssh/page.dart'; @@ -50,10 +49,9 @@ class _SSHTabPageState extends State children: [ Text(e), UIs.width7, - const Icon(Icons.close, size: 17) - .padding(const EdgeInsets.all(7)) - .tap( - onTap: () async { + IconButton( + icon: const Icon(Icons.close, size: 17), + onPressed: () async { final confirm = await context.showRoundDialog( title: Text(l10n.attention), child: Text('${l10n.close} SSH ${l10n.conn}($e) ?'), diff --git a/lib/view/widget/server_func_btns.dart b/lib/view/widget/server_func_btns.dart index c63370f9..0afee9ee 100644 --- a/lib/view/widget/server_func_btns.dart +++ b/lib/view/widget/server_func_btns.dart @@ -7,7 +7,6 @@ import 'package:toolbox/core/extension/context/locale.dart'; import 'package:toolbox/core/extension/context/snackbar.dart'; import 'package:toolbox/core/extension/ssh_client.dart'; import 'package:toolbox/core/extension/uint8list.dart'; -import 'package:toolbox/core/extension/widget.dart'; import 'package:toolbox/core/utils/platform/base.dart'; import 'package:toolbox/core/utils/platform/path.dart'; import 'package:toolbox/data/model/app/menu/server_func.dart'; @@ -89,17 +88,20 @@ class ServerFuncBtns extends StatelessWidget { tooltip: e.toStr, icon: Icon(e.icon, size: iconSize ?? 15), ) - : Column( - mainAxisSize: MainAxisSize.min, - children: [ - IconButton( - onPressed: () => _onTapMoreBtns(e, spi, context), - padding: EdgeInsets.zero, - icon: Icon(e.icon, size: iconSize ?? 15), - ), - Text(e.toStr, style: UIs.text11Grey) - ], - ).padding(const EdgeInsets.only(bottom: 13)), + : Padding( + padding: const EdgeInsets.only(bottom: 13), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + IconButton( + onPressed: () => _onTapMoreBtns(e, spi, context), + padding: EdgeInsets.zero, + icon: Icon(e.icon, size: iconSize ?? 15), + ), + Text(e.toStr, style: UIs.text11Grey) + ], + ), + ), ) .toList(), ); diff --git a/lib/view/widget/tag.dart b/lib/view/widget/tag.dart index 9b499125..749e46d9 100644 --- a/lib/view/widget/tag.dart +++ b/lib/view/widget/tag.dart @@ -2,7 +2,6 @@ import 'package:flutter/material.dart'; import 'package:toolbox/core/extension/context/common.dart'; import 'package:toolbox/core/extension/context/dialog.dart'; import 'package:toolbox/core/extension/context/locale.dart'; -import 'package:toolbox/core/extension/widget.dart'; import 'package:toolbox/data/res/ui.dart'; import 'package:toolbox/view/widget/input_field.dart'; import 'package:toolbox/view/widget/cardx.dart'; @@ -60,12 +59,14 @@ class _TagEditorState extends State { return CardX( child: ListTile( // Align the place of TextField.prefixIcon - leading: const Icon(Icons.tag).padding(const EdgeInsets.only(left: 6)), + leading: const Padding( + padding: EdgeInsets.only(left: 6), + child: Icon(Icons.tag), + ), title: _buildTags(widget.tags), - trailing: const Icon(Icons.add).tap( - onTap: () { - _showAddTagDialog(); - }, + trailing: IconButton( + icon: const Icon(Icons.add), + onPressed: () => _showAddTagDialog(), ), ), ); @@ -238,10 +239,14 @@ Widget _wrap( borderRadius: const BorderRadius.all(Radius.circular(20.0)), child: Material( color: primaryColor.withAlpha(20), - child: child.padding(const EdgeInsets.fromLTRB(11.7, 2.7, 11.7, 0)).tap( - onTap: onTap, - onLongTap: onLongPress, - ), + child: InkWell( + onTap: onTap, + onLongPress: onLongPress, + child: Padding( + padding: const EdgeInsets.fromLTRB(11.7, 2.7, 11.7, 0), + child: child, + ), + ), ), ), );