Files
moxxy/lib/service/conversation.dart

142 lines
4.5 KiB
Dart

import 'package:get_it/get_it.dart';
import 'package:moxlib/moxlib.dart';
import 'package:moxxmpp/moxxmpp.dart';
import 'package:moxxyv2/service/database/database.dart';
import 'package:moxxyv2/service/not_specified.dart';
import 'package:moxxyv2/service/preferences.dart';
import 'package:moxxyv2/shared/cache.dart';
import 'package:moxxyv2/shared/models/conversation.dart';
import 'package:moxxyv2/shared/models/message.dart';
class ConversationService {
ConversationService()
: _conversationCache = LRUCache(100),
_loadedConversations = false;
final LRUCache<int, Conversation> _conversationCache;
bool _loadedConversations;
/// Wrapper around DatabaseService's loadConversations that adds the loaded
/// to the cache.
Future<void> _loadConversations() async {
final conversations = await GetIt.I.get<DatabaseService>().loadConversations();
for (final c in conversations) {
_conversationCache.cache(c.id, c);
}
}
/// Returns the conversation with jid [jid] or null if not found.
Future<Conversation?> getConversationByJid(String jid) async {
if (!_loadedConversations) {
await _loadConversations();
_loadedConversations = true;
}
return firstWhereOrNull(
// TODO(Unknown): Maybe have it accept an iterable
_conversationCache.getValues(),
(Conversation c) => c.jid == jid,
);
}
/// Returns the conversation by its database id or null if it does not exist.
Future<Conversation?> _getConversationById(int id) async {
if (!_loadedConversations) {
await _loadConversations();
_loadedConversations = true;
}
return _conversationCache.getValue(id);
}
/// For modifying the cache without writing it to disk. Useful, for example, when
/// changing the chat state.
void setConversation(Conversation conversation) {
_conversationCache.cache(conversation.id, conversation);
}
/// Wrapper around [DatabaseService]'s [updateConversation] that modifies the cache.
Future<Conversation> updateConversation(int id, {
int? lastChangeTimestamp,
Message? lastMessage,
bool? open,
int? unreadCounter,
String? avatarUrl,
ChatState? chatState,
bool? muted,
bool? encrypted,
Object? contactId = notSpecified,
Object? contactAvatarPath = notSpecified,
Object? contactDisplayName = notSpecified,
}) async {
final conversation = (await _getConversationById(id))!;
var newConversation = await GetIt.I.get<DatabaseService>().updateConversation(
id,
lastMessage: lastMessage,
lastChangeTimestamp: lastChangeTimestamp,
open: open,
unreadCounter: unreadCounter,
avatarUrl: avatarUrl,
chatState: conversation.chatState,
muted: muted,
encrypted: encrypted,
contactId: contactId,
contactAvatarPath: contactAvatarPath,
contactDisplayName: contactDisplayName,
);
// Copy over the old lastMessage if a new one was not set
if (conversation.lastMessage != null && lastMessage == null) {
newConversation = newConversation.copyWith(lastMessage: conversation.lastMessage);
}
_conversationCache.cache(id, newConversation);
return newConversation;
}
/// Wrapper around [DatabaseService]'s [addConversationFromData] that updates the cache.
Future<Conversation> addConversationFromData(
String title,
Message? lastMessage,
String avatarUrl,
String jid,
int unreadCounter,
int lastChangeTimestamp,
bool open,
bool muted,
bool encrypted,
String? contactId,
String? contactAvatarPath,
String? contactDisplayName,
) async {
final newConversation = await GetIt.I.get<DatabaseService>().addConversationFromData(
title,
lastMessage,
avatarUrl,
jid,
unreadCounter,
lastChangeTimestamp,
open,
muted,
encrypted,
contactId,
contactAvatarPath,
contactDisplayName,
);
_conversationCache.cache(newConversation.id, newConversation);
return newConversation;
}
/// Returns true if the stanzas to the conversation with [jid] should be encrypted.
/// If not, returns false.
///
/// If the conversation does not exist, then the value of the preference for
/// enableOmemoByDefault is used.
Future<bool> shouldEncryptForConversation(JID jid) async {
final prefs = await GetIt.I.get<PreferencesService>().getPreferences();
final conversation = await getConversationByJid(jid.toString());
return conversation?.encrypted ?? prefs.enableOmemoByDefault;
}
}