mirror of
https://github.com/twonlyapp/twonly-app.git
synced 2026-01-15 09:08:40 +00:00
Some checks are pending
Flutter analyze & test / flutter_analyze_and_test (push) Waiting to run
180 lines
6 KiB
Dart
180 lines
6 KiB
Dart
import 'dart:async';
|
|
import 'package:drift/drift.dart';
|
|
import 'package:twonly/globals.dart';
|
|
import 'package:twonly/src/database/tables/mediafiles.table.dart';
|
|
import 'package:twonly/src/database/tables/messages.table.dart';
|
|
import 'package:twonly/src/database/twonly.db.dart';
|
|
import 'package:twonly/src/model/protobuf/client/generated/messages.pb.dart';
|
|
import 'package:twonly/src/services/api/mediafiles/download.service.dart';
|
|
import 'package:twonly/src/services/api/utils.dart';
|
|
import 'package:twonly/src/services/mediafiles/mediafile.service.dart';
|
|
import 'package:twonly/src/utils/log.dart';
|
|
|
|
Future<void> handleMedia(
|
|
int fromUserId,
|
|
String groupId,
|
|
EncryptedContent_Media media,
|
|
) async {
|
|
Log.info(
|
|
'Got a media message: ${media.senderMessageId} from $groupId with type ${media.type}',
|
|
);
|
|
|
|
late MediaType mediaType;
|
|
switch (media.type) {
|
|
case EncryptedContent_Media_Type.REUPLOAD:
|
|
final message = await twonlyDB.messagesDao
|
|
.getMessageById(media.senderMessageId)
|
|
.getSingleOrNull();
|
|
if (message == null ||
|
|
message.senderId != fromUserId ||
|
|
message.mediaId == null) {
|
|
return;
|
|
}
|
|
|
|
// in case there was already a downloaded file delete it...
|
|
final mediaService = await MediaFileService.fromMediaId(message.mediaId!);
|
|
if (mediaService != null) {
|
|
mediaService.tempPath.deleteSync();
|
|
}
|
|
|
|
await twonlyDB.mediaFilesDao.updateMedia(
|
|
message.mediaId!,
|
|
MediaFilesCompanion(
|
|
downloadState: const Value(DownloadState.pending),
|
|
downloadToken: Value(Uint8List.fromList(media.downloadToken)),
|
|
encryptionKey: Value(Uint8List.fromList(media.encryptionKey)),
|
|
encryptionMac: Value(Uint8List.fromList(media.encryptionMac)),
|
|
encryptionNonce: Value(Uint8List.fromList(media.encryptionNonce)),
|
|
),
|
|
);
|
|
|
|
final mediaFile =
|
|
await twonlyDB.mediaFilesDao.getMediaFileById(message.mediaId!);
|
|
|
|
if (mediaFile != null) {
|
|
unawaited(startDownloadMedia(mediaFile, false));
|
|
}
|
|
|
|
return;
|
|
case EncryptedContent_Media_Type.IMAGE:
|
|
mediaType = MediaType.image;
|
|
case EncryptedContent_Media_Type.VIDEO:
|
|
mediaType = MediaType.video;
|
|
case EncryptedContent_Media_Type.GIF:
|
|
mediaType = MediaType.gif;
|
|
case EncryptedContent_Media_Type.AUDIO:
|
|
mediaType = MediaType.audio;
|
|
}
|
|
|
|
int? displayLimitInMilliseconds;
|
|
if (media.hasDisplayLimitInMilliseconds()) {
|
|
if (media.displayLimitInMilliseconds.toInt() < 1000) {
|
|
displayLimitInMilliseconds =
|
|
media.displayLimitInMilliseconds.toInt() * 1000;
|
|
} else {
|
|
displayLimitInMilliseconds = media.displayLimitInMilliseconds.toInt();
|
|
}
|
|
}
|
|
|
|
final mediaFile = await twonlyDB.mediaFilesDao.insertMedia(
|
|
MediaFilesCompanion(
|
|
downloadState: const Value(DownloadState.pending),
|
|
type: Value(mediaType),
|
|
requiresAuthentication: Value(media.requiresAuthentication),
|
|
displayLimitInMilliseconds: Value(
|
|
displayLimitInMilliseconds,
|
|
),
|
|
downloadToken: Value(Uint8List.fromList(media.downloadToken)),
|
|
encryptionKey: Value(Uint8List.fromList(media.encryptionKey)),
|
|
encryptionMac: Value(Uint8List.fromList(media.encryptionMac)),
|
|
encryptionNonce: Value(Uint8List.fromList(media.encryptionNonce)),
|
|
createdAt: Value(fromTimestamp(media.timestamp)),
|
|
),
|
|
);
|
|
|
|
if (mediaFile == null) {
|
|
Log.error('Could not insert media file into database');
|
|
return;
|
|
}
|
|
|
|
final message = await twonlyDB.messagesDao.insertMessage(
|
|
MessagesCompanion(
|
|
messageId: Value(media.senderMessageId),
|
|
senderId: Value(fromUserId),
|
|
groupId: Value(groupId),
|
|
mediaId: Value(mediaFile.mediaId),
|
|
type: const Value(MessageType.media),
|
|
quotesMessageId: Value(
|
|
media.hasQuoteMessageId() ? media.quoteMessageId : null,
|
|
),
|
|
createdAt: Value(fromTimestamp(media.timestamp)),
|
|
),
|
|
);
|
|
if (message != null) {
|
|
await twonlyDB.groupsDao
|
|
.increaseLastMessageExchange(groupId, fromTimestamp(media.timestamp));
|
|
Log.info('Inserted a new media message with ID: ${message.messageId}');
|
|
await twonlyDB.groupsDao.incFlameCounter(
|
|
message.groupId,
|
|
true,
|
|
fromTimestamp(media.timestamp),
|
|
);
|
|
|
|
unawaited(startDownloadMedia(mediaFile, false));
|
|
}
|
|
}
|
|
|
|
Future<void> handleMediaUpdate(
|
|
int fromUserId,
|
|
EncryptedContent_MediaUpdate mediaUpdate,
|
|
) async {
|
|
final message = await twonlyDB.messagesDao
|
|
.getMessageById(mediaUpdate.targetMessageId)
|
|
.getSingleOrNull();
|
|
if (message == null) {
|
|
Log.error(
|
|
'Got media update to message ${mediaUpdate.targetMessageId} but message not found.',
|
|
);
|
|
}
|
|
final mediaFile =
|
|
await twonlyDB.mediaFilesDao.getMediaFileById(message!.mediaId!);
|
|
if (mediaFile == null) {
|
|
Log.info(
|
|
'Got media file update, but media file was not found ${message.mediaId}',
|
|
);
|
|
return;
|
|
}
|
|
|
|
switch (mediaUpdate.type) {
|
|
case EncryptedContent_MediaUpdate_Type.REOPENED:
|
|
Log.info('Got media file reopened ${mediaFile.mediaId}');
|
|
await twonlyDB.messagesDao.updateMessageId(
|
|
message.messageId,
|
|
const MessagesCompanion(
|
|
mediaReopened: Value(true),
|
|
),
|
|
);
|
|
case EncryptedContent_MediaUpdate_Type.STORED:
|
|
Log.info('Got media file stored ${mediaFile.mediaId}');
|
|
final mediaService = MediaFileService(mediaFile);
|
|
await mediaService.storeMediaFile();
|
|
await twonlyDB.messagesDao.updateMessageId(
|
|
message.messageId,
|
|
const MessagesCompanion(
|
|
mediaStored: Value(true),
|
|
),
|
|
);
|
|
|
|
case EncryptedContent_MediaUpdate_Type.DECRYPTION_ERROR:
|
|
Log.info('Got media file decryption error ${mediaFile.mediaId}');
|
|
final reuploadRequestedBy = mediaFile.reuploadRequestedBy ?? [];
|
|
reuploadRequestedBy.add(fromUserId);
|
|
await twonlyDB.mediaFilesDao.updateMedia(
|
|
mediaFile.mediaId,
|
|
MediaFilesCompanion(
|
|
uploadState: const Value(UploadState.uploading),
|
|
reuploadRequestedBy: Value(reuploadRequestedBy),
|
|
),
|
|
);
|
|
}
|
|
}
|