Skip to content

Commit

Permalink
Fix invalidation of selection when transforming
Browse files Browse the repository at this point in the history
  • Loading branch information
CodeDoctorDE committed Oct 31, 2023
1 parent 2065258 commit 1fb4e5d
Show file tree
Hide file tree
Showing 11 changed files with 67 additions and 57 deletions.
3 changes: 2 additions & 1 deletion app/lib/api/file_system/file_system.dart
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,8 @@ abstract class DocumentFileSystem extends GeneralFileSystem {
} else {
return remote?.map(
dav: (e) => DavRemoteDocumentFileSystem(e),
local: (e) => IODocumentFileSystem(e.fullDocumentsPath),
local: (e) =>
IODocumentFileSystem(e.fullDocumentsPath, remote.identifier),
) ??
IODocumentFileSystem();
}
Expand Down
26 changes: 13 additions & 13 deletions app/lib/api/file_system/file_system_io.dart
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@ Future<String> getButterflyDirectory([bool root = false]) async {

class IODocumentFileSystem extends DocumentFileSystem {
final String? root;
final String remoteName;

IODocumentFileSystem([this.root]);
IODocumentFileSystem([this.root, this.remoteName = '']);

@override
Future<void> deleteAsset(String path) async {
Expand All @@ -58,29 +59,27 @@ class IODocumentFileSystem extends DocumentFileSystem {
if (!path.startsWith('/')) {
path = '/$path';
}
var absolutePath = await getAbsolutePath(path);
final location = AssetLocation(path: path, remote: remoteName);
final absolutePath = await getAbsolutePath(path);
// Test if path is a file
var file = File(absolutePath);
final file = File(absolutePath);
// Test if path is a directory
var directory = Directory(absolutePath);
final directory = Directory(absolutePath);
if (await file.exists()) {
var data = await file.readAsBytes();
yield AppDocumentFile(AssetLocation.local(path), data: data);
yield AppDocumentFile(location, data: data);
try {
yield await getAppDocumentFile(
AssetLocation.local(path),
data,
);
yield await getAppDocumentFile(location, data);
} catch (_) {}
} else if (await directory.exists()) {
yield AppDocumentDirectory(AssetLocation.local(path), []);
yield AppDocumentDirectory(location, []);
if (listFiles) {
final streams = fetchAssets(
directory.list().map(
(e) => '$path/${e.path.replaceAll('\\', '/').split('/').last}'),
false);
await for (final files in streams) {
yield AppDocumentDirectory(AssetLocation.local(path), files);
yield AppDocumentDirectory(location, files);
}
}
} else {
Expand All @@ -99,7 +98,7 @@ class IODocumentFileSystem extends DocumentFileSystem {
if (!(await file.exists())) {
await file.create(recursive: true);
}
await file.writeAsBytes(data, flush: true);
await file.writeAsBytes(data);

return true;
}
Expand Down Expand Up @@ -135,7 +134,8 @@ class IODocumentFileSystem extends DocumentFileSystem {
assets.add(asset);
}
}
return AppDocumentDirectory(AssetLocation.local(path), assets);
return AppDocumentDirectory(
AssetLocation(path: path, remote: remoteName), assets);
}

@override
Expand Down
4 changes: 2 additions & 2 deletions app/lib/api/open.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Future<Uint8List?> openBfly() async {

void openFile(BuildContext context, AssetLocation location, [Object? data]) {
if (location.isRemote) {
GoRouter.of(context).goNamed('remote',
GoRouter.of(context).pushReplacementNamed('remote',
pathParameters: {
'remote': location.remote,
'path': location.pathWithoutLeadingSlash,
Expand All @@ -44,7 +44,7 @@ void openFile(BuildContext context, AssetLocation location, [Object? data]) {
extra: data);
return;
}
GoRouter.of(context).goNamed('local',
GoRouter.of(context).pushReplacementNamed('local',
pathParameters: {
'path': location.pathWithoutLeadingSlash,
},
Expand Down
42 changes: 23 additions & 19 deletions app/lib/bloc/document_bloc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -191,16 +191,19 @@ class DocumentBloc extends ReplayBloc<DocumentEvent, DocumentState> {
var selection = current.currentIndexCubit.state.selection;
final page = current.page;
bool shouldRefresh = false;
for (final renderer in current.renderers) {
final oldRenderers = current.renderers;
for (final renderer in oldRenderers) {
final index = page.content.indexOf(renderer.element);
final updated = event.elements[index];
if (updated != null) {
renderer.dispose();
final updatedRenderers = <Renderer<PadElement>>[];
for (final element in updated) {
final newRenderer = Renderer.fromInstance(element);
await newRenderer.setup(
current.data, current.assetService, current.page);
renderer.dispose();
renderers.add(newRenderer);
updatedRenderers.add(newRenderer);
var newSelection = selection?.remove(renderer);
if (newSelection != selection && selection != null) {
if (newSelection == null) {
Expand All @@ -210,33 +213,36 @@ class DocumentBloc extends ReplayBloc<DocumentEvent, DocumentState> {
}
selection = newSelection;
}
shouldRefresh = shouldRefresh ||
current.currentIndexCubit
.getHandler()
.onRendererUpdated(current.page, renderer, newRenderer);
}
shouldRefresh = current.currentIndexCubit
.getHandler()
.onRendererUpdated(
current.page, renderer, updatedRenderers) ||
shouldRefresh;
} else {
renderers.add(renderer);
}
}
current.currentIndexCubit.unbake(unbakedElements: renderers);
final content = List.of(page.content);
if (shouldRefresh) {
refresh();
}
for (final updated in event.elements.entries) {
if (updated.key >= content.length || updated.key < 0) continue;
content.removeAt(updated.key);
content.insertAll(updated.key, updated.value);
}
await _saveState(
emit,
current.copyWith(
page: page.copyWith(
content: content,
),
),
null);
emit,
current.copyWith(
page: page.copyWith(
content: content,
),
),
null)
.then((value) {
if (shouldRefresh) {
return refresh();
}
});
}, transformer: sequential());
on<ElementsArranged>((event, emit) async {
final current = state;
Expand Down Expand Up @@ -860,9 +866,7 @@ class DocumentBloc extends ReplayBloc<DocumentEvent, DocumentState> {
emit(current);

if (unbakedElements == null) {
current.currentIndexCubit.unbake(
unbakedElements: List<Renderer<PadElement>>.from(elements)
..addAll(cameraViewport.bakedElements));
current.currentIndexCubit.unbake();
} else {
current.currentIndexCubit.withUnbaked(elements);
}
Expand Down
3 changes: 2 additions & 1 deletion app/lib/handlers/handler.dart
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,8 @@ abstract class Handler<T> {
[Area? currentArea]) =>
[];

bool onRendererUpdated(DocumentPage page, Renderer old, Renderer updated) =>
bool onRendererUpdated(
DocumentPage page, Renderer old, List<Renderer> updated) =>
false;

bool onRenderersCreated(DocumentPage page, List<Renderer> renderers) => false;
Expand Down
33 changes: 17 additions & 16 deletions app/lib/handlers/select.dart
Original file line number Diff line number Diff line change
Expand Up @@ -201,21 +201,24 @@ class SelectHandler extends Handler<SelectTool> {
}

@override
bool onRendererUpdated(DocumentPage page, Renderer old, Renderer updated) {
bool onRendererUpdated(
DocumentPage page, Renderer old, List<Renderer> updated) {
bool changed = false;
if (old is Renderer<PadElement> &&
_selected.contains(old) &&
updated is Renderer<PadElement>) {
updated is List<Renderer<PadElement>>) {
_selected.remove(old);
_selected.add(updated);
} else if (old is Renderer<PadElement> &&
_selected.addAll(updated);
changed = true;
}
if (old is Renderer<PadElement> &&
_transformed.contains(old) &&
updated is Renderer<PadElement>) {
updated is List<Renderer<PadElement>>) {
_transformed.remove(old);
_transformed.add(updated);
} else {
return false;
_transformed.addAll(updated);
changed = true;
}
return true;
return changed;
}

Rect? getSelectionRect() {
Expand Down Expand Up @@ -342,22 +345,20 @@ class SelectHandler extends Handler<SelectTool> {
return foregrounds;
}

Future<bool> _submitTransform(DocumentBloc bloc) async {
bool _submitTransform(DocumentBloc bloc) {
if (_transformed.isEmpty) return false;
final state = bloc.state;
if (state is! DocumentLoadSuccess) return false;
final current = _getTransformed();
_selected = _transformed;
_transformCorner = null;
_transformMode = HandTransformMode.scale;
final transformed = _transformed;
_transformed = [];
await bloc.refresh();
await Future.sync(() => bloc.add(_duplicate
bloc.add(_duplicate
? ElementsCreated(current!.map((e) => e.element).toList())
: ElementsChanged(Map.fromEntries(current!.mapIndexed((i, e) =>
MapEntry(state.page.content.indexOf(transformed[i].element),
[e.element]))))));
MapEntry(state.page.content.indexOf(_selected[i].element),
[e.element])))));
return true;
}

Expand Down Expand Up @@ -609,7 +610,7 @@ class SelectHandler extends Handler<SelectTool> {
_rulerRotation = null;
return;
}
if (await _submitTransform(context.getDocumentBloc())) return;
if (_submitTransform(context.getDocumentBloc())) return;
_lassoFreeSelection = null;
_rectangleFreeSelection = null;
if (!context.isCtrlPressed) {
Expand Down
4 changes: 2 additions & 2 deletions app/lib/services/sync.dart
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,8 @@ class RemoteSync {
return;
}
_statusSubject.add(SyncStatus.syncing);
final fileSystem = DocumentFileSystem.fromPlatform(remote: remoteStorage)
as DocumentRemoteSystem;
final fileSystem = DocumentFileSystem.fromPlatform(remote: remoteStorage);
if (fileSystem is! DocumentRemoteSystem) return;
var files = <SyncFile>[];
_filesSubject.add([]);
final currentFiles = await fileSystem.getAllSyncFiles();
Expand Down
1 change: 1 addition & 0 deletions app/lib/views/zoom.dart
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ class _ZoomViewState extends State<ZoomView> with TickerProviderStateMixin {
},
onEditingComplete: () => zoom(scale),
onTapOutside: (event) {
if (!_focusNode.hasFocus) return;
zoom(scale);
_focusNode.unfocus();
},
Expand Down
4 changes: 2 additions & 2 deletions app/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -724,8 +724,8 @@ packages:
dependency: "direct main"
description:
path: "packages/material_leap"
ref: a03583f3e365521dd96de8924737676a41fc7f93
resolved-ref: a03583f3e365521dd96de8924737676a41fc7f93
ref: "7466e9723fa1cd802baa508b8b4ee4a54cb53dc2"
resolved-ref: "7466e9723fa1cd802baa508b8b4ee4a54cb53dc2"
url: "https://github.com/LinwoodDev/dart_pkgs.git"
source: git
version: "0.0.1"
Expand Down
2 changes: 1 addition & 1 deletion app/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ dependencies:
material_leap:
git:
url: https://github.com/LinwoodDev/dart_pkgs.git
ref: a03583f3e365521dd96de8924737676a41fc7f93
ref: 7466e9723fa1cd802baa508b8b4ee4a54cb53dc2
path: packages/material_leap
lw_sysinfo:
git:
Expand Down
2 changes: 2 additions & 0 deletions fastlane/metadata/android/en-US/changelogs/78.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
* Add recent colors to color picker
* Improve action buttons in add dialog
* Improve color picker dialog
* Fix invalidation of selection when transforming ([#517](https://github.com/LinwoodDev/Butterfly/issues/517))
* Fix folder creation ([#513](https://github.com/LinwoodDev/Butterfly/issues/513))
* Fix locale spacing
* Fix pack updating
* Fix saving files in local external directory
* Fixing missing saving of pdf quality and platform theme settings

View all changes in the blog: https://linwood.dev/butterfly/2.0.0-beta.14

0 comments on commit 1fb4e5d

Please sign in to comment.