From cbeaa9705f992e06f2409efa1f1f4a90b2506796 Mon Sep 17 00:00:00 2001 From: lollipopkit Date: Fri, 12 May 2023 18:35:56 +0800 Subject: [PATCH] #35 new: `servers` tab `reorderable` --- ios/Runner.xcodeproj/project.pbxproj | 12 ++++---- lib/data/provider/server.dart | 44 ++++++++++++++++++++++++---- lib/data/res/build_data.dart | 6 ++-- lib/data/store/setting.dart | 4 +++ lib/view/page/server/tab.dart | 41 ++++++++++---------------- macos/Podfile.lock | 4 +-- 6 files changed, 70 insertions(+), 41 deletions(-) diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 606379e7..a3500791 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -360,7 +360,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 295; + CURRENT_PROJECT_VERSION = 300; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -368,7 +368,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.295; + MARKETING_VERSION = 1.0.300; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -491,7 +491,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 295; + CURRENT_PROJECT_VERSION = 300; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -499,7 +499,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.295; + MARKETING_VERSION = 1.0.300; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -516,7 +516,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 295; + CURRENT_PROJECT_VERSION = 300; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -524,7 +524,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.295; + MARKETING_VERSION = 1.0.300; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; diff --git a/lib/data/provider/server.dart b/lib/data/provider/server.dart index 99ab0408..ad12bfd3 100644 --- a/lib/data/provider/server.dart +++ b/lib/data/provider/server.dart @@ -18,10 +18,31 @@ import '../store/server.dart'; import '../store/setting.dart'; typedef ServersMap = Map; +typedef ServerOrder = List; + +extension ServerOrderX on ServerOrder { + void move(int oldIndex, int newIndex) { + if (oldIndex == newIndex) return; + if (oldIndex < newIndex) { + newIndex -= 1; + } + final item = this[oldIndex]; + removeAt(oldIndex); + insert(newIndex, item); + locator().serverOrder.put(this); + } + + void update(String id, String newId) { + final index = indexOf(id); + if (index == -1) return; + this[index] = newId; + } +} class ServerProvider extends BusyProvider { final ServersMap _servers = {}; ServersMap get servers => _servers; + final ServerOrder serverOrder = []; final _limiter = TryLimiter(); @@ -29,14 +50,21 @@ class ServerProvider extends BusyProvider { final _logger = Logger('SERVER'); - final _store = locator(); + final _serverStore = locator(); + final _settingStore = locator(); Future loadLocalData() async { setBusyState(true); - final infos = _store.fetch(); + final infos = _serverStore.fetch(); for (final info in infos) { _servers[info.id] = genServer(info); } + final serverOrder_ = _settingStore.serverOrder.fetch(); + if (serverOrder_ != null) { + serverOrder.addAll(serverOrder_); + } else { + serverOrder.addAll(_servers.keys); + } setBusyState(false); notifyListeners(); } @@ -107,14 +135,18 @@ class ServerProvider extends BusyProvider { void addServer(ServerPrivateInfo spi) { _servers[spi.id] = genServer(spi); notifyListeners(); - _store.put(spi); + _serverStore.put(spi); + serverOrder.add(spi.id); + _settingStore.serverOrder.put(serverOrder); refreshData(spi: spi); } void delServer(String id) { _servers.remove(id); + serverOrder.remove(id); + _settingStore.serverOrder.put(serverOrder); notifyListeners(); - _store.delete(id); + _serverStore.delete(id); } Future updateServer( @@ -122,9 +154,11 @@ class ServerProvider extends BusyProvider { ServerPrivateInfo newSpi, ) async { _servers.remove(old.id); - _store.update(old, newSpi); + _serverStore.update(old, newSpi); _servers[newSpi.id] = genServer(newSpi); _servers[newSpi.id]?.client = await genClient(newSpi); + serverOrder.update(old.id, newSpi.id); + _settingStore.serverOrder.put(serverOrder); await refreshData(spi: newSpi); } diff --git a/lib/data/res/build_data.dart b/lib/data/res/build_data.dart index 9256750a..dc9bb754 100644 --- a/lib/data/res/build_data.dart +++ b/lib/data/res/build_data.dart @@ -2,8 +2,8 @@ class BuildData { static const String name = "ServerBox"; - static const int build = 295; + static const int build = 300; static const String engine = "3.10.0"; - static const String buildAt = "2023-05-11 12:17:12.803987"; - static const int modifications = 3; + static const String buildAt = "2023-05-12 16:42:47.988995"; + static const int modifications = 1; } diff --git a/lib/data/store/setting.dart b/lib/data/store/setting.dart index fb69649f..6ab0baf4 100644 --- a/lib/data/store/setting.dart +++ b/lib/data/store/setting.dart @@ -39,4 +39,8 @@ class SettingStore extends PersistentStore { /// Backgroud running (Android) StoreProperty get bgRun => property('bgRun', defaultValue: isAndroid); + + // Server order + StoreProperty> get serverOrder => + property('serverOrder', defaultValue: null); } diff --git a/lib/view/page/server/tab.dart b/lib/view/page/server/tab.dart index 753eed9a..e61ffdcd 100644 --- a/lib/view/page/server/tab.dart +++ b/lib/view/page/server/tab.dart @@ -83,7 +83,7 @@ class _ServerPageState extends State await _serverProvider.refreshData(onlyFailed: true), child: Consumer( builder: (_, pro, __) { - if (pro.servers.isEmpty) { + if (pro.serverOrder.isEmpty) { return Center( child: Text( _s.serverTabEmpty, @@ -91,21 +91,15 @@ class _ServerPageState extends State ), ); } - final keys = pro.servers.keys.toList(); - return ListView.separated( + return ReorderableListView( padding: const EdgeInsets.fromLTRB(7, 10, 7, 7), - controller: ScrollController(), physics: const AlwaysScrollableScrollPhysics(), - itemBuilder: (ctx, idx) { - if (idx == pro.servers.length) { - return SizedBox(height: _media.padding.bottom); - } - return _buildEachServerCard(pro.servers[keys[idx]]); - }, - itemCount: pro.servers.length, - separatorBuilder: (_, __) => const SizedBox( - height: 3, - ), + onReorder: (oldIndex, newIndex) => setState(() { + pro.serverOrder.move(oldIndex, newIndex); + }), + children: pro.serverOrder + .map((e) => _buildEachServerCard(pro.servers[e])) + .toList(), ); }, ), @@ -116,21 +110,18 @@ class _ServerPageState extends State if (si == null) { return const SizedBox(); } - return GestureDetector( - onLongPress: () => AppRoute( - ServerEditPage(spi: si.spi), - 'Edit server info page', - ).go(context), - child: RoundRectCard( - Padding( + return RoundRectCard( + GestureDetector( + child: Padding( padding: const EdgeInsets.all(13), child: _buildRealServerCard(si.status, si.spi.name, si.state, si.spi), ), + onTap: () => AppRoute( + ServerDetailPage(si.spi.id), + 'server detail page', + ).go(context), ), - onTap: () => AppRoute( - ServerDetailPage(si.spi.id), - 'server detail page', - ).go(context), + key: Key(si.spi.id), ); } diff --git a/macos/Podfile.lock b/macos/Podfile.lock index 8bfcdcc6..c740e770 100644 --- a/macos/Podfile.lock +++ b/macos/Podfile.lock @@ -10,7 +10,7 @@ PODS: DEPENDENCIES: - FlutterMacOS (from `Flutter/ephemeral`) - - path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/macos`) + - path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`) - share_plus (from `Flutter/ephemeral/.symlinks/plugins/share_plus/macos`) - url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`) @@ -18,7 +18,7 @@ EXTERNAL SOURCES: FlutterMacOS: :path: Flutter/ephemeral path_provider_foundation: - :path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/macos + :path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin share_plus: :path: Flutter/ephemeral/.symlinks/plugins/share_plus/macos url_launcher_macos: