import 'dart:collection'; import '../../backend/modules/messages.dart'; class CachedChatMessages { final List messages; final bool reachedStart; const CachedChatMessages(this.messages, this.reachedStart); } class MessageSessionCache { static const int _capacity = 24; static final LinkedHashMap _store = LinkedHashMap(); 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 messages, { required bool reachedStart, }) { if (messages.isEmpty) return; final key = _key(accountId, chatId); _store.remove(key); _store[key] = CachedChatMessages( List.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.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 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(); }