opt.: tag switcher

This commit is contained in:
lollipopkit
2023-12-15 12:01:55 +08:00
parent f10c5b9ea8
commit ee18b85108
30 changed files with 316 additions and 281 deletions

View File

@@ -586,7 +586,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = 672; CURRENT_PROJECT_VERSION = 674;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
@@ -596,7 +596,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.672; MARKETING_VERSION = 1.0.674;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@@ -720,7 +720,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = 672; CURRENT_PROJECT_VERSION = 674;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
@@ -730,7 +730,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.672; MARKETING_VERSION = 1.0.674;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@@ -748,7 +748,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = 672; CURRENT_PROJECT_VERSION = 674;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
@@ -758,7 +758,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.672; MARKETING_VERSION = 1.0.674;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@@ -779,7 +779,7 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 672; CURRENT_PROJECT_VERSION = 674;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
GCC_C_LANGUAGE_STANDARD = gnu11; GCC_C_LANGUAGE_STANDARD = gnu11;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
@@ -792,7 +792,7 @@
"@executable_path/Frameworks", "@executable_path/Frameworks",
"@executable_path/../../Frameworks", "@executable_path/../../Frameworks",
); );
MARKETING_VERSION = 1.0.672; MARKETING_VERSION = 1.0.674;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget;
@@ -818,7 +818,7 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 672; CURRENT_PROJECT_VERSION = 674;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
GCC_C_LANGUAGE_STANDARD = gnu11; GCC_C_LANGUAGE_STANDARD = gnu11;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
@@ -831,7 +831,7 @@
"@executable_path/Frameworks", "@executable_path/Frameworks",
"@executable_path/../../Frameworks", "@executable_path/../../Frameworks",
); );
MARKETING_VERSION = 1.0.672; MARKETING_VERSION = 1.0.674;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
@@ -854,7 +854,7 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 672; CURRENT_PROJECT_VERSION = 674;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
GCC_C_LANGUAGE_STANDARD = gnu11; GCC_C_LANGUAGE_STANDARD = gnu11;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
@@ -867,7 +867,7 @@
"@executable_path/Frameworks", "@executable_path/Frameworks",
"@executable_path/../../Frameworks", "@executable_path/../../Frameworks",
); );
MARKETING_VERSION = 1.0.672; MARKETING_VERSION = 1.0.674;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
@@ -890,7 +890,7 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 672; CURRENT_PROJECT_VERSION = 674;
DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_ASSET_PATHS = "";
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_PREVIEWS = YES; ENABLE_PREVIEWS = YES;
@@ -902,7 +902,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.672; MARKETING_VERSION = 1.0.674;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd;
@@ -931,7 +931,7 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 672; CURRENT_PROJECT_VERSION = 674;
DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_ASSET_PATHS = "";
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_PREVIEWS = YES; ENABLE_PREVIEWS = YES;
@@ -943,7 +943,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.672; MARKETING_VERSION = 1.0.674;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd;
PRODUCT_NAME = ServerBox; PRODUCT_NAME = ServerBox;
@@ -969,7 +969,7 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 672; CURRENT_PROJECT_VERSION = 674;
DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_ASSET_PATHS = "";
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_PREVIEWS = YES; ENABLE_PREVIEWS = YES;
@@ -981,7 +981,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.672; MARKETING_VERSION = 1.0.674;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd;
PRODUCT_NAME = ServerBox; PRODUCT_NAME = ServerBox;

View File

@@ -0,0 +1,32 @@
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,
);
}
}

View File

@@ -0,0 +1,24 @@
import 'package:flutter/material.dart';
abstract final class Funcs {
static const int _defaultDurationTime = 377;
static const String _defaultThrottleId = 'default';
static final Map<String, int> startTimeMap = <String, int>{
_defaultThrottleId: 0
};
static void throttle(
VoidCallback? func, {
String id = _defaultThrottleId,
int duration = _defaultDurationTime,
Function? continueClick,
}) {
final currentTime = DateTime.now().millisecondsSinceEpoch;
if (currentTime - (startTimeMap[id] ?? 0) > duration) {
func?.call();
startTimeMap[id] = DateTime.now().millisecondsSinceEpoch;
} else {
continueClick?.call();
}
}
}

View File

@@ -2,9 +2,9 @@
class BuildData { class BuildData {
static const String name = "ServerBox"; static const String name = "ServerBox";
static const int build = 672; static const int build = 674;
static const String engine = "3.16.2"; static const String engine = "3.16.3";
static const String buildAt = "2023-12-11 11:40:12"; static const String buildAt = "2023-12-12 18:14:36";
static const int modifications = 3; static const int modifications = 29;
static const int script = 31; static const int script = 31;
} }

View File

