diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 1da0c949..a595bb87 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -586,7 +586,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 738; + CURRENT_PROJECT_VERSION = 740; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -596,7 +596,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.738; + MARKETING_VERSION = 1.0.740; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -720,7 +720,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 738; + CURRENT_PROJECT_VERSION = 740; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -730,7 +730,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.738; + MARKETING_VERSION = 1.0.740; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -748,7 +748,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 738; + CURRENT_PROJECT_VERSION = 740; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -758,7 +758,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.738; + MARKETING_VERSION = 1.0.740; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -779,7 +779,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 738; + CURRENT_PROJECT_VERSION = 740; DEVELOPMENT_TEAM = BA88US33G6; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -792,7 +792,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 1.0.738; + MARKETING_VERSION = 1.0.740; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; @@ -818,7 +818,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 738; + CURRENT_PROJECT_VERSION = 740; DEVELOPMENT_TEAM = BA88US33G6; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -831,7 +831,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 1.0.738; + MARKETING_VERSION = 1.0.740; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -854,7 +854,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 738; + CURRENT_PROJECT_VERSION = 740; DEVELOPMENT_TEAM = BA88US33G6; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -867,7 +867,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 1.0.738; + MARKETING_VERSION = 1.0.740; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -890,7 +890,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 738; + CURRENT_PROJECT_VERSION = 740; DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_PREVIEWS = YES; @@ -902,7 +902,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.738; + MARKETING_VERSION = 1.0.740; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd; @@ -931,7 +931,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 738; + CURRENT_PROJECT_VERSION = 740; DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_PREVIEWS = YES; @@ -943,7 +943,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.738; + MARKETING_VERSION = 1.0.740; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd; PRODUCT_NAME = ServerBox; @@ -969,7 +969,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 738; + CURRENT_PROJECT_VERSION = 740; DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_PREVIEWS = YES; @@ -981,7 +981,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.738; + MARKETING_VERSION = 1.0.740; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd; PRODUCT_NAME = ServerBox; diff --git a/lib/app.dart b/lib/app.dart index 140f2260..b2107a98 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -9,7 +9,6 @@ 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 'package:toolbox/view/page/full_screen.dart'; import 'package:toolbox/view/page/home.dart'; class MyApp extends StatelessWidget { @@ -76,9 +75,7 @@ class MyApp extends StatelessWidget { themeMode: themeMode, theme: light, darkTheme: tMode < 3 ? dark : _getAmoledTheme(dark), - home: Stores.setting.fullScreen.fetch() - ? const FullScreenPage() - : const HomePage(), + home: const HomePage(), ); } } diff --git a/lib/core/route.dart b/lib/core/route.dart index 2cae0eb6..336e7355 100644 --- a/lib/core/route.dart +++ b/lib/core/route.dart @@ -21,7 +21,6 @@ import 'package:toolbox/view/page/storage/local.dart'; import '../data/model/server/snippet.dart'; import '../view/page/debug.dart'; import '../view/page/editor.dart'; -import '../view/page/full_screen.dart'; import '../view/page/process.dart'; import '../view/page/server/edit.dart'; import '../view/page/server/tab.dart'; @@ -175,9 +174,9 @@ class AppRoute { 'editor'); } - static AppRoute fullscreen({Key? key}) { - return AppRoute(FullScreenPage(key: key), 'fullscreen'); - } + // static AppRoute fullscreen({Key? key}) { + // return AppRoute(FullScreenPage(key: key), 'fullscreen'); + // } static AppRoute home({Key? key}) { return AppRoute(HomePage(key: key), 'home'); diff --git a/lib/core/utils/sync/icloud.dart b/lib/core/utils/sync/icloud.dart index 2f67d650..8928c161 100644 --- a/lib/core/utils/sync/icloud.dart +++ b/lib/core/utils/sync/icloud.dart @@ -28,20 +28,26 @@ abstract final class ICloud { String? localPath, }) async { final completer = Completer(); - await ICloudStorage.upload( - containerId: _containerId, - filePath: localPath ?? '${await Paths.doc}/$relativePath', - destinationRelativePath: relativePath, - onProgress: (stream) { - stream.listen( - null, - onDone: () => completer.complete(null), - onError: (e) => completer.complete( - ICloudErr(type: ICloudErrType.generic, message: '$e'), - ), - ); - }, - ); + try { + await ICloudStorage.upload( + containerId: _containerId, + filePath: localPath ?? '${await Paths.doc}/$relativePath', + destinationRelativePath: relativePath, + onProgress: (stream) { + stream.listen( + null, + onDone: () => completer.complete(null), + onError: (e) => completer.complete( + ICloudErr(type: ICloudErrType.generic, message: '$e'), + ), + ); + }, + ); + } catch (e, s) { + _logger.warning('Upload $relativePath failed', e, s); + completer.complete(ICloudErr(type: ICloudErrType.generic, message: '$e')); + } + return completer.future; } @@ -52,10 +58,14 @@ abstract final class ICloud { } static Future delete(String relativePath) async { - await ICloudStorage.delete( - containerId: _containerId, - relativePath: relativePath, - ); + try { + await ICloudStorage.delete( + containerId: _containerId, + relativePath: relativePath, + ); + } catch (e, s) { + _logger.warning('Delete $relativePath failed', e, s); + } } /// Download file from iCloud diff --git a/lib/data/model/container/version.dart b/lib/data/model/container/version.dart index d199d913..2e021a71 100644 --- a/lib/data/model/container/version.dart +++ b/lib/data/model/container/version.dart @@ -26,9 +26,7 @@ class ContainerdClient { final String version; final String goVersion; final String gitCommit; - final String? builtTime; - final int? built; // more fields should be marked nullable - final String? osArch; + final String builtTime; final String os; ContainerdClient({ @@ -37,8 +35,6 @@ class ContainerdClient { required this.goVersion, required this.gitCommit, required this.builtTime, - required this.built, - required this.osArch, required this.os, }); @@ -49,13 +45,11 @@ class ContainerdClient { factory ContainerdClient.fromJson(Map json) => ContainerdClient( - apiVersion: json["ApiVersion"], + apiVersion: json["ApiVersion"], version: json["Version"], goVersion: json["GoVersion"], gitCommit: json["GitCommit"], builtTime: json["BuildTime"], - built: json["Built"], // should be Build? - osArch: json["OsArch"], os: json["Os"], ); @@ -65,8 +59,6 @@ class ContainerdClient { "GoVersion": goVersion, "GitCommit": gitCommit, "BuildTime": builtTime, - "Built": built, - "OsArch": osArch, "Os": os, }; } diff --git a/lib/data/provider/container.dart b/lib/data/provider/container.dart index 7514aa38..0ee4c30b 100644 --- a/lib/data/provider/container.dart +++ b/lib/data/provider/container.dart @@ -139,7 +139,6 @@ class ContainerProvider extends ChangeNotifier { try { final imgLines = imageRaw.split('\n'); imgLines.removeWhere((element) => element.isEmpty); - if (imgLines.isNotEmpty) imgLines.removeAt(0); images = imgLines.map((e) => ContainerImg.fromRawJson(e, type)).toList(); } catch (e, trace) { error = ContainerErr( diff --git a/lib/data/res/build_data.dart b/lib/data/res/build_data.dart index 92e3a8b0..a215593e 100644 --- a/lib/data/res/build_data.dart +++ b/lib/data/res/build_data.dart @@ -2,9 +2,9 @@ class BuildData { static const String name = "ServerBox"; - static const int build = 738; + static const int build = 740; static const String engine = "3.16.9"; - static const String buildAt = "2024-02-02 19:59:49"; - static const int modifications = 6; + static const String buildAt = "2024-02-02 22:52:02"; + static const int modifications = 2; static const int script = 37; } diff --git a/lib/data/res/github_id.dart b/lib/data/res/github_id.dart index d9cd4813..574f0853 100644 --- a/lib/data/res/github_id.dart +++ b/lib/data/res/github_id.dart @@ -4,6 +4,7 @@ abstract final class GithubIds { // Thanks // If you want to change your Github ID, please open an issue. static const contributors = { + 'PaperCube', 'its-tom', 'azkadev', 'kalashnikov', @@ -57,5 +58,6 @@ abstract final class GithubIds { 'bxoooooo', 'KatharsisKing', 'mervinniu', + 'L-Super', }; } diff --git a/lib/data/store/setting.dart b/lib/data/store/setting.dart index bf041504..0691c1c6 100644 --- a/lib/data/store/setting.dart +++ b/lib/data/store/setting.dart @@ -100,7 +100,7 @@ class SettingStore extends PersistentStore { late final termFontSize = property('termFontSize', 13.0); // Locale - late final locale = property('locale', ''); + late final locale = property('locale', ''); // SSH virtual key (ctrl | alt) auto turn off late final sshVirtualKeyAutoOff = property('sshVirtualKeyAutoOff', true); @@ -118,20 +118,20 @@ class SettingStore extends PersistentStore { Defaults.editorDarkTheme, ); - late final fullScreen = property( - 'fullScreen', - false, - ); + // late final fullScreen = property( + // 'fullScreen', + // false, + // ); - late final fullScreenJitter = property( - 'fullScreenJitter', - true, - ); + // late final fullScreenJitter = property( + // 'fullScreenJitter', + // true, + // ); - late final fullScreenRotateQuarter = property( - 'fullScreenRotateQuarter', - 1, - ); + // late final fullScreenRotateQuarter = property( + // 'fullScreenRotateQuarter', + // 1, + // ); late final keyboardType = property( 'keyboardType', diff --git a/lib/view/page/full_screen.dart b/lib/view/page/full_screen.dart deleted file mode 100644 index 36791d65..00000000 --- a/lib/view/page/full_screen.dart +++ /dev/null @@ -1,373 +0,0 @@ -import 'dart:async'; -import 'dart:math'; - -import 'package:after_layout/after_layout.dart'; -import 'package:circle_chart/circle_chart.dart'; -import 'package:flutter/material.dart'; -import 'package:get_it/get_it.dart'; -import 'package:provider/provider.dart'; -import 'package:toolbox/core/extension/context/locale.dart'; -import 'package:toolbox/core/route.dart'; -import 'package:toolbox/data/model/app/shell_func.dart'; -import 'package:toolbox/data/model/server/disk.dart'; -import 'package:toolbox/data/provider/server.dart'; -import 'package:toolbox/data/res/provider.dart'; -import 'package:toolbox/data/res/store.dart'; -import 'package:toolbox/data/res/ui.dart'; - -import '../../core/analysis.dart'; -import '../../core/update.dart'; -import '../../core/utils/ui.dart'; -import '../../data/model/app/net_view.dart'; -import '../../data/model/server/server.dart'; -import '../../data/model/server/server_private_info.dart'; -import '../../data/res/color.dart'; - -class FullScreenPage extends StatefulWidget { - const FullScreenPage({super.key}); - - @override - _FullScreenPageState createState() => _FullScreenPageState(); -} - -class _FullScreenPageState extends State with AfterLayoutMixin { - late MediaQueryData _media; - late ThemeData _theme; - late Timer _timer; - late int _rotateQuarter; - - final _pageController = PageController(initialPage: 0); - - @override - void initState() { - super.initState(); - switchStatusBar(hide: true); - _rotateQuarter = Stores.setting.fullScreenRotateQuarter.fetch(); - _timer = Timer.periodic(const Duration(minutes: 1), (_) { - if (mounted) { - setState(() {}); - } else { - _timer.cancel(); - } - }); - } - - @override - void dispose() { - super.dispose(); - _timer.cancel(); - _pageController.dispose(); - } - - @override - void didChangeDependencies() { - super.didChangeDependencies(); - _media = MediaQuery.of(context); - _theme = Theme.of(context); - } - - double get _offset { - // based on screen width - final x = _screenWidth * 0.03; - final r = Random().nextDouble(); - final n = Random().nextBool() ? -1 : 1; - return n * x * r; - } - - @override - Widget build(BuildContext context) { - final offset = Offset(_offset, _offset); - return Scaffold( - body: SafeArea( - child: Padding( - // Avoid display cutout - // `_screenWidth * 0.03` is the offset value - padding: EdgeInsets.all(_screenWidth * 0.03), - child: ValueListenableBuilder( - valueListenable: - Stores.setting.fullScreenRotateQuarter.listenable(), - builder: (_, val, __) { - _rotateQuarter = val; - return RotatedBox( - quarterTurns: val, - child: Transform.translate( - offset: offset, - child: Stack( - children: [ - _buildMain(), - Positioned( - top: 0, - left: 0, - child: _buildSettingBtn(), - ), - ], - ), - ), - ); - }, - ), - ), - ), - ); - } - - double get _screenWidth => - _rotateQuarter % 2 == 0 ? _media.size.width : _media.size.height; - double get _screenHeight => - _rotateQuarter % 2 == 0 ? _media.size.height : _media.size.width; - - Widget _buildSettingBtn() { - return IconButton( - onPressed: () => AppRoute.settings().go(context), - icon: const Icon(Icons.settings, color: Colors.grey)); - } - - Widget _buildMain() { - return Consumer(builder: (_, pro, __) { - if (pro.serverOrder.isEmpty) { - return Center( - child: TextButton( - onPressed: () => AppRoute.serverEdit().go(context), - child: Text( - l10n.addAServer, - style: const TextStyle(fontSize: 27), - )), - ); - } - return PageView.builder( - controller: _pageController, - itemCount: pro.serverOrder.length, - itemBuilder: (_, idx) { - final s = pro.pick(id: pro.serverOrder[idx]); - if (s == null) { - return Center(child: Text(l10n.noClient)); - } - return _buildRealServerCard(s.status, s.state, s.spi); - }, - ); - }); - } - - Widget _buildRealServerCard( - ServerStatus ss, - ServerState cs, - ServerPrivateInfo spi, - ) { - final rootDisk = findRootDisk(ss.disk); - - return InkWell( - onTap: () => AppRoute.serverDetail(spi: spi).go(context), - child: Stack( - children: [ - Positioned( - top: 0, - left: 0, - right: 0, - child: _buildServerCardTitle(ss, cs, spi)), - Column( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - SizedBox(height: _screenWidth * 0.1), - Row( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - _buildPercentCircle(ss.cpu.usedPercent()), - _buildPercentCircle(ss.mem.usedPercent * 100), - _buildNet(ss), - _buildIOData( - 'Total:\n${rootDisk?.size}', - 'Used:\n${rootDisk?.usedPercent}%', - ) - ], - ), - SizedBox(height: _screenWidth * 0.1), - Row( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - _buildExplainText('CPU'), - _buildExplainText('Mem'), - _buildExplainText('Net'), - _buildExplainText('Disk'), - ], - ), - ], - ), - ], - ), - ); - } - - Widget _buildServerCardTitle( - ServerStatus ss, - ServerState cs, - ServerPrivateInfo spi, - ) { - return Padding( - padding: EdgeInsets.symmetric(vertical: _screenWidth * 0.05), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - UIs.height13, - Row( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - spi.name, - style: const TextStyle( - fontWeight: FontWeight.bold, - fontSize: 19, - ), - textAlign: TextAlign.center, - ), - const Icon( - Icons.keyboard_arrow_right, - size: 21, - color: Colors.grey, - ) - ], - ), - UIs.height13, - _buildTopRightText(ss, cs), - ], - ), - ); - } - - Widget _buildTopRightText(ServerStatus ss, ServerState cs) { - final topRightStr = _getTopRightStr( - cs, - ss.temps.first, - ss.more[StatusCmdType.uptime] ?? '', - ss.err, - ); - return Text( - topRightStr, - style: UIs.text11Grey, - ); - } - - Widget _buildExplainText(String text) { - return SizedBox( - width: _screenHeight * 0.2, - child: Text( - text, - style: const TextStyle(fontSize: 13), - textAlign: TextAlign.center, - ), - ); - } - - String _getTopRightStr( - ServerState cs, - double? temp, - String upTime, - String? failedInfo, - ) { - switch (cs) { - case ServerState.disconnected: - return l10n.disconnected; - case ServerState.connected: - final tempStr = temp == null ? '' : '${temp.toStringAsFixed(1)}°C'; - final items = [tempStr, upTime]; - final str = items.where((element) => element.isNotEmpty).join(' | '); - if (str.isEmpty) return l10n.serverTabLoading; - return str; - case ServerState.connecting: - return l10n.serverTabConnecting; - case ServerState.failed: - if (failedInfo == null) { - return l10n.serverTabFailed; - } - if (failedInfo.contains('encypted')) { - return l10n.serverTabPlzSave; - } - return failedInfo; - default: - return l10n.serverTabUnkown; - } - } - - Widget _buildNet(ServerStatus ss) { - return ValueListenableBuilder( - valueListenable: Stores.setting.netViewType.listenable(), - builder: (_, val, __) { - final (a, b) = val.build(ss); - return AnimatedSwitcher( - duration: const Duration(milliseconds: 177), - child: _buildIOData(a, b), - ); - }, - ); - } - - Widget _buildIOData(String up, String down) { - final statusTextStyle = TextStyle( - fontSize: 13, color: _theme.textTheme.bodyLarge!.color!.withAlpha(177)); - return SizedBox( - width: _screenHeight * 0.23, - child: Column( - children: [ - const SizedBox(height: 5), - Text( - up, - style: statusTextStyle, - textAlign: TextAlign.center, - ), - const SizedBox(height: 3), - Text( - down, - style: statusTextStyle, - textAlign: TextAlign.center, - ) - ], - ), - ); - } - - Widget _buildPercentCircle(double percent) { - if (percent <= 0) percent = 0.01; - if (percent >= 100) percent = 99.9; - return SizedBox( - width: _screenHeight * 0.23, - child: Stack( - children: [ - Center( - child: CircleChart( - progressColor: primaryColor, - progressNumber: percent, - animationDuration: const Duration(milliseconds: 377), - maxNumber: 100, - width: _screenWidth * 0.22, - height: _screenWidth * 0.22, - ), - ), - Positioned.fill( - child: Center( - child: Text( - '${percent.toStringAsFixed(1)}%', - textAlign: TextAlign.center, - style: const TextStyle(fontSize: 15), - ), - ), - ), - ], - ), - ); - } - - @override - Future afterFirstLayout(BuildContext context) async { - if (Stores.setting.autoCheckAppUpdate.fetch()) { - doUpdate(context); - } - await GetIt.I.allReady(); - await Pros.server.load(); - await Pros.server.refresh(); - if (!Analysis.enabled) { - await Analysis.init(); - } - } -} diff --git a/lib/view/page/private_key/edit.dart b/lib/view/page/private_key/edit.dart index 8ba6ada5..9ba9edc5 100644 --- a/lib/view/page/private_key/edit.dart +++ b/lib/view/page/private_key/edit.dart @@ -39,7 +39,7 @@ class _PrivateKeyEditPageState extends State { late FocusScopeNode _focusScope; - Widget? _loading; + final _loading = ValueNotifier(null); @override void initState() { @@ -134,9 +134,7 @@ class _PrivateKeyEditPageState extends State { return; } FocusScope.of(context).unfocus(); - setState(() { - _loading = UIs.centerSizedLoading; - }); + _loading.value = UIs.centerSizedLoading; try { final decrypted = await Computer.shared.start(decyptPem, [key, pwd]); final pki = PrivateKeyInfo(id: name, key: decrypted); @@ -149,9 +147,7 @@ class _PrivateKeyEditPageState extends State { context.showSnackBar(e.toString()); rethrow; } finally { - setState(() { - _loading = null; - }); + _loading.value = null; } context.pop(); }, @@ -219,7 +215,10 @@ class _PrivateKeyEditPageState extends State { icon: Icons.password, ), SizedBox(height: MediaQuery.of(context).size.height * 0.1), - _loading ?? UIs.placeholder, + ValueListenableBuilder( + valueListenable: _loading, + builder: (_, val, __) => val ?? UIs.placeholder, + ), ], ); } diff --git a/lib/view/page/setting/entry.dart b/lib/view/page/setting/entry.dart index 8c82921d..7405bcc7 100644 --- a/lib/view/page/setting/entry.dart +++ b/lib/view/page/setting/entry.dart @@ -51,7 +51,7 @@ class _SettingPageState extends State { final _editorThemeKey = GlobalKey>(); final _editorDarkThemeKey = GlobalKey>(); final _keyboardTypeKey = GlobalKey>(); - final _rotateQuarterKey = GlobalKey>(); + //final _rotateQuarterKey = GlobalKey>(); final _netViewTypeKey = GlobalKey>(); final _setting = Stores.setting; @@ -66,8 +66,8 @@ class _SettingPageState extends State { late final _editorTheme = ValueNotifier(_setting.editorTheme.fetch()); late final _editorDarkTheme = ValueNotifier(_setting.editorDarkTheme.fetch()); late final _keyboardType = ValueNotifier(_setting.keyboardType.fetch()); - late final _rotateQuarter = - ValueNotifier(_setting.fullScreenRotateQuarter.fetch()); + // late final _rotateQuarter = + // ValueNotifier(_setting.fullScreenRotateQuarter.fetch()); late final _netViewType = ValueNotifier(_setting.netViewType.fetch()); late final _textScaler = ValueNotifier(_setting.textFactor.fetch()); @@ -153,8 +153,8 @@ class _SettingPageState extends State { /// Fullscreen Mode is designed for old mobile phone which can be /// used as a status screen, so it's only available on mobile phone. - if (!isDesktop) _buildTitle(l10n.fullScreen), - if (!isDesktop) _buildFullScreen(), + // if (!isDesktop) _buildTitle(l10n.fullScreen), + // if (!isDesktop) _buildFullScreen(), const SizedBox(height: 37), ], ), @@ -191,15 +191,15 @@ class _SettingPageState extends State { ); } - Widget _buildFullScreen() { - return Column( - children: [ - _buildFullScreenSwitch(), - _buildFullScreenJitter(), - _buildFulScreenRotateQuarter(), - ].map((e) => CardX(child: e)).toList(), - ); - } + // Widget _buildFullScreen() { + // return Column( + // children: [ + // _buildFullScreenSwitch(), + // _buildFullScreenJitter(), + // _buildFulScreenRotateQuarter(), + // ].map((e) => CardX(child: e)).toList(), + // ); + // } Widget _buildServer() { return Column( @@ -227,7 +227,7 @@ class _SettingPageState extends State { _buildSSHVirtualKeyAutoOff(), // Use hardware keyboard on desktop, so there is no need to set it if (isMobile) _buildKeyboardType(), - _buildSSHVirtKeys(), + if (isMobile) _buildSSHVirtKeys(), ].map((e) => CardX(child: e)).toList(), ); } @@ -740,56 +740,56 @@ class _SettingPageState extends State { ); } - Widget _buildFullScreenSwitch() { - return ListTile( - title: Text(l10n.fullScreen), - trailing: StoreSwitch( - prop: _setting.fullScreen, - callback: (_) => RebuildNodes.app.rebuild(), - ), - ); - } + // Widget _buildFullScreenSwitch() { + // return ListTile( + // title: Text(l10n.fullScreen), + // trailing: StoreSwitch( + // prop: _setting.fullScreen, + // callback: (_) => RebuildNodes.app.rebuild(), + // ), + // ); + // } - Widget _buildFullScreenJitter() { - return ListTile( - title: Text(l10n.fullScreenJitter), - subtitle: Text(l10n.fullScreenJitterHelp, style: UIs.textGrey), - trailing: StoreSwitch(prop: _setting.fullScreenJitter), - ); - } + // Widget _buildFullScreenJitter() { + // return ListTile( + // title: Text(l10n.fullScreenJitter), + // subtitle: Text(l10n.fullScreenJitterHelp, style: UIs.textGrey), + // trailing: StoreSwitch(prop: _setting.fullScreenJitter), + // ); + // } - Widget _buildFulScreenRotateQuarter() { - final degrees = List.generate(4, (idx) => '${idx * 90}°').toList(); - final items = List.generate(4, (idx) { - return PopupMenuItem( - value: idx, - child: Text(degrees[idx]), - ); - }).toList(); + // Widget _buildFulScreenRotateQuarter() { + // final degrees = List.generate(4, (idx) => '${idx * 90}°').toList(); + // final items = List.generate(4, (idx) { + // return PopupMenuItem( + // value: idx, + // child: Text(degrees[idx]), + // ); + // }).toList(); - return ListTile( - title: Text(l10n.rotateAngel), - onTap: () { - _rotateQuarterKey.currentState?.showButtonMenu(); - }, - trailing: ListenableBuilder( - listenable: _rotateQuarter, - builder: (_, __) => PopupMenuButton( - key: _rotateQuarterKey, - itemBuilder: (BuildContext context) => items, - initialValue: _rotateQuarter.value, - onSelected: (int idx) { - _rotateQuarter.value = idx; - _setting.fullScreenRotateQuarter.put(idx); - }, - child: Text( - degrees[_rotateQuarter.value], - style: UIs.text15, - ), - ), - ), - ); - } + // return ListTile( + // title: Text(l10n.rotateAngel), + // onTap: () { + // _rotateQuarterKey.currentState?.showButtonMenu(); + // }, + // trailing: ListenableBuilder( + // listenable: _rotateQuarter, + // builder: (_, __) => PopupMenuButton( + // key: _rotateQuarterKey, + // itemBuilder: (BuildContext context) => items, + // initialValue: _rotateQuarter.value, + // onSelected: (int idx) { + // _rotateQuarter.value = idx; + // _setting.fullScreenRotateQuarter.put(idx); + // }, + // child: Text( + // degrees[_rotateQuarter.value], + // style: UIs.text15, + // ), + // ), + // ), + // ); + // } Widget _buildKeyboardType() { const List names = [ diff --git a/lib/view/page/setting/seq/srv_detail_seq.dart b/lib/view/page/setting/seq/srv_detail_seq.dart index 5601ce6a..b78a8356 100644 --- a/lib/view/page/setting/seq/srv_detail_seq.dart +++ b/lib/view/page/setting/seq/srv_detail_seq.dart @@ -17,6 +17,8 @@ class ServerDetailOrderPage extends StatefulWidget { } class _ServerDetailOrderPageState extends State { + final prop = Stores.setting.detailCardOrder; + @override Widget build(BuildContext context) { return Scaffold( @@ -28,36 +30,36 @@ class _ServerDetailOrderPageState extends State { } Widget _buildBody() { - final keys_ = Stores.setting.detailCardOrder.fetch(); - final keys = []; - for (final key in keys_) { - keys.add(key); - } - final disabled = - Defaults.detailCardOrder.where((e) => !keys.contains(e)).toList(); - final allKeys = [...keys, ...disabled]; - return ReorderableListView.builder( - padding: const EdgeInsets.all(7), - itemBuilder: (_, idx) { - final key = allKeys[idx]; - return CardX( - key: ValueKey(idx), - child: ListTile( - title: Text(key), - leading: _buildCheckBox(keys, key, idx, idx < keys.length), - trailing: isDesktop ? null : const Icon(Icons.drag_handle), - ), + return ValueListenableBuilder( + valueListenable: prop.listenable(), + builder: (_, vals, __) { + final keys = List.from(vals); + final disabled = + Defaults.detailCardOrder.where((e) => !keys.contains(e)).toList(); + final allKeys = [...keys, ...disabled]; + return ReorderableListView.builder( + padding: const EdgeInsets.all(7), + itemBuilder: (_, idx) { + final key = allKeys[idx]; + return CardX( + key: ValueKey(idx), + child: ListTile( + title: Text(key), + leading: _buildCheckBox(keys, key, idx, idx < keys.length), + trailing: isDesktop ? null : const Icon(Icons.drag_handle), + ), + ); + }, + itemCount: allKeys.length, + onReorder: (o, n) { + if (o >= keys.length || n >= keys.length) { + context.showSnackBar(l10n.disabled); + return; + } + keys.moveByItem(keys, o, n, property: prop); + }, ); }, - itemCount: allKeys.length, - onReorder: (o, n) { - if (o >= keys.length || n >= keys.length) { - context.showSnackBar(l10n.disabled); - return; - } - keys.moveByItem(keys, o, n, property: Stores.setting.detailCardOrder); - setState(() {}); - }, ); } @@ -75,8 +77,7 @@ class _ServerDetailOrderPageState extends State { } else { keys.remove(key); } - Stores.setting.detailCardOrder.put(keys); - setState(() {}); + prop.put(keys); }, ); } diff --git a/lib/view/page/setting/seq/srv_func_seq.dart b/lib/view/page/setting/seq/srv_func_seq.dart index 6d502b0a..3c275a5b 100644 --- a/lib/view/page/setting/seq/srv_func_seq.dart +++ b/lib/view/page/setting/seq/srv_func_seq.dart @@ -17,6 +17,8 @@ class ServerFuncBtnsOrderPage extends StatefulWidget { } class _ServerDetailOrderPageState extends State { + final prop = Stores.setting.serverFuncBtns; + @override Widget build(BuildContext context) { return Scaffold( @@ -28,38 +30,38 @@ class _ServerDetailOrderPageState extends State { } Widget _buildBody() { - final keys_ = Stores.setting.serverFuncBtns.fetch(); - final keys = []; - for (final key in keys_) { - keys.add(key); - } - final disabled = ServerFuncBtn.values - .map((e) => e.index) - .where((e) => !keys.contains(e)) - .toList(); - final allKeys = [...keys, ...disabled]; - return ReorderableListView.builder( - padding: const EdgeInsets.all(7), - itemBuilder: (_, idx) { - final key = allKeys[idx]; - return CardX( - key: ValueKey(idx), - child: ListTile( - title: Text(ServerFuncBtn.values[key].toStr), - leading: _buildCheckBox(keys, key, idx, idx < keys.length), - trailing: isDesktop ? null : const Icon(Icons.drag_handle), - ), + return ValueListenableBuilder( + valueListenable: prop.listenable(), + builder: (_, vals, __) { + final keys = List.from(vals); + final disabled = ServerFuncBtn.values + .map((e) => e.index) + .where((e) => !keys.contains(e)) + .toList(); + final allKeys = [...keys, ...disabled]; + return ReorderableListView.builder( + padding: const EdgeInsets.all(7), + itemBuilder: (_, idx) { + final key = allKeys[idx]; + return CardX( + key: ValueKey(idx), + child: ListTile( + title: Text(ServerFuncBtn.values[key].toStr), + leading: _buildCheckBox(keys, key, idx, idx < keys.length), + trailing: isDesktop ? null : const Icon(Icons.drag_handle), + ), + ); + }, + itemCount: allKeys.length, + onReorder: (o, n) { + if (o >= keys.length || n >= keys.length) { + context.showSnackBar(l10n.disabled); + return; + } + keys.moveByItem(keys, o, n, property: prop); + }, ); }, - itemCount: allKeys.length, - onReorder: (o, n) { - if (o >= keys.length || n >= keys.length) { - context.showSnackBar(l10n.disabled); - return; - } - keys.moveByItem(keys, o, n, property: Stores.setting.serverFuncBtns); - setState(() {}); - }, ); } @@ -82,8 +84,7 @@ class _ServerDetailOrderPageState extends State { } else { keys.remove(key); } - Stores.setting.serverFuncBtns.put(keys); - setState(() {}); + prop.put(keys); }, ); } diff --git a/lib/view/page/setting/seq/virt_key.dart b/lib/view/page/setting/seq/virt_key.dart index 894b8ae8..4b64ce7a 100644 --- a/lib/view/page/setting/seq/virt_key.dart +++ b/lib/view/page/setting/seq/virt_key.dart @@ -18,6 +18,8 @@ class SSHVirtKeySettingPage extends StatefulWidget { } class _SSHVirtKeySettingPageState extends State { + final prop = Stores.setting.sshVirtKeys; + @override Widget build(BuildContext context) { return Scaffold( @@ -29,41 +31,41 @@ class _SSHVirtKeySettingPageState extends State { } Widget _buildBody() { - final keys_ = Stores.setting.sshVirtKeys.fetch(); - final keys = []; - for (final key in keys_) { - keys.add(key); - } - final disabled = VirtKey.values - .map((e) => e.index) - .where((e) => !keys.contains(e)) - .toList(); - final allKeys = [...keys, ...disabled]; - return ReorderableListView.builder( - padding: const EdgeInsets.all(7), - itemBuilder: (_, idx) { - final key = allKeys[idx]; - final item = VirtKey.values[key]; - final help = item.help; - return CardX( - key: ValueKey(idx), - child: ListTile( - title: _buildTitle(item), - subtitle: help == null ? null : Text(help, style: UIs.textGrey), - leading: _buildCheckBox(keys, key, idx, idx < keys.length), - trailing: isDesktop ? null : const Icon(Icons.drag_handle), - ), + return ValueListenableBuilder( + valueListenable: prop.listenable(), + builder: (_, vals, __) { + final keys = List.from(vals); + final disabled = VirtKey.values + .map((e) => e.index) + .where((e) => !keys.contains(e)) + .toList(); + final allKeys = [...keys, ...disabled]; + return ReorderableListView.builder( + padding: const EdgeInsets.all(7), + itemBuilder: (_, idx) { + final key = allKeys[idx]; + final item = VirtKey.values[key]; + final help = item.help; + return CardX( + key: ValueKey(idx), + child: ListTile( + title: _buildTitle(item), + subtitle: help == null ? null : Text(help, style: UIs.textGrey), + leading: _buildCheckBox(keys, key, idx, idx < keys.length), + trailing: isDesktop ? null : const Icon(Icons.drag_handle), + ), + ); + }, + itemCount: allKeys.length, + onReorder: (o, n) { + if (o >= keys.length || n >= keys.length) { + context.showSnackBar(l10n.disabled); + return; + } + keys.moveByItem(keys, o, n, property: prop); + }, ); }, - itemCount: allKeys.length, - onReorder: (o, n) { - if (o >= keys.length || n >= keys.length) { - context.showSnackBar(l10n.disabled); - return; - } - keys.moveByItem(keys, o, n, property: Stores.setting.sshVirtKeys); - setState(() {}); - }, ); } @@ -93,8 +95,7 @@ class _SSHVirtKeySettingPageState extends State { } else { keys.remove(key); } - Stores.setting.sshVirtKeys.put(keys); - setState(() {}); + prop.put(keys); }, ); } diff --git a/macos/Runner.xcodeproj/project.pbxproj b/macos/Runner.xcodeproj/project.pbxproj index 7e174759..f1df4001 100644 --- a/macos/Runner.xcodeproj/project.pbxproj +++ b/macos/Runner.xcodeproj/project.pbxproj @@ -439,7 +439,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 738; + CURRENT_PROJECT_VERSION = 740; DEVELOPMENT_TEAM = BA88US33G6; INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = "Server Box"; @@ -449,7 +449,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.15; - MARKETING_VERSION = 1.0.738; + MARKETING_VERSION = 1.0.740; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "Server Box"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -574,7 +574,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 738; + CURRENT_PROJECT_VERSION = 740; DEVELOPMENT_TEAM = BA88US33G6; INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = "Server Box"; @@ -584,7 +584,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.15; - MARKETING_VERSION = 1.0.738; + MARKETING_VERSION = 1.0.740; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "Server Box"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -604,7 +604,7 @@ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "3rd Party Mac Developer Application"; CODE_SIGN_STYLE = Manual; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 738; + CURRENT_PROJECT_VERSION = 740; DEVELOPMENT_TEAM = ""; "DEVELOPMENT_TEAM[sdk=macosx*]" = BA88US33G6; INFOPLIST_FILE = Runner/Info.plist; @@ -615,7 +615,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.15; - MARKETING_VERSION = 1.0.738; + MARKETING_VERSION = 1.0.740; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "Server Box"; PROVISIONING_PROFILE_SPECIFIER = "";