Handle joins/leaves safely

This commit is contained in:
Travis Ralston 2019-02-13 14:08:19 -07:00
parent 9175655c16
commit b741b76797

View file

@ -154,7 +154,6 @@ class RoomListStore extends Store {
// break; // break;
case 'MatrixActions.Room.myMembership': { case 'MatrixActions.Room.myMembership': {
if (!logicallyReady) break; if (!logicallyReady) break;
// TODO: Slot room into list
this._roomUpdateTriggered(payload.room.roomId); this._roomUpdateTriggered(payload.room.roomId);
} }
break; break;
@ -163,25 +162,25 @@ class RoomListStore extends Store {
// a member. // a member.
case 'MatrixActions.Room': { case 'MatrixActions.Room': {
if (!logicallyReady) break; if (!logicallyReady) break;
// TODO: Slot room into list
this._roomUpdateTriggered(payload.room.roomId); this._roomUpdateTriggered(payload.room.roomId);
} }
break; break;
case 'RoomListActions.tagRoom.pending': { // TODO: Re-enable optimistic updates when we support dragging again
if (!logicallyReady) break; // case 'RoomListActions.tagRoom.pending': {
// XXX: we only show one optimistic update at any one time. // if (!logicallyReady) break;
// Ideally we should be making a list of in-flight requests // // XXX: we only show one optimistic update at any one time.
// that are backed by transaction IDs. Until the js-sdk // // Ideally we should be making a list of in-flight requests
// supports this, we're stuck with only being able to use // // that are backed by transaction IDs. Until the js-sdk
// the most recent optimistic update. // // supports this, we're stuck with only being able to use
console.log("!! Optimistic tag: ", payload); // // the most recent optimistic update.
} // console.log("!! Optimistic tag: ", payload);
break; // }
case 'RoomListActions.tagRoom.failure': { // break;
if (!logicallyReady) break; // case 'RoomListActions.tagRoom.failure': {
// Reset state according to js-sdk // if (!logicallyReady) break;
console.log("!! Optimistic tag failure: ", payload); // // Reset state according to js-sdk
} // console.log("!! Optimistic tag failure: ", payload);
// }
break; break;
case 'on_logged_out': { case 'on_logged_out': {
// Reset state without pushing an update to the view, which generally assumes that // Reset state without pushing an update to the view, which generally assumes that
@ -218,11 +217,18 @@ class RoomListStore extends Store {
const listsClone = {}; const listsClone = {};
const targetCatIndex = CATEGORY_ORDER.indexOf(category); const targetCatIndex = CATEGORY_ORDER.indexOf(category);
const myMembership = room.getMyMembership();
let doInsert = true;
if (myMembership !== "join" && myMembership !== "invite") {
doInsert = false;
}
// We need to update all instances of a room to ensure that they are correctly organized // We need to update all instances of a room to ensure that they are correctly organized
// in the list. We do this by shallow-cloning the entire `lists` object using a single // in the list. We do this by shallow-cloning the entire `lists` object using a single
// iterator. Within the loop, we also rebuild the list of rooms per tag (key) so that the // iterator. Within the loop, we also rebuild the list of rooms per tag (key) so that the
// updated room gets slotted into the right spot. // updated room gets slotted into the right spot.
let inserted = false;
for (const key of Object.keys(this._state.lists)) { for (const key of Object.keys(this._state.lists)) {
listsClone[key] = []; listsClone[key] = [];
let pushedEntry = false; let pushedEntry = false;
@ -231,7 +237,7 @@ class RoomListStore extends Store {
// if the list is a recent list, and the room appears in this list, and we're not looking at a sticky // if the list is a recent list, and the room appears in this list, and we're not looking at a sticky
// room (sticky rooms have unreliable categories), try to slot the new room in // room (sticky rooms have unreliable categories), try to slot the new room in
if (LIST_ORDERS[key] === 'recent' && hasRoom && entry.room.roomId !== this._state.stickyRoomId) { if (LIST_ORDERS[key] === 'recent' && hasRoom && entry.room.roomId !== this._state.stickyRoomId) {
if (!pushedEntry) { if (!pushedEntry && doInsert) {
// If we've hit the top of a boundary (either because there's no rooms in the target or // If we've hit the top of a boundary (either because there's no rooms in the target or
// we've reached the grouping of rooms), insert our room ahead of the others in the category. // we've reached the grouping of rooms), insert our room ahead of the others in the category.
// This ensures that our room is on top (more recent) than the others. // This ensures that our room is on top (more recent) than the others.
@ -239,6 +245,7 @@ class RoomListStore extends Store {
if (changedBoundary) { if (changedBoundary) {
listsClone[key].push({room: room, category: category}); listsClone[key].push({room: room, category: category});
pushedEntry = true; pushedEntry = true;
inserted = true;
} }
} }
@ -253,6 +260,29 @@ class RoomListStore extends Store {
} }
} }
if (!inserted) {
// There's a good chance that we just joined the room, so we need to organize it
// We also could have left it...
let tags = [];
if (doInsert) {
tags = Object.keys(room.tags);
if (tags.length === 0) {
tags.push(myMembership === 'join' ? 'im.vector.fake.recent' : 'im.vector.fake.invite');
}
} else {
tags = ['im.vector.fake.archived'];
}
for (const tag of tags) {
for (let i = 0; i < listsClone[tag].length; i++) {
const catIdxAtPosition = CATEGORY_ORDER.indexOf(listsClone[tag][i].category);
if (catIdxAtPosition >= targetCatIndex) {
listsClone[tag].splice(i, 0, {room: room, category: category});
break;
}
}
}
}
this._setState({lists: listsClone}); this._setState({lists: listsClone});
} }