Skip to content

Commit

Permalink
refactor(nextcloud,neon_files): Introduce PathUri for WebDAV path han…
Browse files Browse the repository at this point in the history
…dling

Signed-off-by: jld3103 <jld3103yt@gmail.com>
  • Loading branch information
provokateurin committed Nov 11, 2023
1 parent 144e021 commit c026f98
Show file tree
Hide file tree
Showing 17 changed files with 444 additions and 204 deletions.
22 changes: 11 additions & 11 deletions packages/neon/neon_files/lib/blocs/browser.dart
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
part of '../neon_files.dart';

abstract interface class FilesBrowserBlocEvents {
void setPath(final List<String> path);
void setPath(final PathUri path);

void createFolder(final List<String> path);
void createFolder(final PathUri path);
}

abstract interface class FilesBrowserBlocStates {
BehaviorSubject<Result<List<WebDavFile>>> get files;

BehaviorSubject<List<String>> get path;
BehaviorSubject<PathUri> get path;
}

class FilesBrowserBloc extends InteractiveBloc implements FilesBrowserBlocEvents, FilesBrowserBlocStates {
FilesBrowserBloc(
this.options,
this.account, {
final List<String>? initialPath,
final PathUri? initialPath,
}) {
if (initialPath != null) {
path.add(initialPath);
Expand All @@ -39,16 +39,16 @@ class FilesBrowserBloc extends InteractiveBloc implements FilesBrowserBlocEvents
BehaviorSubject<Result<List<WebDavFile>>> files = BehaviorSubject<Result<List<WebDavFile>>>();

@override
BehaviorSubject<List<String>> path = BehaviorSubject<List<String>>.seeded([]);
BehaviorSubject<PathUri> path = BehaviorSubject.seeded(PathUri.cwd());

@override
Future<void> refresh() async {
await RequestManager.instance.wrapWebDav<List<WebDavFile>>(
account.id,
'files-${path.value.join('/')}',
'files-${path.value.path}',
files,
() => account.client.webdav.propfind(
Uri(pathSegments: path.value),
path.value,
prop: WebDavPropWithoutValues.fromBools(
davgetcontenttype: true,
davgetetag: true,
Expand All @@ -65,13 +65,13 @@ class FilesBrowserBloc extends InteractiveBloc implements FilesBrowserBlocEvents
}

@override
void setPath(final List<String> p) {
path.add(p);
void setPath(final PathUri path) {
this.path.add(path);
unawaited(refresh());
}

@override
void createFolder(final List<String> path) {
wrapAction(() async => account.client.webdav.mkcol(Uri(pathSegments: path)));
void createFolder(final PathUri path) {
wrapAction(() async => account.client.webdav.mkcol(path));
}
}
70 changes: 35 additions & 35 deletions packages/neon/neon_files/lib/blocs/files.dart
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
part of '../neon_files.dart';

abstract interface class FilesBlocEvents {
void uploadFile(final List<String> path, final String localPath);
void uploadFile(final PathUri path, final String localPath);

void syncFile(final List<String> path);
void syncFile(final PathUri path);

void openFile(final List<String> path, final String etag, final String? mimeType);
void openFile(final PathUri path, final String etag, final String? mimeType);

void shareFileNative(final List<String> path, final String etag);
void shareFileNative(final PathUri path, final String etag);

void delete(final List<String> path);
void delete(final PathUri path);

void rename(final List<String> path, final String name);
void rename(final PathUri path, final String name);

void move(final List<String> path, final List<String> destination);
void move(final PathUri path, final PathUri destination);

void copy(final List<String> path, final List<String> destination);
void copy(final PathUri path, final PathUri destination);

void addFavorite(final List<String> path);
void addFavorite(final PathUri path);

void removeFavorite(final List<String> path);
void removeFavorite(final PathUri path);
}

abstract interface class FilesBlocStates {
Expand Down Expand Up @@ -58,32 +58,32 @@ class FilesBloc extends InteractiveBloc implements FilesBlocEvents, FilesBlocSta
BehaviorSubject<List<FilesTask>> tasks = BehaviorSubject<List<FilesTask>>.seeded([]);

@override
void addFavorite(final List<String> path) {
void addFavorite(final PathUri path) {
wrapAction(
() async => account.client.webdav.proppatch(
Uri(pathSegments: path),
path,
set: WebDavProp(ocfavorite: 1),
),
);
}

@override
void copy(final List<String> path, final List<String> destination) {
wrapAction(() async => account.client.webdav.copy(Uri(pathSegments: path), Uri(pathSegments: destination)));
void copy(final PathUri path, final PathUri destination) {
wrapAction(() async => account.client.webdav.copy(path, destination));
}

@override
void delete(final List<String> path) {
wrapAction(() async => account.client.webdav.delete(Uri(pathSegments: path)));
void delete(final PathUri path) {
wrapAction(() async => account.client.webdav.delete(path));
}

@override
void move(final List<String> path, final List<String> destination) {
wrapAction(() async => account.client.webdav.move(Uri(pathSegments: path), Uri(pathSegments: destination)));
void move(final PathUri path, final PathUri destination) {
wrapAction(() async => account.client.webdav.move(path, destination));
}

@override
void openFile(final List<String> path, final String etag, final String? mimeType) {
void openFile(final PathUri path, final String etag, final String? mimeType) {
wrapAction(
() async {
final file = await _cacheFile(path, etag);
Expand All @@ -98,7 +98,7 @@ class FilesBloc extends InteractiveBloc implements FilesBlocEvents, FilesBlocSta
}

@override
void shareFileNative(final List<String> path, final String etag) {
void shareFileNative(final PathUri path, final String etag) {
wrapAction(
() async {
final file = await _cacheFile(path, etag);
Expand All @@ -115,36 +115,36 @@ class FilesBloc extends InteractiveBloc implements FilesBlocEvents, FilesBlocSta
}

@override
void removeFavorite(final List<String> path) {
void removeFavorite(final PathUri path) {
wrapAction(
() async => account.client.webdav.proppatch(
Uri(pathSegments: path),
path,
set: WebDavProp(ocfavorite: 0),
),
);
}

@override
void rename(final List<String> path, final String name) {
void rename(final PathUri path, final String name) {
wrapAction(
() async => account.client.webdav.move(
Uri(pathSegments: path),
Uri(pathSegments: List.from(path)..last = name),
path,
path.rename(name),
),
);
}

@override
void syncFile(final List<String> path) {
void syncFile(final PathUri path) {
wrapAction(
() async {
final file = File(
p.join(
p.joinAll([
await NeonPlatform.instance.userAccessibleAppDataPath,
account.humanReadableID,
'files',
path.join(Platform.pathSeparator),
),
...path.pathSegments,
]),
);
if (!file.parent.existsSync()) {
file.parent.createSync(recursive: true);
Expand All @@ -156,7 +156,7 @@ class FilesBloc extends InteractiveBloc implements FilesBlocEvents, FilesBlocSta
}

@override
void uploadFile(final List<String> path, final String localPath) {
void uploadFile(final PathUri path, final String localPath) {
wrapAction(
() async {
final task = FilesUploadTask(
Expand All @@ -171,12 +171,12 @@ class FilesBloc extends InteractiveBloc implements FilesBlocEvents, FilesBlocSta
);
}

Future<File> _cacheFile(final List<String> path, final String etag) async {
Future<File> _cacheFile(final PathUri path, final String etag) async {
final cacheDir = await getApplicationCacheDirectory();
final file = File(p.join(cacheDir.path, 'files', etag.replaceAll('"', ''), path.last));
final file = File(p.join(cacheDir.path, 'files', etag.replaceAll('"', ''), path.name));

if (!file.existsSync()) {
debugPrint('Downloading ${Uri(pathSegments: path)} since it does not exist');
debugPrint('Downloading $path since it does not exist');
if (!file.parent.existsSync()) {
await file.parent.create(recursive: true);
}
Expand All @@ -187,7 +187,7 @@ class FilesBloc extends InteractiveBloc implements FilesBlocEvents, FilesBlocSta
}

Future<void> _downloadFile(
final List<String> path,
final PathUri path,
final File file,
) async {
final task = FilesDownloadTask(
Expand All @@ -200,7 +200,7 @@ class FilesBloc extends InteractiveBloc implements FilesBlocEvents, FilesBlocSta
}

FilesBrowserBloc getNewFilesBrowserBloc({
final List<String>? initialPath,
final PathUri? initialPath,
}) =>
FilesBrowserBloc(
options,
Expand Down
11 changes: 7 additions & 4 deletions packages/neon/neon_files/lib/dialogs/choose_create.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class FilesChooseCreateDialog extends StatefulWidget {
});

final FilesBloc bloc;
final List<String> basePath;
final PathUri basePath;

@override
State<FilesChooseCreateDialog> createState() => _FilesChooseCreateDialogState();
Expand Down Expand Up @@ -43,7 +43,10 @@ class _FilesChooseCreateDialogState extends State<FilesChooseCreateDialog> {
}
}
}
widget.bloc.uploadFile([...widget.basePath, p.basename(file.path)], file.path);
widget.bloc.uploadFile(
widget.basePath.join(PathUri.parse(p.basename(file.path))),
file.path,
);
}

@override
Expand Down Expand Up @@ -104,12 +107,12 @@ class _FilesChooseCreateDialogState extends State<FilesChooseCreateDialog> {
onTap: () async {
Navigator.of(context).pop();

final result = await showDialog<List<String>>(
final result = await showDialog<String>(
context: context,
builder: (final context) => const FilesCreateFolderDialog(),
);
if (result != null) {
widget.bloc.browser.createFolder([...widget.basePath, ...result]);
widget.bloc.browser.createFolder(widget.basePath.join(PathUri.parse(result)));
}
},
),
Expand Down
12 changes: 6 additions & 6 deletions packages/neon/neon_files/lib/dialogs/choose_folder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class FilesChooseFolderDialog extends StatelessWidget {
final FilesBrowserBloc bloc;
final FilesBloc filesBloc;

final List<String> originalPath;
final PathUri originalPath;

@override
Widget build(final BuildContext context) => AlertDialog(
Expand All @@ -28,7 +28,7 @@ class FilesChooseFolderDialog extends StatelessWidget {
mode: FilesBrowserMode.selectDirectory,
),
),
StreamBuilder<List<String>>(
StreamBuilder<PathUri>(
stream: bloc.path,
builder: (final context, final pathSnapshot) => pathSnapshot.hasData
? Container(
Expand All @@ -38,19 +38,19 @@ class FilesChooseFolderDialog extends StatelessWidget {
children: [
ElevatedButton(
onPressed: () async {
final result = await showDialog<List<String>>(
final result = await showDialog<String>(
context: context,
builder: (final context) => const FilesCreateFolderDialog(),
);
if (result != null) {
bloc.createFolder([...pathSnapshot.requireData, ...result]);
bloc.createFolder(pathSnapshot.requireData.join(PathUri.parse(result)));
}
},
child: Text(FilesLocalizations.of(context).folderCreate),
),
ElevatedButton(
onPressed: !(const ListEquality<String>().equals(originalPath, pathSnapshot.data))
? () => Navigator.of(context).pop(pathSnapshot.data)
onPressed: originalPath != pathSnapshot.requireData
? () => Navigator.of(context).pop(pathSnapshot.requireData)
: null,
child: Text(FilesLocalizations.of(context).folderChoose),
),
Expand Down
2 changes: 1 addition & 1 deletion packages/neon/neon_files/lib/dialogs/create_folder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class _FilesCreateFolderDialogState extends State<FilesCreateFolderDialog> {

void submit() {
if (formKey.currentState!.validate()) {
Navigator.of(context).pop(controller.text.split('/'));
Navigator.of(context).pop(controller.text);
}
}

Expand Down
13 changes: 4 additions & 9 deletions packages/neon/neon_files/lib/models/file_details.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ part of '../neon_files.dart';
class FileDetails {
const FileDetails({
required this.path,
required this.isDirectory,
required this.size,
required this.etag,
required this.mimeType,
Expand All @@ -15,9 +14,7 @@ class FileDetails {

FileDetails.fromWebDav({
required final WebDavFile file,
required final List<String> path,
}) : path = List.from(path)..add(file.name),
isDirectory = file.isDirectory,
}) : path = file.path,
size = file.size,
etag = file.etag,
mimeType = file.mimeType,
Expand All @@ -31,7 +28,6 @@ class FileDetails {
}) : path = task.path,
size = task.stat.size,
lastModified = task.stat.modified,
isDirectory = false,
etag = null,
mimeType = null,
hasPreview = null,
Expand All @@ -41,7 +37,6 @@ class FileDetails {
required FilesDownloadTask this.task,
required final WebDavFile file,
}) : path = task.path,
isDirectory = file.isDirectory,
size = file.size,
etag = file.etag,
mimeType = file.mimeType,
Expand All @@ -64,11 +59,11 @@ class FileDetails {
}
}

String get name => path.last;
String get name => path.name;

final List<String> path;
bool get isDirectory => path.isDirectory;

final bool isDirectory;
final PathUri path;

final int? size;

Expand Down
4 changes: 2 additions & 2 deletions packages/neon/neon_files/lib/pages/details.dart
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ class FilesDetailsPage extends StatelessWidget {
details.isDirectory
? FilesLocalizations.of(context).detailsFolderName
: FilesLocalizations.of(context).detailsFileName: details.name,
FilesLocalizations.of(context).detailsParentFolder:
details.path.length == 1 ? '/' : details.path.sublist(0, details.path.length - 1).join('/'),
if (details.path.parent != null)
FilesLocalizations.of(context).detailsParentFolder: details.path.parent!.path,
if (details.size != null) ...{
details.isDirectory
? FilesLocalizations.of(context).detailsFolderSize
Expand Down
Loading

0 comments on commit c026f98

Please sign in to comment.