fixing more issues

This commit is contained in:
otsmr 2025-10-20 09:03:17 +02:00
parent 2f3f927914
commit 0207aaf074
10 changed files with 849 additions and 668 deletions

View file

@ -348,6 +348,10 @@ class MessagesDao extends DatabaseAccessor<TwonlyDB> with _$MessagesDaoMixin {
return select(messages)..where((t) => t.messageId.equals(messageId)); return select(messages)..where((t) => t.messageId.equals(messageId));
} }
Future<List<Message>> getMessagesByMediaId(String mediaId) async {
return (select(messages)..where((t) => t.mediaId.equals(mediaId))).get();
}
// Future<List<Message>> getMessagesByMediaUploadId(int mediaUploadId) async { // Future<List<Message>> getMessagesByMediaUploadId(int mediaUploadId) async {
// return (select(messages) // return (select(messages)
// ..where((t) => t.mediaUploadId.equals(mediaUploadId))) // ..where((t) => t.mediaUploadId.equals(mediaUploadId)))

View file

@ -4,10 +4,10 @@ part of 'messages.dao.dart';
// ignore_for_file: type=lint // ignore_for_file: type=lint
mixin _$MessagesDaoMixin on DatabaseAccessor<TwonlyDB> { mixin _$MessagesDaoMixin on DatabaseAccessor<TwonlyDB> {
$GroupsTable get groups => attachedDatabase.groups;
$ContactsTable get contacts => attachedDatabase.contacts; $ContactsTable get contacts => attachedDatabase.contacts;
$MediaFilesTable get mediaFiles => attachedDatabase.mediaFiles; $MediaFilesTable get mediaFiles => attachedDatabase.mediaFiles;
$MessagesTable get messages => attachedDatabase.messages; $MessagesTable get messages => attachedDatabase.messages;
$MessageHistoriesTable get messageHistories => $MessageHistoriesTable get messageHistories =>
attachedDatabase.messageHistories; attachedDatabase.messageHistories;
$GroupsTable get groups => attachedDatabase.groups;
} }

View file

@ -4,6 +4,7 @@ part of 'reactions.dao.dart';
// ignore_for_file: type=lint // ignore_for_file: type=lint
mixin _$ReactionsDaoMixin on DatabaseAccessor<TwonlyDB> { mixin _$ReactionsDaoMixin on DatabaseAccessor<TwonlyDB> {
$GroupsTable get groups => attachedDatabase.groups;
$ContactsTable get contacts => attachedDatabase.contacts; $ContactsTable get contacts => attachedDatabase.contacts;
$MediaFilesTable get mediaFiles => attachedDatabase.mediaFiles; $MediaFilesTable get mediaFiles => attachedDatabase.mediaFiles;
$MessagesTable get messages => attachedDatabase.messages; $MessagesTable get messages => attachedDatabase.messages;

View file

@ -5,6 +5,7 @@ part of 'receipts.dao.dart';
// ignore_for_file: type=lint // ignore_for_file: type=lint
mixin _$ReceiptsDaoMixin on DatabaseAccessor<TwonlyDB> { mixin _$ReceiptsDaoMixin on DatabaseAccessor<TwonlyDB> {
$ContactsTable get contacts => attachedDatabase.contacts; $ContactsTable get contacts => attachedDatabase.contacts;
$GroupsTable get groups => attachedDatabase.groups;
$MediaFilesTable get mediaFiles => attachedDatabase.mediaFiles; $MediaFilesTable get mediaFiles => attachedDatabase.mediaFiles;
$MessagesTable get messages => attachedDatabase.messages; $MessagesTable get messages => attachedDatabase.messages;
$ReceiptsTable get receipts => attachedDatabase.receipts; $ReceiptsTable get receipts => attachedDatabase.receipts;

View file

@ -16,7 +16,7 @@ enum UploadState {
receiverNotified, receiverNotified,
} }
enum DownloadState { pending, downloading } enum DownloadState { pending, downloading, reuploadRequested }
@DataClassName('MediaFile') @DataClassName('MediaFile')
class MediaFiles extends Table { class MediaFiles extends Table {

View file

@ -1,11 +1,13 @@
import 'package:drift/drift.dart'; import 'package:drift/drift.dart';
import 'package:hashlib/random.dart'; import 'package:hashlib/random.dart';
import 'package:twonly/src/database/tables/contacts.table.dart'; import 'package:twonly/src/database/tables/contacts.table.dart';
import 'package:twonly/src/database/tables/groups.table.dart';
import 'package:twonly/src/database/tables/mediafiles.table.dart'; import 'package:twonly/src/database/tables/mediafiles.table.dart';
@DataClassName('Message') @DataClassName('Message')
class Messages extends Table { class Messages extends Table {
TextColumn get groupId => text()(); TextColumn get groupId =>
text().references(Groups, #groupId, onDelete: KeyAction.cascade)();
TextColumn get messageId => text().clientDefault(() => uuid.v7())(); TextColumn get messageId => text().clientDefault(() => uuid.v7())();
// in case senderId is null, it was send by user itself // in case senderId is null, it was send by user itself

File diff suppressed because it is too large Load diff

View file

@ -1,15 +1,16 @@
import 'package:drift/drift.dart'; import 'package:drift/drift.dart';
import 'package:fixnum/fixnum.dart'; import 'package:fixnum/fixnum.dart';
import 'package:twonly/globals.dart'; import 'package:twonly/globals.dart';
import 'package:twonly/src/database/tables/messages_table.dart'; import 'package:twonly/src/database/tables/mediafiles.table.dart';
import 'package:twonly/src/database/twonly.db.dart'; import 'package:twonly/src/database/twonly.db.dart';
import 'package:twonly/src/model/json/message_old.dart';
import 'package:twonly/src/model/protobuf/api/websocket/client_to_server.pb.dart' import 'package:twonly/src/model/protobuf/api/websocket/client_to_server.pb.dart'
as client; as client;
import 'package:twonly/src/model/protobuf/api/websocket/client_to_server.pbserver.dart'; import 'package:twonly/src/model/protobuf/api/websocket/client_to_server.pbserver.dart';
import 'package:twonly/src/model/protobuf/api/websocket/error.pb.dart'; import 'package:twonly/src/model/protobuf/api/websocket/error.pb.dart';
import 'package:twonly/src/model/protobuf/api/websocket/server_to_client.pb.dart' import 'package:twonly/src/model/protobuf/api/websocket/server_to_client.pb.dart'
as server; as server;
import 'package:twonly/src/model/protobuf/client/generated/messages.pbserver.dart'
hide Message;
import 'package:twonly/src/services/api/messages.dart'; import 'package:twonly/src/services/api/messages.dart';
import 'package:twonly/src/services/signal/session.signal.dart'; import 'package:twonly/src/services/signal/session.signal.dart';
@ -57,44 +58,41 @@ ClientToServer createClientToServerFromApplicationData(
} }
Future<void> deleteContact(int contactId) async { Future<void> deleteContact(int contactId) async {
await twonlyDB.messagesDao.deleteAllMessagesByContactId(contactId);
await twonlyDB.signalDao.deleteAllByContactId(contactId); await twonlyDB.signalDao.deleteAllByContactId(contactId);
await deleteSessionWithTarget(contactId); await deleteSessionWithTarget(contactId);
await twonlyDB.contactsDao.deleteContactByUserId(contactId); await twonlyDB.contactsDao.deleteContactByUserId(contactId);
} }
Future<void> rejectUser(int contactId) async { Future<void> rejectUser(int contactId) async {
await encryptAndSendMessageAsync( await sendCipherText(
null,
contactId, contactId,
MessageJson( EncryptedContent(
kind: MessageKind.rejectRequest, contactRequest: EncryptedContent_ContactRequest(
timestamp: DateTime.now(), type: EncryptedContent_ContactRequest_Type.REJECT,
content: MessageContent(), ),
), ),
); );
} }
Future<void> handleMediaError(Message message) async { Future<void> handleMediaError(MediaFile media) async {
await twonlyDB.messagesDao.updateMessageByMessageId( await twonlyDB.mediaFilesDao.updateMedia(
message.messageId, media.mediaId,
const MessagesCompanion( const MediaFilesCompanion(
errorWhileSending: Value(true), downloadState: Value(DownloadState.reuploadRequested),
mediaRetransmissionState: Value( ),
MediaRetransmitting.requested, );
final messages =
await twonlyDB.messagesDao.getMessagesByMediaId(media.mediaId);
if (messages.length != 1) return;
final message = messages.first;
if (message.senderId == null) return;
await sendCipherText(
message.senderId!,
EncryptedContent(
mediaUpdate: EncryptedContent_MediaUpdate(
type: EncryptedContent_MediaUpdate_Type.DECRYPTION_ERROR,
targetMessageId: message.messageId,
), ),
), ),
); );
if (message.messageOtherId != null) {
await encryptAndSendMessageAsync(
null,
message.contactId,
MessageJson(
kind: MessageKind.receiveMediaError,
timestamp: DateTime.now(),
content: MessageContent(),
messageReceiverId: message.messageOtherId,
),
);
}
} }

View file

@ -1,10 +1,10 @@
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
import 'package:drift/drift.dart'; import 'package:drift/drift.dart';
import 'package:fixnum/fixnum.dart';
import 'package:twonly/globals.dart'; import 'package:twonly/globals.dart';
import 'package:twonly/src/database/daos/contacts.dao.dart'; import 'package:twonly/src/database/daos/contacts.dao.dart';
import 'package:twonly/src/database/tables/messages_table.dart';
import 'package:twonly/src/database/twonly.db.dart'; import 'package:twonly/src/database/twonly.db.dart';
import 'package:twonly/src/model/json/message_old.dart' as my; import 'package:twonly/src/model/protobuf/client/generated/messages.pb.dart';
import 'package:twonly/src/services/api/messages.dart'; import 'package:twonly/src/services/api/messages.dart';
import 'package:twonly/src/utils/misc.dart'; import 'package:twonly/src/utils/misc.dart';
import 'package:twonly/src/utils/storage.dart'; import 'package:twonly/src/utils/storage.dart';
@ -38,17 +38,15 @@ Future<void> syncFlameCounters() async {
// only sync when flame counter is higher than three days // only sync when flame counter is higher than three days
if (flameCounter < 1 && bestFriend.userId != contact.userId) continue; if (flameCounter < 1 && bestFriend.userId != contact.userId) continue;
await encryptAndSendMessageAsync( await sendCipherText(
null,
contact.userId, contact.userId,
my.MessageJson( EncryptedContent(
kind: MessageKind.flameSync, flameSync: EncryptedContent_FlameSync(
content: my.FlameSyncContent( flameCounter: Int64(flameCounter),
flameCounter: flameCounter, lastFlameCounterChange:
lastFlameCounterChange: contact.lastFlameCounterChange!, Int64(contact.lastFlameCounterChange!.millisecondsSinceEpoch),
bestFriend: contact.userId == bestFriend.userId, bestFriend: contact.userId == bestFriend.userId,
), ),
timestamp: DateTime.now(),
), ),
); );

View file

@ -7,9 +7,11 @@ import 'package:cryptography_plus/cryptography_plus.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
import 'package:twonly/src/constants/secure_storage_keys.dart'; import 'package:twonly/src/constants/secure_storage_keys.dart';
import 'package:twonly/src/model/protobuf/client/generated/push_notification.pb.dart';
import 'package:twonly/src/model/protobuf/client/generated/push_notification.pbenum.dart'; import 'package:twonly/src/model/protobuf/client/generated/push_notification.pbenum.dart';
import 'package:twonly/src/services/notifications/pushkeys.notifications.dart'; import 'package:twonly/src/services/notifications/pushkeys.notifications.dart';
import 'package:twonly/src/utils/log.dart'; import 'package:twonly/src/utils/log.dart';
import 'package:twonly/src/utils/misc.dart';
import 'package:twonly/src/views/camera/share_image_editor_view.dart' import 'package:twonly/src/views/camera/share_image_editor_view.dart'
show gMediaShowInfinite; show gMediaShowInfinite;
@ -75,7 +77,10 @@ Future<void> handlePushData(String pushDataB64) async {
); );
} else if (foundPushUser != null) { } else if (foundPushUser != null) {
if (pushNotification.hasMessageId()) { if (pushNotification.hasMessageId()) {
if (pushNotification.messageId <= foundPushUser.lastMessageId) { if (isUUIDNewer(
foundPushUser.lastMessageId,
pushNotification.messageId,
)) {
Log.info( Log.info(
'Got a push notification for a message which was already opened.', 'Got a push notification for a message which was already opened.',
); );