Merge pull request #6382 from matrix-org/t3chguy/console

pull/21833/head
Michael Telatynski 2021-07-15 13:50:13 +01:00 committed by GitHub
commit ea20e041b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 74 additions and 70 deletions

View File

@ -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
// 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"
const senderName = ev.sender ? ev.sender.name : ev.getSender();
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();
return () => _t('%(senderDisplayName)s changed the topic to "%(topic)s".', {
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();
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();
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();
switch (ev.getContent().join_rule) {
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();
switch (ev.getContent().guest_access) {
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 groups = ev.getContent().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 prevContent = ev.getPrevContent();
const current = ev.getContent();
@ -255,7 +255,7 @@ function textForServerACLEvent(ev): () => string | null {
return getText;
}
function textForMessageEvent(ev): () => string | null {
function textForMessageEvent(ev: MatrixEvent): () => string | null {
return () => {
const senderDisplayName = ev.sender && ev.sender.name ? ev.sender.name : ev.getSender();
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 oldAlias = ev.getPrevContent().alias;
const oldAltAliases = ev.getPrevContent().alt_aliases || [];
@ -682,7 +682,7 @@ for (const evType of ALL_RULE_TYPES) {
stateHandlers[evType] = textForMjolnirEvent;
}
export function hasText(ev): boolean {
export function hasText(ev: MatrixEvent): boolean {
const handler = (ev.isState() ? stateHandlers : handlers)[ev.getType()];
return Boolean(handler?.(ev));
}

View File

@ -917,6 +917,7 @@ export default class RoomView extends React.Component<IProps, IState> {
// called when state.room is first initialised (either at initial load,
// after a successful peek, or after we join the room).
private onRoomLoaded = (room: Room) => {
if (this.unmounted) return;
// Attach a widget store listener only when we get a room
WidgetLayoutStore.instance.on(WidgetLayoutStore.emissionForRoom(room), this.onWidgetLayoutChange);
this.onWidgetLayoutChange(); // provoke an update
@ -931,9 +932,9 @@ export default class RoomView extends React.Component<IProps, IState> {
};
private async calculateRecommendedVersion(room: Room) {
this.setState({
upgradeRecommendation: await room.getRecommendedVersion(),
});
const upgradeRecommendation = await room.getRecommendedVersion();
if (this.unmounted) return;
this.setState({ upgradeRecommendation });
}
private async loadMembersIfJoined(room: Room) {
@ -1023,23 +1024,19 @@ export default class RoomView extends React.Component<IProps, IState> {
};
private async updateE2EStatus(room: Room) {
if (!this.context.isRoomEncrypted(room.roomId)) {
return;
}
if (!this.context.isCryptoEnabled()) {
// If crypto is not currently enabled, we aren't tracking devices at all,
// so we don't know what the answer is. Let's error on the safe side and show
// a warning for this case.
this.setState({
e2eStatus: E2EStatus.Warning,
});
return;
if (!this.context.isRoomEncrypted(room.roomId)) return;
// If crypto is not currently enabled, we aren't tracking devices at all,
// so we don't know what the answer is. Let's error on the safe side and show
// a warning for this case.
let e2eStatus = E2EStatus.Warning;
if (this.context.isCryptoEnabled()) {
/* At this point, the user has encryption on and cross-signing on */
e2eStatus = await shieldStatusForRoom(this.context, room);
}
/* At this point, the user has encryption on and cross-signing on */
this.setState({
e2eStatus: await shieldStatusForRoom(this.context, room),
});
if (this.unmounted) return;
this.setState({ e2eStatus });
}
private onAccountData = (event: MatrixEvent) => {

View File

@ -1051,6 +1051,8 @@ class TimelinePanel extends React.Component<IProps, IState> {
{ windowLimit: this.props.timelineCap });
const onLoaded = () => {
if (this.unmounted) return;
// clear the timeline min-height when
// (re)loading the timeline
if (this.messagePanel.current) {
@ -1092,6 +1094,8 @@ class TimelinePanel extends React.Component<IProps, IState> {
};
const onError = (error) => {
if (this.unmounted) return;
this.setState({ timelineLoading: false });
console.error(
`Error loading timeline panel at ${eventId}: ${error}`,

View File

@ -15,12 +15,14 @@
*/
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 FlairStore from '../../../stores/FlairStore';
import { getUserNameColorClass } from '../../../utils/FormattingUtils';
import MatrixClientContext from "../../../contexts/MatrixClientContext";
import { replaceableComponent } from "../../../utils/replaceableComponent";
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
interface IProps {
mxEvent: MatrixEvent;
@ -36,7 +38,7 @@ interface IState {
@replaceableComponent("views.messages.SenderProfile")
export default class SenderProfile extends React.Component<IProps, IState> {
static contextType = MatrixClientContext;
private unmounted: boolean;
private unmounted = false;
constructor(props: IProps) {
super(props);
@ -49,8 +51,7 @@ export default class SenderProfile extends React.Component<IProps, IState> {
}
componentDidMount() {
this.unmounted = false;
this._updateRelatedGroups();
this.updateRelatedGroups();
if (this.state.userGroups.length === 0) {
this.getPublicisedGroups();
@ -64,35 +65,29 @@ export default class SenderProfile extends React.Component<IProps, IState> {
this.context.removeListener('RoomState.events', this.onRoomStateEvents);
}
async getPublicisedGroups() {
if (!this.unmounted) {
const userGroups = await FlairStore.getPublicisedGroupsCached(
this.context, this.props.mxEvent.getSender(),
);
this.setState({ userGroups });
}
private async getPublicisedGroups() {
const userGroups = await FlairStore.getPublicisedGroupsCached(this.context, this.props.mxEvent.getSender());
if (this.unmounted) return;
this.setState({ userGroups });
}
onRoomStateEvents = event => {
if (event.getType() === 'm.room.related_groups' &&
event.getRoomId() === this.props.mxEvent.getRoomId()
) {
this._updateRelatedGroups();
private onRoomStateEvents = (event: MatrixEvent) => {
if (event.getType() === 'm.room.related_groups' && event.getRoomId() === this.props.mxEvent.getRoomId()) {
this.updateRelatedGroups();
}
};
_updateRelatedGroups() {
if (this.unmounted) return;
private updateRelatedGroups() {
const room = this.context.getRoom(this.props.mxEvent.getRoomId());
if (!room) return;
const relatedGroupsEvent = room.currentState.getStateEvents('m.room.related_groups', '');
this.setState({
relatedGroups: relatedGroupsEvent ? relatedGroupsEvent.getContent().groups || [] : [],
relatedGroups: relatedGroupsEvent?.getContent().groups || [],
});
}
_getDisplayedGroups(userGroups, relatedGroups) {
private getDisplayedGroups(userGroups?: string[], relatedGroups?: string[]) {
let displayedGroups = userGroups || [];
if (relatedGroups && relatedGroups.length > 0) {
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 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
}
@ -128,7 +123,7 @@ export default class SenderProfile extends React.Component<IProps, IState> {
let flair;
if (this.props.enableFlair) {
const displayedGroups = this._getDisplayedGroups(
const displayedGroups = this.getDisplayedGroups(
this.state.userGroups, this.state.relatedGroups,
);

View File

@ -1152,11 +1152,11 @@ export default class EventTile extends React.Component<IProps, IState> {
"aria-live": ariaLive,
"aria-atomic": true,
"data-scroll-tokens": scrollToken,
}, [
ircTimestamp,
avatar,
sender,
ircPadlock,
}, <>
{ ircTimestamp }
{ avatar }
{ sender }
{ ircPadlock }
<div className="mx_EventTile_reply" key="mx_EventTile_reply">
{ groupTimestamp }
{ groupPadlock }
@ -1169,8 +1169,8 @@ export default class EventTile extends React.Component<IProps, IState> {
replacingEventId={this.props.replacingEventId}
showUrlPreview={false}
/>
</div>,
]);
</div>
</>);
}
default: {
const thread = ReplyThread.makeThread(
@ -1193,10 +1193,10 @@ export default class EventTile extends React.Component<IProps, IState> {
"data-scroll-tokens": scrollToken,
"onMouseEnter": () => this.setState({ hover: true }),
"onMouseLeave": () => this.setState({ hover: false }),
}, [
ircTimestamp,
sender,
ircPadlock,
}, <>
{ ircTimestamp }
{ sender }
{ ircPadlock }
<div className="mx_EventTile_line" key="mx_EventTile_line">
{ groupTimestamp }
{ groupPadlock }
@ -1214,11 +1214,10 @@ export default class EventTile extends React.Component<IProps, IState> {
{ keyRequestInfo }
{ reactionsRow }
{ actionBar }
</div>,
msgOption,
avatar,
])
</div>
{ msgOption }
{ avatar }
</>)
);
}
}

View File

@ -40,10 +40,12 @@ const LinkPreviewGroup: React.FC<IProps> = ({ links, mxEvent, onCancelClick, onH
const ts = mxEvent.getTs();
const previews = useAsyncMemo<[string, IPreviewUrlResponse][]>(async () => {
return Promise.all<[string, IPreviewUrlResponse] | void>(links.map(link => {
return cli.getUrlPreview(link, ts).then(preview => [link, preview], error => {
return Promise.all<[string, IPreviewUrlResponse] | void>(links.map(async link => {
try {
return [link, await cli.getUrlPreview(link, ts)];
} catch (error) {
console.error("Failed to get URL preview: " + error);
});
}
})).then(a => a.filter(Boolean)) as Promise<[string, IPreviewUrlResponse][]>;
}, [links, ts], []);

View File

@ -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 themeTimer: number;
private unmounted = false;
constructor(props: IProps) {
super(props);
@ -101,6 +102,7 @@ export default class AppearanceUserSettingsTab extends React.Component<IProps, I
const client = MatrixClientPeg.get();
const userId = client.getUserId();
const profileInfo = await client.getProfileInfo(userId);
if (this.unmounted) return;
this.setState({
userId,
@ -109,6 +111,10 @@ export default class AppearanceUserSettingsTab extends React.Component<IProps, I
});
}
componentWillUnmount() {
this.unmounted = true;
}
private calculateThemeState(): IThemeState {
// We have to mirror the logic from ThemeWatcher.getEffectiveTheme so we
// show the right values for things.

View File

@ -74,6 +74,7 @@ export class RoomListStoreClass extends AsyncStoreWithClient<IState> {
constructor() {
super(defaultDispatcher);
this.setMaxListeners(20); // CustomRoomTagStore + RoomList + LeftPanel + 8xRoomSubList + spares
}
private setupWatchers() {