diff --git a/.vscode/launch.json b/.vscode/launch.json index c3691ce3..879a7789 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -13,7 +13,11 @@ "name": "toolbox (profile mode)", "request": "launch", "type": "dart", - "flutterMode": "profile" + "flutterMode": "profile", + "args": [ + "--cache-sksl", + // "--purge-persistent-cache" + ] } ] } \ No newline at end of file diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 08f4e706..a35e4417 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -354,7 +354,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = 76; + CURRENT_PROJECT_VERSION = 77; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; @@ -362,7 +362,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.76; + MARKETING_VERSION = 1.0.77; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -484,7 +484,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = 76; + CURRENT_PROJECT_VERSION = 77; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; @@ -492,7 +492,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.76; + MARKETING_VERSION = 1.0.77; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -508,7 +508,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = 76; + CURRENT_PROJECT_VERSION = 77; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; @@ -516,7 +516,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.76; + MARKETING_VERSION = 1.0.77; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; diff --git a/lib/data/provider/server.dart b/lib/data/provider/server.dart index 51f55fc7..d0608d14 100644 --- a/lib/data/provider/server.dart +++ b/lib/data/provider/server.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'dart:convert'; import 'package:dartssh2/dartssh2.dart'; +import 'package:flutter/foundation.dart'; import 'package:logging/logging.dart'; import 'package:toolbox/core/extension/stringx.dart'; import 'package:toolbox/core/provider_base.dart'; @@ -20,6 +21,12 @@ import 'package:toolbox/data/store/server.dart'; import 'package:toolbox/data/store/setting.dart'; import 'package:toolbox/locator.dart'; +/// Must put this func out of any Class +/// https://stackoverflow.com/questions/51998995/invalid-arguments-illegal-argument-in-isolate-message-object-is-a-closure +List loadIndentity(Map auth) { + return SSHKeyPair.fromPem(auth['privateKey'], auth['passphrase']); +} + class ServerProvider extends BusyProvider { List _servers = []; List get servers => _servers; @@ -72,8 +79,7 @@ class ServerProvider extends BusyProvider { } final auth = spi.authorization as Map; return SSHClient(socket, - username: spi.user, - identities: SSHKeyPair.fromPem(auth['privateKey'], auth['passphrase'])); + username: spi.user, identities: await compute(loadIndentity, auth)); } Future refreshData({int? idx}) async { @@ -104,7 +110,6 @@ class ServerProvider extends BusyProvider { locator().serverStatusUpdateInterval.fetch()!; if (duration == 0) return; stopAutoRefresh(); - Future.delayed(const Duration(milliseconds: 677), () => refreshData()); _timer = Timer.periodic(Duration(seconds: duration), (_) async { await refreshData(); }); diff --git a/lib/data/res/build_data.dart b/lib/data/res/build_data.dart index 7301c779..428ffb0e 100644 --- a/lib/data/res/build_data.dart +++ b/lib/data/res/build_data.dart @@ -2,8 +2,9 @@ class BuildData { static const String name = "ToolBox"; - static const int build = 79; - static const String engine = "Flutter 2.8.1 • channel stable • https://github.com/flutter/flutter.git\nFramework • revision 77d935af4d (3 weeks ago) • 2021-12-16 08:37:33 -0800\nEngine • revision 890a5fca2e\nTools • Dart 2.15.1\n"; - static const String buildAt = "2022-01-09 23:06:53.086748"; - static const int modifications = 0; + static const int build = 77; + static const String engine = + "Flutter 2.8.1 • channel stable • https://github.com/flutter/flutter.git\nFramework • revision 77d935af4d (3 weeks ago) • 2021-12-16 08:37:33 -0800\nEngine • revision 890a5fca2e\nTools • Dart 2.15.1\n"; + static const String buildAt = "2022-01-10 10:55:03.676581"; + static const int modifications = 7; } diff --git a/lib/view/page/convert.dart b/lib/view/page/convert.dart index cc7172fa..a5551db5 100644 --- a/lib/view/page/convert.dart +++ b/lib/view/page/convert.dart @@ -3,6 +3,7 @@ import 'dart:convert'; import 'package:clipboard/clipboard.dart'; import 'package:flutter/material.dart'; import 'package:flutter_staggered_animations/flutter_staggered_animations.dart'; +import 'package:toolbox/core/utils.dart'; import 'package:toolbox/data/res/color.dart'; class ConvertPage extends StatefulWidget { @@ -70,7 +71,11 @@ class _ConvertPageState extends State ), floatingActionButton: FloatingActionButton( onPressed: () { - _textEditingControllerResult.text = doConvert(); + try { + _textEditingControllerResult.text = doConvert(); + } catch (e) { + showSnackBar(context, Text('Error: \n$e')); + } }, tooltip: 'convert', child: const Icon(Icons.send), @@ -79,7 +84,7 @@ class _ConvertPageState extends State } String doConvert() { - final text = _textEditingController.text; + final text = _textEditingController.text.trim(); switch (_typeOptionIndex) { case 0: return utf8.decode(base64.decode(text)); diff --git a/lib/view/page/server/detail.dart b/lib/view/page/server/detail.dart index 4e684785..47c1721a 100644 --- a/lib/view/page/server/detail.dart +++ b/lib/view/page/server/detail.dart @@ -35,8 +35,8 @@ class _ServerDetailPageState extends State @override Widget build(BuildContext context) { return Consumer(builder: (_, provider, __) { - return _buildMainPage( - provider.servers.firstWhere((e) => '${e.info.ip}:${e.info.port}' == widget.id)); + return _buildMainPage(provider.servers + .firstWhere((e) => '${e.info.ip}:${e.info.port}' == widget.id)); }); } @@ -44,16 +44,6 @@ class _ServerDetailPageState extends State return Scaffold( appBar: AppBar( title: Text(si.info.name), - actions: [ - IconButton( - onPressed: () => AppRoute( - ServerEditPage( - spi: si.info, - ), - 'Edit server info page') - .go(context), - icon: const Icon(Icons.edit)) - ], ), body: ListView( padding: const EdgeInsets.all(17), diff --git a/lib/view/page/server/tab.dart b/lib/view/page/server/tab.dart index 5100bed0..0bc2cfe5 100644 --- a/lib/view/page/server/tab.dart +++ b/lib/view/page/server/tab.dart @@ -115,8 +115,10 @@ class _ServerPageState extends State .go(context), child: Padding( padding: const EdgeInsets.all(13), - child: - _buildRealServerCard(si.status, si.info.name, si.connectionState), + child: SizedBox( + height: _media.size.height * 0.147, + child: _buildRealServerCard( + si.status, si.info.name, si.connectionState)), ), onTap: () => AppRoute(ServerDetailPage('${si.info.ip}:${si.info.port}'), 'server detail page') @@ -239,7 +241,7 @@ class _ServerPageState extends State Widget _buildPercentCircle(double percent, String title) { if (percent <= 0) percent = 0.01; if (percent >= 100) percent = 99.9; - var size = _media.size.height * 0.147; + var size = _media.size.height * 0.15; return SizedBox( width: _media.size.width * 0.2, height: _media.size.height * 0.1, @@ -285,6 +287,7 @@ class _ServerPageState extends State Future afterFirstLayout(BuildContext context) async { await GetIt.I.allReady(); await _serverProvider.loadLocalData(); + _serverProvider.refreshData(); _serverProvider.startAutoRefresh(); } }