diff --git a/lib/src/database/daos/messages.dao.dart b/lib/src/database/daos/messages.dao.dart index 53d717b5..98d045f0 100644 --- a/lib/src/database/daos/messages.dao.dart +++ b/lib/src/database/daos/messages.dao.dart @@ -32,15 +32,24 @@ class MessagesDao extends DatabaseAccessor with _$MessagesDaoMixin { MessagesDao(super.db); Stream> watchMessageNotOpened(String groupId) { - return (select(messages) + final query = + select(messages).join([ + leftOuterJoin( + mediaFiles, + mediaFiles.mediaId.equalsExp(messages.mediaId), + ), + ]) ..where( - (t) => - t.openedAt.isNull() & - t.groupId.equals(groupId) & - t.isDeletedFromSender.equals(false), + messages.openedAt.isNull() & + messages.groupId.equals(groupId) & + messages.isDeletedFromSender.equals(false) & + (messages.mediaId.isNull() | + mediaFiles.downloadState + .equals(DownloadState.reuploadRequested.name) + .not()), ) - ..orderBy([(t) => OrderingTerm.desc(t.createdAt)])) - .watch(); + ..orderBy([OrderingTerm.desc(messages.createdAt)]); + return query.map((row) => row.readTable(messages)).watch(); } Stream> watchMediaNotOpened(String groupId) { @@ -91,26 +100,27 @@ class MessagesDao extends DatabaseAccessor with _$MessagesDaoMixin { milliseconds: group!.deleteMessagesAfterMilliseconds, ), ); - final query = select(messages).join([ - leftOuterJoin( - mediaFiles, - mediaFiles.mediaId.equalsExp(messages.mediaId), - ), - ]) - ..where( - messages.groupId.equals(groupId) & - // messages in groups will only be removed in case all members have received it... - // so ensuring that this message is not shown in the messages anymore - (messages.openedAt.isBiggerThanValue(deletionTime) | - messages.openedAt.isNull() | - messages.mediaStored.equals(true)) & - (mediaFiles.downloadState - .equals(DownloadState.reuploadRequested.name) - .not() | - mediaFiles.downloadState.isNull()), - ) - ..orderBy([OrderingTerm.desc(messages.createdAt)]) - ..limit(1); + final query = + select(messages).join([ + leftOuterJoin( + mediaFiles, + mediaFiles.mediaId.equalsExp(messages.mediaId), + ), + ]) + ..where( + messages.groupId.equals(groupId) & + // messages in groups will only be removed in case all members have received it... + // so ensuring that this message is not shown in the messages anymore + (messages.openedAt.isBiggerThanValue(deletionTime) | + messages.openedAt.isNull() | + messages.mediaStored.equals(true)) & + (mediaFiles.downloadState + .equals(DownloadState.reuploadRequested.name) + .not() | + mediaFiles.downloadState.isNull()), + ) + ..orderBy([OrderingTerm.desc(messages.createdAt)]) + ..limit(1); return query.map((row) => row.readTable(messages)).watchSingleOrNull(); } diff --git a/lib/src/services/api/client2client/media.c2c.dart b/lib/src/services/api/client2client/media.c2c.dart index 476844bc..29ab1a62 100644 --- a/lib/src/services/api/client2client/media.c2c.dart +++ b/lib/src/services/api/client2client/media.c2c.dart @@ -148,6 +148,10 @@ Future handleMedia( return false; } + Log.info( + '[$receiptId] Inserting media message: messageId=${media.senderMessageId}, mediaId=${mediaFile!.mediaId}', + ); + message = await twonlyDB.messagesDao.insertMessage( MessagesCompanion( messageId: Value(media.senderMessageId), diff --git a/lib/src/services/api/mediafiles/download.api.dart b/lib/src/services/api/mediafiles/download.api.dart index e3fef202..57aa5327 100644 --- a/lib/src/services/api/mediafiles/download.api.dart +++ b/lib/src/services/api/mediafiles/download.api.dart @@ -272,6 +272,13 @@ Future downloadFileFast( } Future requestMediaReupload(String mediaId) async { + await twonlyDB.mediaFilesDao.updateMedia( + mediaId, + const MediaFilesCompanion( + downloadState: Value(DownloadState.reuploadRequested), + ), + ); + final messages = await twonlyDB.messagesDao.getMessagesByMediaId(mediaId); for (final message in messages) { @@ -285,12 +292,6 @@ Future requestMediaReupload(String mediaId) async { ), ), ); - await twonlyDB.mediaFilesDao.updateMedia( - mediaId, - const MediaFilesCompanion( - downloadState: Value(DownloadState.reuploadRequested), - ), - ); } } diff --git a/lib/src/visual/views/chats/media_viewer.view.dart b/lib/src/visual/views/chats/media_viewer.view.dart index 3ea80c5b..6e99ff8b 100644 --- a/lib/src/visual/views/chats/media_viewer.view.dart +++ b/lib/src/visual/views/chats/media_viewer.view.dart @@ -359,12 +359,17 @@ class _MediaViewerViewState extends State { if (!mounted) return; if (!currentMediaLocal.tempPath.existsSync()) { - Log.warn('Temp media file not found for media ID: ${currentMediaLocal.mediaFile.mediaId}'); + Log.warn( + 'Temp media file not found for media ID: ${currentMediaLocal.mediaFile.mediaId}', + ); await handleMediaError(currentMediaLocal.mediaFile); return advanceToNextMediaOrExit(); } // The server can now delete the encrypted bytes, as the users has sucessfully opened it. + Log.info( + 'Calling downloadDone for media ID: ${currentMediaLocal.mediaFile.mediaId}', + ); unawaited( apiService.downloadDone(currentMediaLocal.mediaFile.downloadToken!), ); @@ -469,7 +474,11 @@ class _MediaViewerViewState extends State { ..play(); }) .catchError((Object err, StackTrace st) { - Log.error('Video player initialization error', error: err, stackTrace: st); + Log.error( + 'Video player initialization error', + error: err, + stackTrace: st, + ); return null; }); } @@ -563,7 +572,9 @@ class _MediaViewerViewState extends State { currentMedia!.mediaFile.displayLimitInMilliseconds == null) MyIconButton( variant: MyIconButtonVariant.secondary, - onPressed: (currentMedia == null || currentMessage == null) ? null : onPressedSaveToGallery, + onPressed: (currentMedia == null || currentMessage == null) + ? null + : onPressedSaveToGallery, icon: imageSaving ? const SizedBox( width: 16, diff --git a/pubspec.yaml b/pubspec.yaml index 6af3df74..359fad98 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -3,7 +3,7 @@ description: "twonly, a privacy-friendly way to connect with friends through sec publish_to: 'none' -version: 0.3.5+150 +version: 0.3.5+151 environment: sdk: ^3.11.0