@@ -51,10 +51,10 @@ class SettingStore extends PersistentStore {
property('diskIgnorePath', Defaults.diskIgnorePath); property('diskIgnorePath', Defaults.diskIgnorePath);
/// Use double column servers page on Desktop /// Use double column servers page on Desktop
late final doubleColumnServersPage = property( // late final doubleColumnServersPage = property(
'doubleColumnServersPage', // 'doubleColumnServersPage',
isDesktop, // isDesktop,
); // );
/// Disk view: amount / IO /// Disk view: amount / IO
late final serverTabPreferDiskAmount = property( late final serverTabPreferDiskAmount = property(

View File

@@ -53,7 +53,7 @@ class BackupPage extends StatelessWidget {
Widget _buildTip() { Widget _buildTip() {
return CardX( return CardX(
ListTile( child: ListTile(
leading: const Icon(Icons.warning), leading: const Icon(Icons.warning),
title: Text(l10n.attention), title: Text(l10n.attention),
subtitle: Text(l10n.backupTip, style: UIs.textGrey), subtitle: Text(l10n.backupTip, style: UIs.textGrey),
@@ -63,7 +63,7 @@ class BackupPage extends StatelessWidget {
Widget _buildFile(BuildContext context) { Widget _buildFile(BuildContext context) {
return CardX( return CardX(
ExpandTile( child: ExpandTile(
leading: const Icon(Icons.file_open), leading: const Icon(Icons.file_open),
title: Text(l10n.files), title: Text(l10n.files),
initiallyExpanded: true, initiallyExpanded: true,
@@ -94,7 +94,8 @@ class BackupPage extends StatelessWidget {
Widget _buildIcloud(BuildContext context) { Widget _buildIcloud(BuildContext context) {
return CardX( return CardX(
ListTile( child: ListTile(
leading: const Icon(Icons.cloud),
title: const Text('iCloud'), title: const Text('iCloud'),
trailing: StoreSwitch( trailing: StoreSwitch(
prop: Stores.setting.icloudSync, prop: Stores.setting.icloudSync,
@@ -119,7 +120,7 @@ class BackupPage extends StatelessWidget {
Widget _buildWebdav(BuildContext context) { Widget _buildWebdav(BuildContext context) {
return CardX( return CardX(
ExpandTile( child: ExpandTile(
leading: const Icon(Icons.storage), leading: const Icon(Icons.storage),
title: const Text('WebDAV'), title: const Text('WebDAV'),
initiallyExpanded: !(isIOS || isMacOS), initiallyExpanded: !(isIOS || isMacOS),

View File

@@ -214,7 +214,7 @@ class _DockerManagePageState extends State<DockerManagePage> {
_buildPs(), _buildPs(),
_buildImage(), _buildImage(),
_buildEditHost(), _buildEditHost(),
].map((e) => CardX(e)); ].map((e) => CardX(child: e));
return ListView( return ListView(
padding: const EdgeInsets.all(7), padding: const EdgeInsets.all(7),
children: items.toList(), children: items.toList(),

View File

@@ -241,7 +241,7 @@ class _HomePageState extends State<HomePage>
title: Text('${l10n.about} & ${l10n.feedback}'), title: Text('${l10n.about} & ${l10n.feedback}'),
onTap: _showAboutDialog, onTap: _showAboutDialog,
) )
].map((e) => CardX(e)).toList(), ].map((e) => CardX(child: e)).toList(),
), ),
); );
} }

View File

@@ -119,7 +119,7 @@ class _PingPageState extends State<PingPage>
final unknown = l10n.unknown; final unknown = l10n.unknown;
final ms = l10n.ms; final ms = l10n.ms;
return CardX( return CardX(
ListTile( child: ListTile(
contentPadding: const EdgeInsets.symmetric(vertical: 7, horizontal: 17), contentPadding: const EdgeInsets.symmetric(vertical: 7, horizontal: 17),
title: Text( title: Text(
result.serverName, result.serverName,

View File

@@ -54,7 +54,7 @@ class _PrivateKeyListState extends State<PrivateKeysListPage>
itemBuilder: (context, idx) { itemBuilder: (context, idx) {
final item = key.pkis[idx]; final item = key.pkis[idx];
return CardX( return CardX(
ListTile( child: ListTile(
leading: Text( leading: Text(
'#$idx', '#$idx',
style: const TextStyle( style: const TextStyle(

View File

@@ -143,7 +143,8 @@ class _ProcessPageState extends State<ProcessPage> {
? Text(proc.pid.toString()) ? Text(proc.pid.toString())
: TwoLineText(up: proc.pid.toString(), down: proc.user!); : TwoLineText(up: proc.pid.toString(), down: proc.user!);
return CardX( return CardX(
ListTile( key: ValueKey(proc.pid),
child: ListTile(
leading: SizedBox( leading: SizedBox(
width: _media.size.width / 6, width: _media.size.width / 6,
child: leading, child: leading,
@@ -178,7 +179,6 @@ class _ProcessPageState extends State<ProcessPage> {
selected: _lastFocusId == proc.pid, selected: _lastFocusId == proc.pid,
autofocus: _lastFocusId == proc.pid, autofocus: _lastFocusId == proc.pid,
), ),
key: ValueKey(proc.pid),
); );
} }

View File

@@ -4,6 +4,7 @@ import 'package:toolbox/core/extension/context/common.dart';
import 'package:toolbox/core/extension/context/dialog.dart'; import 'package:toolbox/core/extension/context/dialog.dart';
import 'package:toolbox/core/extension/context/locale.dart'; import 'package:toolbox/core/extension/context/locale.dart';
import 'package:toolbox/core/extension/order.dart'; import 'package:toolbox/core/extension/order.dart';
import 'package:toolbox/core/extension/widget.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/disk.dart';
import 'package:toolbox/data/model/server/net_speed.dart'; import 'package:toolbox/data/model/server/net_speed.dart';
@@ -135,7 +136,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
} }
return CardX( return CardX(
ExpandTile( child: ExpandTile(
title: Align( title: Align(
alignment: Alignment.centerLeft, alignment: Alignment.centerLeft,
child: _buildAnimatedText( child: _buildAnimatedText(
@@ -202,7 +203,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
Widget _buildUpTimeAndSys(ServerStatus ss) { Widget _buildUpTimeAndSys(ServerStatus ss) {
return CardX( return CardX(
Padding( child: Padding(
padding: UIs.roundRectCardPadding, padding: UIs.roundRectCardPadding,
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
@@ -230,7 +231,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
final usedStr = used.toStringAsFixed(0); final usedStr = used.toStringAsFixed(0);
return CardX( return CardX(
Padding( child: Padding(
padding: UIs.roundRectCardPadding, padding: UIs.roundRectCardPadding,
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
@@ -275,7 +276,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
final used = ss.swap.usedPercent * 100; final used = ss.swap.usedPercent * 100;
final cached = ss.swap.cached / ss.swap.total * 100; final cached = ss.swap.cached / ss.swap.total * 100;
return CardX( return CardX(
Padding( child: Padding(
padding: UIs.roundRectCardPadding, padding: UIs.roundRectCardPadding,
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
@@ -309,7 +310,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
if (ss.nvdia == null) return UIs.placeholder; if (ss.nvdia == null) return UIs.placeholder;
final children = ss.nvdia!.map((e) => _buildGpuItem(e)).toList(); final children = ss.nvdia!.map((e) => _buildGpuItem(e)).toList();
return CardX( return CardX(
ExpandTile( child: ExpandTile(
title: const Text('GPU'), title: const Text('GPU'),
leading: const Icon(Icons.memory, size: 17), leading: const Icon(Icons.memory, size: 17),
initiallyExpanded: children.length <= 3, initiallyExpanded: children.length <= 3,
@@ -392,7 +393,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
style: UIs.textSize11Grey, style: UIs.textSize11Grey,
textScaler: _textFactor, textScaler: _textFactor,
), ),
trailing: InkWell( trailing: const Icon(Icons.info_outline, size: 17).tap(
onTap: () { onTap: () {
context.showRoundDialog( context.showRoundDialog(
title: SizedBox( title: SizedBox(
@@ -417,7 +418,6 @@ class _ServerDetailPageState extends State<ServerDetailPage>
], ],
); );
}, },
child: const Icon(Icons.info_outline, size: 17),
), ),
); );
} }
@@ -433,7 +433,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
final children = final children =
List.generate(disks.length, (idx) => _buildDiskItem(disks[idx], ss)); List.generate(disks.length, (idx) => _buildDiskItem(disks[idx], ss));
return CardX( return CardX(
ExpandTile( child: ExpandTile(
title: Text(l10n.disk), title: Text(l10n.disk),
childrenPadding: const EdgeInsets.only(bottom: 7), childrenPadding: const EdgeInsets.only(bottom: 7),
leading: const Icon(Icons.storage, size: 17), leading: const Icon(Icons.storage, size: 17),
@@ -497,7 +497,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
children.addAll(devices.map((e) => _buildNetSpeedItem(ns, e))); children.addAll(devices.map((e) => _buildNetSpeedItem(ns, e)));
} }
return CardX( return CardX(
ExpandTile( child: ExpandTile(
title: Row( title: Row(
children: [ children: [
Text(l10n.net), Text(l10n.net),
@@ -579,10 +579,11 @@ class _ServerDetailPageState extends State<ServerDetailPage>
return UIs.placeholder; return UIs.placeholder;
} }
return CardX( return CardX(
ExpandTile( child: ExpandTile(
title: Text(l10n.temperature), title: Text(l10n.temperature),
leading: const Icon(Icons.ac_unit, size: 17), leading: const Icon(Icons.ac_unit, size: 17),
initiallyExpanded: ss.temps.devices.length <= 7, initiallyExpanded: ss.temps.devices.length <= 7,
childrenPadding: EdgeInsets.zero,
children: ss.temps.devices children: ss.temps.devices
.map((key) => _buildTemperatureItem(key, ss.temps.get(key))) .map((key) => _buildTemperatureItem(key, ss.temps.get(key)))
.toList(), .toList(),

View File

@@ -127,16 +127,15 @@ class _ServerEditPageState extends State<ServerEditPage> {
)), )),
UIs.height13, UIs.height13,
if (widget.spi?.server?.canViewDetails ?? false) if (widget.spi?.server?.canViewDetails ?? false)
Row( CheckboxListTile(
children: [
Checkbox(
value: delScripts, value: delScripts,
onChanged: (_) => setState( onChanged: (_) => setState(
() => delScripts = !delScripts, () => delScripts = !delScripts,
), ),
), controlAffinity: ListTileControlAffinity.leading,
Text(l10n.deleteScripts), subtitle: Text(l10n.deleteScripts),
], tileColor: Colors.transparent,
contentPadding: EdgeInsets.zero,
) )
], ],
); );
@@ -315,7 +314,7 @@ class _ServerEditPageState extends State<ServerEditPage> {
), ),
); );
return CardX( return CardX(
Padding( child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 17), padding: const EdgeInsets.symmetric(horizontal: 17),
child: Column( child: Column(
children: tiles, children: tiles,
@@ -375,7 +374,7 @@ class _ServerEditPageState extends State<ServerEditPage> {
onTap: () => _jumpServer.value = null, onTap: () => _jumpServer.value = null,
)); ));
return CardX( return CardX(
ExpandTile( child: ExpandTile(
leading: const Icon(Icons.map), leading: const Icon(Icons.map),
initiallyExpanded: _jumpServer.value != null, initiallyExpanded: _jumpServer.value != null,
title: Text(l10n.jumpServer), title: Text(l10n.jumpServer),

View File

@@ -8,6 +8,7 @@ import 'package:toolbox/core/extension/context/dialog.dart';
import 'package:toolbox/core/extension/context/locale.dart'; import 'package:toolbox/core/extension/context/locale.dart';
import 'package:toolbox/core/extension/media_queryx.dart'; import 'package:toolbox/core/extension/media_queryx.dart';
import 'package:toolbox/core/extension/ssh_client.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/platform/base.dart';
import 'package:toolbox/core/utils/share.dart'; import 'package:toolbox/core/utils/share.dart';
import 'package:toolbox/data/model/app/shell_func.dart'; import 'package:toolbox/data/model/app/shell_func.dart';
@@ -55,6 +56,7 @@ class _ServerPageState extends State<ServerPage>
Widget build(BuildContext context) { Widget build(BuildContext context) {
super.build(context); super.build(context);
return Scaffold( return Scaffold(
appBar: _buildTagsSwitcher(Pros.server),
body: _buildBody(), body: _buildBody(),
floatingActionButton: FloatingActionButton( floatingActionButton: FloatingActionButton(
onPressed: () => AppRoute.serverEdit().go(context), onPressed: () => AppRoute.serverEdit().go(context),
@@ -81,10 +83,10 @@ class _ServerPageState extends State<ServerPage>
} }
final filtered = _filterServers(pro); final filtered = _filterServers(pro);
if (_useDoubleColumn && // if (_useDoubleColumn &&
Stores.setting.doubleColumnServersPage.fetch()) { // Stores.setting.doubleColumnServersPage.fetch()) {
return _buildBodyMedium(pro: pro, filtered: filtered); // return _buildBodyMedium(pro: pro, filtered: filtered);
} // }
return _buildBodySmall(provider: pro, filtered: filtered); return _buildBodySmall(provider: pro, filtered: filtered);
}, },
); );
@@ -99,7 +101,7 @@ class _ServerPageState extends State<ServerPage>
); );
} }
Widget _buildTagsSwitcher(ServerProvider provider) { TagSwitcher _buildTagsSwitcher(ServerProvider provider) {
return TagSwitcher( return TagSwitcher(
tags: provider.tags, tags: provider.tags,
width: _media.size.width, width: _media.size.width,
@@ -115,61 +117,33 @@ class _ServerPageState extends State<ServerPage>
required ServerProvider provider, required ServerProvider provider,
required List<String> filtered, required List<String> filtered,
EdgeInsets? padding = const EdgeInsets.fromLTRB(7, 0, 7, 7), EdgeInsets? padding = const EdgeInsets.fromLTRB(7, 0, 7, 7),
bool buildTags = true,
}) { }) {
final count = buildTags ? filtered.length + 2 : filtered.length + 1; final count = filtered.length + 1;
return ListView.builder( return ListView.builder(
padding: padding, padding: padding,
itemCount: count, itemCount: count,
itemBuilder: (_, index) { itemBuilder: (_, index) {
if (index == 0 && buildTags) return _buildTagsSwitcher(provider);
// Issue #130 // Issue #130
if (index == count - 1) return UIs.height77; if (index == count - 1) return UIs.height77;
if (buildTags) index--;
return _buildEachServerCard(provider.pick(id: filtered[index])); return _buildEachServerCard(provider.pick(id: filtered[index]));
}, },
); );
} }
Widget _buildBodyMedium({ // Widget _buildBodyMedium({
required ServerProvider pro, // required ServerProvider pro,
required List<String> filtered, // required List<String> filtered,
}) { // }) {
final left = filtered.where((e) => filtered.indexOf(e) % 2 == 0).toList(); // return GridView.builder(
final right = filtered.where((e) => filtered.indexOf(e) % 2 == 1).toList(); // gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
return Column( // crossAxisCount: 2,
mainAxisSize: MainAxisSize.min, // ),
children: [ // itemCount: filtered.length,
Padding( // itemBuilder: (context, index) {
padding: const EdgeInsets.symmetric(horizontal: 7), // return _buildEachServerCard(pro.pick(id: filtered[index]));
child: _buildTagsSwitcher(pro), // },
), // );
Expanded( // }
child: Row(
children: [
Expanded(
child: _buildBodySmall(
provider: pro,
filtered: left,
padding: const EdgeInsets.fromLTRB(7, 0, 0, 7),
buildTags: false,
),
),
Expanded(
child: _buildBodySmall(
provider: pro,
filtered: right,
padding: const EdgeInsets.fromLTRB(0, 0, 7, 7),
buildTags: false,
),
),
],
))
],
);
}
Widget _buildEachServerCard(Server? srv) { Widget _buildEachServerCard(Server? srv) {
if (srv == null) { if (srv == null) {
@@ -178,7 +152,7 @@ class _ServerPageState extends State<ServerPage>
return CardX( return CardX(
key: Key(srv.spi.id + (_tag ?? '')), key: Key(srv.spi.id + (_tag ?? '')),
InkWell( child: _buildRealServerCard(srv).padding(const EdgeInsets.all(13)).tap(
onTap: () { onTap: () {
if (srv.canViewDetails) { if (srv.canViewDetails) {
AppRoute.serverDetail(spi: srv.spi).go(context); AppRoute.serverDetail(spi: srv.spi).go(context);
@@ -186,7 +160,7 @@ class _ServerPageState extends State<ServerPage>
_showFailReason(srv.status); _showFailReason(srv.status);
} }
}, },
onLongPress: () { onLongTap: () {
if (srv.state == ServerState.finished) { if (srv.state == ServerState.finished) {
final id = srv.spi.id; final id = srv.spi.id;
final cardStatus = getCardNoti(id); final cardStatus = getCardNoti(id);
@@ -197,10 +171,6 @@ class _ServerPageState extends State<ServerPage>
AppRoute.serverEdit(spi: srv.spi).go(context); AppRoute.serverEdit(spi: srv.spi).go(context);
} }
}, },
child: Padding(
padding: const EdgeInsets.all(13),
child: _buildRealServerCard(srv),
),
), ),
); );
} }

View File

@@ -43,7 +43,7 @@ class _AndroidSettingsPageState extends State<AndroidSettingsPage> {
_buildAndroidWidgetSharedPreference(), _buildAndroidWidgetSharedPreference(),
if (BioAuth.isPlatformSupported) if (BioAuth.isPlatformSupported)
PlatformPublicSettings.buildBioAuth(), PlatformPublicSettings.buildBioAuth(),
].map((e) => CardX(e)).toList(), ].map((e) => CardX(child: e)).toList(),
), ),
); );
} }

View File

@@ -12,6 +12,8 @@ import 'package:toolbox/core/extension/context/snackbar.dart';
import 'package:toolbox/core/extension/locale.dart'; import 'package:toolbox/core/extension/locale.dart';
import 'package:toolbox/core/extension/context/dialog.dart'; import 'package:toolbox/core/extension/context/dialog.dart';
import 'package:toolbox/core/extension/stringx.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/core/utils/platform/base.dart';
import 'package:toolbox/data/res/provider.dart'; import 'package:toolbox/data/res/provider.dart';
import 'package:toolbox/data/res/rebuild.dart'; import 'package:toolbox/data/res/rebuild.dart';
@@ -100,9 +102,8 @@ class _SettingPageState extends State<SettingPage> {
appBar: CustomAppBar( appBar: CustomAppBar(
title: Text(l10n.setting), title: Text(l10n.setting),
actions: [ actions: [
Padding( const Icon(Icons.delete)
padding: const EdgeInsets.only(right: 17), .tap(
child: InkWell(
onTap: () => context.showRoundDialog( onTap: () => context.showRoundDialog(
title: Text(l10n.attention), title: Text(l10n.attention),
child: Text(l10n.askContinue( child: Text(l10n.askContinue(
@@ -146,9 +147,8 @@ class _SettingPageState extends State<SettingPage> {
), ),
], ],
), ),
child: const Icon(Icons.delete), )
), .padding(const EdgeInsets.only(right: 17)),
),
], ],
), ),
body: ListView( body: ListView(
@@ -198,7 +198,7 @@ class _SettingPageState extends State<SettingPage> {
children.add(_buildPlatformSetting()); children.add(_buildPlatformSetting());
} }
return Column( return Column(
children: children.map((e) => CardX(e)).toList(), children: children.map((e) => CardX(child: e)).toList(),
); );
} }
@@ -208,7 +208,7 @@ class _SettingPageState extends State<SettingPage> {
_buildFullScreenSwitch(), _buildFullScreenSwitch(),
_buildFullScreenJitter(), _buildFullScreenJitter(),
_buildFulScreenRotateQuarter(), _buildFulScreenRotateQuarter(),
].map((e) => CardX(e)).toList(), ].map((e) => CardX(child: e)).toList(),
); );
} }
@@ -223,7 +223,7 @@ class _SettingPageState extends State<SettingPage> {
//_buildDiskIgnorePath(), //_buildDiskIgnorePath(),
_buildDeleteServers(), _buildDeleteServers(),
//if (isDesktop) _buildDoubleColumnServersPage(), //if (isDesktop) _buildDoubleColumnServersPage(),
].map((e) => CardX(e)).toList(), ].map((e) => CardX(child: e)).toList(),
); );
} }
@@ -236,7 +236,7 @@ class _SettingPageState extends State<SettingPage> {
// Use hardware keyboard on desktop, so there is no need to set it // Use hardware keyboard on desktop, so there is no need to set it
if (isMobile) _buildKeyboardType(), if (isMobile) _buildKeyboardType(),
_buildSSHVirtKeys(), _buildSSHVirtKeys(),
].map((e) => CardX(e)).toList(), ].map((e) => CardX(child: e)).toList(),
); );
} }
@@ -247,7 +247,7 @@ class _SettingPageState extends State<SettingPage> {
_buildEditorTheme(), _buildEditorTheme(),
_buildEditorDarkTheme(), _buildEditorDarkTheme(),
_buildEditorHighlight(), _buildEditorHighlight(),
].map((e) => CardX(e)).toList(), ].map((e) => CardX(child: e)).toList(),
); );
} }
@@ -267,7 +267,7 @@ class _SettingPageState extends State<SettingPage> {
return ListTile( return ListTile(
title: Text(l10n.autoCheckUpdate), title: Text(l10n.autoCheckUpdate),
subtitle: Text(display, style: UIs.textGrey), subtitle: Text(display, style: UIs.textGrey),
onTap: () => doUpdate(ctx), onTap: () => Funcs.throttle(() => doUpdate(ctx)),
trailing: StoreSwitch(prop: _setting.autoCheckAppUpdate), trailing: StoreSwitch(prop: _setting.autoCheckAppUpdate),
); );
}, },
@@ -861,7 +861,7 @@ class _SettingPageState extends State<SettingPage> {
children: [ children: [
_buildSftpRmrDir(), _buildSftpRmrDir(),
_buildSftpOpenLastPath(), _buildSftpOpenLastPath(),
].map((e) => CardX(e)).toList(), ].map((e) => CardX(child: e)).toList(),
); );
} }

View File

@@ -45,7 +45,7 @@ class _IOSSettingsPageState extends State<IOSSettingsPage> {
_buildWatchApp(), _buildWatchApp(),
if (BioAuth.isPlatformSupported) if (BioAuth.isPlatformSupported)
PlatformPublicSettings.buildBioAuth(), PlatformPublicSettings.buildBioAuth(),
].map((e) => CardX(e)).toList(), ].map((e) => CardX(child: e)).toList(),
), ),
); );
} }

View File

@@ -53,10 +53,12 @@ class _ServerDetailOrderPageState extends State<ServerDetailOrderPage> {
return ReorderableDelayedDragStartListener( return ReorderableDelayedDragStartListener(
key: ValueKey('$index'), key: ValueKey('$index'),
index: index, index: index,
child: CardX(ListTile( child: CardX(
child: ListTile(
title: Text(id), title: Text(id),
trailing: const Icon(Icons.drag_handle), trailing: const Icon(Icons.drag_handle),
)), ),
),
); );
} }
} }

View File

@@ -54,14 +54,16 @@ class _ServerOrderPageState extends State<ServerOrderPage> {
return ReorderableDelayedDragStartListener( return ReorderableDelayedDragStartListener(
key: ValueKey('$index'), key: ValueKey('$index'),
index: index, index: index,
child: CardX(ListTile( child: CardX(
child: ListTile(
title: Text(spi.name), title: Text(spi.name),
subtitle: Text(spi.id, style: UIs.textGrey), subtitle: Text(spi.id, style: UIs.textGrey),
leading: CircleAvatar( leading: CircleAvatar(
child: Text(spi.name[0]), child: Text(spi.name[0]),
), ),
trailing: const Icon(Icons.drag_handle), trailing: const Icon(Icons.drag_handle),
)), ),
),
); );
} }
} }

View File

@@ -43,7 +43,7 @@ class _SSHVirtKeySettingPageState extends State<SSHVirtKeySettingPage> {
final help = key.help; final help = key.help;
return CardX( return CardX(
key: ValueKey(idx), key: ValueKey(idx),
ListTile( child: ListTile(
title: _buildTitle(key), title: _buildTitle(key),
subtitle: help == null ? null : Text(help, style: UIs.textGrey), subtitle: help == null ? null : Text(help, style: UIs.textGrey),
leading: _buildCheckBox(keys, key, idx, idx < keys.length), leading: _buildCheckBox(keys, key, idx, idx < keys.length),

View File

@@ -94,7 +94,7 @@ class _SnippetListPageState extends State<SnippetListPage> {
Widget _buildSnippetItem(Snippet snippet) { Widget _buildSnippetItem(Snippet snippet) {
return CardX( return CardX(
ListTile( child: ListTile(
contentPadding: const EdgeInsets.only(left: 23, right: 17), contentPadding: const EdgeInsets.only(left: 23, right: 17),
title: Text( title: Text(
snippet.name, snippet.name,

View File

@@ -29,7 +29,7 @@ class SnippetResultPage extends StatelessWidget {
final item = results[index]; final item = results[index];
if (item == null) return UIs.placeholder; if (item == null) return UIs.placeholder;
return CardX( return CardX(
ExpandTile( child: ExpandTile(
initiallyExpanded: results.length == 1, initiallyExpanded: results.length == 1,
title: Text(item.dest ?? ''), title: Text(item.dest ?? ''),
subtitle: Text(item.time.toString(), style: UIs.textGrey), subtitle: Text(item.time.toString(), style: UIs.textGrey),

View File

@@ -9,6 +9,7 @@ import 'package:toolbox/core/extension/context/common.dart';
import 'package:toolbox/core/extension/context/dialog.dart'; import 'package:toolbox/core/extension/context/dialog.dart';
import 'package:toolbox/core/extension/context/locale.dart'; import 'package:toolbox/core/extension/context/locale.dart';
import 'package:toolbox/core/utils/platform/base.dart'; import 'package:toolbox/core/utils/platform/base.dart';
import 'package:toolbox/core/utils/server.dart';
import 'package:toolbox/core/utils/share.dart'; import 'package:toolbox/core/utils/share.dart';
import 'package:toolbox/data/model/server/server.dart'; import 'package:toolbox/data/model/server/server.dart';
import 'package:toolbox/data/model/server/snippet.dart'; import 'package:toolbox/data/model/server/snippet.dart';
@@ -58,7 +59,7 @@ class _SSHPageState extends State<SSHPage> with AutomaticKeepAliveClientMixin {
bool _isDark = false; bool _isDark = false;
Timer? _virtKeyLongPressTimer; Timer? _virtKeyLongPressTimer;
late final Server? _server = widget.spi.server; late final Server? _server = widget.spi.server;
late final SSHClient? _client = _server?.client; late SSHClient? _client = _server?.client;
Timer? _discontinuityTimer; Timer? _discontinuityTimer;
@override @override
@@ -329,9 +330,7 @@ class _SSHPageState extends State<SSHPage> with AutomaticKeepAliveClientMixin {
Future<void> _initTerminal() async { Future<void> _initTerminal() async {
_writeLn('Connecting...\r\n'); _writeLn('Connecting...\r\n');
if (_client == null) { _client ??= await genClient(widget.spi);
await Pros.server.refreshData(spi: widget.spi);
}
_writeLn('Starting shell...\r\n'); _writeLn('Starting shell...\r\n');
final session = await _client?.shell( final session = await _client?.shell(

View File

@@ -3,6 +3,7 @@ import 'package:provider/provider.dart';
import 'package:toolbox/core/extension/context/common.dart'; import 'package:toolbox/core/extension/context/common.dart';
import 'package:toolbox/core/extension/context/dialog.dart'; import 'package:toolbox/core/extension/context/dialog.dart';
import 'package:toolbox/core/extension/context/locale.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/provider/server.dart';
import 'package:toolbox/data/res/ui.dart'; import 'package:toolbox/data/res/ui.dart';
import 'package:toolbox/view/page/ssh/page.dart'; import 'package:toolbox/view/page/ssh/page.dart';
@@ -49,12 +50,9 @@ class _SSHTabPageState extends State<SSHTabPage>
children: [ children: [
Text(e), Text(e),
UIs.width7, UIs.width7,
InkWell( const Icon(Icons.close, size: 17)
borderRadius: BorderRadius.circular(17), .padding(const EdgeInsets.all(7))
child: const Padding( .tap(
padding: EdgeInsets.all(7),
child: Icon(Icons.close, size: 17),
),
onTap: () async { onTap: () async {
final confirm = await context.showRoundDialog<bool>( final confirm = await context.showRoundDialog<bool>(
title: Text(l10n.attention), title: Text(l10n.attention),
@@ -89,7 +87,8 @@ class _SSHTabPageState extends State<SSHTabPage>
padding: const EdgeInsets.all(7), padding: const EdgeInsets.all(7),
itemBuilder: (_, idx) { itemBuilder: (_, idx) {
final spi = pro.servers.toList()[idx].spi; final spi = pro.servers.toList()[idx].spi;
return CardX(ListTile( return CardX(
child: ListTile(
title: Text(spi.name), title: Text(spi.name),
subtitle: Text(spi.id, style: UIs.textGrey), subtitle: Text(spi.id, style: UIs.textGrey),
trailing: const Icon(Icons.chevron_right), trailing: const Icon(Icons.chevron_right),
@@ -109,7 +108,8 @@ class _SSHTabPageState extends State<SSHTabPage>
_refreshTabs(); _refreshTabs();
_tabController.animateTo(_tabIds.length - 1); _tabController.animateTo(_tabIds.length - 1);
}, },
)); ),
);
}, },
itemCount: pro.servers.length, itemCount: pro.servers.length,
); );

View File

@@ -139,13 +139,15 @@ class _LocalStoragePageState extends State<LocalStoragePage> {
var stat = file.statSync(); var stat = file.statSync();
var isDir = stat.type == FileSystemEntityType.directory; var isDir = stat.type == FileSystemEntityType.directory;
return CardX(ListTile( return CardX(
child: ListTile(
leading: isDir leading: isDir
? const Icon(Icons.folder) ? const Icon(Icons.folder)
: const Icon(Icons.insert_drive_file), : const Icon(Icons.insert_drive_file),
title: Text(fileName), title: Text(fileName),
subtitle: subtitle: isDir
isDir ? null : Text(stat.size.convertBytes, style: UIs.textGrey), ? null
: Text(stat.size.convertBytes, style: UIs.textGrey),
trailing: Text( trailing: Text(
stat.modified stat.modified
.toString() .toString()
@@ -164,7 +166,8 @@ class _LocalStoragePageState extends State<LocalStoragePage> {
_path!.update(fileName); _path!.update(fileName);
setState(() {}); setState(() {});
}, },
)); ),
);
}, },
); );
} }

View File

@@ -264,7 +264,8 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
style: UIs.textGrey, style: UIs.textGrey,
textAlign: TextAlign.right, textAlign: TextAlign.right,
); );
return CardX(ListTile( return CardX(
child: ListTile(
leading: Icon(isDir ? Icons.folder : Icons.insert_drive_file), leading: Icon(isDir ? Icons.folder : Icons.insert_drive_file),
title: Text(file.filename), title: Text(file.filename),
trailing: trailing, trailing: trailing,
@@ -283,7 +284,8 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
} }
}, },
onLongPress: () => _onItemPress(file, !isDir), onLongPress: () => _onItemPress(file, !isDir),
)); ),
);
} }
void _onItemPress(SftpName file, bool notDir) { void _onItemPress(SftpName file, bool notDir) {

View File

@@ -134,7 +134,7 @@ class _SftpMissionPageState extends State<SftpMissionPage> {
}) { }) {
final time = DateTime.fromMicrosecondsSinceEpoch(status.id); final time = DateTime.fromMicrosecondsSinceEpoch(status.id);
return CardX( return CardX(
ListTile( child: ListTile(
leading: Text(time.hourMinute), leading: Text(time.hourMinute),
title: Text( title: Text(
status.fileName, status.fileName,

View File

@@ -1,7 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class CardX extends StatelessWidget { class CardX extends StatelessWidget {
const CardX(this.child, {super.key, this.color}); const CardX({super.key, required this.child, this.color});
final Widget child; final Widget child;
final Color? color; final Color? color;

View File

@@ -58,7 +58,7 @@ class _InputState extends State<Input> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return CardX( return CardX(
Padding( child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 17), padding: const EdgeInsets.symmetric(horizontal: 17),
child: TextField( child: TextField(
controller: widget.controller, controller: widget.controller,

View File

@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:toolbox/core/extension/context/common.dart'; import 'package:toolbox/core/extension/context/common.dart';
import 'package:toolbox/core/extension/context/dialog.dart'; import 'package:toolbox/core/extension/context/dialog.dart';
import 'package:toolbox/core/extension/context/locale.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/data/res/ui.dart';
import 'package:toolbox/view/widget/input_field.dart'; import 'package:toolbox/view/widget/input_field.dart';
import 'package:toolbox/view/widget/cardx.dart'; import 'package:toolbox/view/widget/cardx.dart';
@@ -56,16 +57,17 @@ class TagEditor extends StatefulWidget {
class _TagEditorState extends State<TagEditor> { class _TagEditorState extends State<TagEditor> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return CardX(ListTile( return CardX(
child: ListTile(
leading: const Icon(Icons.tag), leading: const Icon(Icons.tag),
title: _buildTags(widget.tags), title: _buildTags(widget.tags),
trailing: InkWell( trailing: const Icon(Icons.add).tap(
child: const Icon(Icons.add),
onTap: () { onTap: () {
_showAddTagDialog(); _showAddTagDialog();
}, },
), ),
)); ),
);
} }
Widget _buildTags(List<String> tags) { Widget _buildTags(List<String> tags) {
@@ -176,7 +178,7 @@ class _TagEditorState extends State<TagEditor> {
} }
} }
class TagSwitcher extends StatelessWidget { class TagSwitcher extends StatelessWidget implements PreferredSizeWidget {
final List<String> tags; final List<String> tags;
final double width; final double width;
final void Function(String?) onTagChanged; final void Function(String?) onTagChanged;
@@ -199,6 +201,7 @@ class TagSwitcher extends StatelessWidget {
return Container( return Container(
height: _kTagBtnHeight, height: _kTagBtnHeight,
width: width, width: width,
padding: const EdgeInsets.symmetric(horizontal: 7),
alignment: Alignment.center, alignment: Alignment.center,
color: Colors.transparent, color: Colors.transparent,
child: ListView.builder( child: ListView.builder(
@@ -215,6 +218,9 @@ class TagSwitcher extends StatelessWidget {
), ),
); );
} }
@override
Size get preferredSize => const Size.fromHeight(_kTagBtnHeight);
} }
Widget _wrap( Widget _wrap(
@@ -228,15 +234,9 @@ Widget _wrap(
borderRadius: const BorderRadius.all(Radius.circular(20.0)), borderRadius: const BorderRadius.all(Radius.circular(20.0)),
child: Material( child: Material(
color: primaryColor.withAlpha(20), color: primaryColor.withAlpha(20),
child: InkWell( child: child.padding(const EdgeInsets.fromLTRB(11.7, 2.7, 11.7, 0)).tap(
onTap: onTap, onTap: onTap,
onLongPress: onLongPress, onLongTap: onLongPress,
child: Padding(
/// Hard coded padding
/// For centering the text
padding: const EdgeInsets.fromLTRB(11.7, 2.7, 11.7, 0),
child: child,
),
), ),
), ),
), ),