Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save notmarkmiranda/4c1082981e4903a538ba7bcdc1e11e6a to your computer and use it in GitHub Desktop.
Save notmarkmiranda/4c1082981e4903a538ba7bcdc1e11e6a to your computer and use it in GitHub Desktop.
Undo/Redo with ChangeNotifier
import 'package:flutter/cupertino.dart';
class UndoChangeNotifier<T> extends ChangeNotifier {
final List<T> _history;
int _historyIndex = -1;
UndoChangeNotifier(T initialState) : _history = [initialState];
T get state => hasState ? _history[_historyIndex] : null;
bool get hasState => _history.isNotEmpty;
void updateState(T text) {
_history.add(text);
_historyIndex++;
notifyListeners();
}
void jumpTo(int index) {
_historyIndex = index;
notifyListeners();
}
void undo() {
_historyIndex--;
notifyListeners();
}
void redo() {
_historyIndex++;
notifyListeners();
}
void clear() {
_historyIndex = -1;
_history.clear();
}
}
import 'package:flutter_test/flutter_test.dart';
import 'package:untitled24/undo_change_notifier.dart';
void main() {
group('UndoChangeNotifier', () {
test('should start with an initial state', () {
final cn = UndoChangeNotifier('I');
expect(cn.state, 'I');
});
test('can update the state', () {
final cn = UndoChangeNotifier('I');
cn.updateState('N');
expect(cn.state, 'N');
});
test('can undo a change', () {
final cn = UndoChangeNotifier('I');
cn.updateState('N');
cn.undo();
expect(cn.state, 'I');
});
test('can redo a change', () {
final cn = UndoChangeNotifier('I');
cn.updateState('N');
cn.undo();
cn.redo();
expect(cn.state, 'N');
});
test('can clear the history', () {
final cn = UndoChangeNotifier('I');
cn.clear();
expect(cn.state, isNull);
});
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment