removed unused functions
Some checks are pending
Flutter analyze & test / flutter_analyze_and_test (push) Waiting to run

This commit is contained in:
otsmr 2026-08-28 14:52:28 +02:00
parent bd65268dd2
commit b09d79f5d6
9 changed files with 27 additions and 578 deletions

View file

@ -12,16 +12,6 @@ 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 {
try {
return await into(contacts).insertOnConflictUpdate(contact);
@ -174,26 +164,6 @@ 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() {
return select(contacts).watch();
}

View file

@ -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,16 +21,6 @@ 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 {
await (delete(groups)..where((t) => t.groupId.equals(groupId))).go();
}
@ -61,21 +49,9 @@ 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 {
return _insertGroup(group);
}
Future<void> insertOrUpdateGroupMember(GroupMembersCompanion members) async {
await into(groupMembers).insertOnConflictUpdate(members);
}
Future<void> insertGroupAction(GroupHistoriesCompanion action) async {
var insertAction = action;
if (!action.groupHistoryId.present) {
@ -101,25 +77,6 @@ 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(
int contactId,
GroupsCompanion group,
@ -231,17 +188,6 @@ 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() {
return (select(groups)
..where((t) => t.deletedContent.equals(false))
@ -280,32 +226,6 @@ 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 {
final query =
((select(groups)..where((t) => t.isDirectChat.equals(true))).join([
@ -317,28 +237,6 @@ 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() {
final query = selectOnly(groups)
..addColumns([groups.totalMediaCounter.sum()]);
@ -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();
}
}

View file

@ -43,41 +43,6 @@ 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(
int contactId,
) {
@ -159,56 +124,6 @@ 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) {
final gm = groupMembers;
final directKv = alias(keyVerifications, 'directKv');
@ -376,23 +291,6 @@ 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(
int verificationId,
int contactId,

View file

@ -18,13 +18,6 @@ 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) {
final query = select(contactLabels).join([
innerJoin(labels, labels.id.equalsExp(contactLabels.labelId)),
@ -50,17 +43,6 @@ 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 {
final sanitizedLabelIds = labelIds.take(3).toList();
await transaction(() async {

View file

@ -88,20 +88,6 @@ 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 {
return (select(mediaFiles)..where(
(t) =>
@ -158,14 +144,6 @@ 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) {
if (mediaIds.isEmpty) return Stream.value(const []);
return (select(

View file

@ -285,19 +285,6 @@ 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 {
final allGroups = await select(groups).get();
@ -635,25 +622,6 @@ 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) {
return (delete(messages)..where((t) => t.messageId.equals(messageId))).go();
}
@ -697,18 +665,6 @@ 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) {
return (select(messageHistories)
..where((t) => t.messageId.equals(messageId))

View file

@ -115,21 +115,6 @@ 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) {
final query =
(select(reactions)).join(

View file

@ -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,35 +16,6 @@ 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 {
await (delete(receipts)..where(
(t) => t.receiptId.equals(receiptId),
@ -89,26 +58,6 @@ 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 {
try {
return await (select(receipts)..where(
@ -120,36 +69,6 @@ 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 {
final markedRetriesTime = clock.now().subtract(
const Duration(
@ -171,17 +90,6 @@ 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(
String receiptId,
ReceiptsCompanion updates,
@ -190,24 +98,6 @@ 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(
int contactId,
String messageId,
@ -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.
///
/// 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,
);
}
}

View file

@ -53,47 +53,6 @@ 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() {
final query = select(userDiscoveryAnnouncedUsers).join([
innerJoin(