fix: sync will refresh the entire app (#877)

This commit is contained in:
lollipopkit🏳️‍⚧️
2025-09-01 01:18:06 +08:00
committed by GitHub
parent 3b7fdf36fb
commit 56e67f4725
7 changed files with 54 additions and 30 deletions

View File

@@ -4,6 +4,9 @@ import 'dart:io';
import 'package:fl_lib/fl_lib.dart'; import 'package:fl_lib/fl_lib.dart';
import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:logging/logging.dart'; import 'package:logging/logging.dart';
import 'package:server_box/data/provider/private_key.dart';
import 'package:server_box/data/provider/server/all.dart';
import 'package:server_box/data/provider/snippet.dart';
import 'package:server_box/data/res/misc.dart'; import 'package:server_box/data/res/misc.dart';
import 'package:server_box/data/res/store.dart'; import 'package:server_box/data/res/store.dart';
@@ -44,17 +47,17 @@ abstract class BackupV2 with _$BackupV2 implements Mergeable {
Future<void> merge({bool force = false}) async { Future<void> merge({bool force = false}) async {
_loggerV2.info('Merging...'); _loggerV2.info('Merging...');
// Merge each store // Merge each store and check if changes were made
await Mergeable.mergeStore(backupData: spis, store: Stores.server, force: force); final serverChanged = await Mergeable.mergeStore(backupData: spis, store: Stores.server, force: force);
await Mergeable.mergeStore(backupData: snippets, store: Stores.snippet, force: force); final snippetChanged = await Mergeable.mergeStore(backupData: snippets, store: Stores.snippet, force: force);
await Mergeable.mergeStore(backupData: keys, store: Stores.key, force: force); final keyChanged = await Mergeable.mergeStore(backupData: keys, store: Stores.key, force: force);
await Mergeable.mergeStore(backupData: container, store: Stores.container, force: force); await Mergeable.mergeStore(backupData: container, store: Stores.container, force: force);
await Mergeable.mergeStore(backupData: history, store: Stores.history, force: force); await Mergeable.mergeStore(backupData: history, store: Stores.history, force: force);
await Mergeable.mergeStore(backupData: settings, store: Stores.setting, force: force); await Mergeable.mergeStore(backupData: settings, store: Stores.setting, force: force);
// Reload providers and notify listeners if (serverChanged) GlobalRef.gRef?.read(serversNotifierProvider.notifier).reload();
Provider.reload(); if (snippetChanged) GlobalRef.gRef?.read(snippetNotifierProvider.notifier).reload();
RNodes.app.notify(); if (keyChanged) GlobalRef.gRef?.read(privateKeyNotifierProvider.notifier).reload();
_loggerV2.info('Merge completed'); _loggerV2.info('Merge completed');
} }

View File

@@ -9,17 +9,25 @@ part 'private_key.g.dart';
@freezed @freezed
abstract class PrivateKeyState with _$PrivateKeyState { abstract class PrivateKeyState with _$PrivateKeyState {
const factory PrivateKeyState({ const factory PrivateKeyState({@Default(<PrivateKeyInfo>[]) List<PrivateKeyInfo> keys}) = _PrivateKeyState;
@Default(<PrivateKeyInfo>[]) List<PrivateKeyInfo> keys,
}) = _PrivateKeyState;
} }
@Riverpod(keepAlive: true) @Riverpod(keepAlive: true)
class PrivateKeyNotifier extends _$PrivateKeyNotifier { class PrivateKeyNotifier extends _$PrivateKeyNotifier {
@override @override
PrivateKeyState build() { PrivateKeyState build() {
return _load();
}
void reload() {
final newState = _load();
if (newState == state) return;
state = newState;
}
PrivateKeyState _load() {
final keys = Stores.key.fetch(); final keys = Stores.key.fetch();
return PrivateKeyState(keys: keys); return stateOrNull?.copyWith(keys: keys) ?? PrivateKeyState(keys: keys);
} }
void add(PrivateKeyInfo info) { void add(PrivateKeyInfo info) {

View File

@@ -1,4 +1,3 @@
import 'dart:async'; import 'dart:async';
import 'package:fl_lib/fl_lib.dart'; import 'package:fl_lib/fl_lib.dart';
@@ -30,12 +29,17 @@ abstract class ServersState with _$ServersState {
class ServersNotifier extends _$ServersNotifier { class ServersNotifier extends _$ServersNotifier {
@override @override
ServersState build() { ServersState build() {
// Initialize with empty state, load data asynchronously return _load();
Future.microtask(() => _load());
return const ServersState();
} }
Future<void> _load() async { Future<void> reload() async {
final newState = _load();
if (newState == state) return;
state = newState;
await refresh();
}
ServersState _load() {
final spis = Stores.server.fetch(); final spis = Stores.server.fetch();
final newServers = <String, Spi>{}; final newServers = <String, Spi>{};
final newServerOrder = <String>[]; final newServerOrder = <String>[];
@@ -59,7 +63,8 @@ class ServersNotifier extends _$ServersNotifier {
final newTags = _calculateTags(newServers); final newTags = _calculateTags(newServers);
state = state.copyWith(servers: newServers, serverOrder: newServerOrder, tags: newTags); return stateOrNull?.copyWith(servers: newServers, serverOrder: newServerOrder, tags: newTags) ??
ServersState(servers: newServers, serverOrder: newServerOrder, tags: newTags);
} }
Set<String> _calculateTags(Map<String, Spi> servers) { Set<String> _calculateTags(Map<String, Spi> servers) {
@@ -270,4 +275,4 @@ class ServersNotifier extends _$ServersNotifier {
} }
bakSync.sync(milliDelay: 1000); bakSync.sync(milliDelay: 1000);
} }
} }

View File

@@ -20,24 +20,32 @@ abstract class SnippetState with _$SnippetState {
class SnippetNotifier extends _$SnippetNotifier { class SnippetNotifier extends _$SnippetNotifier {
@override @override
SnippetState build() { SnippetState build() {
return _load();
}
void reload() {
final newState = _load();
if (newState == state) return;
state = newState;
}
SnippetState _load() {
final snippets = Stores.snippet.fetch(); final snippets = Stores.snippet.fetch();
final order = Stores.setting.snippetOrder.fetch(); final order = Stores.setting.snippetOrder.fetch();
List<Snippet> orderedSnippets = snippets; List<Snippet> orderedSnippets = snippets;
if (order.isNotEmpty) { if (order.isNotEmpty) {
final surplus = snippets.reorder( final surplus = snippets.reorder(order: order, finder: (n, name) => n.name == name);
order: order,
finder: (n, name) => n.name == name,
);
order.removeWhere((e) => surplus.any((ele) => ele == e)); order.removeWhere((e) => surplus.any((ele) => ele == e));
if (order != Stores.setting.snippetOrder.fetch()) { if (order != Stores.setting.snippetOrder.fetch()) {
Stores.setting.snippetOrder.put(order); Stores.setting.snippetOrder.put(order);
} }
orderedSnippets = snippets; orderedSnippets = snippets;
} }
final tags = _computeTags(orderedSnippets); final newTags = _computeTags(orderedSnippets);
return SnippetState(snippets: orderedSnippets, tags: tags); return stateOrNull?.copyWith(snippets: orderedSnippets, tags: newTags) ??
SnippetState(snippets: orderedSnippets, tags: newTags);
} }
Set<String> _computeTags(List<Snippet> snippets) { Set<String> _computeTags(List<Snippet> snippets) {

View File

@@ -22,7 +22,7 @@ class HomePage extends ConsumerStatefulWidget {
} }
class _HomePageState extends ConsumerState<HomePage> class _HomePageState extends ConsumerState<HomePage>
with AutomaticKeepAliveClientMixin, AfterLayoutMixin, WidgetsBindingObserver { with AutomaticKeepAliveClientMixin, AfterLayoutMixin, WidgetsBindingObserver, GlobalRef {
late final PageController _pageController; late final PageController _pageController;
final _selectIndex = ValueNotifier(0); final _selectIndex = ValueNotifier(0);

View File

@@ -497,8 +497,8 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
path: "." path: "."
ref: "v1.0.344" ref: "v1.0.345"
resolved-ref: "9c7dd603b125fa3ca7a65d466c8fb41383997bd3" resolved-ref: "1b797643ef7603dd825caf96a6c57b88dbd23c34"
url: "https://github.com/lppcg/fl_lib" url: "https://github.com/lppcg/fl_lib"
source: git source: git
version: "0.0.1" version: "0.0.1"

View File

@@ -63,7 +63,7 @@ dependencies:
fl_lib: fl_lib:
git: git:
url: https://github.com/lppcg/fl_lib url: https://github.com/lppcg/fl_lib
ref: v1.0.344 ref: v1.0.345
flutter_gbk2utf8: ^1.0.1 flutter_gbk2utf8: ^1.0.1
dependency_overrides: dependency_overrides: