From b698e89b76d37f5474b73ec4c879c55b22d856d4 Mon Sep 17 00:00:00 2001 From: CodeDoctorDE Date: Sun, 17 Jul 2022 07:55:02 +0200 Subject: [PATCH] Move save state in current index cubit to allow undo/redo --- app/lib/bloc/document_bloc.dart | 26 ++++--- app/lib/bloc/document_state.dart | 22 +++--- app/lib/cubits/current_index.dart | 7 ++ app/lib/cubits/current_index.freezed.dart | 70 +++++++++++++++++-- app/lib/dialogs/file_system/menu.dart | 10 ++- .../metadata/android/en-US/changelogs/33.txt | 1 + 6 files changed, 99 insertions(+), 37 deletions(-) diff --git a/app/lib/bloc/document_bloc.dart b/app/lib/bloc/document_bloc.dart index 3ed6b9183efa..7bb690b09523 100644 --- a/app/lib/bloc/document_bloc.dart +++ b/app/lib/bloc/document_bloc.dart @@ -440,18 +440,18 @@ class DocumentBloc extends ReplayBloc { .createTemplate(current.document); if (event.deleteDocument) { - emit(current.copyWith( + current.currentIndexCubit.setSaveState( location: - AssetLocation(remote: remote?.identifier ?? '', path: ''))); + AssetLocation(remote: remote?.identifier ?? '', path: '')); } }); on((event, emit) { final current = state; if (current is! DocumentLoadSuccess) return; if (!(current.embedding?.editable ?? true)) return; - emit(current.copyWith( + current.currentIndexCubit.setSaveState( location: AssetLocation( - remote: current.location.remote, path: event.location))); + remote: current.location.remote, path: event.location)); }); on((event, emit) async { final current = state; @@ -507,8 +507,8 @@ class DocumentBloc extends ReplayBloc { final current = state; if (current is! DocumentLoadSuccess) return; if (!(current.embedding?.editable ?? true)) return; - emit(current.copyWith(saved: true, location: event.location)); - if (current.location.path == '') clearHistory(); + current.currentIndexCubit + .setSaveState(saved: true, location: event.location); }); } @@ -524,10 +524,8 @@ class DocumentBloc extends ReplayBloc { elements = List>.from(elements) ..addAll(unbakedElements); } - var nextState = current.copyWith( - saved: false, - document: current.document.copyWith(updatedAt: DateTime.now()), - ); + emit(current); + if (unbakedElements == null) { current.currentIndexCubit.unbake( unbakedElements: List>.from(elements) @@ -535,18 +533,18 @@ class DocumentBloc extends ReplayBloc { } else { current.currentIndexCubit.withUnbaked(elements); } + if (current.embedding != null) { - emit(nextState); + current.currentIndexCubit.setSaveState(saved: true); return; } - emit(nextState); AssetLocation? path = current.location; if (current.hasAutosave()) { - path = await nextState.save(); + path = await current.save(); var currentState = state; if (currentState is! DocumentLoadSuccess) return; if (currentState.location.path == '' && state is DocumentLoadSuccess) { - emit(currentState.copyWith(location: path, saved: true)); + current.currentIndexCubit.setSaveState(saved: true, location: path); clearHistory(); } } diff --git a/app/lib/bloc/document_state.dart b/app/lib/bloc/document_state.dart index 200c76f0ba5a..31724449e044 100644 --- a/app/lib/bloc/document_state.dart +++ b/app/lib/bloc/document_state.dart @@ -16,7 +16,6 @@ class DocumentLoadInProgress extends DocumentState {} class DocumentLoadSuccess extends DocumentState { final AppDocument document; - final AssetLocation location; final StorageType storageType; final String currentLayer; final int currentAreaIndex; @@ -24,18 +23,21 @@ class DocumentLoadSuccess extends DocumentState { final SettingsCubit settingsCubit; final CurrentIndexCubit currentIndexCubit; final Embedding? embedding; - final bool saved; - const DocumentLoadSuccess(this.document, - {required this.location, + DocumentLoadSuccess(this.document, + {AssetLocation? location, this.storageType = StorageType.local, - this.saved = true, + bool saved = true, required this.settingsCubit, required this.currentIndexCubit, this.currentAreaIndex = -1, this.currentLayer = '', this.embedding, - this.invisibleLayers = const []}); + this.invisibleLayers = const []}) { + if (location != null) { + currentIndexCubit.setSaveState(location: location, saved: saved); + } + } @override List get props => [ @@ -61,6 +63,9 @@ class DocumentLoadSuccess extends DocumentState { List> get renderers => currentIndexCubit.renderers; + AssetLocation get location => currentIndexCubit.state.location; + bool get saved => currentIndexCubit.state.saved; + Future load() async { final background = Renderer.fromInstance(document.background); await background.setup(document); @@ -74,22 +79,19 @@ class DocumentLoadSuccess extends DocumentState { DocumentLoadSuccess copyWith({ AppDocument? document, bool? editMode, - AssetLocation? location, String? currentLayer, int? currentAreaIndex, - bool? saved, List? invisibleLayers, }) => DocumentLoadSuccess( document ?? this.document, - location: location ?? this.location, invisibleLayers: invisibleLayers ?? this.invisibleLayers, currentLayer: currentLayer ?? this.currentLayer, currentAreaIndex: currentAreaIndex ?? this.currentAreaIndex, - saved: saved ?? this.saved, settingsCubit: settingsCubit, embedding: embedding, currentIndexCubit: currentIndexCubit, + location: location, ); bool isLayerVisible(String layer) => !invisibleLayers.contains(layer); diff --git a/app/lib/cubits/current_index.dart b/app/lib/cubits/current_index.dart index ef0d028c992c..b5e3e959a140 100644 --- a/app/lib/cubits/current_index.dart +++ b/app/lib/cubits/current_index.dart @@ -38,6 +38,8 @@ class CurrentIndex with _$CurrentIndex { List? temporarySelections, @Default([]) List pointers, @Default(CameraViewport.unbaked()) CameraViewport cameraViewport, + @Default(AssetLocation(path: '')) AssetLocation location, + @Default(false) bool saved, }) = _CurrentIndex; bool get moveEnabled => @@ -331,4 +333,9 @@ class CurrentIndexCubit extends Cubit { emit(state.copyWith( cameraViewport: state.cameraViewport.withUnbaked(unbakedElements))); } + + void setSaveState({AssetLocation? location, bool? saved}) { + emit(state.copyWith( + location: location ?? state.location, saved: saved ?? state.saved)); + } } diff --git a/app/lib/cubits/current_index.freezed.dart b/app/lib/cubits/current_index.freezed.dart index a721f07b70b3..03aaa9218f75 100644 --- a/app/lib/cubits/current_index.freezed.dart +++ b/app/lib/cubits/current_index.freezed.dart @@ -29,6 +29,8 @@ mixin _$CurrentIndex { List? get temporarySelections => throw _privateConstructorUsedError; List get pointers => throw _privateConstructorUsedError; CameraViewport get cameraViewport => throw _privateConstructorUsedError; + AssetLocation get location => throw _privateConstructorUsedError; + bool get saved => throw _privateConstructorUsedError; @JsonKey(ignore: true) $CurrentIndexCopyWith get copyWith => @@ -52,7 +54,11 @@ abstract class $CurrentIndexCopyWith<$Res> { List? temporaryForegrounds, List? temporarySelections, List pointers, - CameraViewport cameraViewport}); + CameraViewport cameraViewport, + AssetLocation location, + bool saved}); + + $AssetLocationCopyWith<$Res> get location; } /// @nodoc @@ -77,6 +83,8 @@ class _$CurrentIndexCopyWithImpl<$Res> implements $CurrentIndexCopyWith<$Res> { Object? temporarySelections = freezed, Object? pointers = freezed, Object? cameraViewport = freezed, + Object? location = freezed, + Object? saved = freezed, }) { return _then(_value.copyWith( index: index == freezed @@ -127,8 +135,23 @@ class _$CurrentIndexCopyWithImpl<$Res> implements $CurrentIndexCopyWith<$Res> { ? _value.cameraViewport : cameraViewport // ignore: cast_nullable_to_non_nullable as CameraViewport, + location: location == freezed + ? _value.location + : location // ignore: cast_nullable_to_non_nullable + as AssetLocation, + saved: saved == freezed + ? _value.saved + : saved // ignore: cast_nullable_to_non_nullable + as bool, )); } + + @override + $AssetLocationCopyWith<$Res> get location { + return $AssetLocationCopyWith<$Res>(_value.location, (value) { + return _then(_value.copyWith(location: value)); + }); + } } /// @nodoc @@ -150,7 +173,12 @@ abstract class _$$_CurrentIndexCopyWith<$Res> List? temporaryForegrounds, List? temporarySelections, List pointers, - CameraViewport cameraViewport}); + CameraViewport cameraViewport, + AssetLocation location, + bool saved}); + + @override + $AssetLocationCopyWith<$Res> get location; } /// @nodoc @@ -178,6 +206,8 @@ class __$$_CurrentIndexCopyWithImpl<$Res> Object? temporarySelections = freezed, Object? pointers = freezed, Object? cameraViewport = freezed, + Object? location = freezed, + Object? saved = freezed, }) { return _then(_$_CurrentIndex( index == freezed @@ -228,6 +258,14 @@ class __$$_CurrentIndexCopyWithImpl<$Res> ? _value.cameraViewport : cameraViewport // ignore: cast_nullable_to_non_nullable as CameraViewport, + location: location == freezed + ? _value.location + : location // ignore: cast_nullable_to_non_nullable + as AssetLocation, + saved: saved == freezed + ? _value.saved + : saved // ignore: cast_nullable_to_non_nullable + as bool, )); } } @@ -244,7 +282,9 @@ class _$_CurrentIndex extends _CurrentIndex { final List? temporaryForegrounds, final List? temporarySelections, final List pointers = const [], - this.cameraViewport = const CameraViewport.unbaked()}) + this.cameraViewport = const CameraViewport.unbaked(), + this.location = const AssetLocation(path: ''), + this.saved = false}) : _foregrounds = foregrounds, _selections = selections, _temporaryForegrounds = temporaryForegrounds, @@ -309,10 +349,16 @@ class _$_CurrentIndex extends _CurrentIndex { @override @JsonKey() final CameraViewport cameraViewport; + @override + @JsonKey() + final AssetLocation location; + @override + @JsonKey() + final bool saved; @override String toString() { - return 'CurrentIndex(index: $index, handler: $handler, settingsCubit: $settingsCubit, transformCubit: $transformCubit, temporaryIndex: $temporaryIndex, temporaryHandler: $temporaryHandler, foregrounds: $foregrounds, selections: $selections, temporaryForegrounds: $temporaryForegrounds, temporarySelections: $temporarySelections, pointers: $pointers, cameraViewport: $cameraViewport)'; + return 'CurrentIndex(index: $index, handler: $handler, settingsCubit: $settingsCubit, transformCubit: $transformCubit, temporaryIndex: $temporaryIndex, temporaryHandler: $temporaryHandler, foregrounds: $foregrounds, selections: $selections, temporaryForegrounds: $temporaryForegrounds, temporarySelections: $temporarySelections, pointers: $pointers, cameraViewport: $cameraViewport, location: $location, saved: $saved)'; } @override @@ -340,7 +386,9 @@ class _$_CurrentIndex extends _CurrentIndex { .equals(other._temporarySelections, _temporarySelections) && const DeepCollectionEquality().equals(other._pointers, _pointers) && const DeepCollectionEquality() - .equals(other.cameraViewport, cameraViewport)); + .equals(other.cameraViewport, cameraViewport) && + const DeepCollectionEquality().equals(other.location, location) && + const DeepCollectionEquality().equals(other.saved, saved)); } @override @@ -357,7 +405,9 @@ class _$_CurrentIndex extends _CurrentIndex { const DeepCollectionEquality().hash(_temporaryForegrounds), const DeepCollectionEquality().hash(_temporarySelections), const DeepCollectionEquality().hash(_pointers), - const DeepCollectionEquality().hash(cameraViewport)); + const DeepCollectionEquality().hash(cameraViewport), + const DeepCollectionEquality().hash(location), + const DeepCollectionEquality().hash(saved)); @JsonKey(ignore: true) @override @@ -375,7 +425,9 @@ abstract class _CurrentIndex extends CurrentIndex { final List? temporaryForegrounds, final List? temporarySelections, final List pointers, - final CameraViewport cameraViewport}) = _$_CurrentIndex; + final CameraViewport cameraViewport, + final AssetLocation location, + final bool saved}) = _$_CurrentIndex; const _CurrentIndex._() : super._(); @override @@ -403,6 +455,10 @@ abstract class _CurrentIndex extends CurrentIndex { @override CameraViewport get cameraViewport; @override + AssetLocation get location; + @override + bool get saved; + @override @JsonKey(ignore: true) _$$_CurrentIndexCopyWith<_$_CurrentIndex> get copyWith => throw _privateConstructorUsedError; diff --git a/app/lib/dialogs/file_system/menu.dart b/app/lib/dialogs/file_system/menu.dart index 0cc3ac998cbb..b18346acf863 100644 --- a/app/lib/dialogs/file_system/menu.dart +++ b/app/lib/dialogs/file_system/menu.dart @@ -65,10 +65,9 @@ class FileSystemAssetMenu extends StatelessWidget { var state = bloc.state; if (state is! DocumentLoadSuccess) return; if (document != null && state.location.path == path) { - bloc.clearHistory(); - bloc.emit(state.copyWith( + state.currentIndexCubit.setSaveState( location: AssetLocation( - remote: state.location.remote, path: path))); + remote: state.location.remote, path: path)); } onRefreshed(); } @@ -173,10 +172,9 @@ class FileSystemAssetMenu extends StatelessWidget { var state = bloc.state; if (state is! DocumentLoadSuccess) return; if (state.location.path == asset.pathWithLeadingSlash) { - bloc.clearHistory(); - bloc.emit(state.copyWith( + state.currentIndexCubit.setSaveState( location: AssetLocation( - remote: state.location.remote, path: newPath))); + remote: state.location.remote, path: newPath)); } }), ), diff --git a/fastlane/metadata/android/en-US/changelogs/33.txt b/fastlane/metadata/android/en-US/changelogs/33.txt index 01872d4f7f13..d6744aadb192 100644 --- a/fastlane/metadata/android/en-US/changelogs/33.txt +++ b/fastlane/metadata/android/en-US/changelogs/33.txt @@ -1,6 +1,7 @@ * Add stylus button input * Add hex input to color dialog * Add constraints to shape painter +* Move save state in current index cubit to allow undo/redo * Fix bake issues * Fix wrong properties when resetting back to hand painter * Fix ignored properties in area painter \ No newline at end of file