1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-11-28 05:03:59 +03:00

prototype how we could store ll members

This commit is contained in:
Bruno Windels
2018-07-18 17:10:23 +02:00
parent ca3981fba8
commit d366ec9c48
5 changed files with 96 additions and 8 deletions

View File

@@ -757,6 +757,20 @@ MatrixClient.prototype.getRoom = function(roomId) {
return this.store.getRoom(roomId);
};
MatrixClient.prototype._loadMembers = async function(room) {
const roomId = room.roomId;
let rawMembersEvents = await this.store.getOutOfBandMembers(roomId);
if (rawMembersEvents.length == 0) {
const lastEventId = room.getLastEventId();
const response = await this.members(roomId, "join", "leave", lastEventId);
rawMembersEvents = response.chunk;
// TODO don't block on writing
await this.store.setOutOfBandMembers(roomId, rawMembersEvents);
}
const memberEvents = rawMembersEvents.map(this.getEventMapper());
return memberEvents;
};
/**
* Preloads the member list for the given room id,
* in case lazy loading of memberships is in use.
@@ -767,13 +781,8 @@ MatrixClient.prototype.loadRoomMembersIfNeeded = async function(roomId) {
if (!room || !room.needsOutOfBandMembers()) {
return;
}
const lastEventId = room.getLastEventId();
const responsePromise = this.members(roomId, "join", "leave", lastEventId);
const eventsPromise = responsePromise.then((response) => {
return response.chunk.map(this.getEventMapper());
});
await room.loadOutOfBandMembers(eventsPromise);
const membersPromise = this._loadMembers(room);
await room.loadOutOfBandMembers(membersPromise);
};
/**

View File

@@ -19,7 +19,7 @@ import Promise from 'bluebird';
import SyncAccumulator from "../sync-accumulator";
import utils from "../utils";
const VERSION = 1;
const VERSION = 2;
function createDatabase(db) {
// Make user store, clobber based on user ID. (userId property of User objects)
@@ -33,6 +33,11 @@ function createDatabase(db) {
db.createObjectStore("sync", { keyPath: ["clobber"] });
}
function upgradeSchemaV2(db) {
const llMembersStore = db.createObjectStore("lazy_loaded_members", { keyPath: ["roomId", "userId"]});
llMembersStore.createIndex("room", "roomId");
}
/**
* Helper method to collect results from a Cursor and promiseify it.
* @param {ObjectStore|Index} store The store to perform openCursor on.
@@ -136,6 +141,9 @@ LocalIndexedDBStoreBackend.prototype = {
if (oldVersion < 1) { // The database did not previously exist.
createDatabase(db);
}
if (oldVersion < 2) {
upgradeSchemaV2(db);
}
// Expand as needed.
};
@@ -187,6 +195,56 @@ LocalIndexedDBStoreBackend.prototype = {
});
},
getOutOfBandMembers: function(roomId) {
return new Promise((resolve, reject) =>{
const tx = this.db.transaction(["lazy_loaded_members"], "readonly");
const store = tx.objectStore("lazy_loaded_members");
const roomIndex = store.index("room");
const range = IDBKeyRange.only(roomId);
const request = roomIndex.openCursor(range);
const members = [];
request.onsuccess = (event) => {
const cursor = event.target.result;
if (!cursor) {
return resolve(members);
}
const record = cursor.value;
members.push({
userId: record.userId,
displayName: record.displayName,
membership: record.membership,
avatarUrl: record.avatarUrl,
});
cursor.continue();
};
request.onerror = (err) => {
reject(err);
};
});
},
setOutOfBandMembers: function(roomId, members) {
function ignoreResult() {};
// run everything in a promise so anything that throws will reject
return new Promise((resolve) =>{
const tx = this.db.transaction(["lazy_loaded_members"], "readwrite");
const store = tx.objectStore("lazy_loaded_members");
const puts = members.map((m) => {
const record = {
roomId: roomId,
userId: m.userId,
displayName: m.displayName,
avatarUrl: m.avatarUrl,
membership: m.membership
};
let putPromise = promiseifyRequest(store.put(record));
return putPromise.then(ignoreResult);
});
resolve(Promise.all(puts).then(ignoreResult));
});
},
/**
* Clear the entire database. This should be used when logging out of a client
* to prevent mixing data between accounts.

View File

@@ -87,6 +87,13 @@ RemoteIndexedDBStoreBackend.prototype = {
return this._doCmd('syncToDatabase', [users]);
},
getOutOfBandMembers: function(roomId) {
return this._doCmd('getOutOfBandMembers', [roomId]);
},
setOutOfBandMembers: function(roomId, members) {
return this._doCmd('setOutOfBandMembers', [roomId, members]);
},
/**
* Load all user presence events from the database. This is not cached.

View File

@@ -92,6 +92,12 @@ class IndexedDBStoreWorker {
case 'getNextBatchToken':
prom = this.backend.getNextBatchToken();
break;
case 'getOutOfBandMembers':
prom = this.backend.getOutOfBandMembers(msg.args[0]);
break;
case 'setOutOfBandMembers':
prom = this.backend.setOutOfBandMembers(msg.args[0], msg.args[1]);
break;
}
if (prom === undefined) {

View File

@@ -219,4 +219,12 @@ IndexedDBStore.prototype.setSyncData = function(syncData) {
return this.backend.setSyncData(syncData);
};
IndexedDBStore.prototype.getOutOfBandMembers = function(roomId) {
return this.backend.getOutOfBandMembers(roomId);
};
IndexedDBStore.prototype.setOutOfBandMembers = function(roomId, members) {
return this.backend.setOutOfBandMembers(roomId, members);
};
module.exports.IndexedDBStore = IndexedDBStore;