Line data Source code
1 : import 'state_notifier.dart'; 2 : 3 : /// a mixin to allows you save a state as a JSON in any local database 4 : mixin PersistentStateMixin<State> on StateNotifier<State> { 5 : State? _state; 6 : 7 : /// the storage sho save and return a cached state 8 : PersistentStateStorage get storage; 9 : 10 : ///a unique key to identifier the state into the storage 11 : String get storageKey; 12 : 13 : /// convert a JSON to one instance of [State] 14 : State? fromJson(Map<String, dynamic> json); 15 : 16 : /// convert one instance of [State] to a JSON 17 : /// to be saved into the storage 18 : /// 19 : /// **IMPORTANT** if this method returns `null` the current state saved 20 : /// won't be modified 21 : Map<String, dynamic>? toJson(State state); 22 : 23 : /// a callback to listen when a cached storage couldn't be parsed 24 : /// or if the state couldn't be saved 25 1 : void onPersistentStateError(Object? e, StackTrace s) {} 26 : 27 3 : @override 28 : State get state { 29 : try { 30 3 : if (_state != null) { 31 3 : return _state!; 32 : } 33 9 : final cachedStateAsJson = storage.get(storageKey); 34 : 35 : final cachedState = cachedStateAsJson != null 36 3 : ? fromJson( 37 : cachedStateAsJson, 38 : ) 39 : : null; 40 : 41 : if (cachedState != null) { 42 2 : _state = cachedState; 43 2 : return _state!; 44 : } 45 6 : _state = super.state; 46 3 : return _state!; 47 : } catch (e, s) { 48 2 : _state = super.state; 49 1 : onPersistentStateError(e, s); 50 1 : return _state!; 51 : } 52 : } 53 : 54 3 : @override 55 : void onStateChanged(State oldState, State currentState) { 56 3 : _state = currentState; 57 3 : final json = toJson(currentState); 58 : if (json != null) { 59 3 : storage 60 3 : .save( 61 3 : storageKey, 62 : json, 63 : ) 64 3 : .onError( 65 3 : onPersistentStateError, 66 : ); 67 : } 68 : } 69 : } 70 : 71 : /// this class defines a storage interface for any StateNotifier 72 : /// that implements the [PersistentStateMixin] 73 : abstract class PersistentStateStorage { 74 : /// return a saved state by key 75 : Map<String, dynamic>? get(String key); 76 : 77 : /// save the state as a json string 78 : Future<void> save(String key, Map<String, dynamic> json); 79 : 80 : /// delete a cached state from the storage 81 : Future<void> delete(String key); 82 : 83 : /// delete all states in your storage 84 : Future<void> deleteAll(); 85 : }