add error handling and media purge

This commit is contained in:
otsmr 2025-06-12 17:18:33 +02:00
parent 6677f89a18
commit b979f3c8d2
4 changed files with 74 additions and 41 deletions

View file

@ -1,4 +1,3 @@
import 'dart:isolate';
import 'package:camera/camera.dart'; import 'package:camera/camera.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -46,10 +45,8 @@ void main() async {
await twonlyDB.messagesDao.handleMediaFilesOlderThan7Days(); await twonlyDB.messagesDao.handleMediaFilesOlderThan7Days();
// purge media files in the background // purge media files in the background
Isolate.run(() {
purgeReceivedMediaFiles(); purgeReceivedMediaFiles();
purgeSendMediaFiles(); purgeSendMediaFiles();
});
await initMediaUploader(); await initMediaUploader();

View file

@ -15,6 +15,7 @@ import 'package:cryptography_plus/cryptography_plus.dart';
import 'package:twonly/src/services/api/utils.dart'; import 'package:twonly/src/services/api/utils.dart';
import 'package:twonly/src/utils/log.dart'; import 'package:twonly/src/utils/log.dart';
import 'package:twonly/src/utils/storage.dart'; import 'package:twonly/src/utils/storage.dart';
import 'package:twonly/src/views/camera/share_image_editor_view.dart';
Map<int, DateTime> downloadStartedForMediaReceived = {}; Map<int, DateTime> downloadStartedForMediaReceived = {};
@ -311,7 +312,16 @@ Future<void> purgeMediaFiles(Directory directory) async {
bool canBeDeleted = true; bool canBeDeleted = true;
for (final message in messages) { for (final message in messages) {
if ((message.openedAt == null && !message.errorWhileSending)) { try {
MediaMessageContent content = MediaMessageContent.fromJson(
jsonDecode(message.contentJson!),
);
DateTime oneDayAgo = DateTime.now().subtract(Duration(days: 1));
if (((message.openedAt == null ||
oneDayAgo.isBefore(message.openedAt!)) &&
!message.errorWhileSending)) {
canBeDeleted = false; canBeDeleted = false;
} else if (message.mediaStored) { } else if (message.mediaStored) {
if (!file.path.contains(".original.") && if (!file.path.contains(".original.") &&
@ -319,6 +329,18 @@ Future<void> purgeMediaFiles(Directory directory) async {
canBeDeleted = false; canBeDeleted = false;
} }
} }
if (message.acknowledgeByServer) {
// preserve images which can be stored by the other person...
if (content.maxShowTime != gMediaShowInfinite) {
canBeDeleted = true;
}
// encrypted or upload data can be removed when acknowledgedByServer
if (file.path.contains(".upload") ||
file.path.contains(".encrypted")) {
canBeDeleted = true;
}
}
} catch (e) {}
} }
if (canBeDeleted) { if (canBeDeleted) {
Log.info("purged media file ${file.path} "); Log.info("purged media file ${file.path} ");

View file

@ -56,18 +56,25 @@ Future initMediaUploader() async {
FileDownloader().updates.listen((update) async { FileDownloader().updates.listen((update) async {
switch (update) { switch (update) {
case TaskStatusUpdate(): case TaskStatusUpdate():
if (update.status == TaskStatus.complete) { bool failed = false;
int mediaUploadId = int.parse(update.task.taskId); int mediaUploadId = int.parse(update.task.taskId);
MediaUpload? media = await twonlyDB.mediaUploadsDao MediaUpload? media = await twonlyDB.mediaUploadsDao
.getMediaUploadById(mediaUploadId) .getMediaUploadById(mediaUploadId)
.getSingleOrNull(); .getSingleOrNull();
if (media == null) { if (media == null) {
Log.error( Log.error(
"Got an upload task but no upload media in the mediaupload atabase"); "Got an upload task but no upload media in the media upload database",
);
return; return;
} }
if (update.status == TaskStatus.failed ||
update.status == TaskStatus.canceled) {
Log.error("Upload failed: ${update.status}");
failed = true;
} else if (update.status == TaskStatus.complete) {
if (update.responseStatusCode == 200) { if (update.responseStatusCode == 200) {
Log.info("Upload was success!"); Log.info("Upload of $mediaUploadId success!");
await twonlyDB.mediaUploadsDao.updateMediaUpload( await twonlyDB.mediaUploadsDao.updateMediaUpload(
mediaUploadId, mediaUploadId,
@ -89,6 +96,15 @@ Future initMediaUploader() async {
} else if (update.responseStatusCode != null) { } else if (update.responseStatusCode != null) {
if (update.responseStatusCode! >= 400 && if (update.responseStatusCode! >= 400 &&
update.responseStatusCode! < 500) { update.responseStatusCode! < 500) {
failed = true;
}
Log.error(
"Got error while uploading: ${update.responseStatusCode}",
);
}
}
if (failed) {
for (final messageId in media.messageIds!) { for (final messageId in media.messageIds!) {
await twonlyDB.messagesDao.updateMessageByMessageId( await twonlyDB.messagesDao.updateMessageByMessageId(
messageId, messageId,
@ -99,10 +115,6 @@ Future initMediaUploader() async {
); );
} }
} }
Log.error(
"Got error while uploading: ${update.responseStatusCode}");
}
}
print('Status update for ${update.task} with status ${update.status}'); print('Status update for ${update.task} with status ${update.status}');
case TaskProgressUpdate(): case TaskProgressUpdate():
@ -117,6 +129,7 @@ Future initMediaUploader() async {
(Config.bypassTLSCertificateValidation, kDebugMode), (Config.bypassTLSCertificateValidation, kDebugMode),
]); ]);
if (kDebugMode) {
FileDownloader().configureNotification( FileDownloader().configureNotification(
running: TaskNotification( running: TaskNotification(
'Uploading', 'Uploading',
@ -126,6 +139,7 @@ Future initMediaUploader() async {
progressBar: true, progressBar: true,
); );
} }
}
/// States: /// States:
/// when user recorded an video /// when user recorded an video

View file

@ -260,7 +260,7 @@ class _MediaViewerViewState extends State<MediaViewerView> {
} }
if (!content.isVideo) { if (!content.isVideo) {
if (content.maxShowTime != 999999) { if (content.maxShowTime != gMediaShowInfinite) {
canBeSeenUntil = DateTime.now().add( canBeSeenUntil = DateTime.now().add(
Duration(seconds: content.maxShowTime), Duration(seconds: content.maxShowTime),
); );