hydrogen-web/src/matrix/room/summary.js

206 lines
5.8 KiB
JavaScript
Raw Normal View History

2019-02-11 01:55:29 +05:30
// import SummaryMembers from "./members";
2018-12-21 19:05:24 +05:30
2019-02-11 01:55:29 +05:30
export default class RoomSummary {
constructor(roomId) {
2019-02-11 01:55:29 +05:30
// this._members = new SummaryMembers();
2018-12-21 19:05:24 +05:30
this._roomId = roomId;
2019-02-11 01:55:29 +05:30
this._name = null;
2019-02-16 07:25:01 +05:30
this._lastMessageBody = null;
2019-02-11 01:55:29 +05:30
this._unreadCount = null;
this._mentionCount = null;
this._isEncrypted = null;
this._isDirectMessage = null;
this._membership = null;
2018-12-21 19:05:24 +05:30
this._inviteCount = 0;
this._joinCount = 0;
2019-02-16 07:25:01 +05:30
this._readMarkerEventId = null;
this._heroes = null;
this._canonicalAlias = null;
this._aliases = null;
2018-12-21 19:05:24 +05:30
}
get name() {
if (this._name) {
return this._name;
}
if (this._canonicalAlias) {
return this._canonicalAlias;
}
if (Array.isArray(this._aliases) && this._aliases.length !== 0) {
return this._aliases[0];
}
if (Array.isArray(this._heroes) && this._heroes.length !== 0) {
return this._heroes.join(", ");
}
return this._roomId;
2018-12-21 19:05:24 +05:30
}
get lastMessage() {
return this._lastMessageBody;
}
get inviteCount() {
return this._inviteCount;
}
get joinCount() {
return this._joinCount;
}
2019-02-28 03:53:09 +05:30
applySync(roomResponse, membership, txn) {
2019-02-11 01:55:29 +05:30
const changed = this._processSyncResponse(roomResponse, membership);
2018-12-21 19:05:24 +05:30
if (changed) {
2019-02-28 03:53:09 +05:30
this._persist(txn);
2018-12-21 19:05:24 +05:30
}
return changed;
}
2019-02-11 01:55:29 +05:30
async load(summary) {
2018-12-21 19:05:24 +05:30
this._roomId = summary.roomId;
2019-02-11 01:55:29 +05:30
this._name = summary.name;
2019-02-16 07:25:01 +05:30
this._lastMessageBody = summary.lastMessageBody;
2019-02-11 01:55:29 +05:30
this._unreadCount = summary.unreadCount;
this._mentionCount = summary.mentionCount;
this._isEncrypted = summary.isEncrypted;
this._isDirectMessage = summary.isDirectMessage;
this._membership = summary.membership;
2018-12-21 19:05:24 +05:30
this._inviteCount = summary.inviteCount;
this._joinCount = summary.joinCount;
2019-02-16 07:25:01 +05:30
this._readMarkerEventId = summary.readMarkerEventId;
this._heroes = summary.heroes;
this._aliases = summary.aliases;
this._canonicalAlias = summary.canonicalAlias;
2018-12-21 19:05:24 +05:30
}
2019-02-11 01:55:29 +05:30
_persist(txn) {
2019-02-16 07:25:01 +05:30
// need to think here how we want to persist
// things like unread status (as read marker, or unread count)?
// we could very well load additional things in the load method
// ... the trade-off is between constantly writing the summary
// on every sync, or doing a bit of extra reading on load
// and have in-memory only variables for visualization
2018-12-21 19:05:24 +05:30
const summary = {
roomId: this._roomId,
2019-02-16 07:25:01 +05:30
name: this._name,
lastMessageBody: this._lastMessageBody,
unreadCount: this._unreadCount,
mentionCount: this._mentionCount,
isEncrypted: this._isEncrypted,
isDirectMessage: this._isDirectMessage,
membership: this._membership,
2018-12-21 19:05:24 +05:30
inviteCount: this._inviteCount,
joinCount: this._joinCount,
2019-02-16 07:25:01 +05:30
readMarkerEventId: this._readMarkerEventId,
heroes: this._heroes,
aliases: this._aliases,
canonicalAlias: this._canonicalAlias,
2018-12-21 19:05:24 +05:30
};
2019-02-11 01:55:29 +05:30
return txn.roomSummary.set(summary);
2018-12-21 19:05:24 +05:30
}
2019-02-11 01:55:29 +05:30
_processSyncResponse(roomResponse, membership) {
2018-12-21 19:05:24 +05:30
let changed = false;
if (roomResponse.summary) {
this._updateSummary(roomResponse.summary);
changed = true;
}
2019-02-11 01:55:29 +05:30
if (membership !== this._membership) {
this._membership = membership;
changed = true;
}
// state comes before timeline
2019-02-16 05:17:24 +05:30
if (roomResponse.state) {
changed = roomResponse.state.events.reduce((changed, e) => {
2018-12-21 19:05:24 +05:30
return this._processEvent(e) || changed;
}, changed);
}
2019-02-11 01:55:29 +05:30
if (roomResponse.timeline) {
changed = roomResponse.timeline.events.reduce((changed, e) => {
return this._processEvent(e) || changed;
}, changed);
}
2018-12-21 19:05:24 +05:30
return changed;
}
_processEvent(event) {
2019-02-16 07:25:01 +05:30
if (event.type === "m.room.encryption") {
if (!this._isEncrypted) {
this._isEncrypted = true;
return true;
}
}
2018-12-21 19:05:24 +05:30
if (event.type === "m.room.name") {
const newName = event.content && event.content.name;
2019-02-11 01:55:29 +05:30
if (newName !== this._name) {
this._name = newName;
2018-12-21 19:05:24 +05:30
return true;
}
} else if (event.type === "m.room.member") {
return this._processMembership(event);
} else if (event.type === "m.room.message") {
const content = event.content;
const body = content && content.body;
const msgtype = content && content.msgtype;
if (msgtype === "m.text") {
this._lastMessageBody = body;
return true;
}
} else if (event.type === "m.room.canonical_alias") {
const content = event.content;
this._canonicalAlias = content.alias;
return true;
} else if (event.type === "m.room.aliases") {
const content = event.content;
this._aliases = content.aliases;
return true;
}
2018-12-21 19:05:24 +05:30
return false;
}
_processMembership(event) {
let changed = false;
const prevMembership = event.prev_content && event.prev_content.membership;
2019-02-11 01:55:29 +05:30
if (!event.content) {
return changed;
}
const content = event.content;
const membership = content.membership;
2018-12-21 19:05:24 +05:30
// danger of a replayed event getting the count out of sync
// but summary api will solve this.
// otherwise we'd have to store all the member ids in here
if (membership !== prevMembership) {
switch (prevMembership) {
2019-02-11 01:55:29 +05:30
case "invite": --this._inviteCount; break;
case "join": --this._joinCount; break;
2018-12-21 19:05:24 +05:30
}
switch (membership) {
2019-02-11 01:55:29 +05:30
case "invite": ++this._inviteCount; break;
case "join": ++this._joinCount; break;
2018-12-21 19:05:24 +05:30
}
changed = true;
}
2019-02-11 01:55:29 +05:30
// if (membership === "join" && content.name) {
// // TODO: avatar_url
// changed = this._members.applyMember(content.name, content.state_key) || changed;
// }
2018-12-21 19:05:24 +05:30
return changed;
}
_updateSummary(summary) {
const heroes = summary["m.heroes"];
const inviteCount = summary["m.joined_member_count"];
const joinCount = summary["m.invited_member_count"];
if (heroes) {
this._heroes = heroes;
}
if (Number.isInteger(inviteCount)) {
this._inviteCount = inviteCount;
}
if (Number.isInteger(joinCount)) {
this._joinCount = joinCount;
}
}
}