Cache for unread total

This commit is contained in:
Serge Tarkovski
2026-02-09 17:18:21 +02:00
parent 2bce14224d
commit c4f5c7b171
+26 -11
View File
@@ -150,6 +150,8 @@ class MeshCoreConnector extends ChangeNotifier {
final Set<String> _knownContactKeys = {}; final Set<String> _knownContactKeys = {};
final Map<String, int> _contactUnreadCount = {}; final Map<String, int> _contactUnreadCount = {};
bool _unreadStateLoaded = false; bool _unreadStateLoaded = false;
int _cachedContactsUnreadTotal = 0;
int _cachedChannelsUnreadTotal = 0;
final Map<String, _RepeaterAckContext> _pendingRepeaterAcks = {}; final Map<String, _RepeaterAckContext> _pendingRepeaterAcks = {};
String? _activeContactKey; String? _activeContactKey;
int? _activeChannelIndex; int? _activeChannelIndex;
@@ -342,22 +344,28 @@ class MeshCoreConnector extends ChangeNotifier {
int getTotalContactsUnreadCount() { int getTotalContactsUnreadCount() {
if (!_unreadStateLoaded) return 0; if (!_unreadStateLoaded) return 0;
var total = 0; return _cachedContactsUnreadTotal;
for (final contact in _contacts) {
total += getUnreadCountForContact(contact);
}
return total;
} }
int getTotalChannelsUnreadCount() { int getTotalChannelsUnreadCount() {
if (!_unreadStateLoaded) return 0; if (!_unreadStateLoaded) return 0;
var total = 0; return _cachedChannelsUnreadTotal;
// Check all channels (from _channels or _cachedChannels) }
/// Recalculates both cached unread totals from scratch.
/// Called when unread state is first loaded.
void _recalculateCachedUnreadTotals() {
_recalculateCachedContactsUnreadTotal();
_recalculateCachedChannelsUnreadTotal();
}
void _recalculateCachedContactsUnreadTotal() {
_cachedContactsUnreadTotal = _contactUnreadCount.values.fold(0, (a, b) => a + b);
}
void _recalculateCachedChannelsUnreadTotal() {
final allChannels = _channels.isNotEmpty ? _channels : _cachedChannels; final allChannels = _channels.isNotEmpty ? _channels : _cachedChannels;
for (final channel in allChannels) { _cachedChannelsUnreadTotal = allChannels.fold(0, (total, ch) => total + ch.unreadCount);
total += channel.unreadCount;
}
return total;
} }
bool isChannelSmazEnabled(int channelIndex) { bool isChannelSmazEnabled(int channelIndex) {
@@ -377,11 +385,13 @@ class MeshCoreConnector extends ChangeNotifier {
..clear() ..clear()
..addAll(await _unreadStore.loadContactUnreadCount()); ..addAll(await _unreadStore.loadContactUnreadCount());
_unreadStateLoaded = true; _unreadStateLoaded = true;
_recalculateCachedUnreadTotals();
notifyListeners(); notifyListeners();
} }
Future<void> loadCachedChannels() async { Future<void> loadCachedChannels() async {
_cachedChannels = await _channelStore.loadChannels(); _cachedChannels = await _channelStore.loadChannels();
_recalculateCachedChannelsUnreadTotal();
} }
void setActiveContact(String? contactKeyHex) { void setActiveContact(String? contactKeyHex) {
@@ -408,6 +418,7 @@ class MeshCoreConnector extends ChangeNotifier {
final previousCount = _contactUnreadCount[contactKeyHex] ?? 0; final previousCount = _contactUnreadCount[contactKeyHex] ?? 0;
if (previousCount > 0) { if (previousCount > 0) {
_contactUnreadCount[contactKeyHex] = 0; _contactUnreadCount[contactKeyHex] = 0;
_cachedContactsUnreadTotal -= previousCount;
_appDebugLogService?.info( _appDebugLogService?.info(
'Contact $contactKeyHex marked as read (was $previousCount unread)', 'Contact $contactKeyHex marked as read (was $previousCount unread)',
tag: 'Unread', tag: 'Unread',
@@ -424,6 +435,7 @@ class MeshCoreConnector extends ChangeNotifier {
if (channel != null && channel.unreadCount > 0) { if (channel != null && channel.unreadCount > 0) {
final previousCount = channel.unreadCount; final previousCount = channel.unreadCount;
channel.unreadCount = 0; channel.unreadCount = 0;
_cachedChannelsUnreadTotal -= previousCount;
_appDebugLogService?.info( _appDebugLogService?.info(
'Channel ${channel.name.isNotEmpty ? channel.name : channelIndex} marked as read (was $previousCount unread)', 'Channel ${channel.name.isNotEmpty ? channel.name : channelIndex} marked as read (was $previousCount unread)',
tag: 'Unread', tag: 'Unread',
@@ -1656,6 +1668,7 @@ class MeshCoreConnector extends ChangeNotifier {
if (completed) { if (completed) {
_hasLoadedChannels = true; _hasLoadedChannels = true;
_previousChannelsCache.clear(); _previousChannelsCache.clear();
_recalculateCachedChannelsUnreadTotal();
} }
// Keep cache on failure/disconnection for future attempts // Keep cache on failure/disconnection for future attempts
} }
@@ -2703,6 +2716,7 @@ class MeshCoreConnector extends ChangeNotifier {
final channel = _findChannelByIndex(channelIndex); final channel = _findChannelByIndex(channelIndex);
if (channel != null) { if (channel != null) {
channel.unreadCount++; channel.unreadCount++;
_cachedChannelsUnreadTotal++;
_appDebugLogService?.info( _appDebugLogService?.info(
'Channel ${channel.name.isNotEmpty ? channel.name : channelIndex} unread count incremented to ${channel.unreadCount}', 'Channel ${channel.name.isNotEmpty ? channel.name : channelIndex} unread count incremented to ${channel.unreadCount}',
tag: 'Unread', tag: 'Unread',
@@ -2747,6 +2761,7 @@ class MeshCoreConnector extends ChangeNotifier {
final currentCount = _contactUnreadCount[contactKey] ?? 0; final currentCount = _contactUnreadCount[contactKey] ?? 0;
_contactUnreadCount[contactKey] = currentCount + 1; _contactUnreadCount[contactKey] = currentCount + 1;
_cachedContactsUnreadTotal++;
_appDebugLogService?.info( _appDebugLogService?.info(
'Contact $contactKey unread count incremented to ${currentCount + 1}', 'Contact $contactKey unread count incremented to ${currentCount + 1}',
tag: 'Unread', tag: 'Unread',