You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2026-01-03 23:22:30 +03:00
Shuffle around how events are stored.
Rather than having MatrixInMemoryStore do it all, we make the right object do the right thing, and keep the store for storing said objects.
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
var httpApi = require("./http-api");
|
||||
var MatrixEvent = require("./models/event").MatrixEvent;
|
||||
var Room = require("./models/room");
|
||||
var MatrixInMemoryStore = require("./store/memory").MatrixInMemoryStore;
|
||||
var utils = require("./utils");
|
||||
|
||||
@@ -592,14 +593,24 @@ module.exports.MatrixClient.prototype = {
|
||||
utils.map(data.presence, eventMapper)
|
||||
);
|
||||
for (i = 0; i < data.rooms.length; i++) {
|
||||
self.store.setStateEvents(
|
||||
utils.map(data.rooms[i].state, eventMapper)
|
||||
);
|
||||
self.store.setEvents(
|
||||
var room = new Room(data.rooms[i].room_id);
|
||||
|
||||
// "old" and "current" state are the same initially; they
|
||||
// start diverging if the user paginates.
|
||||
var stateEvents = utils.map(data.rooms[i].state, eventMapper);
|
||||
room.oldState.setStateEvents(stateEvents);
|
||||
room.currentState.setStateEvents(stateEvents);
|
||||
|
||||
// add events to the timeline *after* setting the state
|
||||
// events so messages use the right display names.
|
||||
room.addEventsToTimeline(
|
||||
utils.map(data.rooms[i].messages.chunk, eventMapper)
|
||||
);
|
||||
|
||||
self.store.storeRoom(room);
|
||||
}
|
||||
}
|
||||
|
||||
if (data) {
|
||||
self.fromToken = data.end;
|
||||
var events = [];
|
||||
@@ -636,19 +647,30 @@ module.exports.MatrixClient.prototype = {
|
||||
from: this.fromToken,
|
||||
timeout: 30000
|
||||
}).done(function(data) {
|
||||
var events = [];
|
||||
if (data) {
|
||||
events = utils.map(data.chunk, function(event) {
|
||||
return new MatrixEvent(event);
|
||||
});
|
||||
}
|
||||
if (self.store) {
|
||||
self.store.setEvents(utils.map(data.chunk,
|
||||
function(event) {
|
||||
return new MatrixEvent(event);
|
||||
for (var i = 0; i < events.length; i++) {
|
||||
var roomId = events[i].getRoomId();
|
||||
// possible to have no room ID e.g. for presence events.
|
||||
if (roomId) {
|
||||
var room = self.store.getRoom(roomId);
|
||||
if (!room) {
|
||||
// TODO: whine about this. We got an event for a room
|
||||
// we don't know about (we should really be doing a
|
||||
// roomInitialSync at this point to pull in state).
|
||||
room = new Room(roomId);
|
||||
}
|
||||
room.addEventsToTimeline([events[i]]);
|
||||
}
|
||||
));
|
||||
}
|
||||
}
|
||||
if (data) {
|
||||
self.fromToken = data.end;
|
||||
var events = [];
|
||||
for (var j = 0; j < data.chunk.length; j++) {
|
||||
events.push(new MatrixEvent(data.chunk[j]));
|
||||
}
|
||||
callback(undefined, events, true);
|
||||
}
|
||||
self._pollForEvents(callback);
|
||||
@@ -668,7 +690,7 @@ module.exports.MatrixClient.prototype = {
|
||||
*/
|
||||
stopClient: function() {
|
||||
this.clientRunning = false;
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,13 +7,15 @@ var utils = require("../utils");
|
||||
/**
|
||||
* Construct room state.
|
||||
* @constructor
|
||||
* @param {string} roomId Required. The ID of the room which has this state.
|
||||
* @prop {Object.<string, RoomMember>} members The room member dictionary, keyed
|
||||
* on the user's ID.
|
||||
* @prop {Object.<string, Object.<string, MatrixEvent>>} stateEvents The state
|
||||
* events dictionary, keyed on the event type and then the state_key value.
|
||||
* @prop {string} paginationToken The pagination token for this state.
|
||||
*/
|
||||
function RoomState() {
|
||||
function RoomState(roomId) {
|
||||
this.roomId = roomId;
|
||||
this.members = {
|
||||
// userId: RoomMember
|
||||
};
|
||||
@@ -42,6 +44,24 @@ RoomState.prototype = {
|
||||
}
|
||||
var event = this.stateEvents[eventType][stateKey];
|
||||
return event ? event : null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Add an array of one or more state MatrixEvents, overwriting
|
||||
* any existing state with the same {type, stateKey} tuple.
|
||||
* @param {MatrixEvent[]} stateEvents a list of state events for this room.
|
||||
*/
|
||||
setStateEvents: function(stateEvents) {
|
||||
for (var i = 0; i < stateEvents.length; i++) {
|
||||
var event = stateEvents[i].event;
|
||||
if (event.getRoomId() !== this.roomId) { continue; }
|
||||
if (!event.isState()) { continue; }
|
||||
|
||||
if (this.stateEvents[event.getType()] === undefined) {
|
||||
this.stateEvents[event.getType()] = {};
|
||||
}
|
||||
this.stateEvents[event.getType()][event.getStateKey()] = stateEvents[i];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
27
lib/models/room-summary.js
Normal file
27
lib/models/room-summary.js
Normal file
@@ -0,0 +1,27 @@
|
||||
"use strict";
|
||||
/**
|
||||
* @module models/room-summary
|
||||
*/
|
||||
|
||||
/**
|
||||
* Construct a new Room Summary. A summary can be used for display on a recent
|
||||
* list, without having to load the entire room list into memory.
|
||||
* @constructor
|
||||
* @param {string} roomId Required. The ID of this room.
|
||||
* @param {Object} info Optional. The summary info. Additional keys are supported.
|
||||
* @param {string} info.title The title of the room (e.g. <code>m.room.name</code>)
|
||||
* @param {string} info.desc The description of the room (e.g.
|
||||
* <code>m.room.topic</code>)
|
||||
* @param {Number} info.numMembers The number of joined users.
|
||||
* @param {string[]} info.aliases The list of aliases for this room.
|
||||
* @param {Number} info.timestamp The timestamp for this room.
|
||||
*/
|
||||
function RoomSummary(roomId, info) {
|
||||
this.roomId = roomId;
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
/**
|
||||
* The RoomSummary class.
|
||||
*/
|
||||
module.exports = RoomSummary;
|
||||
@@ -2,11 +2,12 @@
|
||||
/**
|
||||
* @module models/room
|
||||
*/
|
||||
var RoomState = require("./room-state");
|
||||
|
||||
/**
|
||||
* Construct a new Room.
|
||||
* @constructor
|
||||
* @param {string} roomId The ID of this room.
|
||||
* @param {string} roomId Required. The ID of this room.
|
||||
* @prop {string} roomId The ID of this room.
|
||||
* @prop {string} name The human-readable display name for this room.
|
||||
* @prop {Array<MatrixEvent>} timeline The ordered list of message events for
|
||||
@@ -15,14 +16,35 @@
|
||||
* event in the timeline.
|
||||
* @prop {RoomState} currentState The state of the room at the time of the
|
||||
* newest event in the timeline.
|
||||
* @prop {RoomSummary} summary The room summary.
|
||||
*/
|
||||
function Room(roomId) {
|
||||
this.roomId = roomId;
|
||||
this.name = roomId;
|
||||
this.timeline = [];
|
||||
this.oldState = null;
|
||||
this.currentState = null;
|
||||
this.oldState = new RoomState(roomId);
|
||||
this.currentState = new RoomState(roomId);
|
||||
this.summary = null;
|
||||
}
|
||||
Room.prototype = {
|
||||
/**
|
||||
* Add some events to this room's timeline.
|
||||
* @param {MatrixEvent[]} events A list of events to add.
|
||||
* @param {boolean} toStartOfTimeline True to add these events to the start
|
||||
* (oldest) instead of the end (newest) of the timeline. If true, the oldest
|
||||
* event will be the <b>last</b> element of 'events'.
|
||||
*/
|
||||
addEventsToTimeline: function(events, toStartOfTimeline) {
|
||||
for (var i = 0; i < events.length; i++) {
|
||||
if (toStartOfTimeline) {
|
||||
this.timeline.unshift(events[i]);
|
||||
}
|
||||
else {
|
||||
this.timeline.push(events[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The Room class.
|
||||
|
||||
@@ -9,132 +9,36 @@
|
||||
* @constructor
|
||||
*/
|
||||
module.exports.MatrixInMemoryStore = function MatrixInMemoryStore() {
|
||||
this.rooms = {
|
||||
// state: { },
|
||||
// timeline: [ ],
|
||||
};
|
||||
|
||||
this.presence = {
|
||||
// presence objects keyed by userId
|
||||
};
|
||||
};
|
||||
|
||||
// XXX: this is currently quite procedural - we could possibly pass back
|
||||
// models of Rooms, Users, Events, etc instead.
|
||||
module.exports.MatrixInMemoryStore.prototype = {
|
||||
|
||||
/*
|
||||
* Add an array of one or more state MatrixEvents into the store, overwriting
|
||||
* any existing state with the same {room, type, stateKey} tuple.
|
||||
/**
|
||||
* Store the given room.
|
||||
* @param {Room} room The room to be stored. All properties must be stored.
|
||||
*/
|
||||
setStateEvents: function(stateEvents) {
|
||||
// we store stateEvents indexed by room, event type and state key.
|
||||
for (var i = 0; i < stateEvents.length; i++) {
|
||||
var event = stateEvents[i].event;
|
||||
var roomId = event.room_id;
|
||||
if (this.rooms[roomId] === undefined) {
|
||||
this.rooms[roomId] = {};
|
||||
}
|
||||
if (this.rooms[roomId].state === undefined) {
|
||||
this.rooms[roomId].state = {};
|
||||
}
|
||||
if (this.rooms[roomId].state[event.type] === undefined) {
|
||||
this.rooms[roomId].state[event.type] = {};
|
||||
}
|
||||
this.rooms[roomId].state[event.type][event.state_key] = stateEvents[i];
|
||||
}
|
||||
storeRoom: function(room) {
|
||||
|
||||
},
|
||||
|
||||
/*
|
||||
* Add a single state MatrixEvents into the store, overwriting
|
||||
* any existing state with the same {room, type, stateKey} tuple.
|
||||
/**
|
||||
* Retrieve a room by its' room ID.
|
||||
* @param {string} roomId The room ID.
|
||||
* @return {Room} The room or null.
|
||||
*/
|
||||
setStateEvent: function(stateEvent) {
|
||||
this.setStateEvents([stateEvent]);
|
||||
getRoom: function(roomId) {
|
||||
return null;
|
||||
},
|
||||
|
||||
/*
|
||||
* Return a list of MatrixEvents from the store
|
||||
* @param {String} roomId the Room ID whose state is to be returned
|
||||
* @param {String} type the type of the state events to be returned (optional)
|
||||
* @param {String} stateKey the stateKey of the state events to be returned
|
||||
* (optional, requires type to be specified)
|
||||
* @return {MatrixEvent[]} an array of MatrixEvents from the store,
|
||||
* filtered by roomid, type and state key.
|
||||
/**
|
||||
* Retrieve a summary of all the rooms.
|
||||
* @return {RoomSummary[]} A summary of each room.
|
||||
*/
|
||||
getStateEvents: function(roomId, type, stateKey) {
|
||||
var stateEvents = [];
|
||||
if (stateKey === undefined && type === undefined) {
|
||||
for (type in this.rooms[roomId].state) {
|
||||
if (this.rooms[roomId].state.hasOwnProperty(type)) {
|
||||
for (stateKey in this.rooms[roomId].state[type]) {
|
||||
if (this.rooms[roomId].state[type].hasOwnProperty(stateKey)) {
|
||||
stateEvents.push(
|
||||
this.rooms[roomId].state[type][stateKey]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return stateEvents;
|
||||
}
|
||||
else if (stateKey === undefined) {
|
||||
for (stateKey in this.rooms[roomId].state[type]) {
|
||||
if (this.rooms[roomId].state[type].hasOwnProperty(stateKey)) {
|
||||
stateEvents.push(this.rooms[roomId].state[type][stateKey]);
|
||||
}
|
||||
}
|
||||
return stateEvents;
|
||||
}
|
||||
else {
|
||||
return [this.rooms[roomId].state[type][stateKey]];
|
||||
}
|
||||
},
|
||||
|
||||
/*
|
||||
* Return a single state MatrixEvent from the store for the given roomId
|
||||
* and type.
|
||||
* @param {String} roomId the Room ID whose state is to be returned
|
||||
* @param {String} type the type of the state events to be returned
|
||||
* @param {String} stateKey the stateKey of the state events to be returned
|
||||
* @return {MatrixEvent} a single MatrixEvent from the store, filtered
|
||||
* by roomid, type and state key.
|
||||
*/
|
||||
getStateEvent: function(roomId, type, stateKey) {
|
||||
return this.rooms[roomId].state[type][stateKey];
|
||||
},
|
||||
|
||||
/*
|
||||
* Adds a list of arbitrary MatrixEvents into the store.
|
||||
* If the event is a state event, it is also updates state.
|
||||
*/
|
||||
setEvents: function(events) {
|
||||
for (var i = 0; i < events.length; i++) {
|
||||
var event = events[i].event;
|
||||
if (event.type === "m.presence") {
|
||||
this.setPresenceEvents([events[i]]);
|
||||
continue;
|
||||
}
|
||||
var roomId = event.room_id;
|
||||
if (this.rooms[roomId] === undefined) {
|
||||
this.rooms[roomId] = {};
|
||||
}
|
||||
if (this.rooms[roomId].timeline === undefined) {
|
||||
this.rooms[roomId].timeline = [];
|
||||
}
|
||||
if (event.state_key !== undefined) {
|
||||
this.setStateEvents([events[i]]);
|
||||
}
|
||||
this.rooms[roomId].timeline.push(events[i]);
|
||||
}
|
||||
},
|
||||
|
||||
/*
|
||||
* Get the timeline of events for a given room
|
||||
* TODO: ordering!
|
||||
*/
|
||||
getEvents: function(roomId) {
|
||||
return this.rooms[roomId].timeline;
|
||||
getRoomSummaries: function() {
|
||||
return [];
|
||||
},
|
||||
|
||||
setPresenceEvents: function(presenceEvents) {
|
||||
@@ -146,16 +50,6 @@ module.exports.MatrixInMemoryStore.prototype = {
|
||||
|
||||
getPresenceEvents: function(userId) {
|
||||
return this.presence[userId];
|
||||
},
|
||||
|
||||
getRoomList: function() {
|
||||
var roomIds = [];
|
||||
for (var roomId in this.rooms) {
|
||||
if (this.rooms.hasOwnProperty(roomId)) {
|
||||
roomIds.push(roomId);
|
||||
}
|
||||
}
|
||||
return roomIds;
|
||||
}
|
||||
|
||||
// TODO
|
||||
|
||||
Reference in New Issue
Block a user