Prevent mutations of js-sdk owned objects as it breaks accountData (#7504)
This commit is contained in:
parent
3c70aa15d1
commit
8c20bcfe56
4 changed files with 23 additions and 25 deletions
|
@ -15,6 +15,7 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Room } from "matrix-js-sdk/src/models/room";
|
import { Room } from "matrix-js-sdk/src/models/room";
|
||||||
|
import { EventType } from "matrix-js-sdk/src/@types/event";
|
||||||
|
|
||||||
import { MatrixClientPeg } from './MatrixClientPeg';
|
import { MatrixClientPeg } from './MatrixClientPeg';
|
||||||
import AliasCustomisations from './customisations/Alias';
|
import AliasCustomisations from './customisations/Alias';
|
||||||
|
@ -90,10 +91,10 @@ export function guessAndSetDMRoom(room: Room, isDirect: boolean): Promise<void>
|
||||||
export async function setDMRoom(roomId: string, userId: string): Promise<void> {
|
export async function setDMRoom(roomId: string, userId: string): Promise<void> {
|
||||||
if (MatrixClientPeg.get().isGuest()) return;
|
if (MatrixClientPeg.get().isGuest()) return;
|
||||||
|
|
||||||
const mDirectEvent = MatrixClientPeg.get().getAccountData('m.direct');
|
const mDirectEvent = MatrixClientPeg.get().getAccountData(EventType.Direct);
|
||||||
let dmRoomMap = {};
|
let dmRoomMap = {};
|
||||||
|
|
||||||
if (mDirectEvent !== undefined) dmRoomMap = mDirectEvent.getContent();
|
if (mDirectEvent !== undefined) dmRoomMap = { ...mDirectEvent.getContent() }; // copy as we will mutate
|
||||||
|
|
||||||
// remove it from the lists of any others users
|
// remove it from the lists of any others users
|
||||||
// (it can only be a DM room for one person)
|
// (it can only be a DM room for one person)
|
||||||
|
@ -117,7 +118,7 @@ export async function setDMRoom(roomId: string, userId: string): Promise<void> {
|
||||||
dmRoomMap[userId] = roomList;
|
dmRoomMap[userId] = roomList;
|
||||||
}
|
}
|
||||||
|
|
||||||
await MatrixClientPeg.get().setAccountData('m.direct', dmRoomMap);
|
await MatrixClientPeg.get().setAccountData(EventType.Direct, dmRoomMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -15,7 +15,7 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { ComponentType, createRef } from 'react';
|
import React, { ComponentType, createRef } from 'react';
|
||||||
import { createClient, MatrixClient } from 'matrix-js-sdk/src/matrix';
|
import { createClient, EventType, MatrixClient } from 'matrix-js-sdk/src/matrix';
|
||||||
import { ISyncStateData, SyncState } from 'matrix-js-sdk/src/sync';
|
import { ISyncStateData, SyncState } from 'matrix-js-sdk/src/sync';
|
||||||
import { MatrixError } from 'matrix-js-sdk/src/http-api';
|
import { MatrixError } from 'matrix-js-sdk/src/http-api';
|
||||||
import { InvalidStoreError } from "matrix-js-sdk/src/errors";
|
import { InvalidStoreError } from "matrix-js-sdk/src/errors";
|
||||||
|
@ -1297,16 +1297,10 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
|
||||||
// run without the update to m.direct, making another welcome
|
// run without the update to m.direct, making another welcome
|
||||||
// user room (it doesn't wait for new data from the server, just
|
// user room (it doesn't wait for new data from the server, just
|
||||||
// the saved sync to be loaded).
|
// the saved sync to be loaded).
|
||||||
const saveWelcomeUser = (ev) => {
|
const saveWelcomeUser = (ev: MatrixEvent) => {
|
||||||
if (
|
if (ev.getType() === EventType.Direct && ev.getContent()[this.props.config.welcomeUserId]) {
|
||||||
ev.getType() === 'm.direct' &&
|
|
||||||
ev.getContent() &&
|
|
||||||
ev.getContent()[this.props.config.welcomeUserId]
|
|
||||||
) {
|
|
||||||
MatrixClientPeg.get().store.save(true);
|
MatrixClientPeg.get().store.save(true);
|
||||||
MatrixClientPeg.get().removeListener(
|
MatrixClientPeg.get().removeListener("accountData", saveWelcomeUser);
|
||||||
"accountData", saveWelcomeUser,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
MatrixClientPeg.get().on("accountData", saveWelcomeUser);
|
MatrixClientPeg.get().on("accountData", saveWelcomeUser);
|
||||||
|
|
|
@ -18,6 +18,7 @@ import { MatrixClient } from "matrix-js-sdk/src/client";
|
||||||
import { Room } from "matrix-js-sdk/src/models/room";
|
import { Room } from "matrix-js-sdk/src/models/room";
|
||||||
import { isNullOrUndefined } from "matrix-js-sdk/src/utils";
|
import { isNullOrUndefined } from "matrix-js-sdk/src/utils";
|
||||||
import { logger } from "matrix-js-sdk/src/logger";
|
import { logger } from "matrix-js-sdk/src/logger";
|
||||||
|
import { EventType } from "matrix-js-sdk/src/@types/event";
|
||||||
|
|
||||||
import SettingsStore from "../../settings/SettingsStore";
|
import SettingsStore from "../../settings/SettingsStore";
|
||||||
import { DefaultTagID, isCustomTag, OrderedDefaultTagIDs, RoomUpdateCause, TagID } from "./models";
|
import { DefaultTagID, isCustomTag, OrderedDefaultTagIDs, RoomUpdateCause, TagID } from "./models";
|
||||||
|
@ -281,7 +282,7 @@ export class RoomListStoreClass extends AsyncStoreWithClient<IState> {
|
||||||
}
|
}
|
||||||
await this.handleRoomUpdate(room, RoomUpdateCause.Timeline);
|
await this.handleRoomUpdate(room, RoomUpdateCause.Timeline);
|
||||||
this.updateFn.trigger();
|
this.updateFn.trigger();
|
||||||
} else if (payload.action === 'MatrixActions.accountData' && payload.event_type === 'm.direct') {
|
} else if (payload.action === 'MatrixActions.accountData' && payload.event_type === EventType.Direct) {
|
||||||
const eventPayload = (<any>payload); // TODO: Type out the dispatcher types
|
const eventPayload = (<any>payload); // TODO: Type out the dispatcher types
|
||||||
const dmMap = eventPayload.event.getContent();
|
const dmMap = eventPayload.event.getContent();
|
||||||
for (const userId of Object.keys(dmMap)) {
|
for (const userId of Object.keys(dmMap)) {
|
||||||
|
|
|
@ -18,6 +18,8 @@ import { uniq } from "lodash";
|
||||||
import { Room } from "matrix-js-sdk/src/models/room";
|
import { Room } from "matrix-js-sdk/src/models/room";
|
||||||
import { MatrixClient } from "matrix-js-sdk/src/client";
|
import { MatrixClient } from "matrix-js-sdk/src/client";
|
||||||
import { logger } from "matrix-js-sdk/src/logger";
|
import { logger } from "matrix-js-sdk/src/logger";
|
||||||
|
import { EventType } from "matrix-js-sdk/src/@types/event";
|
||||||
|
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
|
||||||
|
|
||||||
import { MatrixClientPeg } from '../MatrixClientPeg';
|
import { MatrixClientPeg } from '../MatrixClientPeg';
|
||||||
|
|
||||||
|
@ -35,14 +37,14 @@ export default class DMRoomMap {
|
||||||
private roomToUser: {[key: string]: string} = null;
|
private roomToUser: {[key: string]: string} = null;
|
||||||
private userToRooms: {[key: string]: string[]} = null;
|
private userToRooms: {[key: string]: string[]} = null;
|
||||||
private hasSentOutPatchDirectAccountDataPatch: boolean;
|
private hasSentOutPatchDirectAccountDataPatch: boolean;
|
||||||
private mDirectEvent: object;
|
private mDirectEvent: {[key: string]: string[]};
|
||||||
|
|
||||||
constructor(private readonly matrixClient: MatrixClient) {
|
constructor(private readonly matrixClient: MatrixClient) {
|
||||||
// see onAccountData
|
// see onAccountData
|
||||||
this.hasSentOutPatchDirectAccountDataPatch = false;
|
this.hasSentOutPatchDirectAccountDataPatch = false;
|
||||||
|
|
||||||
const mDirectEvent = matrixClient.getAccountData('m.direct');
|
const mDirectEvent = matrixClient.getAccountData(EventType.Direct)?.getContent() ?? {};
|
||||||
this.mDirectEvent = mDirectEvent ? mDirectEvent.getContent() : {};
|
this.mDirectEvent = { ...mDirectEvent }; // copy as we will mutate
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -81,9 +83,9 @@ export default class DMRoomMap {
|
||||||
this.matrixClient.removeListener("accountData", this.onAccountData);
|
this.matrixClient.removeListener("accountData", this.onAccountData);
|
||||||
}
|
}
|
||||||
|
|
||||||
private onAccountData = (ev) => {
|
private onAccountData = (ev: MatrixEvent) => {
|
||||||
if (ev.getType() == 'm.direct') {
|
if (ev.getType() == EventType.Direct) {
|
||||||
this.mDirectEvent = this.matrixClient.getAccountData('m.direct').getContent() || {};
|
this.mDirectEvent = { ...ev.getContent() }; // copy as we will mutate
|
||||||
this.userToRooms = null;
|
this.userToRooms = null;
|
||||||
this.roomToUser = null;
|
this.roomToUser = null;
|
||||||
}
|
}
|
||||||
|
@ -94,7 +96,7 @@ export default class DMRoomMap {
|
||||||
* with ourself, not the other user. Fix it by guessing the other user and
|
* with ourself, not the other user. Fix it by guessing the other user and
|
||||||
* modifying userToRooms
|
* modifying userToRooms
|
||||||
*/
|
*/
|
||||||
private patchUpSelfDMs(userToRooms) {
|
private patchUpSelfDMs(userToRooms: Record<string, string[]>) {
|
||||||
const myUserId = this.matrixClient.getUserId();
|
const myUserId = this.matrixClient.getUserId();
|
||||||
const selfRoomIds = userToRooms[myUserId];
|
const selfRoomIds = userToRooms[myUserId];
|
||||||
if (selfRoomIds) {
|
if (selfRoomIds) {
|
||||||
|
@ -130,7 +132,7 @@ export default class DMRoomMap {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public getDMRoomsForUserId(userId): string[] {
|
public getDMRoomsForUserId(userId: string): string[] {
|
||||||
// Here, we return the empty list if there are no rooms,
|
// Here, we return the empty list if there are no rooms,
|
||||||
// since the number of conversations you have with this user is zero.
|
// since the number of conversations you have with this user is zero.
|
||||||
return this.getUserToRooms()[userId] || [];
|
return this.getUserToRooms()[userId] || [];
|
||||||
|
@ -189,10 +191,10 @@ export default class DMRoomMap {
|
||||||
|
|
||||||
private getUserToRooms(): {[key: string]: string[]} {
|
private getUserToRooms(): {[key: string]: string[]} {
|
||||||
if (!this.userToRooms) {
|
if (!this.userToRooms) {
|
||||||
const userToRooms = this.mDirectEvent as {[key: string]: string[]};
|
const userToRooms = this.mDirectEvent;
|
||||||
const myUserId = this.matrixClient.getUserId();
|
const myUserId = this.matrixClient.getUserId();
|
||||||
const selfDMs = userToRooms[myUserId];
|
const selfDMs = userToRooms[myUserId];
|
||||||
if (selfDMs && selfDMs.length) {
|
if (selfDMs?.length) {
|
||||||
const neededPatching = this.patchUpSelfDMs(userToRooms);
|
const neededPatching = this.patchUpSelfDMs(userToRooms);
|
||||||
// to avoid multiple devices fighting to correct
|
// to avoid multiple devices fighting to correct
|
||||||
// the account data, only try to send the corrected
|
// the account data, only try to send the corrected
|
||||||
|
@ -201,7 +203,7 @@ export default class DMRoomMap {
|
||||||
`(self-chats that shouldn't be), patching it up.`);
|
`(self-chats that shouldn't be), patching it up.`);
|
||||||
if (neededPatching && !this.hasSentOutPatchDirectAccountDataPatch) {
|
if (neededPatching && !this.hasSentOutPatchDirectAccountDataPatch) {
|
||||||
this.hasSentOutPatchDirectAccountDataPatch = true;
|
this.hasSentOutPatchDirectAccountDataPatch = true;
|
||||||
this.matrixClient.setAccountData('m.direct', userToRooms);
|
this.matrixClient.setAccountData(EventType.Direct, userToRooms);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.userToRooms = userToRooms;
|
this.userToRooms = userToRooms;
|
||||||
|
|
Loading…
Reference in a new issue