service: Migrate the basics to sqflite

This commit is contained in:
PapaTutuWawa 2022-09-07 22:10:55 +02:00
parent 6ab4b4062c
commit f8950d9fb3
11 changed files with 341 additions and 371 deletions

View File

@ -1,9 +1,9 @@
import 'package:get_it/get_it.dart';
import 'package:moxxyv2/service/database/database.dart';
import 'package:moxxyv2/service/db/media.dart';
import 'package:moxxyv2/shared/cache.dart';
import 'package:moxxyv2/shared/helpers.dart';
import 'package:moxxyv2/shared/models/conversation.dart';
import 'package:moxxyv2/shared/models/media.dart';
import 'package:moxxyv2/xmpp/xeps/xep_0085.dart';
class ConversationService {
@ -61,7 +61,7 @@ class ConversationService {
bool? open,
int? unreadCounter,
String? avatarUrl,
List<DBSharedMedium>? sharedMedia,
List<SharedMedium>? sharedMedia,
ChatState? chatState,
bool? muted,
}
@ -91,7 +91,7 @@ class ConversationService {
String jid,
int unreadCounter,
int lastChangeTimestamp,
List<DBSharedMedium> sharedMedia,
List<SharedMedium> sharedMedia,
bool open,
bool muted,
) async {

View File

@ -0,0 +1,4 @@
const conversationsTable = 'Conversations';
const messsagesTable = 'Messages';
const rosterTable = 'RosterItems';
const mediaTable = 'SharedMedia';

View File

@ -1,80 +0,0 @@
import 'package:moxxyv2/service/db/conversation.dart';
import 'package:moxxyv2/service/db/media.dart';
import 'package:moxxyv2/service/db/message.dart';
import 'package:moxxyv2/service/db/roster.dart';
import 'package:moxxyv2/shared/models/conversation.dart';
import 'package:moxxyv2/shared/models/media.dart';
import 'package:moxxyv2/shared/models/message.dart';
import 'package:moxxyv2/shared/models/roster.dart';
import 'package:moxxyv2/xmpp/xeps/xep_0085.dart';
SharedMedium sharedMediumDbToModel(DBSharedMedium s) {
return SharedMedium(
s.id!,
s.path,
s.timestamp,
mime: s.mime,
);
}
Conversation conversationDbToModel(DBConversation c, bool inRoster, String subscription, ChatState chatState) {
final media = c.sharedMedia
.map(sharedMediumDbToModel)
.toList();
// ignore: cascade_invocations
media.sort((a, b) => a.timestamp.compareTo(b.timestamp));
return Conversation(
c.title,
c.lastMessageBody,
c.avatarUrl,
c.jid,
c.unreadCounter,
c.lastChangeTimestamp,
media,
c.id!,
c.open,
inRoster,
subscription,
c.muted,
chatState,
);
}
RosterItem rosterDbToModel(DBRosterItem i) {
return RosterItem(
i.id!,
i.avatarUrl,
i.avatarHash,
i.jid,
i.title,
i.subscription,
i.ask,
i.groups,
);
}
Message messageDbToModel(DBMessage m) {
return Message(
m.sender,
m.body,
m.timestamp,
m.sid,
m.id!,
m.conversationJid,
m.isMedia,
m.isFileUploadNotification,
originId: m.originId,
received: m.received,
displayed: m.displayed,
acked: m.acked,
mediaUrl: m.mediaUrl,
mediaType: m.mediaType,
thumbnailData: m.thumbnailData,
thumbnailDimensions: m.thumbnailDimensions,
srcUrl: m.srcUrl,
quotes: m.quotes.value != null ? messageDbToModel(m.quotes.value!) : null,
errorType: m.errorType,
filename: m.filename,
);
}

View File

@ -14,23 +14,23 @@ Future<void> createDatabase(Database db, int version) async {
body TEXT,
timestamp INTEGER NOT NULL,
sid TEXT NOT NULL,
conversation_jid TEXT NOT NULL,
is_media INTEGER NOT NULL,
is_file_upload_notification INTEGER NOT NULL,
error_type INTEGER,
media_url TEXT,
media_type TEXT,
thumbnail_data TEXT,
thumbnail_dimensions TEXT,
conversationJid TEXT NOT NULL,
isMedia INTEGER NOT NULL,
isFileUploadNotification INTEGER NOT NULL,
errorType INTEGER,
mediaUrl TEXT,
mediaType TEXT,
thumbnailData TEXT,
thumbnailDimensions TEXT,
dimensions TEXT,
src_url TEXT,
srcUrl TEXT,
received INTEGER,
displayed INTEGER,
acked INTEGER,
origin_id TEXT,
originId TEXT,
quote_id INTEGER,
filename TEXT,
FOREIGN KEY (quote_id) REFERENCES Messages (id),
FOREIGN KEY (quote_id) REFERENCES Messages (id)
)''',
);
@ -41,12 +41,12 @@ Future<void> createDatabase(Database db, int version) async {
id INTEGER PRIMARY KEY AUTOINCREMENT,
jid TEXT NOT NULL,
title TEXT NOT NULL,
avatar_url TEXT NOT NULL,
last_change_timestamp INTEGER NOT NULL,
unread_counter INTEGER NOT NULL,
last_message_body TEXT NOT NULL,
avatarUrl TEXT NOT NULL,
lastChangeTimestamp INTEGER NOT NULL,
unreadCounter INTEGER NOT NULL,
lastMessageBody TEXT NOT NULL,
open INTEGER NOT NULL,
muted INTEGER NOT NULL,
muted INTEGER NOT NULL
)''',
);
@ -59,7 +59,7 @@ Future<void> createDatabase(Database db, int version) async {
mime TEXT,
timestamp INTEGER NOT NULL,
conversation_id INTEGER NOT NULL,
FOREIGN KEY (conversation_id) REFERENCES Conversations (id),
FOREIGN KEY (conversation_id) REFERENCES Conversations (id)
)''',
);
@ -70,9 +70,10 @@ Future<void> createDatabase(Database db, int version) async {
id INTEGER PRIMARY KEY AUTOINCREMENT,
jid TEXT NOT NULL,
title TEXT NOT NULL,
avatar_hash TEXT NOT NULL,
avatarUrl TEXT NOT NULL,
avatarHash TEXT NOT NULL,
subscription TEXT NOT NULL,
ask TEXT NOT NULL,
ask TEXT NOT NULL
)''',
);
}

View File

@ -1,8 +1,8 @@
import 'dart:async';
import 'package:get_it/get_it.dart';
import 'package:logging/logging.dart';
import 'package:moxxyv2/service/database/conversion.dart';
import 'package:moxxyv2/service/database/creation.dart';
import 'package:moxxyv2/service/database/helpers.dart';
import 'package:moxxyv2/service/roster.dart';
import 'package:moxxyv2/shared/error_types.dart';
import 'package:moxxyv2/shared/models/conversation.dart';
@ -39,38 +39,83 @@ class DatabaseService {
/// Loads all conversations from the database and adds them to the state and cache.
Future<List<Conversation>> loadConversations() async {
final conversationsRaw = await _isar.dBConversations.where().findAll();
final conversationsRaw = await _db.query('Conversations',
orderBy: 'lastChangeTimestamp DESC',
);
_log.finest('Conversations: ${conversationsRaw.length}');
final tmp = List<Conversation>.empty(growable: true);
for (final c in conversationsRaw) {
await c.sharedMedia.load();
final rosterItem = await GetIt.I.get<RosterService>().getRosterItemByJid(c.jid);
final conv = conversationDbToModel(
c,
rosterItem != null,
rosterItem?.subscription ?? 'none',
ChatState.gone,
final id = c['id']! as int;
final sharedMediaRaw = await _db.query(
'SharedMedia',
where: 'conversation_id = ?',
whereArgs: [id],
orderBy: 'timestamp DESC',
);
final sharedMedia = sharedMediaRaw
.map(SharedMedium.fromJson)
.toList();
final rosterItem = await GetIt.I.get<RosterService>()
.getRosterItemByJid(c['jid']! as String);
tmp.add(
Conversation.fromJson({
...c,
'muted': intToBool(c['muted']! as int),
'open': intToBool(c['open']! as int),
'sharedMedia': sharedMedia,
'inRoster': rosterItem != null,
'subscription': rosterItem?.subscription ?? 'none',
'chatState': ConversationChatStateConverter().toJson(ChatState.gone),
}),
);
tmp.add(conv);
}
_log.finest(tmp.toString());
return tmp;
}
/// Load messages for [jid] from the database.
Future<List<Message>> loadMessagesForJid(String jid) async {
final rawMessages = await _isar.dBMessages.where().conversationJidEqualTo(jid).findAll();
final rawMessages = await _db.query(
'Messages',
where: 'conversationJid = ?',
whereArgs: [jid],
orderBy: 'timestamp DESC',
);
final messages = List<Message>.empty(growable: true);
for (final m in rawMessages) {
await m.quotes.load();
Message? quotes;
if (m['quote_id'] != null) {
final rawQuote = await _db.query(
'Messages',
where: 'conversationJid = ?, id = ?',
whereArgs: [jid, m['id']! as int],
);
quotes = Message.fromJson(rawQuote.first);
}
final msg = messageDbToModel(m);
messages.add(msg);
messages.add(
Message.fromJson({
...m,
'quotes': quotes,
'received': intToBool(m['received']! as int),
'displayed': intToBool(m['displayed']! as int),
'acked': intToBool(m['acked']! as int),
'isMedia': intToBool(m['isMedia']! as int),
'isFileUploadNotification': intToBool(m['isFileUploadNotification']! as int),
}),
);
}
return messages;
}
/// Updates the conversation with id [id] inside the database.
Future<Conversation> updateConversation(int id, {
String? lastMessageBody,
@ -78,43 +123,60 @@ class DatabaseService {
bool? open,
int? unreadCounter,
String? avatarUrl,
List<DBSharedMedium>? sharedMedia,
List<SharedMedium>? sharedMedia,
ChatState? chatState,
bool? muted,
}
) async {
final c = (await _isar.dBConversations.get(id))!;
await c.sharedMedia.load();
final cd = (await _db.query(
'Conversations',
where: 'id = ?',
whereArgs: [id],
)).first;
final c = Map<String, dynamic>.from(cd);
//await c.sharedMedia.load();
if (lastMessageBody != null) {
c.lastMessageBody = lastMessageBody;
c['lastMessageBody'] = lastMessageBody;
}
if (lastChangeTimestamp != null) {
c.lastChangeTimestamp = lastChangeTimestamp;
c['lastChangeTimestamp'] = lastChangeTimestamp;
}
if (open != null) {
c.open = open;
c['open'] = boolToInt(open);
}
if (unreadCounter != null) {
c.unreadCounter = unreadCounter;
c['unreadCounter'] = unreadCounter;
}
if (avatarUrl != null) {
c.avatarUrl = avatarUrl;
c['avatarUrl'] = avatarUrl;
}
if (sharedMedia != null) {
c.sharedMedia.addAll(sharedMedia);
// TODO(PapaTutuWawa): Implement
//c.sharedMedia.addAll(sharedMedia);
}
if (muted != null) {
c.muted = muted;
c['muted'] = muted;
}
await _isar.writeTxn(() async {
await _isar.dBConversations.put(c);
await c.sharedMedia.save();
});
await _db.update(
'Conversations',
c,
where: 'id = ?',
whereArgs: [id],
);
final rosterItem = await GetIt.I.get<RosterService>().getRosterItemByJid(c.jid);
final conversation = conversationDbToModel(c, rosterItem != null, rosterItem?.subscription ?? 'none', chatState ?? ChatState.gone);
return conversation;
final rosterItem = await GetIt.I.get<RosterService>().getRosterItemByJid(c['jid']! as String);
return Conversation.fromJson({
...c,
'muted': intToBool(c['muted']! as int),
'open': intToBool(c['open']! as int),
// TODO(PapaTutuWawa): Implement
'sharedMedia': <SharedMedium>[],
'inRoster': rosterItem != null,
'subscription': rosterItem?.subscription ?? 'none',
'chatState': ConversationChatStateConverter().toJson(ChatState.gone),
});
}
/// Creates a [Conversation] inside the database given the data. This is so that the
@ -126,43 +188,67 @@ class DatabaseService {
String jid,
int unreadCounter,
int lastChangeTimestamp,
List<DBSharedMedium> sharedMedia,
List<SharedMedium> sharedMedia,
bool open,
bool muted,
) async {
final c = DBConversation()
..jid = jid
..title = title
..avatarUrl = avatarUrl
..lastChangeTimestamp = lastChangeTimestamp
..unreadCounter = unreadCounter
..lastMessageBody = lastMessageBody
..open = open
..muted = muted;
final rosterItem = await GetIt.I.get<RosterService>().getRosterItemByJid(jid);
final conversation = Conversation(
title,
lastMessageBody,
avatarUrl,
jid,
unreadCounter,
lastChangeTimestamp,
sharedMedia,
-1,
open,
rosterItem != null,
rosterItem?.subscription ?? 'none',
muted,
ChatState.gone,
);
c.sharedMedia.addAll(sharedMedia);
// TODO(PapaTutuWawa): Handle shared media
//c.sharedMedia.addAll(sharedMedia);
await _isar.writeTxn(() async {
await _isar.dBConversations.put(c);
});
final rosterItem = await GetIt.I.get<RosterService>().getRosterItemByJid(c.jid);
final conversation = conversationDbToModel(c, rosterItem != null, rosterItem?.subscription ?? 'none', ChatState.gone);
return conversation;
final map = conversation
.toJson()
..remove('id')
..remove('chatState')
..remove('sharedMedia')
..remove('inRoster')
..remove('subscription');
return conversation.copyWith(
id: await _db.insert(
'Conversations',
{
...map,
'open': boolToInt(conversation.open),
'muted': boolToInt(conversation.muted),
},
),
);
}
/// Like [addConversationFromData] but for [SharedMedium].
Future<DBSharedMedium> addSharedMediumFromData(String path, int timestamp, { String? mime }) async {
final s = DBSharedMedium()
..path = path
..mime = mime
..timestamp = timestamp;
Future<SharedMedium> addSharedMediumFromData(String path, int timestamp, { String? mime }) async {
final s = SharedMedium(
-1,
path,
timestamp,
mime: mime,
);
await _isar.writeTxn(() async {
await _isar.dBSharedMediums.put(s);
});
return s;
final map = s
.toJson()
..remove('id');
return s.copyWith(
id: await _db.insert(
'SharedMedia',
map,
),
);
}
/// Same as [addConversationFromData] but for a [Message].
@ -185,26 +271,30 @@ class DatabaseService {
String? filename,
}
) async {
final m = DBMessage()
..conversationJid = conversationJid
..timestamp = timestamp
..body = body
..sender = sender
..isMedia = isMedia
..mediaType = mediaType
..mediaUrl = mediaUrl
..srcUrl = srcUrl
..sid = sid
..thumbnailData = thumbnailData
..thumbnailDimensions = thumbnailDimensions
..received = false
..displayed = false
..acked = false
..originId = originId
..errorType = noError
..isFileUploadNotification = isFileUploadNotification
..filename = filename;
final m = Message(
sender,
body,
timestamp,
sid,
-1,
conversationJid,
isMedia,
isFileUploadNotification,
errorType: noError,
mediaUrl: mediaUrl,
mediaType: mediaType,
thumbnailData: thumbnailData,
thumbnailDimensions: thumbnailDimensions,
srcUrl: srcUrl,
received: false,
displayed: false,
acked: false,
originId: originId,
filename: filename,
);
// TODO(PapaTutuWawa): Handle quotes
/*
if (quoteId != null) {
final quotes = await getMessageByXmppId(quoteId, conversationJid);
if (quotes != null) {
@ -213,24 +303,63 @@ class DatabaseService {
_log.warning('Failed to add quote for message with id $quoteId');
}
}
*/
await _isar.writeTxn(() async {
await _isar.dBMessages.put(m);
});
final map = m
.toJson()
..remove('id')
..remove('quotes')
..remove('isDownloading')
..remove('isUploading');
final msg = messageDbToModel(m);
return msg;
Message? quotes;
if (quoteId != null) {
quotes = await getMessageByXmppId(quoteId, conversationJid);
if (quotes != null) {
map['quote_id'] = quoteId;
} else {
_log.warning('Failed to add quote for message with id $quoteId');
}
}
return m.copyWith(
id: await _db.insert(
'Messages',
{
...map,
'isMedia': boolToInt(m.isMedia),
'isFileUploadNotification': boolToInt(m.isFileUploadNotification),
'received': boolToInt(m.received),
'displayed': boolToInt(m.displayed),
'acked': boolToInt(m.acked),
},
),
quotes: quotes,
);
}
Future<DBMessage?> getMessageByXmppId(String id, String conversationJid) async {
return _isar.dBMessages.filter()
.conversationJidEqualTo(conversationJid)
.and()
.group((q) => q
.sidEqualTo(id)
.or()
.originIdEqualTo(id),
).findFirst();
Future<Message?> getMessageByXmppId(String id, String conversationJid) async {
_log.finest('id: $id, conversationJid: $conversationJid');
final messagesRaw = await _db.query(
'Messages',
where: 'conversationJid = ? AND (sid = ? or originId = ?)',
whereArgs: [conversationJid, id, id],
limit: 1,
);
if (messagesRaw.isEmpty) return null;
// TODO(PapaTutuWawa): Load the quoted message
final msg = messagesRaw.first;
return Message.fromJson({
...msg,
'isMedia': intToBool(msg['isMedia']! as int),
'isFileUploadNotification': intToBool(msg['isFileUploadNotification']! as int),
'received': intToBool(msg['received']! as int),
'displayed': intToBool(msg['displayed']! as int),
'acked': intToBool(msg['acked']! as int),
});
}
/// Updates the message item with id [id] inside the database.
@ -244,52 +373,73 @@ class DatabaseService {
bool? isFileUploadNotification,
String? srcUrl,
}) async {
final i = (await _isar.dBMessages.get(id))!;
final md = (await _db.query(
'Messages',
where: 'id = ?',
whereArgs: [id],
limit: 1,
)).first;
final m = Map<String, dynamic>.from(md);
if (mediaUrl != null) {
i.mediaUrl = mediaUrl;
m['mediaUrl'] = mediaUrl;
}
if (mediaType != null) {
i.mediaType = mediaType;
m['mediaType'] = mediaType;
}
if (received != null) {
i.received = received;
m['received'] = boolToInt(received);
}
if (displayed != null) {
i.displayed = displayed;
m['displayed'] = boolToInt(displayed);
}
if (acked != null) {
i.acked = acked;
m['acked'] = boolToInt(acked);
}
if (errorType != null) {
i.errorType = errorType;
m['errorType'] = errorType;
}
if (isFileUploadNotification != null) {
i.isFileUploadNotification = isFileUploadNotification;
m['isFileUploadNotification'] = boolToInt(isFileUploadNotification);
}
if (srcUrl != null) {
i.srcUrl = srcUrl;
m['srcUrl'] = srcUrl;
}
await _isar.writeTxn(() async {
await _isar.dBMessages.put(i);
});
await i.quotes.load();
await _db.update(
'Messages',
m,
where: 'id = ?',
whereArgs: [id],
);
final msg = messageDbToModel(i);
return msg;
return Message.fromJson({
...m,
'isMedia': intToBool(m['isMedia']! as int),
'isFileUploadNotification': intToBool(m['isFileUploadNotification']! as int),
'received': intToBool(m['received']! as int),
'displayed': intToBool(m['displayed']! as int),
'acked': intToBool(m['acked']! as int),
});
}
/// Loads roster items from the database
Future<List<RosterItem>> loadRosterItems() async {
final roster = await _isar.dBRosterItems.where().findAll();
return roster.map(rosterDbToModel).toList();
final items = await _db.query('RosterItems');
return items.map((item) {
item['groups'] = <String>[];
return RosterItem.fromJson(item);
}).toList();
}
/// Removes a roster item from the database and cache
Future<void> removeRosterItem(int id) async {
await _isar.writeTxn(() async {
await _isar.dBRosterItems.delete(id);
});
await _db.delete(
'RosterItems',
where: 'id = ?',
whereArgs: [id],
);
}
/// Create a roster item from data
@ -304,21 +454,28 @@ class DatabaseService {
List<String> groups = const [],
}
) async {
final rosterItem = DBRosterItem()
..jid = jid
..title = title
..avatarUrl = avatarUrl
..avatarHash = avatarHash
..subscription = subscription
..ask = ask
..groups = groups;
// TODO(PapaTutuWawa): Handle groups
final i = RosterItem(
-1,
avatarUrl,
avatarHash,
jid,
title,
subscription,
ask,
<String>[],
);
await _isar.writeTxn(() async {
await _isar.dBRosterItems.put(rosterItem);
});
final item = rosterDbToModel(rosterItem);
return item;
final map = i
.toJson()
..remove('id');
return i.copyWith(
id: await _db.insert(
'RosterItems',
map,
),
);
}
/// Updates the roster item with id [id] inside the database.
@ -332,31 +489,41 @@ class DatabaseService {
List<String>? groups,
}
) async {
final i = (await _isar.dBRosterItems.get(id))!;
final id_ = (await _db.query(
'RosterItems',
where: 'id = ?',
whereArgs: [id],
limit: 1,
)).first;
final i = Map<String, dynamic>.from(id_);
if (avatarUrl != null) {
i.avatarUrl = avatarUrl;
i['avatarUrl'] = avatarUrl;
}
if (avatarHash != null) {
i.avatarHash = avatarHash;
i['avatarHash'] = avatarHash;
}
if (title != null) {
i.title = title;
i['title'] = title;
}
/*
if (groups != null) {
i.groups = groups;
}
*/
if (subscription != null) {
i.subscription = subscription;
i['subscription'] = subscription;
}
if (ask != null) {
i.ask = ask;
i['ask'] = ask;
}
await _isar.writeTxn(() async {
await _isar.dBRosterItems.put(i);
});
final item = rosterDbToModel(i);
return item;
await _db.update(
'RosterItems',
i,
where: 'id = ?',
whereArgs: [id],
);
return RosterItem.fromJson(i);
}
}

