From b442e0f91409529b7845a2d3203053950d8d7ea9 Mon Sep 17 00:00:00 2001 From: lollipopkit Date: Fri, 5 Jan 2024 21:58:43 +0800 Subject: [PATCH] new: setting of `default collapse` --- .dart_tool/flutter_gen/gen_l10n/l10n.dart | 12 +++++ .dart_tool/flutter_gen/gen_l10n/l10n_de.dart | 6 +++ .dart_tool/flutter_gen/gen_l10n/l10n_en.dart | 6 +++ .dart_tool/flutter_gen/gen_l10n/l10n_fr.dart | 6 +++ .dart_tool/flutter_gen/gen_l10n/l10n_id.dart | 6 +++ .dart_tool/flutter_gen/gen_l10n/l10n_zh.dart | 12 +++++ lib/app.dart | 23 ++++++--- lib/core/analysis.dart | 1 + lib/core/channel/home_widget.dart | 2 + lib/data/store/setting.dart | 3 ++ lib/l10n/app_de.arb | 2 + lib/l10n/app_en.arb | 2 + lib/l10n/app_fr.arb | 10 ++-- lib/l10n/app_id.arb | 2 + lib/l10n/app_zh.arb | 2 + lib/l10n/app_zh_tw.arb | 2 + lib/view/page/home.dart | 18 +------ lib/view/page/server/detail.dart | 51 ++++++++++---------- lib/view/page/setting/entry.dart | 10 ++++ lib/view/widget/input_field.dart | 2 +- 20 files changed, 125 insertions(+), 53 deletions(-) diff --git a/.dart_tool/flutter_gen/gen_l10n/l10n.dart b/.dart_tool/flutter_gen/gen_l10n/l10n.dart index a3ecfbc4..d79fa3ca 100644 --- a/.dart_tool/flutter_gen/gen_l10n/l10n.dart +++ b/.dart_tool/flutter_gen/gen_l10n/l10n.dart @@ -298,6 +298,18 @@ abstract class S { /// **'Command'** String get cmd; + /// No description provided for @collapseUI. + /// + /// In en, this message translates to: + /// **'Collapse'** + String get collapseUI; + + /// No description provided for @collapseUITip. + /// + /// In en, this message translates to: + /// **'Whether to collapse long lists present in the UI by default'** + String get collapseUITip; + /// No description provided for @conn. /// /// In en, this message translates to: diff --git a/.dart_tool/flutter_gen/gen_l10n/l10n_de.dart b/.dart_tool/flutter_gen/gen_l10n/l10n_de.dart index 51275121..d5134cae 100644 --- a/.dart_tool/flutter_gen/gen_l10n/l10n_de.dart +++ b/.dart_tool/flutter_gen/gen_l10n/l10n_de.dart @@ -105,6 +105,12 @@ class SDe extends S { @override String get cmd => 'Command'; + @override + String get collapseUI => 'Zusammenbrechen'; + + @override + String get collapseUITip => 'Ob lange Listen in der Benutzeroberfläche standardmäßig eingeklappt werden sollen oder nicht'; + @override String get conn => 'Verbindung'; diff --git a/.dart_tool/flutter_gen/gen_l10n/l10n_en.dart b/.dart_tool/flutter_gen/gen_l10n/l10n_en.dart index 5bf91497..82891c9a 100644 --- a/.dart_tool/flutter_gen/gen_l10n/l10n_en.dart +++ b/.dart_tool/flutter_gen/gen_l10n/l10n_en.dart @@ -105,6 +105,12 @@ class SEn extends S { @override String get cmd => 'Command'; + @override + String get collapseUI => 'Collapse'; + + @override + String get collapseUITip => 'Whether to collapse long lists present in the UI by default'; + @override String get conn => 'Connection'; diff --git a/.dart_tool/flutter_gen/gen_l10n/l10n_fr.dart b/.dart_tool/flutter_gen/gen_l10n/l10n_fr.dart index 975ae9b1..d4ee126b 100644 --- a/.dart_tool/flutter_gen/gen_l10n/l10n_fr.dart +++ b/.dart_tool/flutter_gen/gen_l10n/l10n_fr.dart @@ -105,6 +105,12 @@ class SFr extends S { @override String get cmd => 'Commande'; + @override + String get collapseUI => 'обвал'; + + @override + String get collapseUITip => 'Réduction ou non des longues listes présentes dans l\'interface utilisateur par défaut'; + @override String get conn => 'Connexion'; diff --git a/.dart_tool/flutter_gen/gen_l10n/l10n_id.dart b/.dart_tool/flutter_gen/gen_l10n/l10n_id.dart index 50884e0e..19570974 100644 --- a/.dart_tool/flutter_gen/gen_l10n/l10n_id.dart +++ b/.dart_tool/flutter_gen/gen_l10n/l10n_id.dart @@ -105,6 +105,12 @@ class SId extends S { @override String get cmd => 'Memerintah'; + @override + String get collapseUI => 'Runtuh'; + + @override + String get collapseUITip => 'Apakah akan menciutkan daftar panjang yang ada di UI secara default atau tidak'; + @override String get conn => 'Koneksi'; diff --git a/.dart_tool/flutter_gen/gen_l10n/l10n_zh.dart b/.dart_tool/flutter_gen/gen_l10n/l10n_zh.dart index fcde10f0..1ec39c57 100644 --- a/.dart_tool/flutter_gen/gen_l10n/l10n_zh.dart +++ b/.dart_tool/flutter_gen/gen_l10n/l10n_zh.dart @@ -105,6 +105,12 @@ class SZh extends S { @override String get cmd => '命令'; + @override + String get collapseUI => '折叠'; + + @override + String get collapseUITip => '是否默认折叠UI中存在的长列表'; + @override String get conn => '连接'; @@ -918,6 +924,12 @@ class SZhTw extends SZh { @override String get cmd => '命令'; + @override + String get collapseUI => '折疊'; + + @override + String get collapseUITip => '是否預設折疊UI中存在的長列表'; + @override String get conn => '連接'; diff --git a/lib/app.dart b/lib/app.dart index 0c952278..fe2a4c09 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -1,23 +1,24 @@ import 'package:dynamic_color/dynamic_color.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:toolbox/core/analysis.dart'; import 'package:toolbox/core/extension/context/common.dart'; import 'package:toolbox/core/extension/locale.dart'; +import 'package:toolbox/core/update.dart'; +import 'package:toolbox/core/utils/ui.dart'; +import 'package:toolbox/data/res/build_data.dart'; +import 'package:toolbox/data/res/color.dart'; import 'package:toolbox/data/res/rebuild.dart'; import 'package:toolbox/data/res/store.dart'; - -import 'core/utils/ui.dart'; -import 'data/res/build_data.dart'; -import 'data/res/color.dart'; -import 'view/page/full_screen.dart'; -import 'view/page/home.dart'; +import 'package:toolbox/view/page/full_screen.dart'; +import 'package:toolbox/view/page/home.dart'; class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { - setTransparentNavigationBar(context); + _setup(context); return ListenableBuilder( listenable: RebuildNodes.app, builder: (_, __) { @@ -83,6 +84,14 @@ class MyApp extends StatelessWidget { } } +void _setup(BuildContext context) async { + setTransparentNavigationBar(context); + if (Stores.setting.autoCheckAppUpdate.fetch()) { + doUpdate(context); + } + Analysis.init(); +} + ThemeData _getAmoledTheme(ThemeData darkTheme) => darkTheme.copyWith( scaffoldBackgroundColor: Colors.black, dialogBackgroundColor: Colors.black, diff --git a/lib/core/analysis.dart b/lib/core/analysis.dart index df35ebb1..eed02921 100644 --- a/lib/core/analysis.dart +++ b/lib/core/analysis.dart @@ -11,6 +11,7 @@ class Analysis { static bool enabled = false; static Future init() async { + if (enabled) return; if (!BuildMode.isRelease) { return; } diff --git a/lib/core/channel/home_widget.dart b/lib/core/channel/home_widget.dart index 683eb251..2b90c331 100644 --- a/lib/core/channel/home_widget.dart +++ b/lib/core/channel/home_widget.dart @@ -1,10 +1,12 @@ import 'package:flutter/services.dart'; import 'package:toolbox/data/res/misc.dart'; +import 'package:toolbox/data/res/store.dart'; abstract final class HomeWidgetMC { static const _channel = MethodChannel('${Miscs.pkgName}/home_widget'); static void update() { + if (!Stores.setting.autoUpdateHomeWidget.fetch()) return; _channel.invokeMethod('update'); } } diff --git a/lib/data/store/setting.dart b/lib/data/store/setting.dart index d1950665..49bc0346 100644 --- a/lib/data/store/setting.dart +++ b/lib/data/store/setting.dart @@ -205,6 +205,9 @@ class SettingStore extends PersistentStore { late final webdavUser = property('webdavUser', ''); late final webdavPwd = property('webdavPwd', ''); + /// Whether collapse UI items by default + late final collapseUIDefault = property('collapseUIDefault', true); + // Never show these settings for users // // ------BEGIN------ diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index cb02d16d..59465e0b 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -33,6 +33,8 @@ "clear": "Entfernen", "close": "Schließen", "cmd": "Command", + "collapseUI": "Zusammenbrechen", + "collapseUITip": "Ob lange Listen in der Benutzeroberfläche standardmäßig eingeklappt werden sollen oder nicht", "conn": "Verbindung", "connected": "in Verbindung gebracht", "containerName": "Container Name", diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 2b7dee8b..6bbd32d1 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -33,6 +33,8 @@ "clear": "Clear", "close": "Close", "cmd": "Command", + "collapseUI": "Collapse", + "collapseUITip": "Whether to collapse long lists present in the UI by default", "conn": "Connection", "connected": "Connected", "containerName": "Container name", diff --git a/lib/l10n/app_fr.arb b/lib/l10n/app_fr.arb index 26f89cf9..7bcfc924 100644 --- a/lib/l10n/app_fr.arb +++ b/lib/l10n/app_fr.arb @@ -30,9 +30,11 @@ "choose": "Choisir", "chooseFontFile": "Choisir un fichier de police", "choosePrivateKey": "Choisir la clé privée", - "clear": "Effacer", + "clear": "Effacer", "close": "Fermer", "cmd": "Commande", + "collapseUI": "обвал", + "collapseUITip": "Réduction ou non des longues listes présentes dans l'interface utilisateur par défaut", "conn": "Connexion", "connected": "Connecté", "containerName": "Nom du conteneur", @@ -175,7 +177,7 @@ "pushToken": "Jeton d'identification", "pwd": "Mot de passe", "read": "Lire", - "reboot": "Redémarrer", + "reboot": "Redémarrer", "remotePath": "Chemin distant", "rename": "Renommer", "reportBugsOnGithubIssue": "Veuillez signaler les bogues sur {url}", @@ -211,7 +213,7 @@ "sshTip": "Cette fonction est actuellement au stade expérimental.\n\n Veuillez signaler les bogues sur {url} ou rejoignez notre développement.", "sshVirtualKeyAutoOff": "Basculement automatique des touches virtuelles", "start": "Démarrer", - "stats": "Statistiques", + "stats": "Statistiques", "stop": "Arrêter", "success": "Succès", "suspend": "Suspendre", @@ -230,7 +232,7 @@ "traffic": "Trafic", "ttl": "ttl", "unknown": "Inconnu", - "unknownError": "Erreur inconnue", + "unknownError": "Erreur inconnue", "unkownConvertMode": "Mode de conversion inconnu", "update": "Mettre à jour", "updateAll": "Tout mettre à jour", diff --git a/lib/l10n/app_id.arb b/lib/l10n/app_id.arb index 8002bee8..be960f6a 100644 --- a/lib/l10n/app_id.arb +++ b/lib/l10n/app_id.arb @@ -33,6 +33,8 @@ "clear": "Jernih", "close": "Menutup", "cmd": "Memerintah", + "collapseUI": "Runtuh", + "collapseUITip": "Apakah akan menciutkan daftar panjang yang ada di UI secara default atau tidak", "conn": "Koneksi", "connected": "Terhubung", "containerName": "Nama kontainer", diff --git a/lib/l10n/app_zh.arb b/lib/l10n/app_zh.arb index 9a4b0e31..b12ca87d 100644 --- a/lib/l10n/app_zh.arb +++ b/lib/l10n/app_zh.arb @@ -33,6 +33,8 @@ "clear": "清除", "close": "关闭", "cmd": "命令", + "collapseUI": "折叠", + "collapseUITip": "是否默认折叠UI中存在的长列表", "conn": "连接", "connected": "已连接", "containerName": "容器名", diff --git a/lib/l10n/app_zh_tw.arb b/lib/l10n/app_zh_tw.arb index 39f138ba..68969148 100644 --- a/lib/l10n/app_zh_tw.arb +++ b/lib/l10n/app_zh_tw.arb @@ -33,6 +33,8 @@ "clear": "清除", "close": "關閉", "cmd": "命令", + "collapseUI": "折疊", + "collapseUITip": "是否預設折疊UI中存在的長列表", "conn": "連接", "connected": "已連接", "containerName": "容器名稱", diff --git a/lib/view/page/home.dart b/lib/view/page/home.dart index 29be3e1c..1a1c8339 100644 --- a/lib/view/page/home.dart +++ b/lib/view/page/home.dart @@ -16,9 +16,7 @@ import 'package:toolbox/data/res/logger.dart'; import 'package:toolbox/data/res/provider.dart'; import 'package:toolbox/data/res/store.dart'; -import '../../core/analysis.dart'; import '../../core/route.dart'; -import '../../core/update.dart'; import '../../core/utils/ui.dart'; import '../../data/model/app/github_id.dart'; import '../../data/model/app/tab.dart'; @@ -87,7 +85,7 @@ class _HomePageState extends State if (!Pros.server.isAutoRefreshOn) { Pros.server.startAutoRefresh(); } - updateHomeWidget(); + HomeWidgetMC.update(); break; case AppLifecycleState.paused: // Keep running in background on Android device @@ -323,22 +321,10 @@ class _HomePageState extends State Future afterFirstLayout(BuildContext context) async { // Auth required for first launch _auth(); - if (Stores.setting.autoCheckAppUpdate.fetch()) { - doUpdate(context); - } - updateHomeWidget(); + HomeWidgetMC.update(); await GetIt.I.allReady(); await Pros.server.load(); await Pros.server.refreshData(); - if (!Analysis.enabled) { - Analysis.init(); - } - } - - void updateHomeWidget() { - if (Stores.setting.autoUpdateHomeWidget.fetch()) { - HomeWidgetMC.update(); - } } Future _onLongPressSetting() async { diff --git a/lib/view/page/server/detail.dart b/lib/view/page/server/detail.dart index 4dd69563..81e0fc93 100644 --- a/lib/view/page/server/detail.dart +++ b/lib/view/page/server/detail.dart @@ -38,11 +38,6 @@ class ServerDetailPage extends StatefulWidget { class _ServerDetailPageState extends State with SingleTickerProviderStateMixin { - late MediaQueryData _media; - final Order _cardsOrder = []; - - late final _textFactor = TextScaler.linear(Stores.setting.textFactor.fetch()); - late final _cardBuildMap = Map.fromIterables( Defaults.detailCardOrder, [ @@ -58,7 +53,12 @@ class _ServerDetailPageState extends State ], ); - var _netSortType = _NetSortType.device; + late MediaQueryData _media; + final Order _cardsOrder = []; + + final _netSortType = ValueNotifier(_NetSortType.device); + late final _collapse = Stores.setting.collapseUIDefault.fetch(); + late final _textFactor = TextScaler.linear(Stores.setting.textFactor.fetch()); @override void didChangeDependencies() { @@ -127,7 +127,7 @@ class _ServerDetailPageState extends State return CardX( child: ExpandTile( leading: const Icon(Icons.computer), - initiallyExpanded: ss.more.entries.length < 7, + initiallyExpanded: _getInitExpand(ss.more.entries.length), title: Text(l10n.about), childrenPadding: const EdgeInsets.symmetric( horizontal: 17, @@ -175,7 +175,7 @@ class _ServerDetailPageState extends State ), ), childrenPadding: const EdgeInsets.symmetric(vertical: 13), - initiallyExpanded: ss.cpu.coresCount <= 8, + initiallyExpanded: _getInitExpand(ss.cpu.coresCount), trailing: Row( mainAxisSize: MainAxisSize.min, children: details, @@ -319,7 +319,7 @@ class _ServerDetailPageState extends State child: ExpandTile( title: const Text('GPU'), leading: const Icon(Icons.memory, size: 17), - initiallyExpanded: children.length <= 3, + initiallyExpanded: _getInitExpand(children.length, 3), children: children, ), ); @@ -453,7 +453,7 @@ class _ServerDetailPageState extends State title: Text(l10n.disk), childrenPadding: const EdgeInsets.only(bottom: 7), leading: const Icon(Icons.storage, size: 17), - initiallyExpanded: children.length <= 7, + initiallyExpanded: _getInitExpand(children.length), children: children, ), ); @@ -518,7 +518,7 @@ class _ServerDetailPageState extends State )); } else { final devices = ns.devices; - devices.sort(_netSortType.getSortFunc(ns)); + devices.sort(_netSortType.value.getSortFunc(ns)); children.addAll(devices.map((e) => _buildNetSpeedItem(ns, e))); } return CardX( @@ -527,36 +527,31 @@ class _ServerDetailPageState extends State children: [ Text(l10n.net), UIs.width13, - IconButton( - onPressed: () { - setState(() { - _netSortType = _netSortType.next; - }); - }, - icon: AnimatedSwitcher( + ValueListenableBuilder( + valueListenable: _netSortType, + builder: (_, val, __) => AnimatedSwitcher( duration: const Duration(milliseconds: 377), transitionBuilder: (child, animation) => FadeTransition( opacity: animation, child: child, ), child: Row( - key: ValueKey(_netSortType), children: [ const Icon(Icons.sort, size: 17), UIs.width7, Text( - _netSortType.name, + val.name, style: UIs.text13Grey, ), ], ), - ), - ) + ).tap(onTap: () => _netSortType.value = val.next), + ), ], ), childrenPadding: const EdgeInsets.only(bottom: 11), leading: const Icon(Icons.device_hub, size: 17), - initiallyExpanded: children.length <= 7, + initiallyExpanded: _getInitExpand(children.length), children: children, ), ); @@ -589,7 +584,7 @@ class _ServerDetailPageState extends State SizedBox( width: 170, child: Text( - '↑ ${ns.speedOut(device: device)}\n↓ ${ns.speedIn(device: device)}', + '${ns.speedOut(device: device)} ↑\n${ns.speedIn(device: device)} ↓', textAlign: TextAlign.end, style: UIs.text13Grey, ), @@ -607,7 +602,7 @@ class _ServerDetailPageState extends State child: ExpandTile( title: Text(l10n.temperature), leading: const Icon(Icons.ac_unit, size: 17), - initiallyExpanded: ss.temps.devices.length <= 7, + initiallyExpanded: _getInitExpand(ss.temps.devices.length), childrenPadding: const EdgeInsets.only(bottom: 7), children: ss.temps.devices .map((key) => _buildTemperatureItem(key, ss.temps.get(key))) @@ -638,6 +633,7 @@ class _ServerDetailPageState extends State title: Text(l10n.battery), leading: const Icon(Icons.battery_charging_full, size: 17), childrenPadding: const EdgeInsets.only(bottom: 7), + initiallyExpanded: _getInitExpand(ss.batteries.length), children: ss.batteries.map(_buildBatteryItem).toList(), ), ); @@ -684,6 +680,11 @@ class _ServerDetailPageState extends State ), ); } + + bool _getInitExpand(int len, [int? max]) { + if (_collapse && len <= (max ?? 7)) return true; + return false; + } } enum _NetSortType { diff --git a/lib/view/page/setting/entry.dart b/lib/view/page/setting/entry.dart index f4a18c67..ba713ff7 100644 --- a/lib/view/page/setting/entry.dart +++ b/lib/view/page/setting/entry.dart @@ -139,6 +139,7 @@ class _SettingPageState extends State { body: ListView( padding: const EdgeInsets.symmetric(horizontal: 17), children: [ + /// TODO: Remember add new items in front of the each list, so the user can easily find the new items _buildTitle('App'), _buildApp(), _buildTitle(l10n.server), @@ -203,6 +204,7 @@ class _SettingPageState extends State { Widget _buildServer() { return Column( children: [ + _buildCollapseUI(), _buildServerFuncBtns(), _buildSequence(), _buildNetViewType(), @@ -1104,4 +1106,12 @@ class _SettingPageState extends State { trailing: StoreSwitch(prop: _setting.editorHighlight), ); } + + Widget _buildCollapseUI() { + return ListTile( + title: Text(l10n.collapseUI), + subtitle: Text(l10n.collapseUITip, style: UIs.textGrey), + trailing: StoreSwitch(prop: _setting.collapseUIDefault), + ); + } } diff --git a/lib/view/widget/input_field.dart b/lib/view/widget/input_field.dart index ac9f1d90..84408f7c 100644 --- a/lib/view/widget/input_field.dart +++ b/lib/view/widget/input_field.dart @@ -59,7 +59,7 @@ class _InputState extends State { Widget build(BuildContext context) { return CardX( child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 17), + padding: const EdgeInsets.symmetric(horizontal: 7), child: TextField( controller: widget.controller, maxLines: widget.maxLines,