diff --git a/lib/src/database/daos/messages.dao.dart b/lib/src/database/daos/messages.dao.dart index 0f67400d..53556214 100644 --- a/lib/src/database/daos/messages.dao.dart +++ b/lib/src/database/daos/messages.dao.dart @@ -197,6 +197,8 @@ class MessagesDao extends DatabaseAccessor with _$MessagesDaoMixin { await (delete( messageHistories, )..where((t) => t.messageId.equals(messageId))).go(); + + await twonlyDB.receiptsDao.deleteReceiptsByMessageId(messageId); await (update(messages)..where( (t) => t.messageId.equals(messageId), @@ -344,7 +346,7 @@ class MessagesDao extends DatabaseAccessor with _$MessagesDaoMixin { ); } - final rowId = await into(messages).insertOnConflictUpdate(insertMessage); + await into(messages).insertOnConflictUpdate(insertMessage); await twonlyDB.groupsDao.updateGroup( message.groupId.value, @@ -365,9 +367,11 @@ class MessagesDao extends DatabaseAccessor with _$MessagesDaoMixin { ); } + final messageId = insertMessage.messageId.value; + return await (select( messages, - )..where((t) => t.rowId.equals(rowId))).getSingle(); + )..where((t) => t.messageId.equals(messageId))).getSingle(); } catch (e) { Log.error('Could not insert message: $e'); return null; diff --git a/lib/src/database/daos/receipts.dao.dart b/lib/src/database/daos/receipts.dao.dart index b999d488..ee966fa8 100644 --- a/lib/src/database/daos/receipts.dao.dart +++ b/lib/src/database/daos/receipts.dao.dart @@ -53,6 +53,13 @@ class ReceiptsDao extends DatabaseAccessor with _$ReceiptsDaoMixin { )) .go(); } + + Future deleteReceiptsByMessageId(String messageId) async { + await (delete(receipts)..where( + (t) => t.messageId.equals(messageId), + )) + .go(); + } Future deleteReceiptForUser(int contactId) async { await (delete(receipts)..where( @@ -91,10 +98,11 @@ class ReceiptsDao extends DatabaseAccessor with _$ReceiptsDaoMixin { receiptId: Value(uuid.v4()), ); } - final id = await into(receipts).insert(insertEntry); + await into(receipts).insert(insertEntry); + final receiptId = insertEntry.receiptId.value; return await (select( receipts, - )..where((t) => t.rowId.equals(id))).getSingle(); + )..where((t) => t.receiptId.equals(receiptId))).getSingle(); } catch (e) { // ignore error, receipts is already in the database... return null; diff --git a/lib/src/services/api/client2client/media.c2c.dart b/lib/src/services/api/client2client/media.c2c.dart index 26375e29..88a041e0 100644 --- a/lib/src/services/api/client2client/media.c2c.dart +++ b/lib/src/services/api/client2client/media.c2c.dart @@ -178,9 +178,15 @@ Future handleMedia( unawaited(startDownloadMedia(mediaFile!, false)); } else { - Log.error( - 'Could not insert new message as both the message and mediaFile are empty.', - ); + if (mediaFile == null && message == null) { + Log.error( + 'Could not insert new message as both the message and mediaFile are empty.', + ); + } else if (mediaFile == null) { + Log.error('Could not insert new message as the mediaFile is empty.'); + } else { + Log.error('Could not insert new message as the message is empty.'); + } } } diff --git a/lib/src/services/api/mediafiles/upload.api.dart b/lib/src/services/api/mediafiles/upload.api.dart index b3191669..2e7dc975 100644 --- a/lib/src/services/api/mediafiles/upload.api.dart +++ b/lib/src/services/api/mediafiles/upload.api.dart @@ -60,12 +60,23 @@ Future reuploadMediaFiles() async { final content = EncryptedContent.fromBuffer(receipt.message); if (content.hasMedia()) { messageId = content.media.senderMessageId; - await twonlyDB.receiptsDao.updateReceipt( - receipt.receiptId, - ReceiptsCompanion( - messageId: Value(messageId), - ), - ); + final messageExists = await twonlyDB.messagesDao + .getMessageById(messageId) + .getSingleOrNull(); + if (messageExists != null) { + await twonlyDB.receiptsDao.updateReceipt( + receipt.receiptId, + ReceiptsCompanion( + messageId: Value(messageId), + ), + ); + } else { + Log.info( + 'Message $messageId not found in DB for receipt recovery. Deleting stale receipt.', + ); + await twonlyDB.receiptsDao.deleteReceipt(receipt.receiptId); + continue; + } } } catch (e) { Log.error(e); @@ -110,8 +121,8 @@ Future reuploadMediaFiles() async { await twonlyDB.messagesDao.deleteMessagesById(messageId); } await twonlyDB.receiptsDao.deleteReceipt(receipt.receiptId); - Log.error( - 'Message not found for reupload of the receipt (${message == null} - ${message?.mediaId}).', + Log.warn( + 'Message not found for reupload of the receipt, likely deleted from sender (${message == null} - ${message?.mediaId}).', ); continue; } diff --git a/lib/src/visual/views/camera/camera_preview_components/main_camera_controller.dart b/lib/src/visual/views/camera/camera_preview_components/main_camera_controller.dart index 9504306b..491168fe 100644 --- a/lib/src/visual/views/camera/camera_preview_components/main_camera_controller.dart +++ b/lib/src/visual/views/camera/camera_preview_components/main_camera_controller.dart @@ -198,8 +198,8 @@ class MainCameraController { focusPointOffset = Offset(localPosition.dx, localPosition.dy); - final dx = localPosition.dx / box.size.width; - final dy = localPosition.dy / box.size.height; + final dx = (localPosition.dx / box.size.width).clamp(0.0, 1.0); + final dy = (localPosition.dy / box.size.height).clamp(0.0, 1.0); setState(); @@ -208,7 +208,13 @@ class MainCameraController { await cameraController?.setFocusPoint(Offset(dx, dy)); await cameraController?.setFocusMode(FocusMode.auto); } catch (e) { - Log.error(e); + if (e is CameraException && + (e.code == 'setFocusPointFailed' || + e.code == 'setFocusModeFailed')) { + Log.info('Focus point or mode not supported on this device'); + } else { + Log.error(e); + } } // display the focus point at least 500ms