mirror of
https://github.com/cinnyapp/cinny.git
synced 2025-11-14 03:00:29 +03:00
Implement sending read receipt in new pagination
Signed-off-by: Ajay Bura <ajbura@gmail.com>
This commit is contained in:
parent
50db137dea
commit
c1e3645d57
9 changed files with 244 additions and 132 deletions
|
|
@ -1,11 +1,21 @@
|
|||
import EventEmitter from 'events';
|
||||
import cons from './cons';
|
||||
|
||||
function isNotifEvent(mEvent) {
|
||||
const eType = mEvent.getType();
|
||||
if (!cons.supportEventTypes.includes(eType)) return false;
|
||||
if (eType === 'm.room.member') return false;
|
||||
|
||||
if (mEvent.isRedacted()) return false;
|
||||
if (mEvent.getRelation()?.rel_type === 'm.replace') return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
class Notifications extends EventEmitter {
|
||||
constructor(roomList) {
|
||||
super();
|
||||
|
||||
this.supportEvents = ['m.room.message', 'm.room.encrypted', 'm.sticker'];
|
||||
this.matrixClient = roomList.matrixClient;
|
||||
this.roomList = roomList;
|
||||
|
||||
|
|
@ -36,21 +46,14 @@ class Notifications extends EventEmitter {
|
|||
const readUpToId = room.getEventReadUpTo(userId);
|
||||
const liveEvents = room.getLiveTimeline().getEvents();
|
||||
|
||||
if (liveEvents.length
|
||||
&& liveEvents[liveEvents.length - 1].sender
|
||||
&& liveEvents[liveEvents.length - 1].sender.userId === userId
|
||||
&& liveEvents[liveEvents.length - 1].getType() !== 'm.room.member') {
|
||||
if (liveEvents[liveEvents.length - 1]?.getSender() === userId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let i = liveEvents.length - 1; i >= 0; i -= 1) {
|
||||
const event = liveEvents[i];
|
||||
|
||||
if (event.getId() === readUpToId) return false;
|
||||
|
||||
if (this.supportEvents.includes(event.getType())) {
|
||||
return true;
|
||||
}
|
||||
if (isNotifEvent(event)) return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -150,7 +153,7 @@ class Notifications extends EventEmitter {
|
|||
|
||||
_listenEvents() {
|
||||
this.matrixClient.on('Room.timeline', (mEvent, room) => {
|
||||
if (!this.supportEvents.includes(mEvent.getType())) return;
|
||||
if (!isNotifEvent(mEvent)) return;
|
||||
const liveEvents = room.getLiveTimeline().getEvents();
|
||||
|
||||
const lastTimelineEvent = liveEvents[liveEvents.length - 1];
|
||||
|
|
|
|||
|
|
@ -48,6 +48,15 @@ function iterateLinkedTimelines(timeline, backwards, callback) {
|
|||
}
|
||||
}
|
||||
|
||||
function isTimelineLinked(tm1, tm2) {
|
||||
let tm = getFirstLinkedTimeline(tm1);
|
||||
while (tm) {
|
||||
if (tm === tm2) return true;
|
||||
tm = tm.nextTimeline;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
class RoomTimeline extends EventEmitter {
|
||||
constructor(roomId) {
|
||||
super();
|
||||
|
|
@ -93,8 +102,8 @@ class RoomTimeline extends EventEmitter {
|
|||
this.timeline = [];
|
||||
|
||||
// TODO: don't clear these timeline cause there data can be used in other timeline
|
||||
// this.reactionTimeline.clear();
|
||||
// this.editedTimeline.clear();
|
||||
this.reactionTimeline.clear();
|
||||
this.editedTimeline.clear();
|
||||
}
|
||||
|
||||
addToTimeline(mEvent) {
|
||||
|
|
@ -197,22 +206,29 @@ class RoomTimeline extends EventEmitter {
|
|||
return Promise.allSettled(decryptionPromises);
|
||||
}
|
||||
|
||||
markAsRead() {
|
||||
markAllAsRead() {
|
||||
const readEventId = this.getReadUpToEventId();
|
||||
if (this.timeline.length === 0) return;
|
||||
const latestEvent = this.timeline[this.timeline.length - 1];
|
||||
if (readEventId === latestEvent.getId()) return;
|
||||
this.matrixClient.sendReadReceipt(latestEvent);
|
||||
this.emit(cons.events.roomTimeline.MARKED_AS_READ, latestEvent);
|
||||
}
|
||||
|
||||
hasEventInLiveTimeline(eventId) {
|
||||
const timelineSet = this.getUnfilteredTimelineSet();
|
||||
return timelineSet.getTimelineForEvent(eventId) === this.liveTimeline;
|
||||
markAsRead(eventId) {
|
||||
if (this.hasEventInTimeline(eventId)) {
|
||||
const mEvent = this.findEventById(eventId);
|
||||
if (!mEvent) return;
|
||||
this.matrixClient.sendReadReceipt(mEvent);
|
||||
this.emit(cons.events.roomTimeline.MARKED_AS_READ, mEvent);
|
||||
}
|
||||
}
|
||||
|
||||
hasEventInActiveTimeline(eventId) {
|
||||
hasEventInTimeline(eventId, timeline = this.activeTimeline) {
|
||||
const timelineSet = this.getUnfilteredTimelineSet();
|
||||
return timelineSet.getTimelineForEvent(eventId) === this.activeTimeline;
|
||||
const eventTimeline = timelineSet.getTimelineForEvent(eventId);
|
||||
if (!eventTimeline) return false;
|
||||
return isTimelineLinked(eventTimeline, timeline);
|
||||
}
|
||||
|
||||
getUnfilteredTimelineSet() {
|
||||
|
|
@ -242,6 +258,22 @@ class RoomTimeline extends EventEmitter {
|
|||
return [...new Set(readers)];
|
||||
}
|
||||
|
||||
getUnreadEventIndex(readUpToEventId) {
|
||||
if (!this.hasEventInTimeline(readUpToEventId)) return -1;
|
||||
|
||||
const readUpToEvent = this.findEventByIdInTimelineSet(readUpToEventId);
|
||||
if (!readUpToEvent) return -1;
|
||||
const rTs = readUpToEvent.getTs();
|
||||
|
||||
const tLength = this.timeline.length;
|
||||
|
||||
for (let i = 0; i < tLength; i += 1) {
|
||||
const mEvent = this.timeline[i];
|
||||
if (mEvent.getTs() > rTs) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
getReadUpToEventId() {
|
||||
return this.room.getEventReadUpTo(this.matrixClient.getUserId());
|
||||
}
|
||||
|
|
@ -261,7 +293,7 @@ class RoomTimeline extends EventEmitter {
|
|||
deleteFromTimeline(eventId) {
|
||||
const i = this.getEventIndex(eventId);
|
||||
if (i === -1) return undefined;
|
||||
return this.timeline.splice(i, 1);
|
||||
return this.timeline.splice(i, 1)[0];
|
||||
}
|
||||
|
||||
_listenEvents() {
|
||||
|
|
@ -306,12 +338,12 @@ class RoomTimeline extends EventEmitter {
|
|||
this.emit(cons.events.roomTimeline.EVENT, event);
|
||||
};
|
||||
|
||||
this._listenRedaction = (event, room) => {
|
||||
this._listenRedaction = (mEvent, room) => {
|
||||
if (room.roomId !== this.roomId) return;
|
||||
this.deleteFromTimeline(event.getId());
|
||||
this.editedTimeline.delete(event.getId());
|
||||
this.reactionTimeline.delete(event.getId());
|
||||
this.emit(cons.events.roomTimeline.EVENT);
|
||||
const rEvent = this.deleteFromTimeline(mEvent.event.redacts);
|
||||
this.editedTimeline.delete(mEvent.event.redacts);
|
||||
this.reactionTimeline.delete(mEvent.event.redacts);
|
||||
this.emit(cons.events.roomTimeline.EVENT_REDACTED, rEvent, mEvent);
|
||||
};
|
||||
|
||||
this._listenTypingEvent = (event, member) => {
|
||||
|
|
|
|||
|
|
@ -92,6 +92,10 @@ const cons = {
|
|||
PAGINATED: 'PAGINATED',
|
||||
TYPING_MEMBERS_UPDATED: 'TYPING_MEMBERS_UPDATED',
|
||||
LIVE_RECEIPT: 'LIVE_RECEIPT',
|
||||
MARKED_AS_READ: 'MARKED_AS_READ',
|
||||
EVENT_REDACTED: 'EVENT_REDACTED',
|
||||
AT_BOTTOM: 'AT_BOTTOM',
|
||||
SCROLL_TO_LIVE: 'SCROLL_TO_LIVE',
|
||||
},
|
||||
roomsInput: {
|
||||
MESSAGE_SENT: 'MESSAGE_SENT',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue