opt.: mem usage

This commit is contained in:
lollipopkit
2023-09-13 15:22:48 +08:00
parent 278d5984b2
commit eb158e63a2
44 changed files with 333 additions and 360 deletions

View File

@@ -472,7 +472,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 = 547; CURRENT_PROJECT_VERSION = 550;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
@@ -480,7 +480,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.547; MARKETING_VERSION = 1.0.550;
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";
@@ -604,7 +604,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/RunnerDebug.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/RunnerDebug.entitlements;
CURRENT_PROJECT_VERSION = 547; CURRENT_PROJECT_VERSION = 550;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
@@ -612,7 +612,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.547; MARKETING_VERSION = 1.0.550;
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";
@@ -630,7 +630,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 = 547; CURRENT_PROJECT_VERSION = 550;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
@@ -638,7 +638,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.547; MARKETING_VERSION = 1.0.550;
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";
@@ -659,7 +659,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 = 547; CURRENT_PROJECT_VERSION = 550;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
GCC_C_LANGUAGE_STANDARD = gnu11; GCC_C_LANGUAGE_STANDARD = gnu11;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
@@ -672,7 +672,7 @@
"@executable_path/Frameworks", "@executable_path/Frameworks",
"@executable_path/../../Frameworks", "@executable_path/../../Frameworks",
); );
MARKETING_VERSION = 1.0.547; MARKETING_VERSION = 1.0.550;
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;
@@ -698,7 +698,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 = 547; CURRENT_PROJECT_VERSION = 550;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
GCC_C_LANGUAGE_STANDARD = gnu11; GCC_C_LANGUAGE_STANDARD = gnu11;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
@@ -711,7 +711,7 @@
"@executable_path/Frameworks", "@executable_path/Frameworks",
"@executable_path/../../Frameworks", "@executable_path/../../Frameworks",
); );
MARKETING_VERSION = 1.0.547; MARKETING_VERSION = 1.0.550;
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)";
@@ -734,7 +734,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 = 547; CURRENT_PROJECT_VERSION = 550;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
GCC_C_LANGUAGE_STANDARD = gnu11; GCC_C_LANGUAGE_STANDARD = gnu11;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
@@ -747,7 +747,7 @@
"@executable_path/Frameworks", "@executable_path/Frameworks",
"@executable_path/../../Frameworks", "@executable_path/../../Frameworks",
); );
MARKETING_VERSION = 1.0.547; MARKETING_VERSION = 1.0.550;
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)";

View File

@@ -3,12 +3,11 @@ import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:toolbox/core/extension/context/common.dart'; import 'package:toolbox/core/extension/context/common.dart';
import 'package:toolbox/core/extension/locale.dart'; import 'package:toolbox/core/extension/locale.dart';
import 'package:toolbox/data/res/store.dart';
import 'core/utils/ui.dart'; import 'core/utils/ui.dart';
import 'data/res/build_data.dart'; import 'data/res/build_data.dart';
import 'data/res/color.dart'; import 'data/res/color.dart';
import 'data/store/setting.dart';
import 'locator.dart';
import 'view/page/full_screen.dart'; import 'view/page/full_screen.dart';
import 'view/page/home.dart'; import 'view/page/home.dart';
@@ -21,15 +20,13 @@ const _drawerTheme = DrawerThemeData(
); );
class MyApp extends StatelessWidget { class MyApp extends StatelessWidget {
MyApp({Key? key}) : super(key: key); const MyApp({Key? key}) : super(key: key);
final _setting = locator<SettingStore>();
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
setTransparentNavigationBar(context); setTransparentNavigationBar(context);
final child = _wrapTheme(context); final child = _wrapTheme(context);
if (_setting.useSystemPrimaryColor.fetch()) { if (Stores.setting.useSystemPrimaryColor.fetch()) {
return _wrapSystemColor(context, child); return _wrapSystemColor(context, child);
} }
return child; return child;
@@ -37,13 +34,13 @@ class MyApp extends StatelessWidget {
Widget _wrapTheme(BuildContext context) { Widget _wrapTheme(BuildContext context) {
return ValueListenableBuilder<int>( return ValueListenableBuilder<int>(
valueListenable: _setting.themeMode.listenable(), valueListenable: Stores.setting.themeMode.listenable(),
builder: (_, tMode, __) { builder: (_, tMode, __) {
final isAMOLED = tMode >= 0 && tMode <= ThemeMode.values.length - 1; final isAMOLED = tMode >= 0 && tMode <= ThemeMode.values.length - 1;
// Issue #57 // Issue #57
// if not [ok] -> [AMOLED] mode, use [ThemeMode.dark] // if not [ok] -> [AMOLED] mode, use [ThemeMode.dark]
final themeMode = isAMOLED ? ThemeMode.values[tMode] : ThemeMode.dark; final themeMode = isAMOLED ? ThemeMode.values[tMode] : ThemeMode.dark;
final locale = _setting.locale.fetch().toLocale; final locale = Stores.setting.locale.fetch().toLocale;
final darkTheme = ThemeData( final darkTheme = ThemeData(
useMaterial3: true, useMaterial3: true,
brightness: Brightness.dark, brightness: Brightness.dark,
@@ -63,7 +60,7 @@ class MyApp extends StatelessWidget {
colorSchemeSeed: primaryColor, colorSchemeSeed: primaryColor,
), ),
darkTheme: isAMOLED ? darkTheme : _getAmoledTheme(darkTheme), darkTheme: isAMOLED ? darkTheme : _getAmoledTheme(darkTheme),
home: _setting.fullScreen.fetch() home: Stores.setting.fullScreen.fetch()
? const FullScreenPage() ? const FullScreenPage()
: const HomePage(), : const HomePage(),
); );

View File

@@ -3,10 +3,9 @@ import 'dart:async';
import 'package:dartssh2/dartssh2.dart'; import 'package:dartssh2/dartssh2.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:toolbox/data/model/app/error.dart'; import 'package:toolbox/data/model/app/error.dart';
import 'package:toolbox/data/res/store.dart';
import '../../data/model/server/server_private_info.dart'; import '../../data/model/server/server_private_info.dart';
import '../../data/store/private_key.dart';
import '../../locator.dart';
/// Must put this func out of any Class. /// Must put this func out of any Class.
/// ///
@@ -32,7 +31,7 @@ enum GenSSHClientStatus {
} }
String getPrivateKey(String id) { String getPrivateKey(String id) {
final pki = locator<PrivateKeyStore>().get(id); final pki = Stores.key.get(id);
if (pki == null) { if (pki == null) {
throw SSHErr( throw SSHErr(
type: SSHErrType.noPrivateKey, type: SSHErrType.noPrivateKey,

View File

@@ -6,12 +6,7 @@ import 'package:toolbox/data/model/server/server_private_info.dart';
import 'package:toolbox/data/model/server/snippet.dart'; import 'package:toolbox/data/model/server/snippet.dart';
import 'package:toolbox/data/res/logger.dart'; import 'package:toolbox/data/res/logger.dart';
import 'package:toolbox/data/res/path.dart'; import 'package:toolbox/data/res/path.dart';
import 'package:toolbox/data/store/docker.dart'; import 'package:toolbox/data/res/store.dart';
import 'package:toolbox/data/store/private_key.dart';
import 'package:toolbox/data/store/server.dart';
import 'package:toolbox/data/store/setting.dart';
import 'package:toolbox/data/store/snippet.dart';
import 'package:toolbox/locator.dart';
const backupFormatVersion = 1; const backupFormatVersion = 1;
@@ -62,11 +57,11 @@ class Backup {
Backup.loadFromStore() Backup.loadFromStore()
: version = backupFormatVersion, : version = backupFormatVersion,
date = DateTime.now().toString().split('.').first, date = DateTime.now().toString().split('.').first,
spis = _server.fetch(), spis = Stores.server.fetch(),
snippets = _snippet.fetch(), snippets = Stores.snippet.fetch(),
keys = _privateKey.fetch(), keys = Stores.key.fetch(),
dockerHosts = _dockerHosts.fetchAll(), dockerHosts = Stores.docker.fetchAll(),
settings = _setting.toJson(); settings = Stores.setting.toJson();
static Future<void> backup() async { static Future<void> backup() async {
final result = _diyEncrtpt(json.encode(Backup.loadFromStore())); final result = _diyEncrtpt(json.encode(Backup.loadFromStore()));
@@ -75,18 +70,18 @@ class Backup {
Future<void> restore() async { Future<void> restore() async {
for (final s in snippets) { for (final s in snippets) {
_snippet.put(s); Stores.snippet.put(s);
} }
for (final s in spis) { for (final s in spis) {
_server.put(s); Stores.server.put(s);
} }
for (final s in keys) { for (final s in keys) {
_privateKey.put(s); Stores.key.put(s);
} }
for (final k in dockerHosts.keys) { for (final k in dockerHosts.keys) {
final val = dockerHosts[k]; final val = dockerHosts[k];
if (val != null && val is String && val.isNotEmpty) { if (val != null && val is String && val.isNotEmpty) {
_dockerHosts.put(k, val); Stores.docker.put(k, val);
} }
} }
} }
@@ -95,12 +90,6 @@ class Backup {
: this.fromJson(json.decode(_diyDecrypt(raw))); : this.fromJson(json.decode(_diyDecrypt(raw)));
} }
final _server = locator<ServerStore>();
final _snippet = locator<SnippetStore>();
final _privateKey = locator<PrivateKeyStore>();
final _dockerHosts = locator<DockerStore>();
final _setting = locator<SettingStore>();
String _diyEncrtpt(String raw) => json.encode( String _diyEncrtpt(String raw) => json.encode(
raw.codeUnits.map((e) => e * 2 + 1).toList(growable: false), raw.codeUnits.map((e) => e * 2 + 1).toList(growable: false),
); );

View File

@@ -109,8 +109,8 @@ Cpus parseBsdCpu(String raw) {
.allMatches(raw) .allMatches(raw)
.map((e) => double.parse(e.group(1) ?? '0') * 100) .map((e) => double.parse(e.group(1) ?? '0') * 100)
.toList(); .toList();
if (percents.length != 3) return initCpuStatus; if (percents.length != 3) return InitStatus.cpus;
return initCpuStatus return InitStatus.cpus
..now = [ ..now = [
OneTimeCpuStatus('cpu', percents[0].toInt(), 0, 0, OneTimeCpuStatus('cpu', percents[0].toInt(), 0, 0,
percents[2].toInt() + percents[1].toInt(), 0, 0, 0) percents[2].toInt() + percents[1].toInt(), 0, 0, 0)

View File

@@ -1,11 +1,10 @@
import '../../../locator.dart'; import 'package:toolbox/data/res/store.dart';
import '../../store/setting.dart';
class TryLimiter { class TryLimiter {
final Map<String, int> _triedTimes = {}; final Map<String, int> _triedTimes = {};
bool canTry(String id) { bool canTry(String id) {
final maxCount = locator<SettingStore>().maxRetryCount.fetch(); final maxCount = Stores.setting.maxRetryCount.fetch();
if (maxCount <= 0) { if (maxCount <= 0) {
return true; return true;
} }

View File

@@ -38,15 +38,9 @@ class DebugProvider extends ChangeNotifier {
} }
void addMultiline(Object data, [Color color = Colors.blue]) { void addMultiline(Object data, [Color color = Colors.blue]) {
final widget = Text(
'$data',
style: TextStyle(
color: color,
),
);
_addWidget(SingleChildScrollView( _addWidget(SingleChildScrollView(
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
child: widget, child: Text('$data', style: TextStyle(color: color)),
)); ));
} }

View File

@@ -9,8 +9,7 @@ import 'package:toolbox/data/model/docker/image.dart';
import 'package:toolbox/data/model/docker/ps.dart'; import 'package:toolbox/data/model/docker/ps.dart';
import 'package:toolbox/data/model/app/error.dart'; import 'package:toolbox/data/model/app/error.dart';
import 'package:toolbox/data/res/logger.dart'; import 'package:toolbox/data/res/logger.dart';
import 'package:toolbox/data/store/docker.dart'; import 'package:toolbox/data/res/store.dart';
import 'package:toolbox/locator.dart';
final _dockerNotFound = RegExp(r'command not found|Unknown command'); final _dockerNotFound = RegExp(r'command not found|Unknown command');
final _versionReg = RegExp(r'(Version:)\s+([0-9]+\.[0-9]+\.[0-9]+)'); final _versionReg = RegExp(r'(Version:)\s+([0-9]+\.[0-9]+\.[0-9]+)');
@@ -19,8 +18,6 @@ final _editionReg = RegExp(r'Docker Engine - [a-zA-Z]+');
final _dockerPrefixReg = RegExp(r'(sudo )?docker '); final _dockerPrefixReg = RegExp(r'(sudo )?docker ');
class DockerProvider extends ChangeNotifier { class DockerProvider extends ChangeNotifier {
final _dockerStore = locator<DockerStore>();
SSHClient? client; SSHClient? client;
String? userName; String? userName;
List<DockerPsItem>? items; List<DockerPsItem>? items;
@@ -177,7 +174,7 @@ class DockerProvider extends ChangeNotifier {
// judge whether to use DOCKER_HOST // judge whether to use DOCKER_HOST
String _wrap(String cmd) { String _wrap(String cmd) {
final dockerHost = _dockerStore.fetch(hostId!); final dockerHost = Stores.docker.fetch(hostId!);
if (dockerHost == null || dockerHost.isEmpty) { if (dockerHost == null || dockerHost.isEmpty) {
return cmd.withLangExport; return cmd.withLangExport;
} }

View File

@@ -1,26 +1,24 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:toolbox/data/model/server/private_key_info.dart'; import 'package:toolbox/data/model/server/private_key_info.dart';
import 'package:toolbox/data/store/private_key.dart'; import 'package:toolbox/data/res/store.dart';
import 'package:toolbox/locator.dart';
class PrivateKeyProvider extends ChangeNotifier { class PrivateKeyProvider extends ChangeNotifier {
List<PrivateKeyInfo> get pkis => _pkis; List<PrivateKeyInfo> get pkis => _pkis;
final _store = locator<PrivateKeyStore>();
late List<PrivateKeyInfo> _pkis; late List<PrivateKeyInfo> _pkis;
void loadData() { void loadData() {
_pkis = _store.fetch(); _pkis = Stores.key.fetch();
} }
void add(PrivateKeyInfo info) { void add(PrivateKeyInfo info) {
_pkis.add(info); _pkis.add(info);
_store.put(info); Stores.key.put(info);
notifyListeners(); notifyListeners();
} }
void delete(PrivateKeyInfo info) { void delete(PrivateKeyInfo info) {
_pkis.removeWhere((e) => e.id == info.id); _pkis.removeWhere((e) => e.id == info.id);
_store.delete(info); Stores.key.delete(info);
notifyListeners(); notifyListeners();
} }
@@ -31,7 +29,7 @@ class PrivateKeyProvider extends ChangeNotifier {
} else { } else {
_pkis[idx] = newInfo; _pkis[idx] = newInfo;
} }
_store.put(newInfo); Stores.key.put(newInfo);
notifyListeners(); notifyListeners();
} }
} }

View File

@@ -4,19 +4,17 @@ import 'package:flutter/foundation.dart';
import 'package:toolbox/data/model/app/shell_func.dart'; import 'package:toolbox/data/model/app/shell_func.dart';
import 'package:toolbox/data/model/server/system.dart'; import 'package:toolbox/data/model/server/system.dart';
import 'package:toolbox/data/res/logger.dart'; import 'package:toolbox/data/res/logger.dart';
import 'package:toolbox/data/res/store.dart';
import '../../core/extension/order.dart'; import '../../core/extension/order.dart';
import '../../core/extension/uint8list.dart'; import '../../core/extension/uint8list.dart';
import '../../core/utils/server.dart'; import '../../core/utils/server.dart';
import '../../locator.dart';
import '../model/server/server.dart'; import '../model/server/server.dart';
import '../model/server/server_private_info.dart'; import '../model/server/server_private_info.dart';
import '../model/server/server_status_update_req.dart'; import '../model/server/server_status_update_req.dart';
import '../model/server/snippet.dart'; import '../model/server/snippet.dart';
import '../model/server/try_limiter.dart'; import '../model/server/try_limiter.dart';
import '../res/status.dart'; import '../res/status.dart';
import '../store/server.dart';
import '../store/setting.dart';
typedef ServersMap = Map<String, Server>; typedef ServersMap = Map<String, Server>;
@@ -32,20 +30,17 @@ class ServerProvider extends ChangeNotifier {
Timer? _timer; Timer? _timer;
final _serverStore = locator<ServerStore>();
final _settingStore = locator<SettingStore>();
Future<void> loadLocalData() async { Future<void> loadLocalData() async {
// Issue #147 // Issue #147
// Clear all servers because of restarting app will cause duplicate servers // Clear all servers because of restarting app will cause duplicate servers
_servers.clear(); _servers.clear();
_serverOrder.clear(); _serverOrder.clear();
final spis = _serverStore.fetch(); final spis = Stores.server.fetch();
for (final spi in spis) { for (final spi in spis) {
_servers[spi.id] = genServer(spi); _servers[spi.id] = genServer(spi);
} }
final serverOrder_ = _settingStore.serverOrder.fetch(); final serverOrder_ = Stores.setting.serverOrder.fetch();
if (serverOrder_.isNotEmpty) { if (serverOrder_.isNotEmpty) {
spis.reorder( spis.reorder(
order: serverOrder_, order: serverOrder_,
@@ -57,7 +52,7 @@ class ServerProvider extends ChangeNotifier {
} }
// Must use [equals] to compare [Order] here. // Must use [equals] to compare [Order] here.
if (!_serverOrder.equals(serverOrder_)) { if (!_serverOrder.equals(serverOrder_)) {
_settingStore.serverOrder.put(_serverOrder); Stores.setting.serverOrder.put(_serverOrder);
} }
_updateTags(); _updateTags();
notifyListeners(); notifyListeners();
@@ -85,13 +80,13 @@ class ServerProvider extends ChangeNotifier {
s.spi.tags![i] = new_; s.spi.tags![i] = new_;
} }
} }
_serverStore.update(s.spi, s.spi); Stores.server.update(s.spi, s.spi);
} }
_updateTags(); _updateTags();
} }
Server genServer(ServerPrivateInfo spi) { Server genServer(ServerPrivateInfo spi) {
return Server(spi, initStatus, null, ServerState.disconnected); return Server(spi, InitStatus.status, null, ServerState.disconnected);
} }
/// if [spi] is specificed then only refresh this server /// if [spi] is specificed then only refresh this server
@@ -115,7 +110,7 @@ class ServerProvider extends ChangeNotifier {
} }
Future<void> startAutoRefresh() async { Future<void> startAutoRefresh() async {
final duration = _settingStore.serverStatusUpdateInterval.fetch(); final duration = Stores.setting.serverStatusUpdateInterval.fetch();
stopAutoRefresh(); stopAutoRefresh();
if (duration == 0) return; if (duration == 0) return;
_timer = Timer.periodic(Duration(seconds: duration), (_) async { _timer = Timer.periodic(Duration(seconds: duration), (_) async {
@@ -158,9 +153,9 @@ class ServerProvider extends ChangeNotifier {
void addServer(ServerPrivateInfo spi) { void addServer(ServerPrivateInfo spi) {
_servers[spi.id] = genServer(spi); _servers[spi.id] = genServer(spi);
notifyListeners(); notifyListeners();
_serverStore.put(spi); Stores.server.put(spi);
_serverOrder.add(spi.id); _serverOrder.add(spi.id);
_settingStore.serverOrder.put(_serverOrder); Stores.setting.serverOrder.put(_serverOrder);
_updateTags(); _updateTags();
refreshData(spi: spi); refreshData(spi: spi);
} }
@@ -168,19 +163,19 @@ class ServerProvider extends ChangeNotifier {
void delServer(String id) { void delServer(String id) {
_servers.remove(id); _servers.remove(id);
_serverOrder.remove(id); _serverOrder.remove(id);
_settingStore.serverOrder.put(_serverOrder); Stores.setting.serverOrder.put(_serverOrder);
_updateTags(); _updateTags();
notifyListeners(); notifyListeners();
_serverStore.delete(id); Stores.server.delete(id);
} }
void deleteAll() { void deleteAll() {
_servers.clear(); _servers.clear();
_serverOrder.clear(); _serverOrder.clear();
_settingStore.serverOrder.put(_serverOrder); Stores.setting.serverOrder.put(_serverOrder);
_updateTags(); _updateTags();
notifyListeners(); notifyListeners();
_serverStore.deleteAll(); Stores.server.deleteAll();
} }
Future<void> updateServer( Future<void> updateServer(
@@ -188,7 +183,7 @@ class ServerProvider extends ChangeNotifier {
ServerPrivateInfo newSpi, ServerPrivateInfo newSpi,
) async { ) async {
if (old != newSpi) { if (old != newSpi) {
_serverStore.update(old, newSpi); Stores.server.update(old, newSpi);
_servers[old.id]?.spi = newSpi; _servers[old.id]?.spi = newSpi;
if (newSpi.id != old.id) { if (newSpi.id != old.id) {
@@ -196,14 +191,14 @@ class ServerProvider extends ChangeNotifier {
_servers[newSpi.id]?.spi = newSpi; _servers[newSpi.id]?.spi = newSpi;
_servers.remove(old.id); _servers.remove(old.id);
_serverOrder.update(old.id, newSpi.id); _serverOrder.update(old.id, newSpi.id);
_settingStore.serverOrder.put(_serverOrder); Stores.setting.serverOrder.put(_serverOrder);
} }
// Only reconnect if neccessary // Only reconnect if neccessary
if (newSpi.shouldReconnect(old)) { if (newSpi.shouldReconnect(old)) {
_servers[newSpi.id]?.client = await genClient( _servers[newSpi.id]?.client = await genClient(
newSpi, newSpi,
timeout: _settingStore.timeoutD, timeout: Stores.setting.timeoutD,
); );
refreshData(spi: newSpi); refreshData(spi: newSpi);
} }
@@ -239,7 +234,7 @@ class ServerProvider extends ChangeNotifier {
try { try {
s.client = await genClient( s.client = await genClient(
spi, spi,
timeout: _settingStore.timeoutD, timeout: Stores.setting.timeoutD,
); );
} catch (e) { } catch (e) {
_limiter.inc(sid); _limiter.inc(sid);

View File

@@ -2,11 +2,9 @@ import 'dart:convert';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:toolbox/data/model/server/snippet.dart'; import 'package:toolbox/data/model/server/snippet.dart';
import 'package:toolbox/data/store/snippet.dart'; import 'package:toolbox/data/res/store.dart';
import 'package:toolbox/locator.dart';
import '../../core/extension/order.dart'; import '../../core/extension/order.dart';
import '../store/setting.dart';
class SnippetProvider extends ChangeNotifier { class SnippetProvider extends ChangeNotifier {
late Order<Snippet> _snippets; late Order<Snippet> _snippets;
@@ -15,20 +13,17 @@ class SnippetProvider extends ChangeNotifier {
final _tags = <String>[]; final _tags = <String>[];
List<String> get tags => _tags; List<String> get tags => _tags;
final _store = locator<SnippetStore>();
final _setting = locator<SettingStore>();
void loadData() { void loadData() {
_snippets = _store.fetch(); _snippets = Stores.snippet.fetch();
final order = _setting.snippetOrder.fetch(); final order = Stores.setting.snippetOrder.fetch();
if (order.isNotEmpty) { if (order.isNotEmpty) {
final surplus = _snippets.reorder( final surplus = _snippets.reorder(
order: order, order: order,
finder: (n, name) => n.name == name, finder: (n, name) => n.name == name,
); );
order.removeWhere((e) => surplus.any((ele) => ele == e)); order.removeWhere((e) => surplus.any((ele) => ele == e));
if (order != _setting.snippetOrder.fetch()) { if (order != Stores.setting.snippetOrder.fetch()) {
_setting.snippetOrder.put(order); Stores.setting.snippetOrder.put(order);
} }
} }
_addInternal(); _addInternal();
@@ -36,12 +31,12 @@ class SnippetProvider extends ChangeNotifier {
} }
void _addInternal() { void _addInternal() {
if (!_setting.fTISBM.fetch()) { if (!Stores.setting.fTISBM.fetch()) {
return; return;
} }
_snippets.add(installSBM); _snippets.add(installSBM);
_store.put(installSBM); Stores.snippet.put(installSBM);
_setting.fTISBM.put(false); Stores.setting.fTISBM.put(false);
} }
void _updateTags() { void _updateTags() {
@@ -58,21 +53,21 @@ class SnippetProvider extends ChangeNotifier {
void add(Snippet snippet) { void add(Snippet snippet) {
_snippets.add(snippet); _snippets.add(snippet);
_store.put(snippet); Stores.snippet.put(snippet);
_updateTags(); _updateTags();
notifyListeners(); notifyListeners();
} }
void del(Snippet snippet) { void del(Snippet snippet) {
_snippets.remove(snippet); _snippets.remove(snippet);
_store.delete(snippet); Stores.snippet.delete(snippet);
_updateTags(); _updateTags();
notifyListeners(); notifyListeners();
} }
void update(Snippet old, Snippet newOne) { void update(Snippet old, Snippet newOne) {
_store.delete(old); Stores.snippet.delete(old);
_store.put(newOne); Stores.snippet.put(newOne);
_snippets.remove(old); _snippets.remove(old);
_snippets.add(newOne); _snippets.add(newOne);
_updateTags(); _updateTags();
@@ -84,7 +79,7 @@ class SnippetProvider extends ChangeNotifier {
if (s.tags?.contains(old) ?? false) { if (s.tags?.contains(old) ?? false) {
s.tags?.remove(old); s.tags?.remove(old);
s.tags?.add(newOne); s.tags?.add(newOne);
_store.put(s); Stores.snippet.put(s);
} }
} }
_updateTags(); _updateTags();

View File

@@ -1,9 +1,7 @@
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:toolbox/data/res/store.dart';
import 'package:xterm/core.dart'; import 'package:xterm/core.dart';
import '../../locator.dart';
import '../store/setting.dart';
class VirtualKeyboard extends TerminalInputHandler with ChangeNotifier { class VirtualKeyboard extends TerminalInputHandler with ChangeNotifier {
VirtualKeyboard(); VirtualKeyboard();
@@ -25,8 +23,6 @@ class VirtualKeyboard extends TerminalInputHandler with ChangeNotifier {
} }
} }
final _setting = locator<SettingStore>();
void reset(TerminalKeyboardEvent e) { void reset(TerminalKeyboardEvent e) {
if (e.ctrl) { if (e.ctrl) {
ctrl = false; ctrl = false;
@@ -43,7 +39,7 @@ class VirtualKeyboard extends TerminalInputHandler with ChangeNotifier {
ctrl: event.ctrl || ctrl, ctrl: event.ctrl || ctrl,
alt: event.alt || alt, alt: event.alt || alt,
); );
if (_setting.sshVirtualKeyAutoOff.fetch()) { if (Stores.setting.sshVirtualKeyAutoOff.fetch()) {
reset(e); reset(e);
} }
return defaultInputHandler.call(e); return defaultInputHandler.call(e);

View File

@@ -2,9 +2,9 @@
class BuildData { class BuildData {
static const String name = "ServerBox"; static const String name = "ServerBox";
static const int build = 547; static const int build = 550;
static const String engine = "3.13.2"; static const String engine = "3.13.2";
static const String buildAt = "2023-09-12 14:04:07.018274"; static const String buildAt = "2023-09-13 15:19:48";
static const int modifications = 4; static const int modifications = 45;
static const int script = 14; static const int script = 15;
} }

View File

@@ -5,6 +5,8 @@ import '../model/app/dynamic_color.dart';
late Color primaryColor; late Color primaryColor;
class DynamicColors { class DynamicColors {
const DynamicColors._();
static const content = DynamicColor(Colors.black87, Colors.white70); static const content = DynamicColor(Colors.black87, Colors.white70);
static const bg = DynamicColor(Colors.white, Colors.black); static const bg = DynamicColor(Colors.white, Colors.black);
static const progress = DynamicColor(Colors.black12, Colors.white10); static const progress = DynamicColor(Colors.black12, Colors.white10);

View File

@@ -3,6 +3,8 @@ import 'dart:ui';
import 'package:toolbox/data/model/ssh/virtual_key.dart'; import 'package:toolbox/data/model/ssh/virtual_key.dart';
class Defaults { class Defaults {
const Defaults._();
// default server details page cards order // default server details page cards order
static const detailCardOrder = [ static const detailCardOrder = [
'uptime', 'uptime',

View File

@@ -1,6 +1,8 @@
import 'package:toolbox/data/model/app/github_id.dart'; import 'package:toolbox/data/model/app/github_id.dart';
class GithubIds { class GithubIds {
const GithubIds._();
// Thanks // Thanks
// If you want to change the url, please open an issue. // If you want to change the url, please open an issue.
static const contributors = <GhId>{ static const contributors = <GhId>{

View File

@@ -33,6 +33,8 @@ import 'package:highlight/languages/xml.dart';
import 'package:highlight/languages/yaml.dart'; import 'package:highlight/languages/yaml.dart';
class Highlights { class Highlights {
const Highlights._();
/// - KEY: fileNameSuffix /// - KEY: fileNameSuffix
/// - VAL: highlight /// - VAL: highlight
static final all = { static final all = {

View File

@@ -1,6 +1,8 @@
import 'package:logging/logging.dart'; import 'package:logging/logging.dart';
class Loggers { class Loggers {
const Loggers._();
static final app = Logger('App'); static final app = Logger('App');
static final parse = Logger('Parse'); static final parse = Logger('Parse');
} }

View File

@@ -3,6 +3,8 @@ import 'dart:convert';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
class Miscs { class Miscs {
const Miscs._();
/// RegExp for number /// RegExp for number
static final numReg = RegExp(r'\s{1,}'); static final numReg = RegExp(r'\s{1,}');

View File

@@ -4,6 +4,8 @@ import 'package:path_provider/path_provider.dart';
import 'package:toolbox/core/utils/platform.dart'; import 'package:toolbox/core/utils/platform.dart';
class Paths { class Paths {
const Paths._();
static String? _docDir; static String? _docDir;
static String? _sftpDir; static String? _sftpDir;
static String? _fontDir; static String? _fontDir;

View File

@@ -8,13 +8,10 @@ import '../model/server/server_status.dart';
import '../model/server/conn.dart'; import '../model/server/conn.dart';
import '../model/server/system.dart'; import '../model/server/system.dart';
Memory get _initMemory => const Memory( class InitStatus {
total: 1, const InitStatus._();
free: 1,
cache: 0, static OneTimeCpuStatus get _initOneTimeCpuStatus => OneTimeCpuStatus(
avail: 1,
);
OneTimeCpuStatus get _initOneTimeCpuStatus => OneTimeCpuStatus(
'cpu', 'cpu',
0, 0,
0, 0,
@@ -24,28 +21,28 @@ OneTimeCpuStatus get _initOneTimeCpuStatus => OneTimeCpuStatus(
0, 0,
0, 0,
); );
Cpus get initCpuStatus => Cpus( static Cpus get cpus => Cpus(
[_initOneTimeCpuStatus], [_initOneTimeCpuStatus],
[_initOneTimeCpuStatus], [_initOneTimeCpuStatus],
); );
NetSpeedPart get _initNetSpeedPart => NetSpeedPart( static NetSpeedPart get _initNetSpeedPart => NetSpeedPart(
'', '',
BigInt.zero, BigInt.zero,
BigInt.zero, BigInt.zero,
0, 0,
); );
NetSpeed get initNetSpeed => NetSpeed( static NetSpeed get netSpeed => NetSpeed(
[_initNetSpeedPart], [_initNetSpeedPart],
[_initNetSpeedPart], [_initNetSpeedPart],
); );
Swap get _initSwap => const Swap( static ServerStatus get status => ServerStatus(
total: 0, cpu: cpus,
free: 0, mem: const Memory(
cached: 0, total: 1,
); free: 1,
ServerStatus get initStatus => ServerStatus( cache: 0,
cpu: initCpuStatus, avail: 1,
mem: _initMemory, ),
sysVer: 'Loading...', sysVer: 'Loading...',
uptime: '', uptime: '',
disk: [ disk: [
@@ -59,8 +56,13 @@ ServerStatus get initStatus => ServerStatus(
) )
], ],
tcp: const Conn(maxConn: 0, active: 0, passive: 0, fail: 0), tcp: const Conn(maxConn: 0, active: 0, passive: 0, fail: 0),
netSpeed: initNetSpeed, netSpeed: netSpeed,
swap: _initSwap, swap: const Swap(
total: 0,
free: 0,
cached: 0,
),
system: SystemType.linux, system: SystemType.linux,
temps: Temperatures(), temps: Temperatures(),
); );
}

18
lib/data/res/store.dart Normal file
View File

@@ -0,0 +1,18 @@
import 'package:toolbox/data/store/docker.dart';
import 'package:toolbox/data/store/history.dart';
import 'package:toolbox/data/store/private_key.dart';
import 'package:toolbox/data/store/server.dart';
import 'package:toolbox/data/store/setting.dart';
import 'package:toolbox/data/store/snippet.dart';
import 'package:toolbox/locator.dart';
class Stores {
const Stores._();
static final setting = locator<SettingStore>();
static final server = locator<ServerStore>();
static final docker = locator<DockerStore>();
static final history = locator<HistoryStore>();
static final key = locator<PrivateKeyStore>();
static final snippet = locator<SnippetStore>();
}

View File

@@ -1,7 +1,10 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:xterm/ui.dart'; import 'package:xterm/ui.dart';
const termDarkTheme = TerminalTheme( class TerminalThemes {
const TerminalThemes._();
static const dark = TerminalTheme(
cursor: Color.fromARGB(137, 174, 175, 173), cursor: Color.fromARGB(137, 174, 175, 173),
selection: Color.fromARGB(147, 174, 175, 173), selection: Color.fromARGB(147, 174, 175, 173),
foreground: Color(0XFFCCCCCC), foreground: Color(0XFFCCCCCC),
@@ -26,8 +29,7 @@ const termDarkTheme = TerminalTheme(
brightWhite: Color.fromARGB(255, 233, 235, 235), brightWhite: Color.fromARGB(255, 233, 235, 235),
black: Colors.black, black: Colors.black,
); );
static const light = TerminalTheme(
const termLightTheme = TerminalTheme(
cursor: Color.fromARGB(153, 174, 175, 173), cursor: Color.fromARGB(153, 174, 175, 173),
selection: Color.fromARGB(102, 174, 175, 173), selection: Color.fromARGB(102, 174, 175, 173),
foreground: Color(0XFF000000), foreground: Color(0XFF000000),
@@ -52,3 +54,4 @@ const termLightTheme = TerminalTheme(
brightWhite: Color.fromARGB(255, 233, 235, 235), brightWhite: Color.fromARGB(255, 233, 235, 235),
black: Colors.black, black: Colors.black,
); );
}

View File

@@ -1,6 +1,8 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class UIs { class UIs {
const UIs._();
/// Font style /// Font style
static const textSize9Grey = TextStyle(color: Colors.grey, fontSize: 9); static const textSize9Grey = TextStyle(color: Colors.grey, fontSize: 9);

View File

@@ -1,4 +1,6 @@
class Urls { class Urls {
const Urls._();
static const resBase = 'https://res.lolli.tech/serverbox'; static const resBase = 'https://res.lolli.tech/serverbox';
static const myGithub = 'https://github.com/lollipopkit'; static const myGithub = 'https://github.com/lollipopkit';
static const appHelp = '$myGithub/flutter_server_box#-help'; static const appHelp = '$myGithub/flutter_server_box#-help';

View File

@@ -6,6 +6,7 @@ import 'package:logging/logging.dart';
import 'package:macos_window_utils/window_manipulator.dart'; import 'package:macos_window_utils/window_manipulator.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'package:toolbox/data/res/store.dart';
import 'app.dart'; import 'app.dart';
import 'core/analysis.dart'; import 'core/analysis.dart';
@@ -27,7 +28,6 @@ import 'data/provider/snippet.dart';
import 'data/provider/virtual_keyboard.dart'; import 'data/provider/virtual_keyboard.dart';
import 'data/res/color.dart'; import 'data/res/color.dart';
import 'data/res/misc.dart'; import 'data/res/misc.dart';
import 'data/store/setting.dart';
import 'locator.dart'; import 'locator.dart';
import 'view/widget/custom_appbar.dart'; import 'view/widget/custom_appbar.dart';
import 'view/widget/rebuild.dart'; import 'view/widget/rebuild.dart';
@@ -49,7 +49,7 @@ Future<void> main() async {
ChangeNotifierProvider(create: (_) => locator<PrivateKeyProvider>()), ChangeNotifierProvider(create: (_) => locator<PrivateKeyProvider>()),
ChangeNotifierProvider(create: (_) => locator<SftpProvider>()), ChangeNotifierProvider(create: (_) => locator<SftpProvider>()),
], ],
child: RebuildWidget( child: const RebuildWidget(
child: MyApp(), child: MyApp(),
), ),
), ),
@@ -61,12 +61,6 @@ void _runInZone(void Function() body) {
final zoneSpec = ZoneSpecification( final zoneSpec = ZoneSpecification(
print: (Zone self, ZoneDelegate parent, Zone zone, String line) { print: (Zone self, ZoneDelegate parent, Zone zone, String line) {
parent.print(zone, line); parent.print(zone, line);
// This is a hack to avoid
// `setState() or markNeedsBuild() called during build`
// error.
Future.delayed(const Duration(milliseconds: 1), () {
_debug?.addText(line);
});
}, },
); );
@@ -90,16 +84,15 @@ Future<void> initApp() async {
_setupProviders(); _setupProviders();
// Load font // Load font
final settings = locator<SettingStore>(); primaryColor = Color(Stores.setting.primaryColor.fetch());
loadFontFile(settings.fontPath.fetch()); loadFontFile(Stores.setting.fontPath.fetch());
primaryColor = Color(settings.primaryColor.fetch());
// Don't call it via `await`, it will block the main thread. // Don't call it via `await`, it will block the main thread.
if (settings.icloudSync.fetch()) ICloud.syncDb(); if (Stores.setting.icloudSync.fetch()) ICloud.syncDb();
if (isAndroid) { if (isAndroid) {
// Only start service when [bgRun] is true. // Only start service when [bgRun] is true.
if (locator<SettingStore>().bgRun.fetch()) { if (Stores.setting.bgRun.fetch()) {
Miscs.bgRunChannel.invokeMethod('startService'); Miscs.bgRunChannel.invokeMethod('startService');
} }
// SharedPreferences is only used on Android for saving home widgets settings. // SharedPreferences is only used on Android for saving home widgets settings.
@@ -126,6 +119,7 @@ void _setupLogger() {
Logger.root.level = Level.ALL; Logger.root.level = Level.ALL;
Logger.root.onRecord.listen((record) { Logger.root.onRecord.listen((record) {
var str = '[${record.loggerName}][${record.level.name}]: ${record.message}'; var str = '[${record.loggerName}][${record.level.name}]: ${record.message}';
_debug?.addText(str);
if (record.error != null) { if (record.error != null) {
str += '\n${record.error}'; str += '\n${record.error}';
_debug?.addMultiline(record.error.toString(), Colors.red); _debug?.addMultiline(record.error.toString(), Colors.red);

View File

@@ -11,19 +11,16 @@ import 'package:toolbox/core/utils/platform.dart';
import 'package:toolbox/data/model/app/backup.dart'; import 'package:toolbox/data/model/app/backup.dart';
import 'package:toolbox/data/res/logger.dart'; import 'package:toolbox/data/res/logger.dart';
import 'package:toolbox/data/res/path.dart'; import 'package:toolbox/data/res/path.dart';
import 'package:toolbox/data/res/store.dart';
import 'package:toolbox/view/widget/round_rect_card.dart'; import 'package:toolbox/view/widget/round_rect_card.dart';
import '../../core/utils/misc.dart'; import '../../core/utils/misc.dart';
import '../../data/res/ui.dart'; import '../../data/res/ui.dart';
import '../../data/store/setting.dart';
import '../../locator.dart';
import '../widget/custom_appbar.dart'; import '../widget/custom_appbar.dart';
import '../widget/store_switch.dart'; import '../widget/store_switch.dart';
class BackupPage extends StatelessWidget { class BackupPage extends StatelessWidget {
BackupPage({Key? key}) : super(key: key); const BackupPage({Key? key}) : super(key: key);
final _setting = locator<SettingStore>();
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@@ -118,7 +115,7 @@ class BackupPage extends StatelessWidget {
// }, // },
// icon: const Icon(Icons.sync)), // icon: const Icon(Icons.sync)),
// width13, // width13,
StoreSwitch(prop: _setting.icloudSync) StoreSwitch(prop: Stores.setting.icloudSync)
], ],
); );
} }

View File

@@ -6,6 +6,7 @@ import 'package:toolbox/core/extension/context/dialog.dart';
import 'package:toolbox/core/extension/context/snackbar.dart'; import 'package:toolbox/core/extension/context/snackbar.dart';
import 'package:toolbox/core/route.dart'; import 'package:toolbox/core/route.dart';
import 'package:toolbox/data/model/docker/image.dart'; import 'package:toolbox/data/model/docker/image.dart';
import 'package:toolbox/data/res/store.dart';
import 'package:toolbox/view/widget/input_field.dart'; import 'package:toolbox/view/widget/input_field.dart';
import '../../data/model/docker/ps.dart'; import '../../data/model/docker/ps.dart';
@@ -16,7 +17,6 @@ import '../../data/model/app/error.dart';
import '../../data/model/app/menu.dart'; import '../../data/model/app/menu.dart';
import '../../data/res/ui.dart'; import '../../data/res/ui.dart';
import '../../data/res/url.dart'; import '../../data/res/url.dart';
import '../../data/store/docker.dart';
import '../../locator.dart'; import '../../locator.dart';
import '../widget/custom_appbar.dart'; import '../widget/custom_appbar.dart';
import '../widget/popup_menu.dart'; import '../widget/popup_menu.dart';
@@ -34,7 +34,6 @@ class DockerManagePage extends StatefulWidget {
class _DockerManagePageState extends State<DockerManagePage> { class _DockerManagePageState extends State<DockerManagePage> {
final _docker = locator<DockerProvider>(); final _docker = locator<DockerProvider>();
final _store = locator<DockerStore>();
final _textController = TextEditingController(); final _textController = TextEditingController();
late S _s; late S _s;
@@ -479,7 +478,7 @@ class _DockerManagePageState extends State<DockerManagePage> {
Future<void> _showEditHostDialog() async { Future<void> _showEditHostDialog() async {
final id = widget.spi.id; final id = widget.spi.id;
final host = _store.fetch(id) ?? 'unix:///run/user/1000/docker.sock'; final host = Stores.docker.fetch(id) ?? 'unix:///run/user/1000/docker.sock';
final ctrl = TextEditingController(text: host); final ctrl = TextEditingController(text: host);
await context.showRoundDialog( await context.showRoundDialog(
title: Text(_s.dockerEditHost), title: Text(_s.dockerEditHost),
@@ -499,7 +498,7 @@ class _DockerManagePageState extends State<DockerManagePage> {
void _onSaveDockerHost(String val) { void _onSaveDockerHost(String val) {
context.pop(); context.pop();
_store.put(widget.spi.id, val.trim()); Stores.docker.put(widget.spi.id, val.trim());
_docker.refresh(); _docker.refresh();
} }
} }

View File

@@ -11,8 +11,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/utils/misc.dart'; import 'package:toolbox/core/utils/misc.dart';
import 'package:toolbox/data/res/highlight.dart'; import 'package:toolbox/data/res/highlight.dart';
import 'package:toolbox/data/store/setting.dart'; import 'package:toolbox/data/res/store.dart';
import 'package:toolbox/locator.dart';
import '../widget/custom_appbar.dart'; import '../widget/custom_appbar.dart';
import '../widget/two_line_text.dart'; import '../widget/two_line_text.dart';
@@ -45,12 +44,12 @@ class EditorPage extends StatefulWidget {
class _EditorPageState extends State<EditorPage> { class _EditorPageState extends State<EditorPage> {
final _focusNode = FocusNode(); final _focusNode = FocusNode();
final _setting = locator<SettingStore>();
late CodeController _controller; late CodeController _controller;
late Map<String, TextStyle> _codeTheme; late Map<String, TextStyle> _codeTheme;
late S _s; late S _s;
late final _textStyle = TextStyle(fontSize: _setting.editorFontSize.fetch()); late final _textStyle =
TextStyle(fontSize: Stores.setting.editorFontSize.fetch());
String? _langCode; String? _langCode;
@@ -81,9 +80,11 @@ class _EditorPageState extends State<EditorPage> {
_s = S.of(context)!; _s = S.of(context)!;
if (context.isDark) { if (context.isDark) {
_codeTheme = themeMap[_setting.editorDarkTheme.fetch()] ?? monokaiTheme; _codeTheme =
themeMap[Stores.setting.editorDarkTheme.fetch()] ?? monokaiTheme;
} else { } else {
_codeTheme = themeMap[_setting.editorTheme.fetch()] ?? a11yLightTheme; _codeTheme =
themeMap[Stores.setting.editorTheme.fetch()] ?? a11yLightTheme;
} }
_focusNode.requestFocus(); _focusNode.requestFocus();
} }

View File

@@ -10,8 +10,8 @@ import 'package:provider/provider.dart';
import 'package:toolbox/core/route.dart'; import 'package:toolbox/core/route.dart';
import 'package:toolbox/data/model/server/disk.dart'; import 'package:toolbox/data/model/server/disk.dart';
import 'package:toolbox/data/provider/server.dart'; import 'package:toolbox/data/provider/server.dart';
import 'package:toolbox/data/res/store.dart';
import 'package:toolbox/data/res/ui.dart'; import 'package:toolbox/data/res/ui.dart';
import 'package:toolbox/data/store/setting.dart';
import 'package:toolbox/locator.dart'; import 'package:toolbox/locator.dart';
import '../../core/analysis.dart'; import '../../core/analysis.dart';
@@ -39,13 +39,12 @@ class _FullScreenPageState extends State<FullScreenPage> with AfterLayoutMixin {
final _pageController = PageController(initialPage: 0); final _pageController = PageController(initialPage: 0);
final _serverProvider = locator<ServerProvider>(); final _serverProvider = locator<ServerProvider>();
final _setting = locator<SettingStore>();
@override @override
void initState() { void initState() {
super.initState(); super.initState();
switchStatusBar(hide: true); switchStatusBar(hide: true);
_rotateQuarter = _setting.fullScreenRotateQuarter.fetch(); _rotateQuarter = Stores.setting.fullScreenRotateQuarter.fetch();
_timer = Timer.periodic(const Duration(minutes: 1), (_) { _timer = Timer.periodic(const Duration(minutes: 1), (_) {
if (mounted) { if (mounted) {
setState(() {}); setState(() {});
@@ -88,7 +87,8 @@ class _FullScreenPageState extends State<FullScreenPage> with AfterLayoutMixin {
// `_screenWidth * 0.03` is the offset value // `_screenWidth * 0.03` is the offset value
padding: EdgeInsets.all(_screenWidth * 0.03), padding: EdgeInsets.all(_screenWidth * 0.03),
child: ValueListenableBuilder<int>( child: ValueListenableBuilder<int>(
valueListenable: _setting.fullScreenRotateQuarter.listenable(), valueListenable:
Stores.setting.fullScreenRotateQuarter.listenable(),
builder: (_, val, __) { builder: (_, val, __) {
_rotateQuarter = val; _rotateQuarter = val;
return RotatedBox( return RotatedBox(
@@ -297,7 +297,7 @@ class _FullScreenPageState extends State<FullScreenPage> with AfterLayoutMixin {
Widget _buildNet(ServerStatus ss) { Widget _buildNet(ServerStatus ss) {
return ValueListenableBuilder<NetViewType>( return ValueListenableBuilder<NetViewType>(
valueListenable: _setting.netViewType.listenable(), valueListenable: Stores.setting.netViewType.listenable(),
builder: (_, val, __) { builder: (_, val, __) {
final data = val.build(ss); final data = val.build(ss);
return AnimatedSwitcher( return AnimatedSwitcher(
@@ -368,7 +368,7 @@ class _FullScreenPageState extends State<FullScreenPage> with AfterLayoutMixin {
@override @override
Future<void> afterFirstLayout(BuildContext context) async { Future<void> afterFirstLayout(BuildContext context) async {
if (_setting.autoCheckAppUpdate.fetch()) { if (Stores.setting.autoCheckAppUpdate.fetch()) {
doUpdate(context); doUpdate(context);
} }
await GetIt.I.allReady(); await GetIt.I.allReady();

View File

@@ -7,6 +7,7 @@ import 'package:get_it/get_it.dart';
import 'package:toolbox/core/extension/context/dialog.dart'; import 'package:toolbox/core/extension/context/dialog.dart';
import 'package:toolbox/data/res/github_id.dart'; import 'package:toolbox/data/res/github_id.dart';
import 'package:toolbox/data/res/logger.dart'; import 'package:toolbox/data/res/logger.dart';
import 'package:toolbox/data/res/store.dart';
import '../../core/analysis.dart'; import '../../core/analysis.dart';
import '../../core/route.dart'; import '../../core/route.dart';
@@ -21,7 +22,6 @@ import '../../data/res/build_data.dart';
import '../../data/res/misc.dart'; import '../../data/res/misc.dart';
import '../../data/res/ui.dart'; import '../../data/res/ui.dart';
import '../../data/res/url.dart'; import '../../data/res/url.dart';
import '../../data/store/setting.dart';
import '../../locator.dart'; import '../../locator.dart';
import '../widget/custom_appbar.dart'; import '../widget/custom_appbar.dart';
import '../widget/round_rect_card.dart'; import '../widget/round_rect_card.dart';
@@ -41,7 +41,6 @@ class _HomePageState extends State<HomePage>
AfterLayoutMixin, AfterLayoutMixin,
WidgetsBindingObserver { WidgetsBindingObserver {
final _serverProvider = locator<ServerProvider>(); final _serverProvider = locator<ServerProvider>();
final _setting = locator<SettingStore>();
final _app = locator<AppProvider>(); final _app = locator<AppProvider>();
late final PageController _pageController; late final PageController _pageController;
@@ -56,7 +55,7 @@ class _HomePageState extends State<HomePage>
super.initState(); super.initState();
switchStatusBar(hide: false); switchStatusBar(hide: false);
WidgetsBinding.instance.addObserver(this); WidgetsBinding.instance.addObserver(this);
_selectIndex.value = _setting.launchPage.fetch(); _selectIndex.value = Stores.setting.launchPage.fetch();
// avoid index out of range // avoid index out of range
if (_selectIndex.value >= AppTab.values.length || _selectIndex.value < 0) { if (_selectIndex.value >= AppTab.values.length || _selectIndex.value < 0) {
_selectIndex.value = 0; _selectIndex.value = 0;
@@ -92,7 +91,7 @@ class _HomePageState extends State<HomePage>
break; break;
case AppLifecycleState.paused: case AppLifecycleState.paused:
// Keep running in background on Android device // Keep running in background on Android device
if (isAndroid && _setting.bgRun.fetch()) { if (isAndroid && Stores.setting.bgRun.fetch()) {
if (_app.moveBg) { if (_app.moveBg) {
Miscs.bgRunChannel.invokeMethod('sendToBackground'); Miscs.bgRunChannel.invokeMethod('sendToBackground');
} }
@@ -210,7 +209,8 @@ class _HomePageState extends State<HomePage>
TextButton( TextButton(
onPressed: () => context.showRoundDialog( onPressed: () => context.showRoundDialog(
title: Text(_versionStr), title: Text(_versionStr),
child: const Text(BuildData.buildAt), child: const Text(
'${BuildData.buildAt}\nFlutter ${BuildData.engine}'),
), ),
child: Text( child: Text(
'${BuildData.name}\n$_versionStr', '${BuildData.name}\n$_versionStr',
@@ -333,7 +333,7 @@ class _HomePageState extends State<HomePage>
if (BuildData.modifications != 0) { if (BuildData.modifications != 0) {
mod = '(+${BuildData.modifications})'; mod = '(+${BuildData.modifications})';
} }
return 'Ver: 1.0.${BuildData.build}$mod'; return 'v1.0.${BuildData.build}$mod';
} }
@override @override
@@ -341,7 +341,7 @@ class _HomePageState extends State<HomePage>
@override @override
Future<void> afterFirstLayout(BuildContext context) async { Future<void> afterFirstLayout(BuildContext context) async {
if (_setting.autoCheckAppUpdate.fetch()) { if (Stores.setting.autoCheckAppUpdate.fetch()) {
doUpdate(context); doUpdate(context);
} }
updateHomeWidget(); updateHomeWidget();
@@ -354,14 +354,14 @@ class _HomePageState extends State<HomePage>
} }
void updateHomeWidget() { void updateHomeWidget() {
if (_setting.autoUpdateHomeWidget.fetch()) { if (Stores.setting.autoUpdateHomeWidget.fetch()) {
Miscs.homeWidgetChannel.invokeMethod('update'); Miscs.homeWidgetChannel.invokeMethod('update');
} }
} }
Future<void> _onLongPressSetting() async { Future<void> _onLongPressSetting() async {
/// Encode [map] to String with indent `\t` /// Encode [map] to String with indent `\t`
final map = _setting.toJson(); final map = Stores.setting.toJson();
final keys = map.keys; final keys = map.keys;
final text = Miscs.jsonEncoder.convert(map); final text = Miscs.jsonEncoder.convert(map);
final result = await AppRoute.editor( final result = await AppRoute.editor(
@@ -374,11 +374,11 @@ class _HomePageState extends State<HomePage>
} }
try { try {
final newSettings = json.decode(result) as Map<String, dynamic>; final newSettings = json.decode(result) as Map<String, dynamic>;
_setting.box.putAll(newSettings); Stores.setting.box.putAll(newSettings);
final newKeys = newSettings.keys; final newKeys = newSettings.keys;
final removedKeys = keys.where((e) => !newKeys.contains(e)); final removedKeys = keys.where((e) => !newKeys.contains(e));
for (final key in removedKeys) { for (final key in removedKeys) {
_setting.box.delete(key); Stores.setting.box.delete(key);
} }
} catch (e, trace) { } catch (e, trace) {
context.showRoundDialog( context.showRoundDialog(

View File

@@ -6,8 +6,7 @@ import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:provider/provider.dart'; 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/data/store/private_key.dart'; import 'package:toolbox/data/res/store.dart';
import 'package:toolbox/locator.dart';
import '../../../core/route.dart'; import '../../../core/route.dart';
import '../../../core/utils/platform.dart'; import '../../../core/utils/platform.dart';
@@ -83,9 +82,8 @@ class _PrivateKeyListState extends State<PrivateKeysListPage>
} }
void autoAddSystemPriavteKey() { void autoAddSystemPriavteKey() {
final store = locator<PrivateKeyStore>();
// Only trigger on desktop platform and no private key saved // Only trigger on desktop platform and no private key saved
if (isDesktop && store.box.keys.isEmpty) { if (isDesktop && Stores.snippet.box.keys.isEmpty) {
final home = getHomeDir(); final home = getHomeDir();
if (home == null) return; if (home == null) return;
final idRsaFile = File(joinPath(home, '.ssh/id_rsa')); final idRsaFile = File(joinPath(home, '.ssh/id_rsa'));

View File

@@ -8,13 +8,13 @@ import 'package:toolbox/core/extension/context/dialog.dart';
import 'package:toolbox/core/extension/context/snackbar.dart'; import 'package:toolbox/core/extension/context/snackbar.dart';
import 'package:toolbox/core/extension/uint8list.dart'; import 'package:toolbox/core/extension/uint8list.dart';
import 'package:toolbox/core/utils/misc.dart'; import 'package:toolbox/core/utils/misc.dart';
import 'package:toolbox/data/res/store.dart';
import '../../data/model/app/shell_func.dart'; import '../../data/model/app/shell_func.dart';
import '../../data/model/server/proc.dart'; import '../../data/model/server/proc.dart';
import '../../data/model/server/server_private_info.dart'; import '../../data/model/server/server_private_info.dart';
import '../../data/provider/server.dart'; import '../../data/provider/server.dart';
import '../../data/res/ui.dart'; import '../../data/res/ui.dart';
import '../../data/store/setting.dart';
import '../../locator.dart'; import '../../locator.dart';
import '../widget/custom_appbar.dart'; import '../widget/custom_appbar.dart';
import '../widget/round_rect_card.dart'; import '../widget/round_rect_card.dart';
@@ -33,8 +33,6 @@ class _ProcessPageState extends State<ProcessPage> {
late Timer _timer; late Timer _timer;
late MediaQueryData _media; late MediaQueryData _media;
final _setting = locator<SettingStore>();
SSHClient? _client; SSHClient? _client;
PsResult _result = const PsResult(procs: []); PsResult _result = const PsResult(procs: []);
@@ -53,7 +51,7 @@ class _ProcessPageState extends State<ProcessPage> {
super.initState(); super.initState();
_client = _serverProvider.servers[widget.spi.id]?.client; _client = _serverProvider.servers[widget.spi.id]?.client;
final duration = final duration =
Duration(seconds: _setting.serverStatusUpdateInterval.fetch()); Duration(seconds: Stores.setting.serverStatusUpdateInterval.fetch());
_timer = Timer.periodic(duration, (_) => _refresh()); _timer = Timer.periodic(duration, (_) => _refresh());
} }

View File

@@ -6,6 +6,7 @@ import 'package:toolbox/core/extension/order.dart';
import 'package:toolbox/data/model/server/cpu.dart'; import 'package:toolbox/data/model/server/cpu.dart';
import 'package:toolbox/data/model/server/server_private_info.dart'; import 'package:toolbox/data/model/server/server_private_info.dart';
import 'package:toolbox/data/model/server/system.dart'; import 'package:toolbox/data/model/server/system.dart';
import 'package:toolbox/data/res/store.dart';
import 'package:toolbox/view/widget/server_func_btns.dart'; import 'package:toolbox/view/widget/server_func_btns.dart';
import '../../../core/extension/numx.dart'; import '../../../core/extension/numx.dart';
@@ -17,8 +18,6 @@ import '../../../data/provider/server.dart';
import '../../../data/res/color.dart'; import '../../../data/res/color.dart';
import '../../../data/res/default.dart'; import '../../../data/res/default.dart';
import '../../../data/res/ui.dart'; import '../../../data/res/ui.dart';
import '../../../data/store/setting.dart';
import '../../../locator.dart';
import '../../widget/custom_appbar.dart'; import '../../widget/custom_appbar.dart';
import '../../widget/round_rect_card.dart'; import '../../widget/round_rect_card.dart';
@@ -36,9 +35,8 @@ class _ServerDetailPageState extends State<ServerDetailPage>
late MediaQueryData _media; late MediaQueryData _media;
late S _s; late S _s;
final Order<String> _cardsOrder = []; final Order<String> _cardsOrder = [];
final _setting = locator<SettingStore>();
late final _textFactor = _setting.textFactor.fetch(); late final _textFactor = Stores.setting.textFactor.fetch();
late final _cardBuildMap = Map.fromIterables( late final _cardBuildMap = Map.fromIterables(
Defaults.detailCardOrder, Defaults.detailCardOrder,
@@ -63,7 +61,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_cardsOrder.addAll(_setting.detailCardOrder.fetch()); _cardsOrder.addAll(Stores.setting.detailCardOrder.fetch());
} }
@override @override
@@ -82,7 +80,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
} }
Widget _buildMainPage(Server si) { Widget _buildMainPage(Server si) {
final buildFuncs = !_setting.moveOutServerTabFuncBtns.fetch(); final buildFuncs = !Stores.setting.moveOutServerTabFuncBtns.fetch();
return Scaffold( return Scaffold(
appBar: CustomAppBar( appBar: CustomAppBar(
title: Text(si.spi.name, style: UIs.textSize18), title: Text(si.spi.name, style: UIs.textSize18),
@@ -309,7 +307,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
Widget _buildDiskView(ServerStatus ss) { Widget _buildDiskView(ServerStatus ss) {
final disk = ss.disk; final disk = ss.disk;
disk.removeWhere((e) { disk.removeWhere((e) {
for (final ingorePath in _setting.diskIgnorePath.fetch()) { for (final ingorePath in Stores.setting.diskIgnorePath.fetch()) {
if (e.path.startsWith(ingorePath)) return true; if (e.path.startsWith(ingorePath)) return true;
} }
return false; return false;

View File

@@ -8,6 +8,7 @@ import 'package:toolbox/core/extension/context/dialog.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/data/model/app/shell_func.dart'; import 'package:toolbox/data/model/app/shell_func.dart';
import 'package:toolbox/data/res/store.dart';
import '../../../core/route.dart'; import '../../../core/route.dart';
import '../../../core/utils/misc.dart'; import '../../../core/utils/misc.dart';
@@ -20,7 +21,6 @@ import '../../../data/model/server/server_status.dart';
import '../../../data/provider/server.dart'; import '../../../data/provider/server.dart';
import '../../../data/res/color.dart'; import '../../../data/res/color.dart';
import '../../../data/res/ui.dart'; import '../../../data/res/ui.dart';
import '../../../data/store/setting.dart';
import '../../../locator.dart'; import '../../../locator.dart';
import '../../widget/round_rect_card.dart'; import '../../widget/round_rect_card.dart';
import '../../widget/server_func_btns.dart'; import '../../widget/server_func_btns.dart';
@@ -40,7 +40,6 @@ class _ServerPageState extends State<ServerPage>
final _flipedCardIds = <String>{}; final _flipedCardIds = <String>{};
final _serverProvider = locator<ServerProvider>(); final _serverProvider = locator<ServerProvider>();
final _setting = locator<SettingStore>();
String? _tag; String? _tag;
bool _useDoubleColumn = false; bool _useDoubleColumn = false;
@@ -83,7 +82,8 @@ class _ServerPageState extends State<ServerPage>
} }
final filtered = _filterServers(pro); final filtered = _filterServers(pro);
if (_useDoubleColumn && _setting.doubleColumnServersPage.fetch()) { if (_useDoubleColumn &&
Stores.setting.doubleColumnServersPage.fetch()) {
return _buildBodyMedium(pro); return _buildBodyMedium(pro);
} }
return _buildBodySmall(provider: pro, filtered: filtered); return _buildBodySmall(provider: pro, filtered: filtered);
@@ -290,9 +290,9 @@ class _ServerPageState extends State<ServerPage>
), ),
), ),
UIs.height13, UIs.height13,
if (_setting.moveOutServerTabFuncBtns.fetch() && if (Stores.setting.moveOutServerTabFuncBtns.fetch() &&
// Discussion #146 // Discussion #146
!_setting.serverTabUseOldUI.fetch()) !Stores.setting.serverTabUseOldUI.fetch())
SizedBox( SizedBox(
height: 27, height: 27,
child: ServerFuncBtns(spi: spi, s: _s), child: ServerFuncBtns(spi: spi, s: _s),
@@ -318,7 +318,7 @@ class _ServerPageState extends State<ServerPage>
), ),
), ),
); );
} else if (_setting.serverTabUseOldUI.fetch()) { } else if (Stores.setting.serverTabUseOldUI.fetch()) {
rightCorner = ServerFuncBtnsTopRight(spi: spi, s: _s); rightCorner = ServerFuncBtnsTopRight(spi: spi, s: _s);
} }
return Padding( return Padding(
@@ -392,7 +392,7 @@ class _ServerPageState extends State<ServerPage>
Widget _buildNet(ServerStatus ss) { Widget _buildNet(ServerStatus ss) {
return ValueListenableBuilder<NetViewType>( return ValueListenableBuilder<NetViewType>(
valueListenable: _setting.netViewType.listenable(), valueListenable: Stores.setting.netViewType.listenable(),
builder: (_, val, __) { builder: (_, val, __) {
final data = val.build(ss); final data = val.build(ss);
return AnimatedSwitcher( return AnimatedSwitcher(
@@ -510,9 +510,9 @@ class _ServerPageState extends State<ServerPage>
if (_flipedCardIds.contains(id)) { if (_flipedCardIds.contains(id)) {
return 77.0; return 77.0;
} }
if (_setting.moveOutServerTabFuncBtns.fetch() && if (Stores.setting.moveOutServerTabFuncBtns.fetch() &&
// Discussion #146 // Discussion #146
!_setting.serverTabUseOldUI.fetch()) { !Stores.setting.serverTabUseOldUI.fetch()) {
return 132; return 132;
} }
return 107; return 107;

View File

@@ -12,6 +12,7 @@ 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/data/res/store.dart';
import '../../../core/persistant_store.dart'; import '../../../core/persistant_store.dart';
import '../../../core/route.dart'; import '../../../core/route.dart';
@@ -25,8 +26,6 @@ import '../../../data/res/build_data.dart';
import '../../../data/res/color.dart'; import '../../../data/res/color.dart';
import '../../../data/res/path.dart'; import '../../../data/res/path.dart';
import '../../../data/res/ui.dart'; import '../../../data/res/ui.dart';
import '../../../data/store/server.dart';
import '../../../data/store/setting.dart';
import '../../../locator.dart'; import '../../../locator.dart';
import '../../widget/color_picker.dart'; import '../../widget/color_picker.dart';
import '../../widget/custom_appbar.dart'; import '../../widget/custom_appbar.dart';
@@ -53,9 +52,9 @@ class _SettingPageState extends State<SettingPage> {
final _keyboardTypeKey = GlobalKey<PopupMenuButtonState<int>>(); final _keyboardTypeKey = GlobalKey<PopupMenuButtonState<int>>();
final _rotateQuarterKey = GlobalKey<PopupMenuButtonState<int>>(); final _rotateQuarterKey = GlobalKey<PopupMenuButtonState<int>>();
final _netViewTypeKey = GlobalKey<PopupMenuButtonState<NetViewType>>(); final _netViewTypeKey = GlobalKey<PopupMenuButtonState<NetViewType>>();
final _serverProvider = locator<ServerProvider>();
final _setting = Stores.setting;
late final SettingStore _setting;
late final ServerProvider _serverProvider;
late S _s; late S _s;
late SharedPreferences _sp; late SharedPreferences _sp;
@@ -89,8 +88,6 @@ class _SettingPageState extends State<SettingPage> {
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_serverProvider = locator<ServerProvider>();
_setting = locator<SettingStore>();
_nightMode.value = _setting.themeMode.fetch(); _nightMode.value = _setting.themeMode.fetch();
_updateInterval.value = _setting.serverStatusUpdateInterval.fetch(); _updateInterval.value = _setting.serverStatusUpdateInterval.fetch();
_maxRetryCount.value = _setting.maxRetryCount.fetch(); _maxRetryCount.value = _setting.maxRetryCount.fetch();
@@ -964,7 +961,7 @@ class _SettingPageState extends State<SettingPage> {
title: Text(_s.deleteServers), title: Text(_s.deleteServers),
trailing: const Icon(Icons.delete_forever), trailing: const Icon(Icons.delete_forever),
onTap: () async { onTap: () async {
final all = locator<ServerStore>().box.keys.map( final all = Stores.server.box.keys.map(
(e) => TextButton( (e) => TextButton(
onPressed: () => context.showRoundDialog( onPressed: () => context.showRoundDialog(
title: Text(_s.attention), title: Text(_s.attention),

View File

@@ -1,9 +1,8 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:toolbox/data/res/store.dart';
import '../../../core/extension/order.dart'; import '../../../core/extension/order.dart';
import '../../../data/store/setting.dart';
import '../../../locator.dart';
import '../../widget/custom_appbar.dart'; import '../../widget/custom_appbar.dart';
import '../../widget/round_rect_card.dart'; import '../../widget/round_rect_card.dart';
@@ -15,8 +14,6 @@ class ServerDetailOrderPage extends StatefulWidget {
} }
class _ServerDetailOrderPageState extends State<ServerDetailOrderPage> { class _ServerDetailOrderPageState extends State<ServerDetailOrderPage> {
final _store = locator<SettingStore>();
final Order<String> _cardsOrder = []; final Order<String> _cardsOrder = [];
late S _s; late S _s;
@@ -30,7 +27,7 @@ class _ServerDetailOrderPageState extends State<ServerDetailOrderPage> {
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_cardsOrder.addAll(_store.detailCardOrder.fetch()); _cardsOrder.addAll(Stores.setting.detailCardOrder.fetch());
} }
@override @override
@@ -50,7 +47,7 @@ class _ServerDetailOrderPageState extends State<ServerDetailOrderPage> {
_cardsOrder.move( _cardsOrder.move(
oldIndex, oldIndex,
newIndex, newIndex,
property: _store.detailCardOrder, property: Stores.setting.detailCardOrder,
); );
}), }),
padding: const EdgeInsets.symmetric(horizontal: 7, vertical: 3), padding: const EdgeInsets.symmetric(horizontal: 7, vertical: 3),

View File

@@ -1,10 +1,10 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:toolbox/core/extension/order.dart'; import 'package:toolbox/core/extension/order.dart';
import 'package:toolbox/data/res/store.dart';
import 'package:toolbox/view/widget/round_rect_card.dart'; import 'package:toolbox/view/widget/round_rect_card.dart';
import '../../../data/provider/server.dart'; import '../../../data/provider/server.dart';
import '../../../data/store/setting.dart';
import '../../../locator.dart'; import '../../../locator.dart';
import '../../widget/custom_appbar.dart'; import '../../widget/custom_appbar.dart';
@@ -16,7 +16,6 @@ class ServerOrderPage extends StatefulWidget {
} }
class _ServerOrderPageState extends State<ServerOrderPage> { class _ServerOrderPageState extends State<ServerOrderPage> {
final _store = locator<SettingStore>();
final _provider = locator<ServerProvider>(); final _provider = locator<ServerProvider>();
late S _s; late S _s;
@@ -44,7 +43,7 @@ class _ServerOrderPageState extends State<ServerOrderPage> {
_provider.serverOrder.move( _provider.serverOrder.move(
oldIndex, oldIndex,
newIndex, newIndex,
property: _store.serverOrder, property: Stores.setting.serverOrder,
); );
}), }),
padding: const EdgeInsets.symmetric(horizontal: 7, vertical: 3), padding: const EdgeInsets.symmetric(horizontal: 7, vertical: 3),

View File

@@ -4,9 +4,8 @@ import 'package:toolbox/core/extension/context/snackbar.dart';
import 'package:toolbox/core/extension/order.dart'; import 'package:toolbox/core/extension/order.dart';
import 'package:toolbox/core/utils/platform.dart'; import 'package:toolbox/core/utils/platform.dart';
import 'package:toolbox/data/model/ssh/virtual_key.dart'; import 'package:toolbox/data/model/ssh/virtual_key.dart';
import 'package:toolbox/data/res/store.dart';
import 'package:toolbox/data/res/ui.dart'; import 'package:toolbox/data/res/ui.dart';
import 'package:toolbox/data/store/setting.dart';
import 'package:toolbox/locator.dart';
import 'package:toolbox/view/widget/round_rect_card.dart'; import 'package:toolbox/view/widget/round_rect_card.dart';
import '../../widget/custom_appbar.dart'; import '../../widget/custom_appbar.dart';
@@ -19,7 +18,6 @@ class SSHVirtKeySettingPage extends StatefulWidget {
} }
class _SSHVirtKeySettingPageState extends State<SSHVirtKeySettingPage> { class _SSHVirtKeySettingPageState extends State<SSHVirtKeySettingPage> {
final _setting = locator<SettingStore>();
late S _s; late S _s;
@override @override
@@ -39,7 +37,7 @@ class _SSHVirtKeySettingPageState extends State<SSHVirtKeySettingPage> {
} }
Widget _buildBody() { Widget _buildBody() {
final keys_ = _setting.sshVirtKeys.fetch(); final keys_ = Stores.setting.sshVirtKeys.fetch();
final keys = <VirtKey>[]; final keys = <VirtKey>[];
for (final key in keys_) { for (final key in keys_) {
keys.add(key); keys.add(key);
@@ -67,7 +65,7 @@ class _SSHVirtKeySettingPageState extends State<SSHVirtKeySettingPage> {
context.showSnackBar(_s.disabled); context.showSnackBar(_s.disabled);
return; return;
} }
keys.moveByItem(keys, o, n, property: _setting.sshVirtKeys); keys.moveByItem(keys, o, n, property: Stores.setting.sshVirtKeys);
setState(() {}); setState(() {});
}, },
); );
@@ -99,7 +97,7 @@ class _SSHVirtKeySettingPageState extends State<SSHVirtKeySettingPage> {
} else { } else {
keys.remove(key); keys.remove(key);
} }
_setting.sshVirtKeys.put(keys); Stores.setting.sshVirtKeys.put(keys);
setState(() {}); setState(() {});
}, },
); );

View File

@@ -3,13 +3,13 @@ import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:toolbox/core/extension/context/dialog.dart'; import 'package:toolbox/core/extension/context/dialog.dart';
import 'package:toolbox/core/extension/order.dart'; import 'package:toolbox/core/extension/order.dart';
import 'package:toolbox/data/res/store.dart';
import '../../../core/utils/misc.dart'; import '../../../core/utils/misc.dart';
import '../../../data/model/server/server.dart'; import '../../../data/model/server/server.dart';
import '../../../data/model/server/snippet.dart'; import '../../../data/model/server/snippet.dart';
import '../../../data/provider/server.dart'; import '../../../data/provider/server.dart';
import '../../../data/res/ui.dart'; import '../../../data/res/ui.dart';
import '../../../data/store/setting.dart';
import '../../../locator.dart'; import '../../../locator.dart';
import '../../widget/tag.dart'; import '../../widget/tag.dart';
import '/core/route.dart'; import '/core/route.dart';
@@ -27,8 +27,6 @@ class _SnippetListPageState extends State<SnippetListPage> {
late S _s; late S _s;
late MediaQueryData _media; late MediaQueryData _media;
final _settingStore = locator<SettingStore>();
String? _tag; String? _tag;
@override @override
@@ -72,7 +70,7 @@ class _SnippetListPageState extends State<SnippetListPage> {
oldIdx, oldIdx,
newIdx, newIdx,
onMove: (p0) { onMove: (p0) {
_settingStore.snippetOrder.put(p0.map((e) => e.name).toList()); Stores.setting.snippetOrder.put(p0.map((e) => e.name).toList());
}, },
); );
}), }),

View File

@@ -10,7 +10,9 @@ 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/snackbar.dart'; import 'package:toolbox/core/extension/context/snackbar.dart';
import 'package:xterm/xterm.dart'; import 'package:toolbox/data/res/store.dart';
import 'package:xterm/core.dart';
import 'package:xterm/ui.dart' hide TerminalThemes;
import '../../core/route.dart'; import '../../core/route.dart';
import '../../core/utils/platform.dart'; import '../../core/utils/platform.dart';
@@ -21,7 +23,6 @@ import '../../data/model/ssh/virtual_key.dart';
import '../../data/provider/virtual_keyboard.dart'; import '../../data/provider/virtual_keyboard.dart';
import '../../data/res/color.dart'; import '../../data/res/color.dart';
import '../../data/res/terminal.dart'; import '../../data/res/terminal.dart';
import '../../data/store/setting.dart';
import '../../locator.dart'; import '../../locator.dart';
const echoPWD = 'echo \$PWD'; const echoPWD = 'echo \$PWD';
@@ -37,7 +38,6 @@ class SSHPage extends StatefulWidget {
class _SSHPageState extends State<SSHPage> { class _SSHPageState extends State<SSHPage> {
final _keyboard = locator<VirtualKeyboard>(); final _keyboard = locator<VirtualKeyboard>();
final _setting = locator<SettingStore>();
late final _terminal = Terminal(inputHandler: _keyboard); late final _terminal = Terminal(inputHandler: _keyboard);
final TerminalController _terminalController = TerminalController(); final TerminalController _terminalController = TerminalController();
final List<List<VirtKey>> _virtKeysList = []; final List<List<VirtKey>> _virtKeysList = [];
@@ -59,13 +59,13 @@ class _SSHPageState extends State<SSHPage> {
@override @override
void initState() { void initState() {
super.initState(); super.initState();
final fontFamilly = getFileName(_setting.fontPath.fetch()); final fontFamilly = getFileName(Stores.setting.fontPath.fetch());
final textStyle = TextStyle( final textStyle = TextStyle(
fontFamily: fontFamilly, fontFamily: fontFamilly,
fontSize: _setting.termFontSize.fetch(), fontSize: Stores.setting.termFontSize.fetch(),
); );
_terminalStyle = TerminalStyle.fromTextStyle(textStyle); _terminalStyle = TerminalStyle.fromTextStyle(textStyle);
_keyboardType = TextInputType.values[_setting.keyboardType.fetch()]; _keyboardType = TextInputType.values[Stores.setting.keyboardType.fetch()];
_initTerminal(); _initTerminal();
_initVirtKeys(); _initVirtKeys();
} }
@@ -89,7 +89,7 @@ class _SSHPageState extends State<SSHPage> {
_isDark = context.isDark; _isDark = context.isDark;
_media = MediaQuery.of(context); _media = MediaQuery.of(context);
_s = S.of(context)!; _s = S.of(context)!;
_terminalTheme = _isDark ? termDarkTheme : termLightTheme; _terminalTheme = _isDark ? TerminalThemes.dark : TerminalThemes.light;
// Because the virtual keyboard only displayed on mobile devices // Because the virtual keyboard only displayed on mobile devices
if (isMobile) { if (isMobile) {
@@ -299,7 +299,7 @@ class _SSHPageState extends State<SSHPage> {
} }
void _initVirtKeys() { void _initVirtKeys() {
final virtKeys = List<VirtKey>.from(_setting.sshVirtKeys.fetch()); final virtKeys = List<VirtKey>.from(Stores.setting.sshVirtKeys.fetch());
for (int len = 0; len < virtKeys.length; len += 7) { for (int len = 0; len < virtKeys.length; len += 7) {
if (len + 7 > virtKeys.length) { if (len + 7 > virtKeys.length) {
@@ -326,7 +326,7 @@ class _SSHPageState extends State<SSHPage> {
return _write('Sending password to auth...'); return _write('Sending password to auth...');
} }
}, },
timeout: _setting.timeoutD, timeout: Stores.setting.timeoutD,
); );
_write('Connected\r\n'); _write('Connected\r\n');
_write('Terminal size: ${_terminal.viewWidth}x${_terminal.viewHeight}\r\n'); _write('Terminal size: ${_terminal.viewWidth}x${_terminal.viewHeight}\r\n');

View File

@@ -10,7 +10,7 @@ import 'package:toolbox/core/extension/context/snackbar.dart';
import 'package:toolbox/core/extension/sftpfile.dart'; import 'package:toolbox/core/extension/sftpfile.dart';
import 'package:toolbox/data/res/logger.dart'; import 'package:toolbox/data/res/logger.dart';
import 'package:toolbox/data/res/misc.dart'; import 'package:toolbox/data/res/misc.dart';
import 'package:toolbox/data/store/history.dart'; import 'package:toolbox/data/res/store.dart';
import 'package:toolbox/view/widget/round_rect_card.dart'; import 'package:toolbox/view/widget/round_rect_card.dart';
import '../../../core/extension/numx.dart'; import '../../../core/extension/numx.dart';
@@ -26,7 +26,6 @@ import '../../../data/provider/server.dart';
import '../../../data/provider/sftp.dart'; import '../../../data/provider/sftp.dart';
import '../../../data/res/path.dart'; import '../../../data/res/path.dart';
import '../../../data/res/ui.dart'; import '../../../data/res/ui.dart';
import '../../../data/store/setting.dart';
import '../../../locator.dart'; import '../../../locator.dart';
import '../../widget/custom_appbar.dart'; import '../../widget/custom_appbar.dart';
import '../../widget/fade_in.dart'; import '../../widget/fade_in.dart';
@@ -53,8 +52,6 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
final SftpBrowserStatus _status = SftpBrowserStatus(); final SftpBrowserStatus _status = SftpBrowserStatus();
final _sftp = locator<SftpProvider>(); final _sftp = locator<SftpProvider>();
final _history = locator<HistoryStore>();
final _setting = locator<SettingStore>();
late S _s; late S _s;
@@ -228,10 +225,10 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
title: Text(_s.goto), title: Text(_s.goto),
child: Autocomplete<String>( child: Autocomplete<String>(
optionsBuilder: (val) { optionsBuilder: (val) {
if (!_setting.recordHistory.fetch()) { if (!Stores.setting.recordHistory.fetch()) {
return []; return [];
} }
return _history.sftpPath.all.where( return Stores.history.sftpPath.all.where(
(element) => element.contains(val.text), (element) => element.contains(val.text),
); );
}, },
@@ -254,7 +251,9 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
_status.path?.update(p); _status.path?.update(p);
final suc = await _listDir(path: p); final suc = await _listDir(path: p);
if (suc && _setting.recordHistory.fetch()) _history.sftpPath.add(p); if (suc && Stores.setting.recordHistory.fetch()) {
Stores.history.sftpPath.add(p);
}
}, },
icon: const Icon(Icons.gps_fixed), icon: const Icon(Icons.gps_fixed),
); );
@@ -429,7 +428,7 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
void _delete(BuildContext context, SftpName file) { void _delete(BuildContext context, SftpName file) {
context.pop(); context.pop();
final isDir = file.attr.isDirectory; final isDir = file.attr.isDirectory;
final useRmrf = _setting.sftpRmrfDir.fetch(); final useRmrf = Stores.setting.sftpRmrfDir.fetch();
final dirText = (isDir && !useRmrf) ? '\n${_s.sureDirEmpty}' : ''; final dirText = (isDir && !useRmrf) ? '\n${_s.sureDirEmpty}' : '';
final text = '${_s.sureDelete(file.filename)}$dirText'; final text = '${_s.sureDelete(file.filename)}$dirText';
final child = Text(text); final child = Text(text);

View File

@@ -476,9 +476,9 @@
baseConfigurationReference = C1C758C41C4E208965A68933 /* Pods-RunnerTests.debug.xcconfig */; baseConfigurationReference = C1C758C41C4E208965A68933 /* Pods-RunnerTests.debug.xcconfig */;
buildSettings = { buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)"; BUNDLE_LOADER = "$(TEST_HOST)";
CURRENT_PROJECT_VERSION = 547; CURRENT_PROJECT_VERSION = 550;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0.547; MARKETING_VERSION = 1.0.550;
PRODUCT_BUNDLE_IDENTIFIER = tech.lolli.serverBox.RunnerTests; PRODUCT_BUNDLE_IDENTIFIER = tech.lolli.serverBox.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
@@ -491,9 +491,9 @@
baseConfigurationReference = 15AF97DF993E8968098D6EBE /* Pods-RunnerTests.release.xcconfig */; baseConfigurationReference = 15AF97DF993E8968098D6EBE /* Pods-RunnerTests.release.xcconfig */;
buildSettings = { buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)"; BUNDLE_LOADER = "$(TEST_HOST)";
CURRENT_PROJECT_VERSION = 547; CURRENT_PROJECT_VERSION = 550;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0.547; MARKETING_VERSION = 1.0.550;
PRODUCT_BUNDLE_IDENTIFIER = tech.lolli.serverBox.RunnerTests; PRODUCT_BUNDLE_IDENTIFIER = tech.lolli.serverBox.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
@@ -506,9 +506,9 @@
baseConfigurationReference = 7CFA7DE7FABA75685DFB6948 /* Pods-RunnerTests.profile.xcconfig */; baseConfigurationReference = 7CFA7DE7FABA75685DFB6948 /* Pods-RunnerTests.profile.xcconfig */;
buildSettings = { buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)"; BUNDLE_LOADER = "$(TEST_HOST)";
CURRENT_PROJECT_VERSION = 547; CURRENT_PROJECT_VERSION = 550;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0.547; MARKETING_VERSION = 1.0.550;
PRODUCT_BUNDLE_IDENTIFIER = tech.lolli.serverBox.RunnerTests; PRODUCT_BUNDLE_IDENTIFIER = tech.lolli.serverBox.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;

View File

@@ -76,7 +76,7 @@ Future<Map<String, dynamic>> getBuildData() async {
'name': appName, 'name': appName,
'build': build, 'build': build,
'engine': await getFlutterVersion(), 'engine': await getFlutterVersion(),
'buildAt': DateTime.now().toString(), 'buildAt': DateTime.now().toString().split('.')[0],
'modifications': await getGitModificationCount(), 'modifications': await getGitModificationCount(),
'script': await getScriptCommitCount(), 'script': await getScriptCommitCount(),
}; };