mirror of
https://github.com/lollipopkit/flutter_server_box.git
synced 2025-12-17 07:14:28 +01:00
fix: cant sort servers order (#930)
This commit is contained in:
@@ -58,7 +58,7 @@ final class PveNotifierProvider
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String _$pveNotifierHash() => r'b5da7240db1b9ee7d61f238cebca45821b7a3445';
|
String _$pveNotifierHash() => r'ba5f2d6cb47c33735f7cc09b771b4a86501b86c6';
|
||||||
|
|
||||||
final class PveNotifierFamily extends $Family
|
final class PveNotifierFamily extends $Family
|
||||||
with $ClassFamilyOverride<PveNotifier, PveState, PveState, PveState, Spi> {
|
with $ClassFamilyOverride<PveNotifier, PveState, PveState, PveState, Spi> {
|
||||||
|
|||||||
@@ -239,6 +239,50 @@ class ServersNotifier extends _$ServersNotifier {
|
|||||||
bakSync.sync(milliDelay: 1000);
|
bakSync.sync(milliDelay: 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void updateServerOrder(List<String> order) {
|
||||||
|
final seen = <String>{};
|
||||||
|
final newOrder = <String>[];
|
||||||
|
|
||||||
|
for (final id in order) {
|
||||||
|
if (!state.servers.containsKey(id)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!seen.add(id)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
newOrder.add(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (final id in state.servers.keys) {
|
||||||
|
if (seen.add(id)) {
|
||||||
|
newOrder.add(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_isSameOrder(newOrder, state.serverOrder)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
state = state.copyWith(serverOrder: newOrder);
|
||||||
|
Stores.setting.serverOrder.put(newOrder);
|
||||||
|
bakSync.sync(milliDelay: 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _isSameOrder(List<String> a, List<String> b) {
|
||||||
|
if (identical(a, b)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (a.length != b.length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (var i = 0; i < a.length; i++) {
|
||||||
|
if (a[i] != b[i]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> updateServer(Spi old, Spi newSpi) async {
|
Future<void> updateServer(Spi old, Spi newSpi) async {
|
||||||
if (old != newSpi) {
|
if (old != newSpi) {
|
||||||
Stores.server.update(old, newSpi);
|
Stores.server.update(old, newSpi);
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ final class ServersNotifierProvider
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String _$serversNotifierHash() => r'2b29ad3027a203c7a20bfd0142d384a503cbbcaa';
|
String _$serversNotifierHash() => r'3292bdce7d602ff64687b05ff81d120e71761ec2';
|
||||||
|
|
||||||
abstract class _$ServersNotifier extends $Notifier<ServersState> {
|
abstract class _$ServersNotifier extends $Notifier<ServersState> {
|
||||||
ServersState build();
|
ServersState build();
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ final class ServerNotifierProvider
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String _$serverNotifierHash() => r'd9724fbe6d132f2e2ea4dfa5af73aeab168e1c57';
|
String _$serverNotifierHash() => r'185c6b4546c3bc526f5b2ca79d16aed665818863';
|
||||||
|
|
||||||
final class ServerNotifierFamily extends $Family
|
final class ServerNotifierFamily extends $Family
|
||||||
with
|
with
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ final class SystemdNotifierProvider
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String _$systemdNotifierHash() => r'98466bd176518545be49cae52f8dbe12af3a88a6';
|
String _$systemdNotifierHash() => r'030d556efc3d897419cd3462d37cb705813e24c7';
|
||||||
|
|
||||||
final class SystemdNotifierFamily extends $Family
|
final class SystemdNotifierFamily extends $Family
|
||||||
with
|
with
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import 'dart:ui';
|
import 'dart:ui';
|
||||||
import 'package:fl_lib/fl_lib.dart';
|
import 'package:fl_lib/fl_lib.dart';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:server_box/core/extension/context/locale.dart';
|
import 'package:server_box/core/extension/context/locale.dart';
|
||||||
import 'package:server_box/data/model/server/server_private_info.dart';
|
import 'package:server_box/data/model/server/server_private_info.dart';
|
||||||
import 'package:server_box/data/provider/server/all.dart';
|
import 'package:server_box/data/provider/server/all.dart';
|
||||||
import 'package:server_box/data/res/store.dart';
|
|
||||||
|
|
||||||
class ServerOrderPage extends ConsumerStatefulWidget {
|
class ServerOrderPage extends ConsumerStatefulWidget {
|
||||||
const ServerOrderPage({super.key});
|
const ServerOrderPage({super.key});
|
||||||
@@ -17,15 +17,32 @@ class ServerOrderPage extends ConsumerStatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _ServerOrderPageState extends ConsumerState<ServerOrderPage> {
|
class _ServerOrderPageState extends ConsumerState<ServerOrderPage> {
|
||||||
|
late List<String> _order;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_order = List<String>.from(ref.read(serversProvider).serverOrder);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
ref.listen<ServersState>(serversProvider, (_, next) {
|
||||||
|
if (listEquals(_order, next.serverOrder)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setState(() {
|
||||||
|
_order = List<String>.from(next.serverOrder);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: CustomAppBar(title: Text(l10n.serverOrder)),
|
appBar: CustomAppBar(title: Text(l10n.serverOrder)),
|
||||||
body: _buildBody(),
|
body: _buildBody(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _proxyDecorator(Widget child, int index, Animation<double> animation) {
|
Widget _proxyDecorator(Widget child, int _, Animation<double> animation) {
|
||||||
return AnimatedBuilder(
|
return AnimatedBuilder(
|
||||||
animation: animation,
|
animation: animation,
|
||||||
builder: (BuildContext context, Widget? child) {
|
builder: (BuildContext context, Widget? child) {
|
||||||
@@ -37,13 +54,13 @@ class _ServerOrderPageState extends ConsumerState<ServerOrderPage> {
|
|||||||
child: Card(elevation: elevation, child: child),
|
child: Card(elevation: elevation, child: child),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
child: _buildCardTile(index),
|
child: child,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildBody() {
|
Widget _buildBody() {
|
||||||
final serverState = ref.watch(serversProvider);
|
final serverState = ref.watch(serversProvider);
|
||||||
final order = serverState.serverOrder;
|
final order = _order;
|
||||||
|
|
||||||
if (order.isEmpty) {
|
if (order.isEmpty) {
|
||||||
return Center(child: Text(libL10n.empty));
|
return Center(child: Text(libL10n.empty));
|
||||||
@@ -51,36 +68,47 @@ class _ServerOrderPageState extends ConsumerState<ServerOrderPage> {
|
|||||||
return ReorderableListView.builder(
|
return ReorderableListView.builder(
|
||||||
footer: const SizedBox(height: 77),
|
footer: const SizedBox(height: 77),
|
||||||
onReorder: (oldIndex, newIndex) {
|
onReorder: (oldIndex, newIndex) {
|
||||||
setState(() {
|
var targetIndex = newIndex;
|
||||||
|
if (targetIndex > oldIndex) {
|
||||||
|
targetIndex -= 1;
|
||||||
|
}
|
||||||
|
if (targetIndex == oldIndex) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
final newOrder = List<String>.from(order);
|
final newOrder = List<String>.from(order);
|
||||||
newOrder.move(oldIndex, newIndex);
|
final moved = newOrder.removeAt(oldIndex);
|
||||||
Stores.setting.serverOrder.put(newOrder);
|
newOrder.insert(targetIndex, moved);
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
_order = newOrder;
|
||||||
});
|
});
|
||||||
|
ref.read(serversProvider.notifier).updateServerOrder(newOrder);
|
||||||
},
|
},
|
||||||
padding: const EdgeInsets.all(8),
|
padding: const EdgeInsets.all(8),
|
||||||
buildDefaultDragHandles: false,
|
buildDefaultDragHandles: false,
|
||||||
itemBuilder: (_, idx) => _buildItem(idx, order[idx]),
|
itemBuilder: (_, idx) {
|
||||||
|
final id = order[idx];
|
||||||
|
final spi = serverState.servers[id];
|
||||||
|
return _buildItem(idx, id, spi);
|
||||||
|
},
|
||||||
itemCount: order.length,
|
itemCount: order.length,
|
||||||
proxyDecorator: _proxyDecorator,
|
proxyDecorator: _proxyDecorator,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildItem(int index, String id) {
|
Widget _buildItem(int index, String id, Spi? spi) {
|
||||||
return ReorderableDelayedDragStartListener(
|
return ReorderableDelayedDragStartListener(
|
||||||
key: ValueKey('server_item_$id'),
|
key: ValueKey('server_item_$id'),
|
||||||
index: index,
|
index: index,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(bottom: 8),
|
padding: const EdgeInsets.only(bottom: 3),
|
||||||
child: CardX(child: _buildCardTile(index)),
|
child: _buildCardTile(index, spi).cardx,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildCardTile(int index) {
|
Widget _buildCardTile(int index, Spi? spi) {
|
||||||
final serverState = ref.watch(serversProvider);
|
|
||||||
final order = serverState.serverOrder;
|
|
||||||
final id = order[index];
|
|
||||||
final spi = serverState.servers[id];
|
|
||||||
if (spi == null) {
|
if (spi == null) {
|
||||||
return const SizedBox();
|
return const SizedBox();
|
||||||
}
|
}
|
||||||
@@ -89,8 +117,6 @@ class _ServerOrderPageState extends ConsumerState<ServerOrderPage> {
|
|||||||
title: Text(spi.name, style: const TextStyle(fontWeight: FontWeight.w500)),
|
title: Text(spi.name, style: const TextStyle(fontWeight: FontWeight.w500)),
|
||||||
subtitle: Text(spi.oldId, style: UIs.textGrey),
|
subtitle: Text(spi.oldId, style: UIs.textGrey),
|
||||||
leading: CircleAvatar(
|
leading: CircleAvatar(
|
||||||
backgroundColor: Theme.of(context).colorScheme.primary,
|
|
||||||
foregroundColor: Theme.of(context).colorScheme.onPrimary,
|
|
||||||
child: Text(spi.name[0]),
|
child: Text(spi.name[0]),
|
||||||
),
|
),
|
||||||
trailing: ReorderableDragStartListener(index: index, child: const Icon(Icons.drag_handle)),
|
trailing: ReorderableDragStartListener(index: index, child: const Icon(Icons.drag_handle)),
|
||||||
|
|||||||
Reference in New Issue
Block a user