@@ -236,6 +236,57 @@ class MessageEntry {
236236 }
237237}
238238
239+ class ReactionEntry {
240+ int ? id;
241+ final String time;
242+ final String replyNetworkMsgid;
243+ final int buffer;
244+ final String raw;
245+
246+ IrcMessage ? _msg;
247+ DateTime ? _dateTime;
248+ String ? _text;
249+
250+ ReactionEntry (IrcMessage msg, this .buffer) :
251+ time = msg.tags['time' ] ?? formatIrcTime (DateTime .now ()),
252+ replyNetworkMsgid = msg.tags['+draft/reply' ]! ,
253+ raw = msg.toString (),
254+ _text = msg.tags['+draft/react' ]! ,
255+ _msg = msg;
256+
257+ Map <String , Object ?> toMap () {
258+ return < String , Object ? > {
259+ 'id' : id,
260+ 'time' : time,
261+ 'reply_network_msgid' : replyNetworkMsgid,
262+ 'buffer' : buffer,
263+ 'raw' : raw,
264+ };
265+ }
266+
267+ ReactionEntry .fromMap (Map <String , dynamic > m) :
268+ id = m['id' ] as int ,
269+ time = m['time' ] as String ,
270+ replyNetworkMsgid = m['reply_network_msgid' ] as String ,
271+ buffer = m['buffer' ] as int ,
272+ raw = m['raw' ] as String ;
273+
274+ IrcMessage get msg {
275+ _msg ?? = IrcMessage .parse (raw);
276+ return _msg! ;
277+ }
278+
279+ String get text {
280+ _text ?? = msg.tags['+draft/react' ]! ;
281+ return _text! ;
282+ }
283+
284+ DateTime get dateTime {
285+ _dateTime ?? = DateTime .parse (time);
286+ return _dateTime! ;
287+ }
288+ }
289+
239290class WebPushSubscriptionEntry {
240291 int ? id;
241292 final int network;
@@ -392,6 +443,17 @@ const _schema = [
392443 ON Message(buffer, time)
393444 ''' ,
394445 'CREATE INDEX index_message_network_msgid on Message(network_msgid)' ,
446+ '''
447+ CREATE TABLE Reaction (
448+ id INTEGER PRIMARY KEY,
449+ buffer INTEGER NOT NULL,
450+ time TEXT NOT NULL,
451+ raw TEXT NOT NULL,
452+ reply_network_msgid TEXT NOT NULL,
453+ FOREIGN KEY (buffer) REFERENCES Buffer(id) ON DELETE CASCADE
454+ )
455+ ''' ,
456+ 'CREATE INDEX index_reaction_reply_network_msgid on Reaction(reply_network_msgid)' ,
395457 '''
396458 CREATE TABLE WebPushSubscription (
397459 id INTEGER PRIMARY KEY,
@@ -465,6 +527,17 @@ const _migrations = [
465527 'ALTER TABLE LinkPreview ADD COLUMN image_url TEXT' ,
466528 'ALTER TABLE Network ADD COLUMN last_delivered_time TEXT' ,
467529 'ALTER TABLE Server ADD COLUMN pinned_cert_sha1 TEXT' ,
530+ '''
531+ CREATE TABLE Reaction (
532+ id INTEGER PRIMARY KEY,
533+ buffer INTEGER NOT NULL,
534+ time TEXT NOT NULL,
535+ raw TEXT NOT NULL,
536+ reply_network_msgid TEXT NOT NULL,
537+ FOREIGN KEY (buffer) REFERENCES Buffer(id) ON DELETE CASCADE
538+ )
539+ ''' ,
540+ 'CREATE INDEX index_reaction_reply_network_msgid on Reaction(reply_network_msgid)' ,
468541];
469542
470543class DB {
@@ -724,6 +797,45 @@ class DB {
724797 });
725798 }
726799
800+ Future <Map <String , List <ReactionEntry >>> fetchReactionSetBetweenMessages (int buffer, MessageEntry initialMessage, MessageEntry finalMessage) async {
801+ var entries = await _db.rawQuery ('''
802+ SELECT *
803+ FROM Reaction
804+ WHERE buffer = ? AND reply_network_msgid IN (
805+ SELECT network_msgid
806+ FROM Message
807+ WHERE buffer = ? AND time BETWEEN (
808+ SELECT time FROM Message WHERE id = ?
809+ ) AND (
810+ SELECT time FROM Message WHERE id = ?
811+ )
812+ )
813+ ''' , < Object > [buffer, buffer, initialMessage.id! , finalMessage.id! ]);
814+ Map <String , List <ReactionEntry >> reactions = {};
815+ for (var m in entries) {
816+ var entry = ReactionEntry .fromMap (m);
817+ reactions.update (
818+ entry.replyNetworkMsgid,
819+ (l) => l..add (entry),
820+ ifAbsent: () => [entry],
821+ );
822+ }
823+ return reactions;
824+ }
825+
826+ Future <void > storeReactions (List <ReactionEntry > entries) async {
827+ await _db.transaction ((txn) async {
828+ await Future .wait (entries.map ((entry) async {
829+ if (entry.id == null ) {
830+ var id = await txn.insert ('Reaction' , entry.toMap ());
831+ entry.id = id;
832+ } else {
833+ await _updateById ('Reaction' , entry.toMap (), executor: txn);
834+ }
835+ }));
836+ });
837+ }
838+
727839 Future <List <WebPushSubscriptionEntry >> listWebPushSubscriptions () async {
728840 var entries = await _db.rawQuery ('''
729841 SELECT * FROM WebPushSubscription
0 commit comments