Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save ThinkDigitalSoftware/737e6007f496f581285367d2d6afd42e to your computer and use it in GitHub Desktop.

Select an option

Save ThinkDigitalSoftware/737e6007f496f581285367d2d6afd42e to your computer and use it in GitHub Desktop.

Revisions

  1. ThinkDigitalSoftware revised this gist Apr 9, 2020. 1 changed file with 68 additions and 0 deletions.
    68 changes: 68 additions & 0 deletions state_persisting_change_notifier.dart
    Original file line number Diff line number Diff line change
    @@ -52,3 +52,71 @@ abstract class StatePersistingChangeNotifier<T extends SerializableClass>
    abstract class SerializableClass<T> {
    Map<String, dynamic> toJson();
    }



    class SettingsNotifier extends StatePersistingChangeNotifier<SettingsState> {
    @override
    SettingsState get initialState => SettingsState.initial();

    static SettingsNotifier of(BuildContext context, {bool listen = false}) =>
    Provider.of<SettingsNotifier>(context, listen: listen);

    void changeViewMode(ViewMode viewMode) =>
    state = state.copyWith(viewMode: viewMode);

    @override
    SettingsState fromJson(Map<dynamic, dynamic> json) {
    return SettingsState.fromJson(json);
    }
    }

    @immutable
    class SettingsState extends SerializableClass {
    final ViewMode viewMode;

    SettingsState({@required this.viewMode});

    @override
    String toString() {
    return 'SettingsState{viewMode: $viewMode}';
    }

    SettingsState.initial() : viewMode = ViewMode.card;

    @override
    factory SettingsState.fromJson(Map json) {
    if (json == null) {
    return SettingsState.initial();
    }
    return SettingsState(
    viewMode: viewModeFromString(json['viewMode']),
    );
    }

    @override
    Map<String, dynamic> toJson() => {'viewMode': viewMode.toString()};

    static ViewMode viewModeFromString(String viewModeString) {
    switch (viewModeString) {
    case 'ViewMode.card':
    return ViewMode.card;
    case 'ViewMode.gallery':
    return ViewMode.gallery;
    default:
    {
    debugPrint(
    '$viewModeString is not a supported ViewMode setting. Returning ViewMode.card');
    return ViewMode.card;
    }
    }
    }

    SettingsState copyWith({
    ViewMode viewMode,
    }) =>
    SettingsState(
    viewMode: viewMode ?? this.viewMode,
    );
    }

  2. ThinkDigitalSoftware created this gist Apr 9, 2020.
    54 changes: 54 additions & 0 deletions state_persisting_change_notifier.dart
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,54 @@
    import 'dart:async';

    import 'package:flutter/cupertino.dart';
    import 'package:flutter/foundation.dart';
    import 'package:fritter_for_reddit/exports.dart';
    import 'package:hive/hive.dart';

    /// Every time notifyListeners is called, the state is persisted to allow easy app persistence.
    /// Persistence is based on Hive with a box opened with the class name.
    /// If this is not desired, supply an alternative [boxName] in the constructor.
    ///
    /// Listeners are automatically notified whenever [state] changes.
    abstract class StatePersistingChangeNotifier<T extends SerializableClass>
    extends ChangeNotifier {
    final Completer<bool> isInitializedCompleter = Completer();

    Future<bool> get initializationFuture => isInitializedCompleter.future;

    Box _storage;
    T _state;

    T get state => _state;

    set state(T state) {
    _state = state;
    writeState(state);
    notifyListeners();
    }

    StatePersistingChangeNotifier({String boxName}) {
    _state = initialState;
    Hive.openBox(boxName ?? runtimeType.toString()).then((box) {
    _storage = box;
    isInitializedCompleter.complete(true);
    state = fromJson(_storage.get('state')) ?? initialState;
    notifyListeners();
    });
    }

    T fromJson(Map json);

    @mustCallSuper
    void writeState(T state) async {
    await initializationFuture;
    debugPrint('Writing state: $state');
    _storage.put('state', state.toJson());
    }

    T get initialState;
    }

    abstract class SerializableClass<T> {
    Map<String, dynamic> toJson();
    }