improved performance and battery usage on older devices
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import 'dart:async';
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:hydrated_bloc/hydrated_bloc.dart';
|
||||
|
||||
import '../../../../../storage/settings.dart';
|
||||
@@ -10,6 +11,8 @@ import '../../../../../view/pages/settings/data/default_settings.dart';
|
||||
class SettingsCubit extends HydratedCubit<Settings> {
|
||||
static const _debounceTag = 'settings_persist';
|
||||
bool _emitScheduled = false;
|
||||
Map<String, dynamic>? _lastEmittedJson;
|
||||
Timer? _silentSave;
|
||||
|
||||
SettingsCubit() : super(DefaultSettings.get());
|
||||
|
||||
@@ -34,21 +37,53 @@ class SettingsCubit extends HydratedCubit<Settings> {
|
||||
return state;
|
||||
}
|
||||
|
||||
/// Persists in-place mutations without notifying listeners. For high-frequency
|
||||
/// writes nobody renders live (chat drafts per keystroke): a regular write
|
||||
/// would rebuild the app root and every settings watcher on each change.
|
||||
void saveSilently() {
|
||||
_silentSave?.cancel();
|
||||
_silentSave = Timer(const Duration(milliseconds: 800), flushSilentSave);
|
||||
}
|
||||
|
||||
/// Writes a pending [saveSilently] right away (e.g. when the app pauses).
|
||||
void flushSilentSave() {
|
||||
if (_silentSave == null) return;
|
||||
_silentSave!.cancel();
|
||||
_silentSave = null;
|
||||
HydratedBloc.storage.write(storageToken, state.toJson());
|
||||
}
|
||||
|
||||
void _emitFreshInstance() {
|
||||
try {
|
||||
emit(Settings.fromJson(state.toJson()));
|
||||
final json = state.toJson();
|
||||
// The debounced emit usually follows the microtask emit with identical
|
||||
// content; skip it instead of rebuilding every listener a second time.
|
||||
if (const DeepCollectionEquality().equals(json, _lastEmittedJson)) {
|
||||
return;
|
||||
}
|
||||
_lastEmittedJson = json;
|
||||
emit(Settings.fromJson(json));
|
||||
} catch (e) {
|
||||
log('Failed to refresh settings state: $e');
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> reset() async {
|
||||
_silentSave?.cancel();
|
||||
_silentSave = null;
|
||||
_lastEmittedJson = null;
|
||||
emit(DefaultSettings.get());
|
||||
}
|
||||
|
||||
// Modules missing from a stale persisted moduleOrder are handled at read
|
||||
// time by AppModule.effectiveModuleOrder (inserted at their default
|
||||
// position) — no healing on hydration needed.
|
||||
@override
|
||||
Future<void> close() {
|
||||
flushSilentSave();
|
||||
return super.close();
|
||||
}
|
||||
|
||||
@override
|
||||
Settings fromJson(Map<String, dynamic> json) {
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user