mirror of
https://github.com/twonlyapp/twonly-app.git
synced 2026-06-03 02:32:12 +00:00
245 lines
7.6 KiB
Dart
245 lines
7.6 KiB
Dart
import 'package:drift/drift.dart';
|
|
import 'package:twonly/src/database/tables/contacts.table.dart';
|
|
import 'package:twonly/src/database/tables/user_discovery.table.dart';
|
|
import 'package:twonly/src/database/twonly.db.dart';
|
|
import 'package:twonly/src/utils/log.dart';
|
|
|
|
part 'user_discovery.dao.g.dart';
|
|
|
|
typedef AnnouncedUsersWithRelations =
|
|
Map<UserDiscoveryAnnouncedUser, List<(Contact, DateTime?)>>;
|
|
|
|
@DriftAccessor(
|
|
tables: [
|
|
UserDiscoveryAnnouncedUsers,
|
|
UserDiscoveryUserRelations,
|
|
UserDiscoveryOwnPromotions,
|
|
UserDiscoveryOtherPromotions,
|
|
UserDiscoveryShares,
|
|
Contacts,
|
|
],
|
|
)
|
|
class UserDiscoveryDao extends DatabaseAccessor<TwonlyDB>
|
|
with _$UserDiscoveryDaoMixin {
|
|
// this constructor is required so that the main database can create an instance
|
|
// of this object.
|
|
// ignore: matching_super_parameters
|
|
UserDiscoveryDao(super.db);
|
|
|
|
/// 1. Get count for contacts which are in announced but not in the contacts table
|
|
|
|
/// Returns all users which are not yet in the contacts table but have no data loaded (e.g. Avatar, username and display name)
|
|
Future<List<UserDiscoveryAnnouncedUser>>
|
|
getNewAnnouncementsWithoutData() async {
|
|
final query =
|
|
select(userDiscoveryAnnouncedUsers).join([
|
|
leftOuterJoin(
|
|
contacts,
|
|
contacts.userId.equalsExp(
|
|
userDiscoveryAnnouncedUsers.announcedUserId,
|
|
),
|
|
),
|
|
])
|
|
// Apply filters:
|
|
// 1. The user must NOT exist in the contacts table
|
|
// 2. The username must be null
|
|
..where(
|
|
contacts.userId.isNull() &
|
|
userDiscoveryAnnouncedUsers.username.isNull(),
|
|
);
|
|
|
|
return (await query.get())
|
|
.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(
|
|
userDiscoveryUserRelations,
|
|
userDiscoveryUserRelations.announcedUserId.equalsExp(
|
|
userDiscoveryAnnouncedUsers.announcedUserId,
|
|
),
|
|
),
|
|
innerJoin(
|
|
contacts,
|
|
contacts.userId.equalsExp(
|
|
userDiscoveryUserRelations.fromContactId,
|
|
),
|
|
),
|
|
])..where(userDiscoveryAnnouncedUsers.username.isNotNull());
|
|
|
|
return query.watch().map((rows) {
|
|
// 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);
|
|
}
|
|
|
|
Log.info('results = ${results.length}');
|
|
|
|
return results;
|
|
});
|
|
}
|
|
|
|
Stream<AnnouncedUsersWithRelations> watchNewAnnouncedUsersWithRelations() {
|
|
final announcedContact = alias(contacts, 'announcedContact');
|
|
final query =
|
|
select(userDiscoveryAnnouncedUsers).join([
|
|
innerJoin(
|
|
userDiscoveryUserRelations,
|
|
userDiscoveryUserRelations.announcedUserId.equalsExp(
|
|
userDiscoveryAnnouncedUsers.announcedUserId,
|
|
),
|
|
),
|
|
innerJoin(
|
|
contacts,
|
|
contacts.userId.equalsExp(
|
|
userDiscoveryUserRelations.fromContactId,
|
|
),
|
|
),
|
|
leftOuterJoin(
|
|
announcedContact,
|
|
announcedContact.userId.equalsExp(
|
|
userDiscoveryAnnouncedUsers.announcedUserId,
|
|
),
|
|
),
|
|
])..where(
|
|
userDiscoveryAnnouncedUsers.username.isNotNull() &
|
|
userDiscoveryAnnouncedUsers.isHidden.equals(false) &
|
|
(announcedContact.userId.isNull() |
|
|
announcedContact.deletedByUser.equals(true)),
|
|
);
|
|
|
|
return query.watch().map((rows) {
|
|
// 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<int> watchNewAnnouncementsWithDataCount() {
|
|
final countExp = userDiscoveryAnnouncedUsers.announcedUserId.count();
|
|
|
|
final query = selectOnly(userDiscoveryAnnouncedUsers)
|
|
..addColumns([countExp])
|
|
..where(
|
|
// Filters: Has a username AND has not been shown to the user yet
|
|
userDiscoveryAnnouncedUsers.username.isNotNull() &
|
|
userDiscoveryAnnouncedUsers.wasShownToTheUser.equals(false) &
|
|
userDiscoveryAnnouncedUsers.isHidden.equals(false),
|
|
);
|
|
|
|
return query.watchSingle().map((row) => row.read(countExp) ?? 0);
|
|
}
|
|
|
|
Future<void> markAllValidAnnouncedUsersAsShown() async {
|
|
await (update(userDiscoveryAnnouncedUsers)..where(
|
|
(t) =>
|
|
t.username.isNotNull() &
|
|
t.wasShownToTheUser.equals(false) &
|
|
t.isHidden.equals(false),
|
|
))
|
|
.write(
|
|
const UserDiscoveryAnnouncedUsersCompanion(
|
|
wasShownToTheUser: Value(true),
|
|
),
|
|
);
|
|
}
|
|
|
|
Future<void> updateAnnouncedUser(
|
|
int announcedUserId,
|
|
UserDiscoveryAnnouncedUsersCompanion updatedValues,
|
|
) async {
|
|
await (update(
|
|
userDiscoveryAnnouncedUsers,
|
|
)..where((c) => c.announcedUserId.equals(announcedUserId))).write(
|
|
updatedValues,
|
|
);
|
|
}
|
|
|
|
Stream<List<UserDiscoveryAnnouncedUser>> watchAllAnnouncedUsers() =>
|
|
select(userDiscoveryAnnouncedUsers).watch();
|
|
|
|
Stream<List<UserDiscoveryUserRelation>> watchAllUserRelations() =>
|
|
select(userDiscoveryUserRelations).watch();
|
|
|
|
Stream<List<UserDiscoveryOwnPromotion>> watchAllOwnPromotions() =>
|
|
select(userDiscoveryOwnPromotions).watch();
|
|
|
|
Stream<List<UserDiscoveryOtherPromotion>> watchAllOtherPromotions() =>
|
|
select(userDiscoveryOtherPromotions).watch();
|
|
|
|
Stream<List<UserDiscoveryShare>> watchAllShares() =>
|
|
select(userDiscoveryShares).watch();
|
|
}
|