From bbd4a1a68bd465f2bc70a14b53763c7d2029c6e2 Mon Sep 17 00:00:00 2001 From: Jonas Sander <29028262+Jonas-Sander@users.noreply.github.com> Date: Mon, 6 Nov 2023 17:59:34 +0100 Subject: [PATCH] Add support for private CloudFiles. (#1150) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * `private` property will now be added to files by the client * If a file is private the `FileSheet` will display "Privat (nur für dich sichtbar)" ![grafik](https://github.com/SharezoneApp/sharezone-app/assets/29028262/07ee331e-f5bc-43d7-83ad-1645329ec0c7) Linked PR: https://github.com/SharezoneApp/backend-mono/pull/27 Closes #132 --- app/lib/filesharing/file_sharing_api.dart | 6 ++++-- .../firebase_file_uploader/firebase_file_uploader.dart | 2 ++ .../implementation/firebase_file_uploader_impl.dart | 2 ++ app/lib/filesharing/widgets/sheet.dart | 6 ++++++ .../homework/homework_dialog/homework_dialog_bloc.dart | 4 +++- app/test/homework/homework_dialog_test.dart | 1 + .../filesharing_logic/lib/src/models/cloud_file.dart | 9 +++++++++ 7 files changed, 27 insertions(+), 3 deletions(-) diff --git a/app/lib/filesharing/file_sharing_api.dart b/app/lib/filesharing/file_sharing_api.dart index ae6f6475f..5fa5a84aa 100644 --- a/app/lib/filesharing/file_sharing_api.dart +++ b/app/lib/filesharing/file_sharing_api.dart @@ -55,8 +55,9 @@ class FileSharingGateway { IList localFiles, String courseID, String authorID, - String authorName, - ) async { + String authorName, { + bool isPrivate = false, + }) async { final attachments = []; final hasAttachments = localFiles.isNotEmpty; if (hasAttachments) { @@ -67,6 +68,7 @@ class FileSharingGateway { creatorName: authorName, localFile: localFile, path: FolderPath.attachments, + isPrivate: isPrivate, ); final snapshot = await uploadTask.onComplete; diff --git a/app/lib/filesharing/logic/firebase_file_uploader/firebase_file_uploader.dart b/app/lib/filesharing/logic/firebase_file_uploader/firebase_file_uploader.dart index fb2beebe6..291c792b2 100644 --- a/app/lib/filesharing/logic/firebase_file_uploader/firebase_file_uploader.dart +++ b/app/lib/filesharing/logic/firebase_file_uploader/firebase_file_uploader.dart @@ -28,6 +28,7 @@ class FirebaseFileUploader { required String creatorID, required String creatorName, FolderPath path = FolderPath.root, + bool isPrivate = false, }) async { return implementation.uploadFile( localFile: localFile, @@ -35,6 +36,7 @@ class FirebaseFileUploader { path: path, creatorID: creatorID, creatorName: creatorName, + isPrivate: isPrivate, ); } } diff --git a/app/lib/filesharing/logic/firebase_file_uploader/implementation/firebase_file_uploader_impl.dart b/app/lib/filesharing/logic/firebase_file_uploader/implementation/firebase_file_uploader_impl.dart index a9f1e9a32..d0925a325 100644 --- a/app/lib/filesharing/logic/firebase_file_uploader/implementation/firebase_file_uploader_impl.dart +++ b/app/lib/filesharing/logic/firebase_file_uploader/implementation/firebase_file_uploader_impl.dart @@ -25,6 +25,7 @@ class FirebaseFileUploaderImplementation { required LocalFile localFile, required String creatorID, required String creatorName, + required isPrivate, FolderPath path = FolderPath.root, }) async { final ref = filesCollection.doc(); @@ -36,6 +37,7 @@ class FirebaseFileUploaderImplementation { creatorName: creatorName, courseID: courseID, path: path, + isPrivate: isPrivate, ).copyWith( fileFormat: fileFormat, forUsers: {creatorID: true}, diff --git a/app/lib/filesharing/widgets/sheet.dart b/app/lib/filesharing/widgets/sheet.dart index 40f55b5bb..17ddf848b 100644 --- a/app/lib/filesharing/widgets/sheet.dart +++ b/app/lib/filesharing/widgets/sheet.dart @@ -70,6 +70,7 @@ Future showCloudFileSheet({ icon: FileIcon(fileFormat: cloudFile.fileFormat), creatorName: cloudFile.creatorName, sizeBytes: cloudFile.sizeBytes, + isPrivate: cloudFile.isPrivate, items: CloudFileActionsColumn( hasPermissionToEdit: hasPermissionToEdit, onSelectCloudFileAction: (context, sheetOption) => @@ -95,6 +96,7 @@ class FileSheet extends StatelessWidget { this.fileType, this.icon, this.sizeBytes, + this.isPrivate, }) : super(key: key); final String? name; @@ -103,6 +105,7 @@ class FileSheet extends StatelessWidget { final FileFormat? fileType; final Widget? icon; final int? sizeBytes; + final bool? isPrivate; @override Widget build(BuildContext context) { @@ -147,6 +150,9 @@ class FileSheet extends StatelessWidget { "Ersteller: $creatorName", style: greyTextStyle, ), + if (isPrivate == true) + Text('Privat (nur für dich sichtbar)', + style: greyTextStyle), sizeBytes != null ? Text( "Größe: ${KiloByteSize(bytes: sizeBytes!).inMegabytes.toStringAsFixed(2)} MB", diff --git a/app/lib/homework/homework_dialog/homework_dialog_bloc.dart b/app/lib/homework/homework_dialog/homework_dialog_bloc.dart index 84e68b88a..15af50f3a 100644 --- a/app/lib/homework/homework_dialog/homework_dialog_bloc.dart +++ b/app/lib/homework/homework_dialog/homework_dialog_bloc.dart @@ -795,7 +795,8 @@ class HomeworkDialogApi { final typeOfUser = user.typeOfUser; final attachments = await _api.fileSharing.uploadAttachments( - localFiles, courseId.id, authorReference.id, authorName); + localFiles, courseId.id, authorReference.id, authorName, + isPrivate: userInput.private); final homework = HomeworkDto.create( courseReference: _api.references.getCourseReference(course.id), @@ -855,6 +856,7 @@ class HomeworkDialogApi { oldHomework.courseReference!.id, editorID, editorName, + isPrivate: userInput.private, ); attachments.addAll(newAttachments); diff --git a/app/test/homework/homework_dialog_test.dart b/app/test/homework/homework_dialog_test.dart index d8a67f424..a06997e14 100644 --- a/app/test/homework/homework_dialog_test.dart +++ b/app/test/homework/homework_dialog_test.dart @@ -192,6 +192,7 @@ CloudFile randomAttachmentCloudFileWith( 'Random Assignment Creator Name ${randomAlphaNumeric(5)}', courseID: courseId, creatorID: 'random_file_creator_id_${randomAlphaNumeric(5)}', + isPrivate: randomBool(), path: FolderPath.fromPathString('/$courseId/${FolderPath.attachments}')) .copyWith(name: name, fileFormat: fileType); diff --git a/lib/filesharing/filesharing_logic/lib/src/models/cloud_file.dart b/lib/filesharing/filesharing_logic/lib/src/models/cloud_file.dart index 949a724d0..c520d84d1 100644 --- a/lib/filesharing/filesharing_logic/lib/src/models/cloud_file.dart +++ b/lib/filesharing/filesharing_logic/lib/src/models/cloud_file.dart @@ -34,6 +34,8 @@ class CloudFile { final int? sizeBytes; final FileFormat fileFormat; + final bool isPrivate; + /// Aufgrund der Security-Rules müssen die UIs in dem CloudFile-Dokument /// stehen. Da für die Anhänge bereits array_contains in der Query /// verwendet wird, kann nicht ein zweites array_contains benutzt @@ -57,6 +59,7 @@ class CloudFile { required this.sizeBytes, required this.fileFormat, required this.forUsers, + required this.isPrivate, }); factory CloudFile.create({ @@ -64,6 +67,7 @@ class CloudFile { required String creatorID, required String creatorName, required String courseID, + bool isPrivate = false, FolderPath path = FolderPath.root, }) { return CloudFile._( @@ -82,6 +86,7 @@ class CloudFile { sizeBytes: null, fileFormat: FileFormat.unknown, forUsers: {}, + isPrivate: isPrivate, ); } @@ -108,6 +113,7 @@ class CloudFile { // und somit direkt die Files-Dokumente geladen werden können (ohne auf die CF zu // warten). forUsers: {}, + isPrivate: data['private'] ?? false, ); } @@ -129,6 +135,7 @@ class CloudFile { 'sizeBytes': sizeBytes, 'fileType': fileTypeEnumToString(fileFormat), 'forUsers': forUsers, + 'private': isPrivate, }; } @@ -148,6 +155,7 @@ class CloudFile { int? sizeBytes, FileFormat? fileFormat, Map? forUsers, + bool? isPrivate, }) { return CloudFile._( id: id ?? this.id, @@ -165,6 +173,7 @@ class CloudFile { sizeBytes: sizeBytes ?? this.sizeBytes, fileFormat: fileFormat ?? this.fileFormat, forUsers: forUsers ?? this.forUsers, + isPrivate: isPrivate ?? this.isPrivate, ); }