You've already forked matrix-react-sdk
mirror of
https://github.com/matrix-org/matrix-react-sdk.git
synced 2025-11-07 10:46:24 +03:00
Merge pull request #6382 from matrix-org/t3chguy/console
This commit is contained in:
@@ -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) => {
|
||||
|
||||
@@ -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}`,
|
||||
|
||||
@@ -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,
|
||||
);
|
||||
|
||||
|
||||
@@ -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 }
|
||||
</>)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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], []);
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user