View File

@ -0,0 +1,2 @@
int boolToInt(bool b) => b ? 0 : 1;
bool intToBool(int i) => i == 0 ? false : true;

View File

@ -1,29 +0,0 @@
import 'package:isar/isar.dart';
import 'package:moxxyv2/service/db/media.dart';
part 'conversation.g.dart';
@Collection()
@Name('Conversation')
class DBConversation {
Id? id;
@Index(caseSensitive: false)
late String jid;
late String title;
late String avatarUrl;
late int lastChangeTimestamp;
late int unreadCounter;
late String lastMessageBody;
late bool open;
late bool muted;
final sharedMedia = IsarLinks<DBSharedMedium>();
}

View File

@ -1,17 +0,0 @@
import 'package:isar/isar.dart';
part 'media.g.dart';
@Collection()
@Name('SharedMedium')
class DBSharedMedium {
Id? id;
@Index(caseSensitive: true)
late String path;
late String? mime;
// The timestamp of the corresponding message
late int timestamp;
}

View File

@ -1,56 +0,0 @@
import 'package:isar/isar.dart';
part 'message.g.dart';
@Collection()
@Name('Message')
class DBMessage {
Id? id;
@Index(caseSensitive: false)
late String conversationJid;
late int timestamp;
late String body;
/// The full JID of the sender
@Index(caseSensitive: false)
late String sender;
late String sid;
String? originId;
/// Indicate if the message was received by the client (via Chat Markers or Delivery Receipts) or acked by the server
late bool acked;
late bool received;
late bool displayed;
/// In case an error is related to the message, this stores an enum-like constant
/// that clearly identifies the error.
late int errorType;
/// If true, then the message is currently a placeholder for a File Upload Notification
/// and may be replaced
late bool isFileUploadNotification;
/// The message that this one quotes
final quotes = IsarLink<DBMessage>();
/// Url a file can be accessed from
String? srcUrl;
/// A file:// URL pointing to the file
String? mediaUrl;
/// If the message should be treated as a media message, e.g. an image
late bool isMedia;
/// The mime type, if available
String? mediaType;
// TODO(Unknown): Add a flag to specify the thumbnail type
/// The data of the thumbnail base64-encoded if needed. Currently assumed to be blurhash
String? thumbnailData;
/// The dimensions of the thumbnail
String? thumbnailDimensions;
/// The filename of the file. Useful for when we don't have the full URL yet
String? filename;
}

View File

@ -1,22 +0,0 @@
import 'package:isar/isar.dart';
part 'roster.g.dart';
@Collection()
@Name('RosterItem')
class DBRosterItem {
Id? id;
late String jid;
late String title;
late String avatarUrl;
late String avatarHash;
late List<String> groups;
late String subscription;
late String ask;
}

View File

@ -14,7 +14,6 @@ import 'package:moxxyv2/service/connectivity.dart';
import 'package:moxxyv2/service/connectivity_watcher.dart';
import 'package:moxxyv2/service/conversation.dart';
import 'package:moxxyv2/service/database/database.dart';
import 'package:moxxyv2/service/db/media.dart';
import 'package:moxxyv2/service/helpers.dart';
import 'package:moxxyv2/service/httpfiletransfer/helpers.dart';
import 'package:moxxyv2/service/httpfiletransfer/httpfiletransfer.dart';
@ -29,6 +28,7 @@ import 'package:moxxyv2/shared/eventhandler.dart';
import 'package:moxxyv2/shared/events.dart';
import 'package:moxxyv2/shared/helpers.dart';
import 'package:moxxyv2/shared/migrator.dart';
import 'package:moxxyv2/shared/models/media.dart';
import 'package:moxxyv2/shared/models/message.dart';
import 'package:moxxyv2/xmpp/connection.dart';
import 'package:moxxyv2/xmpp/events.dart';
@ -365,7 +365,7 @@ class XmppService {
// Create the shared media entries
// Recipient -> [Shared Medium]
final sharedMediaMap = <String, List<DBSharedMedium>>{};
final sharedMediaMap = <String, List<SharedMedium>>{};
final rs = GetIt.I.get<RosterService>();
for (final recipient in recipients) {
for (final path in paths) {
@ -378,7 +378,7 @@ class XmppService {
if (sharedMediaMap.containsKey(recipient)) {
sharedMediaMap[recipient]!.add(medium);
} else {
sharedMediaMap[recipient] = List<DBSharedMedium>.from([medium]);
sharedMediaMap[recipient] = List<SharedMedium>.from([medium]);
}
}
@ -596,7 +596,7 @@ class XmppService {
}
final msg = await ms.updateMessage(
dbMsg.id!,
dbMsg.id,
received: true,
);
@ -616,7 +616,7 @@ class XmppService {
}
final msg = await ms.updateMessage(
dbMsg.id!,
dbMsg.id,
received: dbMsg.received || event.type == 'received' || event.type == 'displayed',
displayed: dbMsg.displayed || event.type == 'displayed',
);
@ -956,7 +956,7 @@ class XmppService {
final ms = GetIt.I.get<MessageService>();
final msg = await db.getMessageByXmppId(event.id, jid);
if (msg != null) {
await ms.updateMessage(msg.id!, acked: true);
await ms.updateMessage(msg.id, acked: true);
} else {
_log.finest('Wanted to mark message as acked but did not find the message to ack');
}