Skip to content

Commit

Permalink
Fix directory export, closes #523
Browse files Browse the repository at this point in the history
  • Loading branch information
CodeDoctorDE committed Nov 3, 2023
1 parent d040b46 commit 840748e
Show file tree
Hide file tree
Showing 7 changed files with 35 additions and 55 deletions.
21 changes: 12 additions & 9 deletions app/lib/api/file_system/file_system.dart
Original file line number Diff line number Diff line change
Expand Up @@ -97,21 +97,23 @@ Future<AppDocumentFile> getAppDocumentFile(
}

abstract class DocumentFileSystem extends GeneralFileSystem {
Future<AppDocumentDirectory> getRootDirectory() {
return getAsset('').then((value) => value as AppDocumentDirectory);
Future<AppDocumentDirectory> getRootDirectory([bool recursive = false]) {
return getAsset('', recursive ? null : true)
.then((value) => value as AppDocumentDirectory);
}

@override
FutureOr<String> getDirectory();

Stream<AppDocumentEntity?> fetchAsset(String path, [bool listFiles = false]);
/// If listFiles is null, it will fetch recursively
Stream<AppDocumentEntity?> fetchAsset(String path, [bool? listFiles = true]);

Stream<List<AppDocumentEntity>> fetchAssets(Stream<String> paths,
[bool listFiles = false]) {
[bool? listFiles = true]) {
final files = <AppDocumentEntity>[];
final streams = paths.asyncExpand((e) async* {
int? index;
await for (final file in fetchAsset(e, false).whereNotNull()) {
await for (final file in fetchAsset(e, listFiles).whereNotNull()) {
if (index == null) {
index = files.length;
files.add(file);
Expand All @@ -125,12 +127,12 @@ abstract class DocumentFileSystem extends GeneralFileSystem {
}

Stream<List<AppDocumentEntity>> fetchAssetsSync(Iterable<String> paths,
[bool listFiles = false]) =>
[bool? listFiles = true]) =>
fetchAssets(Stream.fromIterable(paths), listFiles);

static Stream<List<AppDocumentEntity>> fetchAssetsGlobal(
Stream<AssetLocation> locations, ButterflySettings settings,
[bool listFiles = true]) {
[bool? listFiles = true]) {
final files = <AppDocumentEntity>[];
final streams = locations.asyncExpand((e) async* {
final fileSystem =
Expand All @@ -152,10 +154,11 @@ abstract class DocumentFileSystem extends GeneralFileSystem {

static Stream<List<AppDocumentEntity>> fetchAssetsGlobalSync(
Iterable<AssetLocation> locations, ButterflySettings settings,
[bool listFiles = true]) =>
[bool? listFiles = true]) =>
fetchAssetsGlobal(Stream.fromIterable(locations), settings, listFiles);

Future<AppDocumentEntity?> getAsset(String path) => fetchAsset(path).last;
Future<AppDocumentEntity?> getAsset(String path, [bool? listFiles = true]) =>
fetchAsset(path, listFiles).last;

Future<AppDocumentDirectory> createDirectory(String path);

Expand Down
2 changes: 1 addition & 1 deletion app/lib/api/file_system/file_system_dav.dart
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class DavRemoteDocumentFileSystem extends DocumentRemoteSystem {

@override
Stream<AppDocumentEntity?> fetchAsset(String path,
[bool listFiles = true, bool forceRemote = false]) async* {
[bool? listFiles = true, bool forceRemote = false]) async* {
if (path.endsWith('/')) {
path = path.substring(0, path.length - 1);
}
Expand Down
56 changes: 16 additions & 40 deletions app/lib/api/file_system/file_system_html.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import 'dart:js_util';

import 'package:butterfly/models/defaults.dart';
import 'package:butterfly_api/butterfly_api.dart';
import 'package:collection/collection.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
import 'package:idb_shim/idb.dart';
Expand Down Expand Up @@ -125,7 +124,7 @@ class WebDocumentFileSystem extends DocumentFileSystem {

@override
Stream<AppDocumentEntity?> fetchAsset(String path,
[bool listFiles = true]) async* {
[bool? listFiles = true]) async* {
// Add leading slash
if (!path.startsWith('/')) {
path = '/$path';
Expand All @@ -134,6 +133,7 @@ class WebDocumentFileSystem extends DocumentFileSystem {
path = '/';
}
var db = await _getDatabase();
final location = AssetLocation.local(path);
var txn = db.transaction(['documents', 'documents-data'], 'readonly');

Future<List<int>?> getData(String path) async {
Expand All @@ -159,49 +159,25 @@ class WebDocumentFileSystem extends DocumentFileSystem {
yield null;
return;
}
final file = getAppDocumentFile(AssetLocation.local(path), data);
final file = getAppDocumentFile(location, data);
await txn.completed;
yield await file;
return;
} else if (map['type'] == 'directory') {
if (!listFiles) {
await txn.completed;
yield AppDocumentDirectory(AssetLocation.local(path), const []);
return;
}
var cursor = store.openCursor(autoAdvance: true);
var assets = await Future.wait(
await cursor.map<Future<AppDocumentEntity?>>((cursor) async {
// Add leading slash
var key = cursor.key.toString();
if (!key.startsWith('/')) {
key = '/$key';
}
// Is in current directory
if (key.startsWith(path) &&
key != path &&
!key.substring(path.length + 1).contains('/')) {
var data = cursor.value as Map<dynamic, dynamic>;
if (data['type'] == 'file') {
final data = await getData(key);
if (data == null) return null;
return getAppDocumentFile(AssetLocation.local(key), data);
} else if (data['type'] == 'directory') {
return AppDocumentDirectory(AssetLocation.local(key), const []);
}
return null;
yield AppDocumentDirectory(location, []);
if (listFiles ?? true) {
var cursor = store.openKeyCursor(autoAdvance: true);
final streams = fetchAssetsSync(
await cursor.map((e) => e.key.toString()).where((e) {
return e.startsWith(path) &&
e != path &&
!e.substring(path.length + 1).contains('/');
}).toList(),
listFiles == null ? null : false);
await for (var stream in streams) {
yield AppDocumentDirectory(location, stream);
}
return null;
}).toList())
.then((value) => value.whereNotNull().toList());
// Sort assets, AppDocumentDirectory should be first, AppDocumentFile should be sorted by name
assets.sort((a, b) => a is AppDocumentDirectory
? -1
: (a as AppDocumentFile).fileName.compareTo(b is AppDocumentDirectory
? ''
: (b as AppDocumentFile).fileName));
await txn.completed;
yield AppDocumentDirectory(AssetLocation.local(path), assets.toList());
}
return;
}
yield null;
Expand Down
2 changes: 1 addition & 1 deletion app/lib/api/file_system/file_system_html_stub.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class WebDocumentFileSystem extends DocumentFileSystem {
}

@override
Stream<AppDocumentEntity?> fetchAsset(String path, [bool listFiles = true]) {
Stream<AppDocumentEntity?> fetchAsset(String path, [bool? listFiles = true]) {
throw UnimplementedError();
}

Expand Down
6 changes: 3 additions & 3 deletions app/lib/api/file_system/file_system_io.dart
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class IODocumentFileSystem extends DocumentFileSystem {

@override
Stream<AppDocumentEntity?> fetchAsset(String path,
[bool listFiles = true]) async* {
[bool? listFiles = true]) async* {
// Add leading slash
if (!path.startsWith('/')) {
path = '/$path';
Expand All @@ -73,11 +73,11 @@ class IODocumentFileSystem extends DocumentFileSystem {
} catch (_) {}
} else if (await directory.exists()) {
yield AppDocumentDirectory(location, []);
if (listFiles) {
if (listFiles ?? true) {
final streams = fetchAssets(
directory.list().map(
(e) => '$path/${e.path.replaceAll('\\', '/').split('/').last}'),
false);
listFiles == null ? null : false);
await for (final files in streams) {
yield AppDocumentDirectory(location, files);
}
Expand Down
2 changes: 1 addition & 1 deletion app/lib/settings/data.dart
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ class _DataSettingsPageState extends State<DataSettingsPage> {
final fileSystem =
DocumentFileSystem.fromPlatform();
final directory =
await fileSystem.getRootDirectory();
await fileSystem.getRootDirectory(true);
final archive = exportDirectory(directory);
final encoder = ZipEncoder();
final bytes = encoder.encode(archive);
Expand Down
1 change: 1 addition & 0 deletions fastlane/metadata/android/en-US/changelogs/78.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
* Fix locale spacing
* Fix pack updating
* Fix pdf operations on web
* Fix exporting whole directory ([#523](https://github.com/LinwoodDev/Butterfly/issues/523))
* Set full screen tool to action tool
* Fix saving files in local external directory
* Fixing missing saving of pdf quality and platform theme settings
Expand Down

0 comments on commit 840748e

Please sign in to comment.