mirror of
https://github.com/twonlyapp/twonly-app.git
synced 2026-04-18 17:32:54 +00:00
181 lines
6.1 KiB
Dart
181 lines
6.1 KiB
Dart
import 'package:clock/clock.dart';
|
|
import 'package:collection/collection.dart';
|
|
import 'package:drift/drift.dart';
|
|
import 'package:fixnum/fixnum.dart';
|
|
import 'package:twonly/globals.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/messages.dart';
|
|
import 'package:twonly/src/utils/misc.dart';
|
|
import 'package:twonly/src/utils/storage.dart';
|
|
|
|
Future<void> syncFlameCounters({String? forceForGroup}) async {
|
|
final groups = await twonlyDB.groupsDao.getAllGroups();
|
|
if (groups.isEmpty) return;
|
|
final maxMessageCounter = groups.map((x) => x.totalMediaCounter).max;
|
|
final bestFriend = groups.firstWhere(
|
|
(x) => x.totalMediaCounter == maxMessageCounter,
|
|
);
|
|
|
|
if (gUser.myBestFriendGroupId != bestFriend.groupId) {
|
|
await updateUserdata((user) {
|
|
user.myBestFriendGroupId = bestFriend.groupId;
|
|
return user;
|
|
});
|
|
}
|
|
|
|
for (final group in groups) {
|
|
if (group.lastFlameCounterChange == null) continue;
|
|
if (!isToday(group.lastFlameCounterChange!)) continue;
|
|
if (forceForGroup == null || group.groupId != forceForGroup) {
|
|
if (group.lastFlameSync != null) {
|
|
if (isToday(group.lastFlameSync!)) continue;
|
|
}
|
|
}
|
|
|
|
final flameCounter = getFlameCounterFromGroup(group);
|
|
|
|
// only sync when flame counter is higher three or when they are bestFriends
|
|
if (flameCounter <= 2 && bestFriend.groupId != group.groupId) continue;
|
|
|
|
await sendCipherTextToGroup(
|
|
group.groupId,
|
|
EncryptedContent(
|
|
flameSync: EncryptedContent_FlameSync(
|
|
flameCounter: Int64(flameCounter),
|
|
lastFlameCounterChange: Int64(
|
|
group.lastFlameCounterChange!.millisecondsSinceEpoch,
|
|
),
|
|
bestFriend: group.groupId == bestFriend.groupId,
|
|
forceUpdate: group.groupId == forceForGroup,
|
|
),
|
|
),
|
|
);
|
|
|
|
await twonlyDB.groupsDao.updateGroup(
|
|
group.groupId,
|
|
GroupsCompanion(
|
|
lastFlameSync: Value(clock.now()),
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
int getFlameCounterFromGroup(Group? group) {
|
|
if (group == null) return 0;
|
|
if (group.lastMessageSend == null ||
|
|
group.lastMessageReceived == null ||
|
|
group.lastFlameCounterChange == null) {
|
|
return 0;
|
|
}
|
|
final now = clock.now();
|
|
final startOfToday = DateTime(now.year, now.month, now.day);
|
|
final twoDaysAgo = startOfToday.subtract(const Duration(days: 2));
|
|
final oneDayAgo = startOfToday.subtract(const Duration(days: 1));
|
|
if (group.lastMessageSend!.isAfter(twoDaysAgo) &&
|
|
group.lastMessageReceived!.isAfter(twoDaysAgo) ||
|
|
group.lastFlameCounterChange!.isAfter(oneDayAgo)) {
|
|
return group.flameCounter;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
Future<void> incFlameCounter(
|
|
String groupId,
|
|
bool received,
|
|
DateTime timestamp,
|
|
) async {
|
|
final group = await twonlyDB.groupsDao.getGroup(groupId);
|
|
if (group == null) return;
|
|
|
|
final totalMediaCounter = group.totalMediaCounter + 1;
|
|
var flameCounter = group.flameCounter;
|
|
var maxFlameCounter = group.maxFlameCounter;
|
|
var maxFlameCounterFrom = group.maxFlameCounterFrom;
|
|
|
|
if (group.lastMessageReceived != null && group.lastMessageSend != null) {
|
|
final now = clock.now();
|
|
final startOfToday = DateTime(now.year, now.month, now.day);
|
|
final twoDaysAgo = startOfToday.subtract(const Duration(days: 2));
|
|
if (group.lastMessageSend!.isBefore(twoDaysAgo) ||
|
|
group.lastMessageReceived!.isBefore(twoDaysAgo)) {
|
|
flameCounter = 0;
|
|
}
|
|
}
|
|
|
|
var lastMessageSend = const Value<DateTime?>.absent();
|
|
var lastMessageReceived = const Value<DateTime?>.absent();
|
|
var lastFlameCounterChange = const Value<DateTime?>.absent();
|
|
|
|
final now = clock.now();
|
|
final startOfToday = DateTime(now.year, now.month, now.day);
|
|
|
|
if (group.lastFlameCounterChange == null ||
|
|
group.lastFlameCounterChange!.isBefore(startOfToday)) {
|
|
// last flame update was yesterday. check if it can be updated.
|
|
var updateFlame = false;
|
|
if (received) {
|
|
if (group.lastMessageSend != null &&
|
|
group.lastMessageSend!.isAfter(startOfToday)) {
|
|
// today a message was already send -> update flame
|
|
updateFlame = true;
|
|
}
|
|
} else if (group.lastMessageReceived != null &&
|
|
group.lastMessageReceived!.isAfter(startOfToday)) {
|
|
// today a message was already received -> update flame
|
|
updateFlame = true;
|
|
}
|
|
if (updateFlame) {
|
|
flameCounter += 1;
|
|
if (group.lastFlameCounterChange == null ||
|
|
group.lastFlameCounterChange!.isBefore(timestamp)) {
|
|
// only update if the timestamp is newer
|
|
lastFlameCounterChange = Value(timestamp);
|
|
}
|
|
// Overwrite max flame counter either the current is bigger or the the max flame counter is older then 4 days
|
|
if (flameCounter >= maxFlameCounter ||
|
|
maxFlameCounterFrom == null ||
|
|
maxFlameCounterFrom.isBefore(
|
|
clock.now().subtract(const Duration(days: 5)),
|
|
)) {
|
|
maxFlameCounter = flameCounter;
|
|
maxFlameCounterFrom = clock.now();
|
|
}
|
|
}
|
|
}
|
|
|
|
if (received) {
|
|
if (group.lastMessageReceived == null ||
|
|
group.lastMessageReceived!.isBefore(timestamp)) {
|
|
lastMessageReceived = Value(timestamp);
|
|
}
|
|
} else {
|
|
if (group.lastMessageSend == null ||
|
|
group.lastMessageSend!.isBefore(timestamp)) {
|
|
lastMessageSend = Value(timestamp);
|
|
}
|
|
}
|
|
|
|
await twonlyDB.groupsDao.updateGroup(
|
|
groupId,
|
|
GroupsCompanion(
|
|
totalMediaCounter: Value(totalMediaCounter),
|
|
lastFlameCounterChange: lastFlameCounterChange,
|
|
lastMessageReceived: lastMessageReceived,
|
|
lastMessageSend: lastMessageSend,
|
|
flameCounter: Value(flameCounter),
|
|
maxFlameCounter: Value(maxFlameCounter),
|
|
maxFlameCounterFrom: Value(maxFlameCounterFrom),
|
|
),
|
|
);
|
|
}
|
|
|
|
bool isItPossibleToRestoreFlames(Group group) {
|
|
final flameCounter = getFlameCounterFromGroup(group);
|
|
return group.maxFlameCounter > 2 &&
|
|
flameCounter < group.maxFlameCounter &&
|
|
group.maxFlameCounterFrom!.isAfter(
|
|
clock.now().subtract(const Duration(days: 7)),
|
|
);
|
|
}
|