You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
106 lines
3.4 KiB
106 lines
3.4 KiB
2 years ago
|
part of '../neon_files.dart';
|
||
|
|
||
|
@immutable
|
||
|
class FilesSync implements SyncImplementation<FilesSyncMapping, WebDavFile, FileSystemEntity> {
|
||
|
const FilesSync();
|
||
|
|
||
|
@override
|
||
|
String get appId => AppIDs.files;
|
||
|
|
||
|
@override
|
||
|
Future<FilesSyncSources> getSources(final Account account, final FilesSyncMapping mapping) async {
|
||
|
// This shouldn't be necessary, but it sadly is because of https://github.com/flutter/flutter/issues/25659.
|
||
|
// Alternative would be to use https://pub.dev/packages/shared_storage,
|
||
|
// but to be efficient we'd need https://github.com/alexrintt/shared-storage/issues/91
|
||
|
// or copy the files to the app cache (which is also not optimal).
|
||
|
if (Platform.isAndroid && !await Permission.manageExternalStorage.request().isGranted) {
|
||
|
throw const MissingPermissionException(Permission.manageExternalStorage);
|
||
|
}
|
||
|
return FilesSyncSources(
|
||
|
account.client,
|
||
|
mapping.remotePath,
|
||
|
mapping.localPath,
|
||
|
);
|
||
|
}
|
||
|
|
||
|
@override
|
||
|
Map<String, dynamic> serializeMapping(final FilesSyncMapping mapping) => mapping.toJson();
|
||
|
|
||
|
@override
|
||
|
FilesSyncMapping deserializeMapping(final Map<String, dynamic> json) => FilesSyncMapping.fromJson(json);
|
||
|
|
||
|
@override
|
||
|
Future<FilesSyncMapping?> addMapping(final BuildContext context, final Account account) async {
|
||
|
final accountsBloc = NeonProvider.of<AccountsBloc>(context);
|
||
|
final appsBloc = accountsBloc.getAppsBlocFor(account);
|
||
|
final filesBloc = appsBloc.getAppBlocByID(AppIDs.files)! as FilesBloc;
|
||
|
final filesBrowserBloc = filesBloc.getNewFilesBrowserBloc();
|
||
|
|
||
|
final remotePath = await showDialog<PathUri>(
|
||
|
context: context,
|
||
|
builder: (final context) => FilesChooseFolderDialog(
|
||
|
bloc: filesBrowserBloc,
|
||
|
filesBloc: filesBloc,
|
||
|
originalPath: PathUri.cwd(),
|
||
|
),
|
||
|
);
|
||
|
filesBrowserBloc.dispose();
|
||
|
if (remotePath == null) {
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
final localPath = await FileUtils.pickDirectory();
|
||
|
if (localPath == null) {
|
||
|
return null;
|
||
|
}
|
||
|
if (!context.mounted) {
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
return FilesSyncMapping(
|
||
|
appId: AppIDs.files,
|
||
|
accountId: account.id,
|
||
|
remotePath: remotePath,
|
||
|
localPath: Directory(localPath),
|
||
|
journal: SyncJournal(),
|
||
|
);
|
||
|
}
|
||
|
|
||
|
@override
|
||
|
String getMappingDisplayTitle(final FilesSyncMapping mapping) => mapping.remotePath.toString();
|
||
|
|
||
|
@override
|
||
|
String getMappingDisplaySubtitle(final FilesSyncMapping mapping) => mapping.localPath.path;
|
||
|
|
||
|
@override
|
||
|
String getMappingId(final FilesSyncMapping mapping) =>
|
||
|
'${Uri.encodeComponent(mapping.remotePath.toString())}-${Uri.encodeComponent(mapping.localPath.path)}';
|
||
|
|
||
|
@override
|
||
|
Widget getConflictDetailsLocal(final BuildContext context, final FileSystemEntity object) {
|
||
|
final stat = object.statSync();
|
||
|
return FilesFileTile(
|
||
|
showFullPath: true,
|
||
|
filesBloc: NeonProvider.of<FilesBloc>(context),
|
||
|
details: FileDetails(
|
||
|
uri: PathUri.parse(object.path),
|
||
|
size: stat.size,
|
||
|
etag: '',
|
||
|
mimeType: '',
|
||
|
lastModified: stat.modified,
|
||
|
hasPreview: false,
|
||
|
isFavorite: false,
|
||
|
),
|
||
|
);
|
||
|
}
|
||
|
|
||
|
@override
|
||
|
Widget getConflictDetailsRemote(final BuildContext context, final WebDavFile object) => FilesFileTile(
|
||
|
showFullPath: true,
|
||
|
filesBloc: NeonProvider.of<FilesBloc>(context),
|
||
|
details: FileDetails.fromWebDav(
|
||
|
file: object,
|
||
|
),
|
||
|
);
|
||
|
}
|