Merge pull request #6382 from matrix-org/t3chguy/console
commit
ea20e041b1
|
@ -32,7 +32,7 @@ import { MatrixEvent } from "matrix-js-sdk/src/models/event";
|
||||||
// any text to display at all. For this reason they return deferred values
|
// any text to display at all. For this reason they return deferred values
|
||||||
// to avoid the expense of looking up translations when they're not needed.
|
// to avoid the expense of looking up translations when they're not needed.
|
||||||
|
|
||||||
function textForMemberEvent(ev): () => string | null {
|
function textForMemberEvent(ev: MatrixEvent): () => string | null {
|
||||||
// XXX: SYJS-16 "sender is sometimes null for join messages"
|
// XXX: SYJS-16 "sender is sometimes null for join messages"
|
||||||
const senderName = ev.sender ? ev.sender.name : ev.getSender();
|
const senderName = ev.sender ? ev.sender.name : ev.getSender();
|
||||||
const targetName = ev.target ? ev.target.name : ev.getStateKey();
|
const targetName = ev.target ? ev.target.name : ev.getStateKey();
|
||||||
|
@ -127,7 +127,7 @@ function textForMemberEvent(ev): () => string | null {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function textForTopicEvent(ev): () => string | null {
|
function textForTopicEvent(ev: MatrixEvent): () => string | null {
|
||||||
const senderDisplayName = ev.sender && ev.sender.name ? ev.sender.name : ev.getSender();
|
const senderDisplayName = ev.sender && ev.sender.name ? ev.sender.name : ev.getSender();
|
||||||
return () => _t('%(senderDisplayName)s changed the topic to "%(topic)s".', {
|
return () => _t('%(senderDisplayName)s changed the topic to "%(topic)s".', {
|
||||||
senderDisplayName,
|
senderDisplayName,
|
||||||
|
@ -135,7 +135,7 @@ function textForTopicEvent(ev): () => string | null {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function textForRoomNameEvent(ev): () => string | null {
|
function textForRoomNameEvent(ev: MatrixEvent): () => string | null {
|
||||||
const senderDisplayName = ev.sender && ev.sender.name ? ev.sender.name : ev.getSender();
|
const senderDisplayName = ev.sender && ev.sender.name ? ev.sender.name : ev.getSender();
|
||||||
|
|
||||||
if (!ev.getContent().name || ev.getContent().name.trim().length === 0) {
|
if (!ev.getContent().name || ev.getContent().name.trim().length === 0) {
|
||||||
|
@ -154,12 +154,12 @@ function textForRoomNameEvent(ev): () => string | null {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function textForTombstoneEvent(ev): () => string | null {
|
function textForTombstoneEvent(ev: MatrixEvent): () => string | null {
|
||||||
const senderDisplayName = ev.sender && ev.sender.name ? ev.sender.name : ev.getSender();
|
const senderDisplayName = ev.sender && ev.sender.name ? ev.sender.name : ev.getSender();
|
||||||
return () => _t('%(senderDisplayName)s upgraded this room.', { senderDisplayName });
|
return () => _t('%(senderDisplayName)s upgraded this room.', { senderDisplayName });
|
||||||
}
|
}
|
||||||
|
|
||||||
function textForJoinRulesEvent(ev): () => string | null {
|
function textForJoinRulesEvent(ev: MatrixEvent): () => string | null {
|
||||||
const senderDisplayName = ev.sender && ev.sender.name ? ev.sender.name : ev.getSender();
|
const senderDisplayName = ev.sender && ev.sender.name ? ev.sender.name : ev.getSender();
|
||||||
switch (ev.getContent().join_rule) {
|
switch (ev.getContent().join_rule) {
|
||||||
case "public":
|
case "public":
|
||||||
|
@ -179,7 +179,7 @@ function textForJoinRulesEvent(ev): () => string | null {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function textForGuestAccessEvent(ev): () => string | null {
|
function textForGuestAccessEvent(ev: MatrixEvent): () => string | null {
|
||||||
const senderDisplayName = ev.sender && ev.sender.name ? ev.sender.name : ev.getSender();
|
const senderDisplayName = ev.sender && ev.sender.name ? ev.sender.name : ev.getSender();
|
||||||
switch (ev.getContent().guest_access) {
|
switch (ev.getContent().guest_access) {
|
||||||
case "can_join":
|
case "can_join":
|
||||||
|
@ -195,7 +195,7 @@ function textForGuestAccessEvent(ev): () => string | null {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function textForRelatedGroupsEvent(ev): () => string | null {
|
function textForRelatedGroupsEvent(ev: MatrixEvent): () => string | null {
|
||||||
const senderDisplayName = ev.sender && ev.sender.name ? ev.sender.name : ev.getSender();
|
const senderDisplayName = ev.sender && ev.sender.name ? ev.sender.name : ev.getSender();
|
||||||
const groups = ev.getContent().groups || [];
|
const groups = ev.getContent().groups || [];
|
||||||
const prevGroups = ev.getPrevContent().groups || [];
|
const prevGroups = ev.getPrevContent().groups || [];
|
||||||
|
@ -225,7 +225,7 @@ function textForRelatedGroupsEvent(ev): () => string | null {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function textForServerACLEvent(ev): () => string | null {
|
function textForServerACLEvent(ev: MatrixEvent): () => string | null {
|
||||||
const senderDisplayName = ev.sender && ev.sender.name ? ev.sender.name : ev.getSender();
|
const senderDisplayName = ev.sender && ev.sender.name ? ev.sender.name : ev.getSender();
|
||||||
const prevContent = ev.getPrevContent();
|
const prevContent = ev.getPrevContent();
|
||||||
const current = ev.getContent();
|
const current = ev.getContent();
|
||||||
|
@ -255,7 +255,7 @@ function textForServerACLEvent(ev): () => string | null {
|
||||||
return getText;
|
return getText;
|
||||||
}
|
}
|
||||||
|
|
||||||
function textForMessageEvent(ev): () => string | null {
|
function textForMessageEvent(ev: MatrixEvent): () => string | null {
|
||||||
return () => {
|
return () => {
|
||||||
const senderDisplayName = ev.sender && ev.sender.name ? ev.sender.name : ev.getSender();
|
const senderDisplayName = ev.sender && ev.sender.name ? ev.sender.name : ev.getSender();
|
||||||
let message = senderDisplayName + ': ' + ev.getContent().body;
|
let message = senderDisplayName + ': ' + ev.getContent().body;
|
||||||
|
@ -268,7 +268,7 @@ function textForMessageEvent(ev): () => string | null {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function textForCanonicalAliasEvent(ev): () => string | null {
|
function textForCanonicalAliasEvent(ev: MatrixEvent): () => string | null {
|
||||||
const senderName = ev.sender && ev.sender.name ? ev.sender.name : ev.getSender();
|
const senderName = ev.sender && ev.sender.name ? ev.sender.name : ev.getSender();
|
||||||
const oldAlias = ev.getPrevContent().alias;
|
const oldAlias = ev.getPrevContent().alias;
|
||||||
const oldAltAliases = ev.getPrevContent().alt_aliases || [];
|
const oldAltAliases = ev.getPrevContent().alt_aliases || [];
|
||||||
|
@ -682,7 +682,7 @@ for (const evType of ALL_RULE_TYPES) {
|
||||||
stateHandlers[evType] = textForMjolnirEvent;
|
stateHandlers[evType] = textForMjolnirEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function hasText(ev): boolean {
|
export function hasText(ev: MatrixEvent): boolean {
|
||||||
const handler = (ev.isState() ? stateHandlers : handlers)[ev.getType()];
|
const handler = (ev.isState() ? stateHandlers : handlers)[ev.getType()];
|
||||||
return Boolean(handler?.(ev));
|
return Boolean(handler?.(ev));
|
||||||
}
|
}
|
||||||
|
|
|
@ -917,6 +917,7 @@ export default class RoomView extends React.Component<IProps, IState> {
|
||||||
// called when state.room is first initialised (either at initial load,
|
// called when state.room is first initialised (either at initial load,
|
||||||
// after a successful peek, or after we join the room).
|
// after a successful peek, or after we join the room).
|
||||||
private onRoomLoaded = (room: Room) => {
|
private onRoomLoaded = (room: Room) => {
|
||||||
|
if (this.unmounted) return;
|
||||||
// Attach a widget store listener only when we get a room
|
// Attach a widget store listener only when we get a room
|
||||||
WidgetLayoutStore.instance.on(WidgetLayoutStore.emissionForRoom(room), this.onWidgetLayoutChange);
|
WidgetLayoutStore.instance.on(WidgetLayoutStore.emissionForRoom(room), this.onWidgetLayoutChange);
|
||||||
this.onWidgetLayoutChange(); // provoke an update
|
this.onWidgetLayoutChange(); // provoke an update
|
||||||
|
@ -931,9 +932,9 @@ export default class RoomView extends React.Component<IProps, IState> {
|
||||||
};
|
};
|
||||||
|
|
||||||
private async calculateRecommendedVersion(room: Room) {
|
private async calculateRecommendedVersion(room: Room) {
|
||||||
this.setState({
|
const upgradeRecommendation = await room.getRecommendedVersion();
|
||||||
upgradeRecommendation: await room.getRecommendedVersion(),
|
if (this.unmounted) return;
|
||||||
});
|
this.setState({ upgradeRecommendation });
|
||||||
}
|
}
|
||||||
|
|
||||||
private async loadMembersIfJoined(room: Room) {
|
private async loadMembersIfJoined(room: Room) {
|
||||||
|
@ -1023,23 +1024,19 @@ export default class RoomView extends React.Component<IProps, IState> {
|
||||||
};
|
};
|
||||||
|
|
||||||
private async updateE2EStatus(room: Room) {
|
private async updateE2EStatus(room: Room) {
|
||||||
if (!this.context.isRoomEncrypted(room.roomId)) {
|
if (!this.context.isRoomEncrypted(room.roomId)) return;
|
||||||
return;
|
|
||||||
}
|
// If crypto is not currently enabled, we aren't tracking devices at all,
|
||||||
if (!this.context.isCryptoEnabled()) {
|
// so we don't know what the answer is. Let's error on the safe side and show
|
||||||
// If crypto is not currently enabled, we aren't tracking devices at all,
|
// a warning for this case.
|
||||||
// so we don't know what the answer is. Let's error on the safe side and show
|
let e2eStatus = E2EStatus.Warning;
|
||||||
// a warning for this case.
|
if (this.context.isCryptoEnabled()) {
|
||||||
this.setState({
|
/* At this point, the user has encryption on and cross-signing on */
|
||||||
e2eStatus: E2EStatus.Warning,
|
e2eStatus = await shieldStatusForRoom(this.context, room);
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* At this point, the user has encryption on and cross-signing on */
|
if (this.unmounted) return;
|
||||||
this.setState({
|
this.setState({ e2eStatus });
|
||||||
e2eStatus: await shieldStatusForRoom(this.context, room),
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private onAccountData = (event: MatrixEvent) => {
|
private onAccountData = (event: MatrixEvent) => {
|
||||||
|
|
|
@ -1051,6 +1051,8 @@ class TimelinePanel extends React.Component<IProps, IState> {
|
||||||
{ windowLimit: this.props.timelineCap });
|
{ windowLimit: this.props.timelineCap });
|
||||||
|
|
||||||
const onLoaded = () => {
|
const onLoaded = () => {
|
||||||
|
if (this.unmounted) return;
|
||||||
|
|
||||||
// clear the timeline min-height when
|
// clear the timeline min-height when
|
||||||
// (re)loading the timeline
|
// (re)loading the timeline
|
||||||
if (this.messagePanel.current) {
|
if (this.messagePanel.current) {
|
||||||
|
@ -1092,6 +1094,8 @@ class TimelinePanel extends React.Component<IProps, IState> {
|
||||||
};
|
};
|
||||||
|
|
||||||
const onError = (error) => {
|
const onError = (error) => {
|
||||||
|
if (this.unmounted) return;
|
||||||
|
|
||||||
this.setState({ timelineLoading: false });
|
this.setState({ timelineLoading: false });
|
||||||
console.error(
|
console.error(
|
||||||
`Error loading timeline panel at ${eventId}: ${error}`,
|
`Error loading timeline panel at ${eventId}: ${error}`,
|
||||||
|
|
|
@ -15,12 +15,14 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
|
||||||
|
import { MsgType } from "matrix-js-sdk/src/@types/event";
|
||||||
|
|
||||||
import Flair from '../elements/Flair';
|
import Flair from '../elements/Flair';
|
||||||
import FlairStore from '../../../stores/FlairStore';
|
import FlairStore from '../../../stores/FlairStore';
|
||||||
import { getUserNameColorClass } from '../../../utils/FormattingUtils';
|
import { getUserNameColorClass } from '../../../utils/FormattingUtils';
|
||||||
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
||||||
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
||||||
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
|
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
mxEvent: MatrixEvent;
|
mxEvent: MatrixEvent;
|
||||||
|
@ -36,7 +38,7 @@ interface IState {
|
||||||
@replaceableComponent("views.messages.SenderProfile")
|
@replaceableComponent("views.messages.SenderProfile")
|
||||||
export default class SenderProfile extends React.Component<IProps, IState> {
|
export default class SenderProfile extends React.Component<IProps, IState> {
|
||||||
static contextType = MatrixClientContext;
|
static contextType = MatrixClientContext;
|
||||||
private unmounted: boolean;
|
private unmounted = false;
|
||||||
|
|
||||||
constructor(props: IProps) {
|
constructor(props: IProps) {
|
||||||
super(props);
|
super(props);
|
||||||
|
@ -49,8 +51,7 @@ export default class SenderProfile extends React.Component<IProps, IState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.unmounted = false;
|
this.updateRelatedGroups();
|
||||||
this._updateRelatedGroups();
|
|
||||||
|
|
||||||
if (this.state.userGroups.length === 0) {
|
if (this.state.userGroups.length === 0) {
|
||||||
this.getPublicisedGroups();
|
this.getPublicisedGroups();
|
||||||
|
@ -64,35 +65,29 @@ export default class SenderProfile extends React.Component<IProps, IState> {
|
||||||
this.context.removeListener('RoomState.events', this.onRoomStateEvents);
|
this.context.removeListener('RoomState.events', this.onRoomStateEvents);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getPublicisedGroups() {
|
private async getPublicisedGroups() {
|
||||||
if (!this.unmounted) {
|
const userGroups = await FlairStore.getPublicisedGroupsCached(this.context, this.props.mxEvent.getSender());
|
||||||
const userGroups = await FlairStore.getPublicisedGroupsCached(
|
if (this.unmounted) return;
|
||||||
this.context, this.props.mxEvent.getSender(),
|
this.setState({ userGroups });
|
||||||
);
|
|
||||||
this.setState({ userGroups });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onRoomStateEvents = event => {
|
private onRoomStateEvents = (event: MatrixEvent) => {
|
||||||
if (event.getType() === 'm.room.related_groups' &&
|
if (event.getType() === 'm.room.related_groups' && event.getRoomId() === this.props.mxEvent.getRoomId()) {
|
||||||
event.getRoomId() === this.props.mxEvent.getRoomId()
|
this.updateRelatedGroups();
|
||||||
) {
|
|
||||||
this._updateRelatedGroups();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
_updateRelatedGroups() {
|
private updateRelatedGroups() {
|
||||||
if (this.unmounted) return;
|
|
||||||
const room = this.context.getRoom(this.props.mxEvent.getRoomId());
|
const room = this.context.getRoom(this.props.mxEvent.getRoomId());
|
||||||
if (!room) return;
|
if (!room) return;
|
||||||
|
|
||||||
const relatedGroupsEvent = room.currentState.getStateEvents('m.room.related_groups', '');
|
const relatedGroupsEvent = room.currentState.getStateEvents('m.room.related_groups', '');
|
||||||
this.setState({
|
this.setState({
|
||||||
relatedGroups: relatedGroupsEvent ? relatedGroupsEvent.getContent().groups || [] : [],
|
relatedGroups: relatedGroupsEvent?.getContent().groups || [],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_getDisplayedGroups(userGroups, relatedGroups) {
|
private getDisplayedGroups(userGroups?: string[], relatedGroups?: string[]) {
|
||||||
let displayedGroups = userGroups || [];
|
let displayedGroups = userGroups || [];
|
||||||
if (relatedGroups && relatedGroups.length > 0) {
|
if (relatedGroups && relatedGroups.length > 0) {
|
||||||
displayedGroups = relatedGroups.filter((groupId) => {
|
displayedGroups = relatedGroups.filter((groupId) => {
|
||||||
|
@ -113,7 +108,7 @@ export default class SenderProfile extends React.Component<IProps, IState> {
|
||||||
const displayName = mxEvent.sender?.rawDisplayName || mxEvent.getSender() || "";
|
const displayName = mxEvent.sender?.rawDisplayName || mxEvent.getSender() || "";
|
||||||
const mxid = mxEvent.sender?.userId || mxEvent.getSender() || "";
|
const mxid = mxEvent.sender?.userId || mxEvent.getSender() || "";
|
||||||
|
|
||||||
if (msgtype === 'm.emote') {
|
if (msgtype === MsgType.Emote) {
|
||||||
return null; // emote message must include the name so don't duplicate it
|
return null; // emote message must include the name so don't duplicate it
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,7 +123,7 @@ export default class SenderProfile extends React.Component<IProps, IState> {
|
||||||
|
|
||||||
let flair;
|
let flair;
|
||||||
if (this.props.enableFlair) {
|
if (this.props.enableFlair) {
|
||||||
const displayedGroups = this._getDisplayedGroups(
|
const displayedGroups = this.getDisplayedGroups(
|
||||||
this.state.userGroups, this.state.relatedGroups,
|
this.state.userGroups, this.state.relatedGroups,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -1152,11 +1152,11 @@ export default class EventTile extends React.Component<IProps, IState> {
|
||||||
"aria-live": ariaLive,
|
"aria-live": ariaLive,
|
||||||
"aria-atomic": true,
|
"aria-atomic": true,
|
||||||
"data-scroll-tokens": scrollToken,
|
"data-scroll-tokens": scrollToken,
|
||||||
}, [
|
}, <>
|
||||||
ircTimestamp,
|
{ ircTimestamp }
|
||||||
avatar,
|
{ avatar }
|
||||||
sender,
|
{ sender }
|
||||||
ircPadlock,
|
{ ircPadlock }
|
||||||
<div className="mx_EventTile_reply" key="mx_EventTile_reply">
|
<div className="mx_EventTile_reply" key="mx_EventTile_reply">
|
||||||
{ groupTimestamp }
|
{ groupTimestamp }
|
||||||
{ groupPadlock }
|
{ groupPadlock }
|
||||||
|
@ -1169,8 +1169,8 @@ export default class EventTile extends React.Component<IProps, IState> {
|
||||||
replacingEventId={this.props.replacingEventId}
|
replacingEventId={this.props.replacingEventId}
|
||||||
showUrlPreview={false}
|
showUrlPreview={false}
|
||||||
/>
|
/>
|
||||||
</div>,
|
</div>
|
||||||
]);
|
</>);
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
const thread = ReplyThread.makeThread(
|
const thread = ReplyThread.makeThread(
|
||||||
|
@ -1193,10 +1193,10 @@ export default class EventTile extends React.Component<IProps, IState> {
|
||||||
"data-scroll-tokens": scrollToken,
|
"data-scroll-tokens": scrollToken,
|
||||||
"onMouseEnter": () => this.setState({ hover: true }),
|
"onMouseEnter": () => this.setState({ hover: true }),
|
||||||
"onMouseLeave": () => this.setState({ hover: false }),
|
"onMouseLeave": () => this.setState({ hover: false }),
|
||||||
}, [
|
}, <>
|
||||||
ircTimestamp,
|
{ ircTimestamp }
|
||||||
sender,
|
{ sender }
|
||||||
ircPadlock,
|
{ ircPadlock }
|
||||||
<div className="mx_EventTile_line" key="mx_EventTile_line">
|
<div className="mx_EventTile_line" key="mx_EventTile_line">
|
||||||
{ groupTimestamp }
|
{ groupTimestamp }
|
||||||
{ groupPadlock }
|
{ groupPadlock }
|
||||||
|
@ -1214,11 +1214,10 @@ export default class EventTile extends React.Component<IProps, IState> {
|
||||||
{ keyRequestInfo }
|
{ keyRequestInfo }
|
||||||
{ reactionsRow }
|
{ reactionsRow }
|
||||||
{ actionBar }
|
{ actionBar }
|
||||||
</div>,
|
</div>
|
||||||
msgOption,
|
{ msgOption }
|
||||||
avatar,
|
{ avatar }
|
||||||
|
</>)
|
||||||
])
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,10 +40,12 @@ const LinkPreviewGroup: React.FC<IProps> = ({ links, mxEvent, onCancelClick, onH
|
||||||
|
|
||||||
const ts = mxEvent.getTs();
|
const ts = mxEvent.getTs();
|
||||||
const previews = useAsyncMemo<[string, IPreviewUrlResponse][]>(async () => {
|
const previews = useAsyncMemo<[string, IPreviewUrlResponse][]>(async () => {
|
||||||
return Promise.all<[string, IPreviewUrlResponse] | void>(links.map(link => {
|
return Promise.all<[string, IPreviewUrlResponse] | void>(links.map(async link => {
|
||||||
return cli.getUrlPreview(link, ts).then(preview => [link, preview], error => {
|
try {
|
||||||
|
return [link, await cli.getUrlPreview(link, ts)];
|
||||||
|
} catch (error) {
|
||||||
console.error("Failed to get URL preview: " + error);
|
console.error("Failed to get URL preview: " + error);
|
||||||
});
|
}
|
||||||
})).then(a => a.filter(Boolean)) as Promise<[string, IPreviewUrlResponse][]>;
|
})).then(a => a.filter(Boolean)) as Promise<[string, IPreviewUrlResponse][]>;
|
||||||
}, [links, ts], []);
|
}, [links, ts], []);
|
||||||
|
|
||||||
|
|
|
@ -76,6 +76,7 @@ export default class AppearanceUserSettingsTab extends React.Component<IProps, I
|
||||||
private readonly MESSAGE_PREVIEW_TEXT = _t("Hey you. You're the best!");
|
private readonly MESSAGE_PREVIEW_TEXT = _t("Hey you. You're the best!");
|
||||||
|
|
||||||
private themeTimer: number;
|
private themeTimer: number;
|
||||||
|
private unmounted = false;
|
||||||
|
|
||||||
constructor(props: IProps) {
|
constructor(props: IProps) {
|
||||||
super(props);
|
super(props);
|
||||||
|
@ -101,6 +102,7 @@ export default class AppearanceUserSettingsTab extends React.Component<IProps, I
|
||||||
const client = MatrixClientPeg.get();
|
const client = MatrixClientPeg.get();
|
||||||
const userId = client.getUserId();
|
const userId = client.getUserId();
|
||||||
const profileInfo = await client.getProfileInfo(userId);
|
const profileInfo = await client.getProfileInfo(userId);
|
||||||
|
if (this.unmounted) return;
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
userId,
|
userId,
|
||||||
|
@ -109,6 +111,10 @@ export default class AppearanceUserSettingsTab extends React.Component<IProps, I
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
this.unmounted = true;
|
||||||
|
}
|
||||||
|
|
||||||
private calculateThemeState(): IThemeState {
|
private calculateThemeState(): IThemeState {
|
||||||
// We have to mirror the logic from ThemeWatcher.getEffectiveTheme so we
|
// We have to mirror the logic from ThemeWatcher.getEffectiveTheme so we
|
||||||
// show the right values for things.
|
// show the right values for things.
|
||||||
|
|
|
@ -74,6 +74,7 @@ export class RoomListStoreClass extends AsyncStoreWithClient<IState> {
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super(defaultDispatcher);
|
super(defaultDispatcher);
|
||||||
|
this.setMaxListeners(20); // CustomRoomTagStore + RoomList + LeftPanel + 8xRoomSubList + spares
|
||||||
}
|
}
|
||||||
|
|
||||||
private setupWatchers() {
|
private setupWatchers() {
|
||||||
|
|
Loading…
Reference in New Issue