mirror of
https://github.com/twonlyapp/twonly-app.git
synced 2026-09-01 07:24:07 +00:00
removed unused functions
Some checks are pending
Flutter analyze & test / flutter_analyze_and_test (push) Waiting to run
Some checks are pending
Flutter analyze & test / flutter_analyze_and_test (push) Waiting to run
This commit is contained in:
parent
bd65268dd2
commit
b09d79f5d6
9 changed files with 27 additions and 578 deletions
|
|
@ -12,17 +12,7 @@ class ContactsDao extends DatabaseAccessor<TwonlyDB> with _$ContactsDaoMixin {
|
|||
// of this object.
|
||||
// ignore: matching_super_parameters
|
||||
ContactsDao(super.db);
|
||||
|
||||
Future<int?> insertContact(ContactsCompanion contact) async {
|
||||
try {
|
||||
return await into(contacts).insert(contact);
|
||||
} catch (e) {
|
||||
Log.error(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Future<int> insertOnConflictUpdate(ContactsCompanion contact) async {
|
||||
Future<int> insertOnConflictUpdate(ContactsCompanion contact) async {
|
||||
try {
|
||||
return await into(contacts).insertOnConflictUpdate(contact);
|
||||
} catch (e) {
|
||||
|
|
@ -174,27 +164,7 @@ class ContactsDao extends DatabaseAccessor<TwonlyDB> with _$ContactsDaoMixin {
|
|||
}))
|
||||
.watch();
|
||||
}
|
||||
|
||||
Future<List<Contact>> getContactsAnnouncedViaUserDiscovery() async {
|
||||
return (select(contacts)..where((t) {
|
||||
var expr =
|
||||
t.userDiscoveryVersion.isNotNull() &
|
||||
t.userDiscoveryExcluded.equals(false) &
|
||||
t.accountDeleted.equals(false) &
|
||||
t.mediaSendCounter.isBiggerOrEqualValue(
|
||||
userService.currentUser.requiredSendImages,
|
||||
);
|
||||
|
||||
if (userService.currentUser.userDiscoveryRequiresManualApproval) {
|
||||
expr = expr & t.userDiscoveryManualApproved.equals(true);
|
||||
}
|
||||
|
||||
return expr;
|
||||
}))
|
||||
.get();
|
||||
}
|
||||
|
||||
Stream<List<Contact>> watchAllContacts() {
|
||||
Stream<List<Contact>> watchAllContacts() {
|
||||
return select(contacts).watch();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,11 +2,9 @@ import 'package:clock/clock.dart' show clock;
|
|||
import 'package:drift/drift.dart';
|
||||
import 'package:hashlib/random.dart';
|
||||
import 'package:twonly/locator.dart';
|
||||
import 'package:twonly/src/database/daos/contacts.dao.dart';
|
||||
import 'package:twonly/src/database/tables/groups.table.dart';
|
||||
import 'package:twonly/src/database/twonly.db.dart';
|
||||
import 'package:twonly/src/services/flame.service.dart';
|
||||
import 'package:twonly/src/utils/log.dart';
|
||||
import 'package:twonly/src/utils/misc.dart';
|
||||
|
||||
part 'groups.dao.g.dart';
|
||||
|
|
@ -23,17 +21,7 @@ class GroupsDao extends DatabaseAccessor<TwonlyDB> with _$GroupsDaoMixin {
|
|||
// of this object.
|
||||
// ignore: matching_super_parameters
|
||||
GroupsDao(super.db);
|
||||
|
||||
Future<bool> isContactInGroup(int contactId, String groupId) async {
|
||||
final entry =
|
||||
await (select(groupMembers)..where(
|
||||
(t) => t.contactId.equals(contactId) & t.groupId.equals(groupId),
|
||||
))
|
||||
.getSingleOrNull();
|
||||
return entry != null;
|
||||
}
|
||||
|
||||
Future<void> deleteGroup(String groupId) async {
|
||||
Future<void> deleteGroup(String groupId) async {
|
||||
await (delete(groups)..where((t) => t.groupId.equals(groupId))).go();
|
||||
}
|
||||
|
||||
|
|
@ -61,22 +49,10 @@ class GroupsDao extends DatabaseAccessor<TwonlyDB> with _$GroupsDaoMixin {
|
|||
groupMembers,
|
||||
)..where((t) => t.groupId.equals(groupId))).get();
|
||||
}
|
||||
|
||||
Future<GroupMember?> getGroupMemberByPublicKey(Uint8List publicKey) async {
|
||||
return (select(
|
||||
groupMembers,
|
||||
)..where((t) => t.groupPublicKey.equals(publicKey))).getSingleOrNull();
|
||||
}
|
||||
|
||||
Future<Group?> createNewGroup(GroupsCompanion group) async {
|
||||
Future<Group?> createNewGroup(GroupsCompanion group) async {
|
||||
return _insertGroup(group);
|
||||
}
|
||||
|
||||
Future<void> insertOrUpdateGroupMember(GroupMembersCompanion members) async {
|
||||
await into(groupMembers).insertOnConflictUpdate(members);
|
||||
}
|
||||
|
||||
Future<void> insertGroupAction(GroupHistoriesCompanion action) async {
|
||||
Future<void> insertGroupAction(GroupHistoriesCompanion action) async {
|
||||
var insertAction = action;
|
||||
if (!action.groupHistoryId.present) {
|
||||
insertAction = action.copyWith(
|
||||
|
|
@ -101,26 +77,7 @@ class GroupsDao extends DatabaseAccessor<TwonlyDB> with _$GroupsDaoMixin {
|
|||
..orderBy([(t) => OrderingTerm.asc(t.actionAt)]))
|
||||
.watch();
|
||||
}
|
||||
|
||||
Future<void> updateMember(
|
||||
String groupId,
|
||||
int contactId,
|
||||
GroupMembersCompanion updates,
|
||||
) async {
|
||||
await (update(groupMembers)..where(
|
||||
(c) => c.groupId.equals(groupId) & c.contactId.equals(contactId),
|
||||
))
|
||||
.write(updates);
|
||||
}
|
||||
|
||||
Future<void> removeMember(String groupId, int contactId) async {
|
||||
await (delete(groupMembers)..where(
|
||||
(c) => c.groupId.equals(groupId) & c.contactId.equals(contactId),
|
||||
))
|
||||
.go();
|
||||
}
|
||||
|
||||
Future<Group?> createNewDirectChat(
|
||||
Future<Group?> createNewDirectChat(
|
||||
int contactId,
|
||||
GroupsCompanion group,
|
||||
) async {
|
||||
|
|
@ -231,18 +188,7 @@ class GroupsDao extends DatabaseAccessor<TwonlyDB> with _$GroupsDaoMixin {
|
|||
groups,
|
||||
)..where((t) => t.groupId.equals(groupId))).watchSingleOrNull();
|
||||
}
|
||||
|
||||
Stream<Group?> watchDirectChat(int contactId) {
|
||||
final groupId = getUUIDforDirectChat(
|
||||
contactId,
|
||||
userService.currentUser.userId,
|
||||
);
|
||||
return (select(
|
||||
groups,
|
||||
)..where((t) => t.groupId.equals(groupId))).watchSingleOrNull();
|
||||
}
|
||||
|
||||
Stream<List<Group>> watchGroupsForChatList() {
|
||||
Stream<List<Group>> watchGroupsForChatList() {
|
||||
return (select(groups)
|
||||
..where((t) => t.deletedContent.equals(false))
|
||||
..orderBy([(t) => OrderingTerm.desc(t.lastMessageExchange)]))
|
||||
|
|
@ -280,33 +226,7 @@ class GroupsDao extends DatabaseAccessor<TwonlyDB> with _$GroupsDaoMixin {
|
|||
Future<List<Group>> getAllGroups() {
|
||||
return select(groups).get();
|
||||
}
|
||||
|
||||
Future<List<Group>> getAllNotJoinedGroups() {
|
||||
return (select(groups)..where(
|
||||
(t) => t.joinedGroup.equals(false) & t.isDirectChat.equals(false),
|
||||
))
|
||||
.get();
|
||||
}
|
||||
|
||||
Future<List<GroupMember>> getAllGroupMemberWithoutPublicKey() async {
|
||||
try {
|
||||
final query =
|
||||
((select(groupMembers)..where((t) => t.groupPublicKey.isNull())).join(
|
||||
[
|
||||
leftOuterJoin(
|
||||
groups,
|
||||
groups.groupId.equalsExp(groupMembers.groupId),
|
||||
),
|
||||
],
|
||||
)..where(groups.isDirectChat.equals(false)));
|
||||
return await query.map((row) => row.readTable(groupMembers)).get();
|
||||
} catch (e) {
|
||||
Log.error(e);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
Future<Group?> getDirectChat(int userId) async {
|
||||
Future<Group?> getDirectChat(int userId) async {
|
||||
final query =
|
||||
((select(groups)..where((t) => t.isDirectChat.equals(true))).join([
|
||||
leftOuterJoin(
|
||||
|
|
@ -317,29 +237,7 @@ class GroupsDao extends DatabaseAccessor<TwonlyDB> with _$GroupsDaoMixin {
|
|||
|
||||
return query.map((row) => row.readTable(groups)).getSingleOrNull();
|
||||
}
|
||||
|
||||
Future<Group?> createOrGetDirectChat(int contactId) async {
|
||||
var directChat = await getDirectChat(contactId);
|
||||
if (directChat == null) {
|
||||
final contact = await attachedDatabase.contactsDao.getContactById(
|
||||
contactId,
|
||||
);
|
||||
if (contact == null) {
|
||||
Log.error('Contact $contactId not found, cannot create direct chat');
|
||||
return null;
|
||||
}
|
||||
await createNewDirectChat(
|
||||
contactId,
|
||||
GroupsCompanion(
|
||||
groupName: Value(getContactDisplayName(contact)),
|
||||
),
|
||||
);
|
||||
directChat = await getDirectChat(contactId);
|
||||
}
|
||||
return directChat;
|
||||
}
|
||||
|
||||
Stream<int> watchSumTotalMediaCounter() {
|
||||
Stream<int> watchSumTotalMediaCounter() {
|
||||
final query = selectOnly(groups)
|
||||
..addColumns([groups.totalMediaCounter.sum()]);
|
||||
return query.watch().map((rows) {
|
||||
|
|
@ -397,18 +295,4 @@ class GroupsDao extends DatabaseAccessor<TwonlyDB> with _$GroupsDaoMixin {
|
|||
|
||||
return query.map((row) => row.readTable(groups)).watch();
|
||||
}
|
||||
|
||||
Future<List<Group>> getGroupsForMember(int contactId) {
|
||||
final query =
|
||||
select(groups).join([
|
||||
innerJoin(
|
||||
groupMembers,
|
||||
groupMembers.groupId.equalsExp(groups.groupId),
|
||||
),
|
||||
])..where(
|
||||
groupMembers.contactId.equals(contactId),
|
||||
);
|
||||
|
||||
return query.map((row) => row.readTable(groups)).get();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,42 +43,7 @@ class KeyVerificationDao extends DatabaseAccessor<TwonlyDB>
|
|||
|
||||
/// Returns a map of contactId → the verification type of the earliest
|
||||
/// [KeyVerification] row for that contact.
|
||||
Future<Map<int, VerificationType>>
|
||||
getFirstVerificationTypeByContacts() async {
|
||||
final rows = await (select(
|
||||
keyVerifications,
|
||||
)..orderBy([(kv) => OrderingTerm.asc(kv.createdAt)])).get();
|
||||
|
||||
final result = <int, VerificationType>{};
|
||||
for (final row in rows) {
|
||||
result.putIfAbsent(row.contactId, () => row.type);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Future<bool> isContactVerified(int contactId) async {
|
||||
final verifierKv = alias(keyVerifications, 'verifierKv');
|
||||
final query = select(keyVerifications).join([
|
||||
leftOuterJoin(
|
||||
verifierKv,
|
||||
verifierKv.contactId.equalsExp(keyVerifications.verifiedBy),
|
||||
),
|
||||
])..where(keyVerifications.contactId.equals(contactId));
|
||||
|
||||
final rows = await query.get();
|
||||
for (final row in rows) {
|
||||
final kv = row.readTable(keyVerifications);
|
||||
final hasVerifierKv = row.readTableOrNull(verifierKv) != null;
|
||||
if (kv.type == VerificationType.contactSharedByVerified) {
|
||||
if (hasVerifierKv) return true;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Stream<List<(KeyVerification, Contact?)>> watchContactVerification(
|
||||
Stream<List<(KeyVerification, Contact?)>> watchContactVerification(
|
||||
int contactId,
|
||||
) {
|
||||
final verifier = alias(contacts, 'verifier');
|
||||
|
|
@ -159,57 +124,7 @@ class KeyVerificationDao extends DatabaseAccessor<TwonlyDB>
|
|||
}).toList();
|
||||
});
|
||||
}
|
||||
|
||||
Future<int> getTransferredTrustVerificationsCount() async {
|
||||
final kv = keyVerifications;
|
||||
final ur = userDiscoveryUserRelations;
|
||||
|
||||
final query = selectOnly(ur, distinct: true)
|
||||
..addColumns([ur.announcedUserId])
|
||||
..join([
|
||||
innerJoin(contacts, contacts.userId.equalsExp(ur.fromContactId)),
|
||||
innerJoin(kv, kv.contactId.equalsExp(ur.fromContactId)),
|
||||
])
|
||||
..where(
|
||||
ur.publicKeyVerifiedTimestamp.isNotNull() &
|
||||
ur.announcedUserId.equalsExp(ur.fromContactId).not(),
|
||||
)
|
||||
..groupBy([ur.announcedUserId]);
|
||||
|
||||
final rows = await query.get();
|
||||
return rows.length;
|
||||
}
|
||||
|
||||
Future<int> getCountOfContactsWithVerificationBadge() async {
|
||||
final kv = keyVerifications;
|
||||
final ur = userDiscoveryUserRelations;
|
||||
|
||||
final query = selectOnly(ur, distinct: true)
|
||||
..addColumns([ur.announcedUserId])
|
||||
..join([
|
||||
innerJoin(contacts, contacts.userId.equalsExp(ur.fromContactId)),
|
||||
innerJoin(kv, kv.contactId.equalsExp(ur.fromContactId)),
|
||||
])
|
||||
..where(
|
||||
ur.publicKeyVerifiedTimestamp.isNotNull() &
|
||||
ur.announcedUserId.equalsExp(ur.fromContactId).not(),
|
||||
)
|
||||
..groupBy([ur.announcedUserId]);
|
||||
|
||||
final rows = await query.get();
|
||||
final transferredIds = rows.map((r) => r.read(ur.announcedUserId)!).toSet();
|
||||
|
||||
final directVerifications = await select(kv).get();
|
||||
final directIds = directVerifications.map((v) => v.contactId).toSet();
|
||||
|
||||
// Reduce transferred contacts where announcedUserId is already in KeyVerifications
|
||||
transferredIds.removeWhere(directIds.contains);
|
||||
|
||||
// Add count of all users who are in the KeyVerification table
|
||||
return transferredIds.length + directIds.length;
|
||||
}
|
||||
|
||||
Stream<VerificationStatus> watchAllGroupMembersVerified(String groupId) {
|
||||
Stream<VerificationStatus> watchAllGroupMembersVerified(String groupId) {
|
||||
final gm = groupMembers;
|
||||
final directKv = alias(keyVerifications, 'directKv');
|
||||
final ur = userDiscoveryUserRelations;
|
||||
|
|
@ -376,24 +291,7 @@ class KeyVerificationDao extends DatabaseAccessor<TwonlyDB>
|
|||
Log.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> deleteKeyVerification(int contactId) async {
|
||||
try {
|
||||
await (delete(
|
||||
keyVerifications,
|
||||
)..where((kv) => kv.contactId.equals(contactId))).go();
|
||||
if (userService.currentUser.isUserDiscoveryEnabled) {
|
||||
await FlutterUserDiscovery.updateVerificationStateForUser(
|
||||
callbackId: isolateCallbackId,
|
||||
contactId: contactId,
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
Log.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> deleteKeyVerificationById(
|
||||
Future<void> deleteKeyVerificationById(
|
||||
int verificationId,
|
||||
int contactId,
|
||||
) async {
|
||||
|
|
|
|||
|
|
@ -18,14 +18,7 @@ class LabelsDao extends DatabaseAccessor<TwonlyDB> with _$LabelsDaoMixin {
|
|||
labels,
|
||||
)..orderBy([(t) => OrderingTerm(expression: t.name)])).watch();
|
||||
}
|
||||
|
||||
Future<List<Label>> getAllLabels() {
|
||||
return (select(
|
||||
labels,
|
||||
)..orderBy([(t) => OrderingTerm(expression: t.name)])).get();
|
||||
}
|
||||
|
||||
Stream<List<Label>> watchContactLabels(int contactId) {
|
||||
Stream<List<Label>> watchContactLabels(int contactId) {
|
||||
final query = select(contactLabels).join([
|
||||
innerJoin(labels, labels.id.equalsExp(contactLabels.labelId)),
|
||||
])..where(contactLabels.contactId.equals(contactId));
|
||||
|
|
@ -50,18 +43,7 @@ class LabelsDao extends DatabaseAccessor<TwonlyDB> with _$LabelsDaoMixin {
|
|||
.toList(),
|
||||
);
|
||||
}
|
||||
|
||||
Future<List<Label>> getContactLabels(int contactId) {
|
||||
final query = select(contactLabels).join([
|
||||
innerJoin(labels, labels.id.equalsExp(contactLabels.labelId)),
|
||||
])..where(contactLabels.contactId.equals(contactId));
|
||||
|
||||
return query.get().then(
|
||||
(rows) => rows.map((row) => row.readTable(labels)).toList(),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> setContactLabels(int contactId, List<int> labelIds) async {
|
||||
Future<void> setContactLabels(int contactId, List<int> labelIds) async {
|
||||
final sanitizedLabelIds = labelIds.take(3).toList();
|
||||
await transaction(() async {
|
||||
await (delete(
|
||||
|
|
|
|||
|
|
@ -88,21 +88,7 @@ class MediaFilesDao extends DatabaseAccessor<TwonlyDB>
|
|||
mediaFiles,
|
||||
)..where((t) => t.mediaId.equals(mediaId))).watchSingleOrNull();
|
||||
}
|
||||
|
||||
Future<void> resetPendingDownloadState() async {
|
||||
await (update(mediaFiles)..where(
|
||||
(c) => c.downloadState.equals(
|
||||
DownloadState.downloading.name,
|
||||
),
|
||||
))
|
||||
.write(
|
||||
const MediaFilesCompanion(
|
||||
downloadState: Value(DownloadState.pending),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<List<MediaFile>> getAllMediaFilesPendingDownload() async {
|
||||
Future<List<MediaFile>> getAllMediaFilesPendingDownload() async {
|
||||
return (select(mediaFiles)..where(
|
||||
(t) =>
|
||||
t.downloadState.equals(DownloadState.pending.name) |
|
||||
|
|
@ -158,15 +144,7 @@ class MediaFilesDao extends DatabaseAccessor<TwonlyDB>
|
|||
]);
|
||||
return query.map((row) => row.readTable(mediaFiles)).watch();
|
||||
}
|
||||
|
||||
Stream<List<MediaFile>> watchNewestMediaFiles() {
|
||||
return (select(mediaFiles)
|
||||
..orderBy([(t) => OrderingTerm.desc(t.createdAt)])
|
||||
..limit(100))
|
||||
.watch();
|
||||
}
|
||||
|
||||
Stream<List<MediaFile>> watchMediaFilesByIds(Set<String> mediaIds) {
|
||||
Stream<List<MediaFile>> watchMediaFilesByIds(Set<String> mediaIds) {
|
||||
if (mediaIds.isEmpty) return Stream.value(const []);
|
||||
return (select(
|
||||
mediaFiles,
|
||||
|
|
|
|||
|
|
@ -285,20 +285,7 @@ class MessagesDao extends DatabaseAccessor<TwonlyDB> with _$MessagesDaoMixin {
|
|||
.map((row) => (row.readTable(groupMembers), row.readTable(contacts)))
|
||||
.watch();
|
||||
}
|
||||
|
||||
Stream<List<MessageAction>> watchMessageActionChanges(String messageId) {
|
||||
return (select(
|
||||
messageActions,
|
||||
)..where((t) => t.messageId.equals(messageId))).watch();
|
||||
}
|
||||
|
||||
Stream<Message?> watchMessageById(String messageId) {
|
||||
return (select(
|
||||
messages,
|
||||
)..where((t) => t.messageId.equals(messageId))).watchSingleOrNull();
|
||||
}
|
||||
|
||||
Future<void> purgeMessageTable() async {
|
||||
Future<void> purgeMessageTable() async {
|
||||
final allGroups = await select(groups).get();
|
||||
|
||||
final groupedByTime = <int, List<String>>{};
|
||||
|
|
@ -635,26 +622,7 @@ class MessagesDao extends DatabaseAccessor<TwonlyDB> with _$MessagesDaoMixin {
|
|||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Future<MessageAction?> getLastMessageAction(String messageId) async {
|
||||
return (((select(messageActions)..where(
|
||||
(t) => t.messageId.equals(messageId),
|
||||
))
|
||||
..orderBy([(t) => OrderingTerm.desc(t.actionAt)]))
|
||||
..limit(1))
|
||||
.getSingleOrNull();
|
||||
}
|
||||
|
||||
Stream<MessageAction?> watchLastMessageAction(String messageId) {
|
||||
return (((select(messageActions)..where(
|
||||
(t) => t.messageId.equals(messageId),
|
||||
))
|
||||
..orderBy([(t) => OrderingTerm.desc(t.actionAt)]))
|
||||
..limit(1))
|
||||
.watchSingleOrNull();
|
||||
}
|
||||
|
||||
Future<void> deleteMessagesById(String messageId) {
|
||||
Future<void> deleteMessagesById(String messageId) {
|
||||
return (delete(messages)..where((t) => t.messageId.equals(messageId))).go();
|
||||
}
|
||||
|
||||
|
|
@ -697,19 +665,7 @@ class MessagesDao extends DatabaseAccessor<TwonlyDB> with _$MessagesDaoMixin {
|
|||
))
|
||||
.watch();
|
||||
}
|
||||
|
||||
Stream<List<MessageAction>> watchMessageActionsForGroup(String groupId) {
|
||||
final query = select(messageActions).join([
|
||||
innerJoin(
|
||||
messages,
|
||||
messages.messageId.equalsExp(messageActions.messageId),
|
||||
useColumns: false,
|
||||
),
|
||||
])..where(messages.groupId.equals(groupId));
|
||||
return query.map((row) => row.readTable(messageActions)).watch();
|
||||
}
|
||||
|
||||
Stream<List<MessageHistory>> watchMessageHistory(String messageId) {
|
||||
Stream<List<MessageHistory>> watchMessageHistory(String messageId) {
|
||||
return (select(messageHistories)
|
||||
..where((t) => t.messageId.equals(messageId))
|
||||
..orderBy([(t) => OrderingTerm.desc(t.createdAt)]))
|
||||
|
|
|
|||
|
|
@ -115,22 +115,7 @@ class ReactionsDao extends DatabaseAccessor<TwonlyDB> with _$ReactionsDaoMixin {
|
|||
..orderBy([(reaction) => OrderingTerm.desc(reaction.createdAt)]))
|
||||
.watch();
|
||||
}
|
||||
|
||||
Stream<List<Reaction>> watchReactionsForGroup(String groupId) {
|
||||
final query =
|
||||
select(reactions).join([
|
||||
innerJoin(
|
||||
messages,
|
||||
messages.messageId.equalsExp(reactions.messageId),
|
||||
useColumns: false,
|
||||
),
|
||||
])
|
||||
..where(messages.groupId.equals(groupId))
|
||||
..orderBy([OrderingTerm.desc(reactions.createdAt)]);
|
||||
return query.map((row) => row.readTable(reactions)).watch();
|
||||
}
|
||||
|
||||
Stream<Reaction?> watchLastReactions(String groupId) {
|
||||
Stream<Reaction?> watchLastReactions(String groupId) {
|
||||
final query =
|
||||
(select(reactions)).join(
|
||||
[
|
||||
|
|
|
|||
|
|
@ -1,11 +1,9 @@
|
|||
import 'package:clock/clock.dart';
|
||||
import 'package:drift/drift.dart';
|
||||
import 'package:hashlib/random.dart';
|
||||
import 'package:twonly/src/database/tables/contacts.table.dart';
|
||||
import 'package:twonly/src/database/tables/messages.table.dart';
|
||||
import 'package:twonly/src/database/tables/receipts.table.dart';
|
||||
import 'package:twonly/src/database/twonly.db.dart';
|
||||
import 'package:twonly/src/services/api/mediafiles/upload.api.dart';
|
||||
import 'package:twonly/src/utils/log.dart';
|
||||
|
||||
part 'receipts.dao.g.dart';
|
||||
|
|
@ -18,36 +16,7 @@ class ReceiptsDao extends DatabaseAccessor<TwonlyDB> with _$ReceiptsDaoMixin {
|
|||
// of this object.
|
||||
// ignore: matching_super_parameters
|
||||
ReceiptsDao(super.db);
|
||||
|
||||
Future<void> confirmReceipt(String receiptId, int fromUserId) async {
|
||||
final receipt =
|
||||
await (select(receipts)..where(
|
||||
(t) =>
|
||||
t.receiptId.equals(receiptId) &
|
||||
t.contactId.equals(fromUserId),
|
||||
))
|
||||
.getSingleOrNull();
|
||||
|
||||
if (receipt == null) return;
|
||||
|
||||
if (receipt.messageId != null) {
|
||||
await into(messageActions).insertOnConflictUpdate(
|
||||
MessageActionsCompanion(
|
||||
messageId: Value(receipt.messageId!),
|
||||
contactId: Value(fromUserId),
|
||||
type: const Value(MessageActionType.ackByUserAt),
|
||||
),
|
||||
);
|
||||
await handleMediaRelatedResponseFromReceiver(receipt.messageId!);
|
||||
}
|
||||
|
||||
await (delete(receipts)..where(
|
||||
(t) => t.receiptId.equals(receiptId) & t.contactId.equals(fromUserId),
|
||||
))
|
||||
.go();
|
||||
}
|
||||
|
||||
Future<void> deleteReceipt(String receiptId) async {
|
||||
Future<void> deleteReceipt(String receiptId) async {
|
||||
await (delete(receipts)..where(
|
||||
(t) => t.receiptId.equals(receiptId),
|
||||
))
|
||||
|
|
@ -89,27 +58,7 @@ class ReceiptsDao extends DatabaseAccessor<TwonlyDB> with _$ReceiptsDaoMixin {
|
|||
.go();
|
||||
}
|
||||
}
|
||||
|
||||
Future<Receipt?> insertReceipt(ReceiptsCompanion entry) async {
|
||||
try {
|
||||
var insertEntry = entry;
|
||||
if (entry.receiptId == const Value.absent()) {
|
||||
insertEntry = entry.copyWith(
|
||||
receiptId: Value(uuid.v4()),
|
||||
);
|
||||
}
|
||||
await into(receipts).insert(insertEntry);
|
||||
final receiptId = insertEntry.receiptId.value;
|
||||
return await (select(
|
||||
receipts,
|
||||
)..where((t) => t.receiptId.equals(receiptId))).getSingle();
|
||||
} catch (e) {
|
||||
// ignore error, receipts is already in the database...
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Future<Receipt?> getReceiptById(String receiptId) async {
|
||||
Future<Receipt?> getReceiptById(String receiptId) async {
|
||||
try {
|
||||
return await (select(receipts)..where(
|
||||
(t) => t.receiptId.equals(receiptId),
|
||||
|
|
@ -120,37 +69,7 @@ class ReceiptsDao extends DatabaseAccessor<TwonlyDB> with _$ReceiptsDaoMixin {
|
|||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Future<List<Receipt>> getReceiptsByContactAndMessageId(
|
||||
int contactId,
|
||||
String messageId,
|
||||
) async {
|
||||
return (select(receipts)..where(
|
||||
(t) => t.contactId.equals(contactId) & t.messageId.equals(messageId),
|
||||
))
|
||||
.get();
|
||||
}
|
||||
|
||||
Future<List<Receipt>> getReceiptsForRetransmission() async {
|
||||
final markedRetriesTime = clock.now().subtract(
|
||||
const Duration(
|
||||
// give the server time to transmit all messages to the client
|
||||
seconds: 20,
|
||||
),
|
||||
);
|
||||
return (select(receipts)..where(
|
||||
(t) =>
|
||||
(t.ackByServerAt.isNull() |
|
||||
t.markForRetry.isSmallerThanValue(markedRetriesTime) |
|
||||
t.markForRetryAfterAccepted.isSmallerThanValue(
|
||||
markedRetriesTime,
|
||||
)) &
|
||||
t.willBeRetriedByMediaUpload.equals(false),
|
||||
))
|
||||
.get();
|
||||
}
|
||||
|
||||
Future<List<Receipt>> getReceiptsForMediaRetransmissions() async {
|
||||
Future<List<Receipt>> getReceiptsForMediaRetransmissions() async {
|
||||
final markedRetriesTime = clock.now().subtract(
|
||||
const Duration(
|
||||
// give the server time to transmit all messages to the client
|
||||
|
|
@ -171,18 +90,7 @@ class ReceiptsDao extends DatabaseAccessor<TwonlyDB> with _$ReceiptsDaoMixin {
|
|||
Stream<List<Receipt>> watchAll() {
|
||||
return select(receipts).watch();
|
||||
}
|
||||
|
||||
Future<int> getReceiptCountForContact(int contactId) {
|
||||
final countExp = countAll();
|
||||
|
||||
final query = selectOnly(receipts)
|
||||
..addColumns([countExp])
|
||||
..where(receipts.contactId.equals(contactId));
|
||||
|
||||
return query.map((row) => row.read(countExp)!).getSingle();
|
||||
}
|
||||
|
||||
Future<void> updateReceipt(
|
||||
Future<void> updateReceipt(
|
||||
String receiptId,
|
||||
ReceiptsCompanion updates,
|
||||
) async {
|
||||
|
|
@ -190,25 +98,7 @@ class ReceiptsDao extends DatabaseAccessor<TwonlyDB> with _$ReceiptsDaoMixin {
|
|||
receipts,
|
||||
)..where((c) => c.receiptId.equals(receiptId))).write(updates);
|
||||
}
|
||||
|
||||
Future<Receipt?> rotateReceiptId(String oldReceiptId) async {
|
||||
final newReceiptId = uuid.v4();
|
||||
await updateReceipt(
|
||||
oldReceiptId,
|
||||
ReceiptsCompanion(
|
||||
receiptId: Value(newReceiptId),
|
||||
),
|
||||
);
|
||||
final updatedReceipt = await getReceiptById(newReceiptId);
|
||||
if (updatedReceipt == null) {
|
||||
Log.warn(
|
||||
'[$oldReceiptId] Tried to change the receipt ID to $newReceiptId, but could not get the updated receipt...',
|
||||
);
|
||||
}
|
||||
return updatedReceipt;
|
||||
}
|
||||
|
||||
Future<void> updateReceiptByContactAndMessageId(
|
||||
Future<void> updateReceiptByContactAndMessageId(
|
||||
int contactId,
|
||||
String messageId,
|
||||
ReceiptsCompanion updates,
|
||||
|
|
@ -220,61 +110,8 @@ class ReceiptsDao extends DatabaseAccessor<TwonlyDB> with _$ReceiptsDaoMixin {
|
|||
))
|
||||
.write(updates);
|
||||
}
|
||||
|
||||
Future<void> updateReceiptWidthUserId(
|
||||
int fromUserId,
|
||||
String receiptId,
|
||||
ReceiptsCompanion updates,
|
||||
) async {
|
||||
await (update(receipts)..where(
|
||||
(c) => c.receiptId.equals(receiptId) & c.contactId.equals(fromUserId),
|
||||
))
|
||||
.write(updates);
|
||||
}
|
||||
|
||||
Future<void> markMessagesForRetry(int contactId) async {
|
||||
await (update(receipts)..where(
|
||||
(c) => c.contactId.equals(contactId) & c.markForRetry.isNull(),
|
||||
))
|
||||
.write(
|
||||
ReceiptsCompanion(
|
||||
markForRetry: Value(clock.now()),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<bool> isDuplicated(String receiptId) async {
|
||||
return await (select(
|
||||
receivedReceipts,
|
||||
)..where((t) => t.receiptId.equals(receiptId))).getSingleOrNull() !=
|
||||
null;
|
||||
}
|
||||
|
||||
/// Claims a new delivery-receipt attempt after [cooldown] has elapsed.
|
||||
/// Claims a new delivery-receipt attempt after [cooldown] has elapsed.
|
||||
///
|
||||
/// Updating the timestamp before sending prevents repeated server batches from
|
||||
/// starting multiple delivery-receipt attempts during the same cooldown.
|
||||
Future<bool> claimDuplicateReceiptResend(
|
||||
String receiptId,
|
||||
Duration cooldown,
|
||||
) async {
|
||||
final now = clock.now();
|
||||
final updated =
|
||||
await (update(receivedReceipts)..where(
|
||||
(t) =>
|
||||
t.receiptId.equals(receiptId) &
|
||||
t.createdAt.isSmallerOrEqualValue(now.subtract(cooldown)),
|
||||
))
|
||||
.write(ReceivedReceiptsCompanion(createdAt: Value(now)));
|
||||
return updated > 0;
|
||||
}
|
||||
|
||||
Future<void> gotReceipt(String receiptId) async {
|
||||
await into(
|
||||
receivedReceipts,
|
||||
).insert(
|
||||
ReceivedReceiptsCompanion(receiptId: Value(receiptId)),
|
||||
mode: InsertMode.insertOrIgnore,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,48 +53,7 @@ class UserDiscoveryDao extends DatabaseAccessor<TwonlyDB>
|
|||
.map((row) => row.readTable(userDiscoveryAnnouncedUsers))
|
||||
.toList();
|
||||
}
|
||||
|
||||
Future<AnnouncedUsersWithRelations>
|
||||
getAllAnnouncedUsersWithRelations() async {
|
||||
final query = select(userDiscoveryAnnouncedUsers).join([
|
||||
innerJoin(
|
||||
userDiscoveryUserRelations,
|
||||
userDiscoveryUserRelations.announcedUserId.equalsExp(
|
||||
userDiscoveryAnnouncedUsers.announcedUserId,
|
||||
),
|
||||
),
|
||||
innerJoin(
|
||||
contacts,
|
||||
contacts.userId.equalsExp(
|
||||
userDiscoveryUserRelations.fromContactId,
|
||||
),
|
||||
),
|
||||
])..where(userDiscoveryAnnouncedUsers.username.isNotNull());
|
||||
|
||||
final rows = await query.get();
|
||||
// ignore: omit_local_variable_types
|
||||
final AnnouncedUsersWithRelations results = {};
|
||||
|
||||
for (final row in rows) {
|
||||
final user = row.readTable(userDiscoveryAnnouncedUsers);
|
||||
final relation = row.readTable(userDiscoveryUserRelations);
|
||||
final contact = row.readTable(contacts);
|
||||
|
||||
final relationData = (
|
||||
contact,
|
||||
relation.publicKeyVerifiedTimestamp,
|
||||
);
|
||||
|
||||
if (!results.containsKey(user)) {
|
||||
results[user] = [];
|
||||
}
|
||||
results[user]!.add(relationData);
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
Stream<AnnouncedUsersWithRelations> watchAllAnnouncedUsersWithRelations() {
|
||||
Stream<AnnouncedUsersWithRelations> watchAllAnnouncedUsersWithRelations() {
|
||||
final query = select(userDiscoveryAnnouncedUsers).join([
|
||||
innerJoin(
|
||||
userDiscoveryUserRelations,
|
||||
|
|
|
|||
Loading…
Reference in a new issue