aves_mio18/lib/remote/remote_state_store.dart
2026-04-14 09:53:02 +02:00

85 lines
2.4 KiB
Dart

import 'dart:convert';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:uuid/uuid.dart';
class RemoteStateStore {
static const _storage = FlutterSecureStorage(
aOptions: AndroidOptions(
encryptedSharedPreferences: true,
resetOnError: true,
),
);
static const _kWsSessionId = 'ws_session_id';
static const _kProcessedRing = 'ws_processed_events_ring';
static const _kLastSyncIso = 'remote_last_sync_iso';
Future<String> getOrCreateSessionId() async {
var id = await _storage.read(key: _kWsSessionId);
if (id == null || id.isEmpty) {
id = const Uuid().v4();
await _storage.write(key: _kWsSessionId, value: id);
}
return id;
}
Future<void> clearSessionId() => _storage.delete(key: _kWsSessionId);
Future<String?> getLastSyncIso() => _storage.read(key: _kLastSyncIso);
Future<void> setLastSyncIso(String iso) => _storage.write(key: _kLastSyncIso, value: iso);
Future<List<String>> loadProcessedRing({int maxSize = 2000}) async {
final raw = await _storage.read(key: _kProcessedRing);
if (raw == null || raw.isEmpty) return <String>[];
try {
final v = jsonDecode(raw);
if (v is List) {
final list = v.whereType<String>().toList();
return list.length > maxSize ? list.sublist(list.length - maxSize) : list;
}
} catch (_) {}
return <String>[];
}
Future<void> saveProcessedRing(List<String> ring, {int maxSize = 2000}) async {
final trimmed = ring.length > maxSize ? ring.sublist(ring.length - maxSize) : ring;
await _storage.write(key: _kProcessedRing, value: jsonEncode(trimmed));
}
}
class EventRingDeduper {
EventRingDeduper(this.store, {this.maxSize = 2000});
final RemoteStateStore store;
final int maxSize;
final List<String> _ring = [];
final Set<String> _set = {};
Future<void> init() async {
final saved = await store.loadProcessedRing(maxSize: maxSize);
_ring
..clear()
..addAll(saved);
_set
..clear()
..addAll(saved);
}
bool has(String? id) => id != null && id.isNotEmpty && _set.contains(id);
Future<void> mark(String? id) async {
if (id == null || id.isEmpty) return;
if (_set.contains(id)) return;
_ring.add(id);
_set.add(id);
while (_ring.length > maxSize) {
final old = _ring.removeAt(0);
_set.remove(old);
}
await store.saveProcessedRing(_ring, maxSize: maxSize);
}
}