Files
IKAR/lib/core/cache/message_session_cache.dart
T

80 lines
2.3 KiB
Dart

import 'dart:collection';
import '../../backend/modules/messages.dart';
class CachedChatMessages {
final List<CachedMessage> messages;
final bool reachedStart;
const CachedChatMessages(this.messages, this.reachedStart);
}
class MessageSessionCache {
static const int _capacity = 24;
static final LinkedHashMap<String, CachedChatMessages> _store =
LinkedHashMap<String, CachedChatMessages>();
static String _key(int accountId, int chatId) => '$accountId:$chatId';
static CachedChatMessages? get(int accountId, int chatId) {
final key = _key(accountId, chatId);
final entry = _store.remove(key);
if (entry == null) return null;
_store[key] = entry;
return entry;
}
static void save(
int accountId,
int chatId,
List<CachedMessage> messages, {
required bool reachedStart,
}) {
if (messages.isEmpty) return;
final key = _key(accountId, chatId);
_store.remove(key);
_store[key] = CachedChatMessages(
List<CachedMessage>.of(messages),
reachedStart,
);
while (_store.length > _capacity) {
_store.remove(_store.keys.first);
}
}
static void replace(
int accountId,
int chatId,
String messageId,
CachedMessage Function(CachedMessage current) change,
) {
final cached = get(accountId, chatId);
if (cached == null) return;
final list = List<CachedMessage>.of(cached.messages);
final idx = list.indexWhere((m) => m.id == messageId);
if (idx == -1) return;
list[idx] = change(list[idx]);
save(accountId, chatId, list, reachedStart: cached.reachedStart);
}
static void append(int accountId, int chatId, List<CachedMessage> added) {
final cached = _store[_key(accountId, chatId)];
if (cached == null) return;
final known = {for (final message in cached.messages) message.id};
final fresh = [
for (final message in added)
if (!known.contains(message.id)) message,
];
if (fresh.isEmpty) return;
final merged = [...cached.messages, ...fresh]
..sort((a, b) => a.time.compareTo(b.time));
save(accountId, chatId, merged, reachedStart: cached.reachedStart);
}
static void remove(int accountId, int chatId) =>
_store.remove(_key(accountId, chatId));
static void clearAll() => _store.clear();
}