mirror of https://github.com/vector-im/riot-web
Ensure RoomListStore2 gets reset when the client becomes invalidated
Fixes https://github.com/vector-im/riot-web/issues/14384 We also make use of the new AsyncStore type to handle this more safely.pull/21833/head
parent
1f57b85b30
commit
a8829f09d0
|
@ -33,6 +33,7 @@ import { EffectiveMembership, getEffectiveMembership } from "./membership";
|
||||||
import { isNullOrUndefined } from "matrix-js-sdk/src/utils";
|
import { isNullOrUndefined } from "matrix-js-sdk/src/utils";
|
||||||
import RoomListLayoutStore from "./RoomListLayoutStore";
|
import RoomListLayoutStore from "./RoomListLayoutStore";
|
||||||
import { MarkedExecution } from "../../utils/MarkedExecution";
|
import { MarkedExecution } from "../../utils/MarkedExecution";
|
||||||
|
import { AsyncStoreWithClient } from "../AsyncStoreWithClient";
|
||||||
|
|
||||||
interface IState {
|
interface IState {
|
||||||
tagsEnabled?: boolean;
|
tagsEnabled?: boolean;
|
||||||
|
@ -44,14 +45,13 @@ interface IState {
|
||||||
*/
|
*/
|
||||||
export const LISTS_UPDATE_EVENT = "lists_update";
|
export const LISTS_UPDATE_EVENT = "lists_update";
|
||||||
|
|
||||||
export class RoomListStore2 extends AsyncStore<ActionPayload> {
|
export class RoomListStore2 extends AsyncStoreWithClient<ActionPayload> {
|
||||||
/**
|
/**
|
||||||
* Set to true if you're running tests on the store. Should not be touched in
|
* Set to true if you're running tests on the store. Should not be touched in
|
||||||
* any other environment.
|
* any other environment.
|
||||||
*/
|
*/
|
||||||
public static TEST_MODE = false;
|
public static TEST_MODE = false;
|
||||||
|
|
||||||
private _matrixClient: MatrixClient;
|
|
||||||
private initialListsGenerated = false;
|
private initialListsGenerated = false;
|
||||||
private enabled = false;
|
private enabled = false;
|
||||||
private algorithm = new Algorithm();
|
private algorithm = new Algorithm();
|
||||||
|
@ -78,33 +78,30 @@ export class RoomListStore2 extends AsyncStore<ActionPayload> {
|
||||||
return this.algorithm.getOrderedRooms();
|
return this.algorithm.getOrderedRooms();
|
||||||
}
|
}
|
||||||
|
|
||||||
public get matrixClient(): MatrixClient {
|
|
||||||
return this._matrixClient;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Intended for test usage
|
// Intended for test usage
|
||||||
public async resetStore() {
|
public async resetStore() {
|
||||||
await this.reset();
|
await this.reset();
|
||||||
this.tagWatcher = new TagWatcher(this);
|
this.tagWatcher = new TagWatcher(this);
|
||||||
this.filterConditions = [];
|
this.filterConditions = [];
|
||||||
this.initialListsGenerated = false;
|
this.initialListsGenerated = false;
|
||||||
this._matrixClient = null;
|
|
||||||
|
|
||||||
this.algorithm.off(LIST_UPDATED_EVENT, this.onAlgorithmListUpdated);
|
this.algorithm.off(LIST_UPDATED_EVENT, this.onAlgorithmListUpdated);
|
||||||
this.algorithm.off(FILTER_CHANGED, this.onAlgorithmListUpdated);
|
this.algorithm.off(FILTER_CHANGED, this.onAlgorithmListUpdated);
|
||||||
this.algorithm = new Algorithm();
|
this.algorithm = new Algorithm();
|
||||||
this.algorithm.on(LIST_UPDATED_EVENT, this.onAlgorithmListUpdated);
|
this.algorithm.on(LIST_UPDATED_EVENT, this.onAlgorithmListUpdated);
|
||||||
this.algorithm.on(FILTER_CHANGED, this.onAlgorithmListUpdated);
|
this.algorithm.on(FILTER_CHANGED, this.onAlgorithmListUpdated);
|
||||||
|
|
||||||
|
// Reset state without causing updates as the client will have been destroyed
|
||||||
|
// and downstream code will throw NPE errors.
|
||||||
|
await this.reset(null, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Public for test usage. Do not call this.
|
// Public for test usage. Do not call this.
|
||||||
public async makeReady(client: MatrixClient) {
|
public async makeReady() {
|
||||||
// TODO: Remove with https://github.com/vector-im/riot-web/issues/14367
|
// TODO: Remove with https://github.com/vector-im/riot-web/issues/14367
|
||||||
this.checkEnabled();
|
this.checkEnabled();
|
||||||
if (!this.enabled) return;
|
if (!this.enabled) return;
|
||||||
|
|
||||||
this._matrixClient = client;
|
|
||||||
|
|
||||||
// Update any settings here, as some may have happened before we were logically ready.
|
// Update any settings here, as some may have happened before we were logically ready.
|
||||||
// Update any settings here, as some may have happened before we were logically ready.
|
// Update any settings here, as some may have happened before we were logically ready.
|
||||||
console.log("Regenerating room lists: Startup");
|
console.log("Regenerating room lists: Startup");
|
||||||
|
@ -161,7 +158,15 @@ export class RoomListStore2 extends AsyncStore<ActionPayload> {
|
||||||
if (trigger) this.updateFn.trigger();
|
if (trigger) this.updateFn.trigger();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async onDispatch(payload: ActionPayload) {
|
protected async onReady(): Promise<any> {
|
||||||
|
await this.makeReady();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected async onNotReady(): Promise<any> {
|
||||||
|
await this.resetStore();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected async onAction(payload: ActionPayload) {
|
||||||
// When we're running tests we can't reliably use setImmediate out of timing concerns.
|
// When we're running tests we can't reliably use setImmediate out of timing concerns.
|
||||||
// As such, we use a more synchronous model.
|
// As such, we use a more synchronous model.
|
||||||
if (RoomListStore2.TEST_MODE) {
|
if (RoomListStore2.TEST_MODE) {
|
||||||
|
@ -175,29 +180,10 @@ export class RoomListStore2 extends AsyncStore<ActionPayload> {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async onDispatchAsync(payload: ActionPayload) {
|
protected async onDispatchAsync(payload: ActionPayload) {
|
||||||
if (payload.action === 'MatrixActions.sync') {
|
|
||||||
// Filter out anything that isn't the first PREPARED sync.
|
|
||||||
if (!(payload.prevState === 'PREPARED' && payload.state !== 'PREPARED')) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
await this.makeReady(payload.matrixClient);
|
|
||||||
|
|
||||||
return; // no point in running the next conditions - they won't match
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Remove this once the RoomListStore becomes default
|
// TODO: Remove this once the RoomListStore becomes default
|
||||||
if (!this.enabled) return;
|
if (!this.enabled) return;
|
||||||
|
|
||||||
if (payload.action === 'on_client_not_viable' || payload.action === 'on_logged_out') {
|
// Everything here requires a MatrixClient or some sort of logical readiness.
|
||||||
// Reset state without causing updates as the client will have been destroyed
|
|
||||||
// and downstream code will throw NPE errors.
|
|
||||||
await this.reset(null, true);
|
|
||||||
this._matrixClient = null;
|
|
||||||
this.initialListsGenerated = false; // we'll want to regenerate them
|
|
||||||
}
|
|
||||||
|
|
||||||
// Everything below here requires a MatrixClient or some sort of logical readiness.
|
|
||||||
const logicallyReady = this.matrixClient && this.initialListsGenerated;
|
const logicallyReady = this.matrixClient && this.initialListsGenerated;
|
||||||
if (!logicallyReady) return;
|
if (!logicallyReady) return;
|
||||||
|
|
||||||
|
|
|
@ -109,7 +109,7 @@ describe('RoomList', () => {
|
||||||
client.getRoom = (roomId) => roomMap[roomId];
|
client.getRoom = (roomId) => roomMap[roomId];
|
||||||
|
|
||||||
// Now that everything has been set up, prepare and update the store
|
// Now that everything has been set up, prepare and update the store
|
||||||
await RoomListStore.instance.makeReady(client);
|
await RoomListStore.instance.makeReady();
|
||||||
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue