Migrate away from Legacy React Contexts

This commit is contained in:
Michael Telatynski 2019-12-17 17:26:12 +00:00
parent 2e8d66fa36
commit 937b32663c
55 changed files with 651 additions and 750 deletions

View file

@ -80,8 +80,8 @@ export default class BasicMessageEditor extends React.Component {
initialCaret: PropTypes.object, // See DocumentPosition in editor/model.js
};
constructor(props, context) {
super(props, context);
constructor(props) {
super(props);
this.state = {
autoComplete: null,
};

View file

@ -31,6 +31,7 @@ import classNames from 'classnames';
import {EventStatus} from 'matrix-js-sdk';
import BasicMessageComposer from "./BasicMessageComposer";
import {Key} from "../../../Keyboard";
import MatrixClientContext from "../../../contexts/MatrixClientContext";
function _isReply(mxEvent) {
const relatesTo = mxEvent.getContent()["m.relates_to"];
@ -105,12 +106,10 @@ export default class EditMessageComposer extends React.Component {
editState: PropTypes.instanceOf(EditorStateTransfer).isRequired,
};
static contextTypes = {
matrixClient: PropTypes.instanceOf(MatrixClient).isRequired,
};
static contextType = MatrixClientContext;
constructor(props, context) {
super(props, context);
constructor(props) {
super(props);
this.model = null;
this._editorRef = null;
@ -124,7 +123,7 @@ export default class EditMessageComposer extends React.Component {
};
_getRoom() {
return this.context.matrixClient.getRoom(this.props.editState.getEvent().getRoomId());
return this.context.getRoom(this.props.editState.getEvent().getRoomId());
}
_onKeyDown = (event) => {
@ -190,7 +189,7 @@ export default class EditMessageComposer extends React.Component {
if (this._isContentModified(newContent)) {
const roomId = editedEvent.getRoomId();
this._cancelPreviousPendingEdit();
this.context.matrixClient.sendMessage(roomId, editContent);
this.context.sendMessage(roomId, editContent);
}
// close the event editing and focus composer
@ -205,7 +204,7 @@ export default class EditMessageComposer extends React.Component {
previousEdit.status === EventStatus.QUEUED ||
previousEdit.status === EventStatus.NOT_SENT
)) {
this.context.matrixClient.cancelPendingEvent(previousEdit);
this.context.cancelPendingEvent(previousEdit);
}
}
@ -232,7 +231,7 @@ export default class EditMessageComposer extends React.Component {
_createEditorModel() {
const {editState} = this.props;
const room = this._getRoom();
const partCreator = new PartCreator(room, this.context.matrixClient);
const partCreator = new PartCreator(room, this.context);
let parts;
if (editState.hasEditorState()) {
// if restoring state from a previous editor,

View file

@ -31,10 +31,11 @@ const TextForEvent = require('../../../TextForEvent');
import dis from '../../../dispatcher';
import SettingsStore from "../../../settings/SettingsStore";
import {EventStatus, MatrixClient} from 'matrix-js-sdk';
import {EventStatus} from 'matrix-js-sdk';
import {formatTime} from "../../../DateUtils";
import MatrixClientPeg from '../../../MatrixClientPeg';
import {ALL_RULE_TYPES} from "../../../mjolnir/BanList";
import MatrixClientContext from "../../../contexts/MatrixClientContext";
const ObjectUtils = require('../../../ObjectUtils');
@ -222,8 +223,8 @@ module.exports = createReactClass({
};
},
contextTypes: {
matrixClient: PropTypes.instanceOf(MatrixClient).isRequired,
statics: {
contextType: MatrixClientContext,
},
componentWillMount: function() {
@ -237,7 +238,7 @@ module.exports = createReactClass({
componentDidMount: function() {
this._suppressReadReceiptAnimation = false;
const client = this.context.matrixClient;
const client = this.context;
client.on("deviceVerificationChanged", this.onDeviceVerificationChanged);
this.props.mxEvent.on("Event.decrypted", this._onDecrypted);
if (this.props.showReactions) {
@ -262,7 +263,7 @@ module.exports = createReactClass({
},
componentWillUnmount: function() {
const client = this.context.matrixClient;
const client = this.context;
client.removeListener("deviceVerificationChanged", this.onDeviceVerificationChanged);
this.props.mxEvent.removeListener("Event.decrypted", this._onDecrypted);
if (this.props.showReactions) {
@ -291,7 +292,7 @@ module.exports = createReactClass({
return;
}
const verified = await this.context.matrixClient.isEventSenderVerified(mxEvent);
const verified = await this.context.isEventSenderVerified(mxEvent);
this.setState({
verified: verified,
}, () => {
@ -349,11 +350,11 @@ module.exports = createReactClass({
},
shouldHighlight: function() {
const actions = this.context.matrixClient.getPushActionsForEvent(this.props.mxEvent);
const actions = this.context.getPushActionsForEvent(this.props.mxEvent);
if (!actions || !actions.tweaks) { return false; }
// don't show self-highlights from another of our clients
if (this.props.mxEvent.getSender() === this.context.matrixClient.credentials.userId) {
if (this.props.mxEvent.getSender() === this.context.credentials.userId) {
return false;
}
@ -461,7 +462,7 @@ module.exports = createReactClass({
// Cancel any outgoing key request for this event and resend it. If a response
// is received for the request with the required keys, the event could be
// decrypted successfully.
this.context.matrixClient.cancelAndResendEventRoomKeyRequest(this.props.mxEvent);
this.context.cancelAndResendEventRoomKeyRequest(this.props.mxEvent);
},
onPermalinkClicked: function(e) {
@ -494,7 +495,7 @@ module.exports = createReactClass({
}
}
if (this.context.matrixClient.isRoomEncrypted(ev.getRoomId())) {
if (this.context.isRoomEncrypted(ev.getRoomId())) {
// else if room is encrypted
// and event is being encrypted or is not_sent (Unknown Devices/Network Error)
if (ev.status === EventStatus.ENCRYPTING) {
@ -741,7 +742,7 @@ module.exports = createReactClass({
switch (this.props.tileShape) {
case 'notif': {
const room = this.context.matrixClient.getRoom(this.props.mxEvent.getRoomId());
const room = this.context.getRoom(this.props.mxEvent.getRoomId());
return (
<div className={classes}>
<div className="mx_EventTile_roomName">

View file

@ -31,7 +31,6 @@ import React from 'react';
import PropTypes from 'prop-types';
import createReactClass from 'create-react-class';
import classNames from 'classnames';
import { MatrixClient } from 'matrix-js-sdk';
import dis from '../../../dispatcher';
import Modal from '../../../Modal';
import sdk from '../../../index';
@ -48,7 +47,7 @@ import SettingsStore from "../../../settings/SettingsStore";
import E2EIcon from "./E2EIcon";
import AutoHideScrollbar from "../../structures/AutoHideScrollbar";
import MatrixClientPeg from "../../../MatrixClientPeg";
import {EventTimeline} from "matrix-js-sdk";
import MatrixClientContext from "../../../contexts/MatrixClientContext";
module.exports = createReactClass({
displayName: 'MemberInfo',
@ -76,13 +75,13 @@ module.exports = createReactClass({
};
},
contextTypes: {
matrixClient: PropTypes.instanceOf(MatrixClient).isRequired,
statics: {
contextType: MatrixClientContext,
},
componentWillMount: function() {
this._cancelDeviceList = null;
const cli = this.context.matrixClient;
const cli = this.context;
// only display the devices list if our client supports E2E
this._enableDevices = cli.isCryptoEnabled();
@ -112,7 +111,7 @@ module.exports = createReactClass({
},
componentWillUnmount: function() {
const client = this.context.matrixClient;
const client = this.context;
if (client) {
client.removeListener("deviceVerificationChanged", this.onDeviceVerificationChanged);
client.removeListener("Room", this.onRoom);
@ -131,7 +130,7 @@ module.exports = createReactClass({
},
_checkIgnoreState: function() {
const isIgnoring = this.context.matrixClient.isUserIgnored(this.props.member.userId);
const isIgnoring = this.context.isUserIgnored(this.props.member.userId);
this.setState({isIgnoring: isIgnoring});
},
@ -163,7 +162,7 @@ module.exports = createReactClass({
// Promise.resolve to handle transition from static result to promise; can be removed
// in future
Promise.resolve(this.context.matrixClient.getStoredDevicesForUser(userId)).then((devices) => {
Promise.resolve(this.context.getStoredDevicesForUser(userId)).then((devices) => {
this.setState({
devices: devices,
e2eStatus: this._getE2EStatus(devices),
@ -197,7 +196,7 @@ module.exports = createReactClass({
onRoomReceipt: function(receiptEvent, room) {
// because if we read a notification, it will affect notification count
// only bother updating if there's a receipt from us
if (findReadReceiptFromUserId(receiptEvent, this.context.matrixClient.credentials.userId)) {
if (findReadReceiptFromUserId(receiptEvent, this.context.credentials.userId)) {
this.forceUpdate();
}
},
@ -242,7 +241,7 @@ module.exports = createReactClass({
let cancelled = false;
this._cancelDeviceList = function() { cancelled = true; };
const client = this.context.matrixClient;
const client = this.context;
const self = this;
client.downloadKeys([member.userId], true).then(() => {
return client.getStoredDevicesForUser(member.userId);
@ -267,7 +266,7 @@ module.exports = createReactClass({
},
onIgnoreToggle: function() {
const ignoredUsers = this.context.matrixClient.getIgnoredUsers();
const ignoredUsers = this.context.getIgnoredUsers();
if (this.state.isIgnoring) {
const index = ignoredUsers.indexOf(this.props.member.userId);
if (index !== -1) ignoredUsers.splice(index, 1);
@ -275,7 +274,7 @@ module.exports = createReactClass({
ignoredUsers.push(this.props.member.userId);
}
this.context.matrixClient.setIgnoredUsers(ignoredUsers).then(() => {
this.context.setIgnoredUsers(ignoredUsers).then(() => {
return this.setState({isIgnoring: !this.state.isIgnoring});
});
},
@ -293,7 +292,7 @@ module.exports = createReactClass({
if (!proceed) return;
this.setState({ updating: this.state.updating + 1 });
this.context.matrixClient.kick(
this.context.kick(
this.props.member.roomId, this.props.member.userId,
reason || undefined,
).then(function() {
@ -329,11 +328,11 @@ module.exports = createReactClass({
this.setState({ updating: this.state.updating + 1 });
let promise;
if (this.props.member.membership === 'ban') {
promise = this.context.matrixClient.unban(
promise = this.context.unban(
this.props.member.roomId, this.props.member.userId,
);
} else {
promise = this.context.matrixClient.ban(
promise = this.context.ban(
this.props.member.roomId, this.props.member.userId,
reason || undefined,
);
@ -360,7 +359,7 @@ module.exports = createReactClass({
onRedactAllMessages: async function() {
const {roomId, userId} = this.props.member;
const room = this.context.matrixClient.getRoom(roomId);
const room = this.context.getRoom(roomId);
if (!room) {
return;
}
@ -414,7 +413,7 @@ module.exports = createReactClass({
console.info(`Started redacting recent ${count} messages for ${user} in ${roomId}`);
await Promise.all(eventsToRedact.map(async event => {
try {
await this.context.matrixClient.redactEvent(roomId, event.getId());
await this.context.redactEvent(roomId, event.getId());
} catch (err) {
// log and swallow errors
console.error("Could not redact", event.getId());
@ -446,11 +445,11 @@ module.exports = createReactClass({
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
const roomId = this.props.member.roomId;
const target = this.props.member.userId;
const room = this.context.matrixClient.getRoom(roomId);
const room = this.context.getRoom(roomId);
if (!room) return;
// if muting self, warn as it may be irreversible
if (target === this.context.matrixClient.getUserId()) {
if (target === this.context.getUserId()) {
try {
if (!(await this._warnSelfDemote())) return;
} catch (e) {
@ -478,7 +477,7 @@ module.exports = createReactClass({
if (!isNaN(level)) {
this.setState({ updating: this.state.updating + 1 });
this.context.matrixClient.setPowerLevel(roomId, target, level, powerLevelEvent).then(
this.context.setPowerLevel(roomId, target, level, powerLevelEvent).then(
function() {
// NO-OP; rely on the m.room.member event coming down else we could
// get out of sync if we force setState here!
@ -500,13 +499,13 @@ module.exports = createReactClass({
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
const roomId = this.props.member.roomId;
const target = this.props.member.userId;
const room = this.context.matrixClient.getRoom(roomId);
const room = this.context.getRoom(roomId);
if (!room) return;
const powerLevelEvent = room.currentState.getStateEvents("m.room.power_levels", "");
if (!powerLevelEvent) return;
const me = room.getMember(this.context.matrixClient.credentials.userId);
const me = room.getMember(this.context.credentials.userId);
if (!me) return;
const defaultLevel = powerLevelEvent.getContent().users_default;
@ -515,7 +514,7 @@ module.exports = createReactClass({
// toggle the level
const newLevel = this.state.isTargetMod ? defaultLevel : modLevel;
this.setState({ updating: this.state.updating + 1 });
this.context.matrixClient.setPowerLevel(roomId, target, parseInt(newLevel), powerLevelEvent).then(
this.context.setPowerLevel(roomId, target, parseInt(newLevel), powerLevelEvent).then(
function() {
// NO-OP; rely on the m.room.member event coming down else we could
// get out of sync if we force setState here!
@ -550,7 +549,7 @@ module.exports = createReactClass({
danger: true,
onFinished: (accepted) => {
if (!accepted) return;
this.context.matrixClient.deactivateSynapseUser(this.props.member.userId).catch(e => {
this.context.deactivateSynapseUser(this.props.member.userId).catch(e => {
console.error("Failed to deactivate user");
console.error(e);
@ -566,7 +565,7 @@ module.exports = createReactClass({
_applyPowerChange: function(roomId, target, powerLevel, powerLevelEvent) {
this.setState({ updating: this.state.updating + 1 });
this.context.matrixClient.setPowerLevel(roomId, target, parseInt(powerLevel), powerLevelEvent).then(
this.context.setPowerLevel(roomId, target, parseInt(powerLevel), powerLevelEvent).then(
function() {
// NO-OP; rely on the m.room.member event coming down else we could
// get out of sync if we force setState here!
@ -587,7 +586,7 @@ module.exports = createReactClass({
onPowerChange: async function(powerLevel) {
const roomId = this.props.member.roomId;
const target = this.props.member.userId;
const room = this.context.matrixClient.getRoom(roomId);
const room = this.context.getRoom(roomId);
if (!room) return;
const powerLevelEvent = room.currentState.getStateEvents("m.room.power_levels", "");
@ -598,7 +597,7 @@ module.exports = createReactClass({
return;
}
const myUserId = this.context.matrixClient.getUserId();
const myUserId = this.context.getUserId();
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
// If we are changing our own PL it can only ever be decreasing, which we cannot reverse.
@ -650,9 +649,9 @@ module.exports = createReactClass({
_calculateOpsPermissions: async function(member) {
let canDeactivate = false;
if (this.context.matrixClient) {
if (this.context) {
try {
canDeactivate = await this.context.matrixClient.isSynapseAdministrator();
canDeactivate = await this.context.isSynapseAdministrator();
} catch (e) {
console.error(e);
}
@ -665,13 +664,13 @@ module.exports = createReactClass({
},
muted: false,
};
const room = this.context.matrixClient.getRoom(member.roomId);
const room = this.context.getRoom(member.roomId);
if (!room) return defaultPerms;
const powerLevels = room.currentState.getStateEvents("m.room.power_levels", "");
if (!powerLevels) return defaultPerms;
const me = room.getMember(this.context.matrixClient.credentials.userId);
const me = room.getMember(this.context.credentials.userId);
if (!me) return defaultPerms;
const them = member;
@ -738,7 +737,7 @@ module.exports = createReactClass({
const avatarUrl = member.getMxcAvatarUrl();
if (!avatarUrl) return;
const httpUrl = this.context.matrixClient.mxcUrlToHttp(avatarUrl);
const httpUrl = this.context.mxcUrlToHttp(avatarUrl);
const ImageView = sdk.getComponent("elements.ImageView");
const params = {
src: httpUrl,
@ -797,7 +796,7 @@ module.exports = createReactClass({
},
_renderUserOptions: function() {
const cli = this.context.matrixClient;
const cli = this.context;
const member = this.props.member;
let ignoreButton = null;
@ -905,9 +904,9 @@ module.exports = createReactClass({
let synapseDeactivateButton;
let spinner;
if (this.props.member.userId !== this.context.matrixClient.credentials.userId) {
if (this.props.member.userId !== this.context.credentials.userId) {
// TODO: Immutable DMs replaces a lot of this
const dmRoomMap = new DMRoomMap(this.context.matrixClient);
const dmRoomMap = new DMRoomMap(this.context);
// dmRooms will not include dmRooms that we have been invited into but did not join.
// Because DMRoomMap runs off account_data[m.direct] which is only set on join of dm room.
// XXX: we potentially want DMs we have been invited to, to also show up here :L
@ -918,7 +917,7 @@ module.exports = createReactClass({
const tiles = [];
for (const roomId of dmRooms) {
const room = this.context.matrixClient.getRoom(roomId);
const room = this.context.getRoom(roomId);
if (room) {
const myMembership = room.getMyMembership();
// not a DM room if we have are not joined
@ -1064,12 +1063,12 @@ module.exports = createReactClass({
}
}
const room = this.context.matrixClient.getRoom(this.props.member.roomId);
const room = this.context.getRoom(this.props.member.roomId);
const powerLevelEvent = room ? room.currentState.getStateEvents("m.room.power_levels", "") : null;
const powerLevelUsersDefault = powerLevelEvent ? powerLevelEvent.getContent().users_default : 0;
const enablePresenceByHsUrl = SdkConfig.get()["enable_presence_by_hs_url"];
const hsUrl = this.context.matrixClient.baseUrl;
const hsUrl = this.context.baseUrl;
let showPresence = true;
if (enablePresenceByHsUrl && enablePresenceByHsUrl[hsUrl] !== undefined) {
showPresence = enablePresenceByHsUrl[hsUrl];
@ -1108,7 +1107,7 @@ module.exports = createReactClass({
</div>
</div>;
const isEncrypted = this.context.matrixClient.isRoomEncrypted(this.props.member.roomId);
const isEncrypted = this.context.isRoomEncrypted(this.props.member.roomId);
if (this.state.e2eStatus && isEncrypted) {
e2eIconElement = (<E2EIcon status={this.state.e2eStatus} isUser={true} />);
}
@ -1117,7 +1116,7 @@ module.exports = createReactClass({
const avatarUrl = this.props.member.getMxcAvatarUrl();
let avatarElement;
if (avatarUrl) {
const httpUrl = this.context.matrixClient.mxcUrlToHttp(avatarUrl, 800, 800);
const httpUrl = this.context.mxcUrlToHttp(avatarUrl, 800, 800);
avatarElement = <div className="mx_MemberInfo_avatar">
<img src={httpUrl} />
</div>;

View file

@ -107,8 +107,8 @@ class UploadButton extends React.Component {
roomId: PropTypes.string.isRequired,
}
constructor(props, context) {
super(props, context);
constructor(props) {
super(props);
this.onUploadClick = this.onUploadClick.bind(this);
this.onUploadFileInputChange = this.onUploadFileInputChange.bind(this);
@ -165,8 +165,8 @@ class UploadButton extends React.Component {
}
export default class MessageComposer extends React.Component {
constructor(props, context) {
super(props, context);
constructor(props) {
super(props);
this.onInputStateChanged = this.onInputStateChanged.bind(this);
this.onEvent = this.onEvent.bind(this);
this._onRoomStateEvents = this._onRoomStateEvents.bind(this);

View file

@ -141,8 +141,8 @@ export default class MessageComposerInput extends React.Component {
autocomplete: Autocomplete;
historyManager: SlateComposerHistoryManager;
constructor(props, context) {
super(props, context);
constructor(props) {
super(props);
const isRichTextEnabled = SettingsStore.getValue('MessageComposerInput.isRichTextEnabled');

View file

@ -35,8 +35,8 @@ export default class ReplyPreview extends React.Component {
permalinkCreator: PropTypes.instanceOf(RoomPermalinkCreator).isRequired,
};
constructor(props, context) {
super(props, context);
constructor(props) {
super(props);
this.unmounted = false;
this.state = {

View file

@ -26,7 +26,6 @@ import {
unescapeMessage,
} from '../../../editor/serialize';
import {CommandPartCreator} from '../../../editor/parts';
import {MatrixClient} from 'matrix-js-sdk';
import BasicMessageComposer from "./BasicMessageComposer";
import ReplyPreview from "./ReplyPreview";
import RoomViewStore from '../../../stores/RoomViewStore';
@ -40,6 +39,7 @@ import Modal from '../../../Modal';
import {_t, _td} from '../../../languageHandler';
import ContentMessages from '../../../ContentMessages';
import {Key} from "../../../Keyboard";
import MatrixClientContext from "../../../contexts/MatrixClientContext";
function addReplyToMessageContent(content, repliedToEvent, permalinkCreator) {
const replyContent = ReplyThread.makeReplyMixIn(repliedToEvent);
@ -89,12 +89,10 @@ export default class SendMessageComposer extends React.Component {
permalinkCreator: PropTypes.object.isRequired,
};
static contextTypes = {
matrixClient: PropTypes.instanceOf(MatrixClient).isRequired,
};
static contextType = MatrixClientContext;
constructor(props, context) {
super(props, context);
constructor(props) {
super(props);
this.model = null;
this._editorRef = null;
this.currentlyComposedEditorState = null;
@ -245,7 +243,7 @@ export default class SendMessageComposer extends React.Component {
const isReply = !!RoomViewStore.getQuotingEvent();
const {roomId} = this.props.room;
const content = createMessageContent(this.model, this.props.permalinkCreator);
this.context.matrixClient.sendMessage(roomId, content);
this.context.sendMessage(roomId, content);
if (isReply) {
// Clear reply_to_event as we put the message into the queue
// if the send fails, retry will handle resending.
@ -273,7 +271,7 @@ export default class SendMessageComposer extends React.Component {
}
componentWillMount() {
const partCreator = new CommandPartCreator(this.props.room, this.context.matrixClient);
const partCreator = new CommandPartCreator(this.props.room, this.context);
const parts = this._restoreStoredEditorState(partCreator) || [];
this.model = new EditorModel(parts, partCreator);
this.dispatcherRef = dis.register(this.onAction);
@ -361,7 +359,7 @@ export default class SendMessageComposer extends React.Component {
// from Finder) but more images copied from a different website
// / word processor etc.
ContentMessages.sharedInstance().sendContentListToRoom(
Array.from(clipboardData.files), this.props.room.roomId, this.context.matrixClient,
Array.from(clipboardData.files), this.props.room.roomId, this.context,
);
}
}

View file

@ -137,8 +137,8 @@ class UploadButton extends React.Component {
static propTypes = {
roomId: PropTypes.string.isRequired,
}
constructor(props, context) {
super(props, context);
constructor(props) {
super(props);
this.onUploadClick = this.onUploadClick.bind(this);
this.onUploadFileInputChange = this.onUploadFileInputChange.bind(this);
@ -193,8 +193,8 @@ class UploadButton extends React.Component {
}
export default class SlateMessageComposer extends React.Component {
constructor(props, context) {
super(props, context);
constructor(props) {
super(props);
this._onAutocompleteConfirm = this._onAutocompleteConfirm.bind(this);
this.onToggleFormattingClicked = this.onToggleFormattingClicked.bind(this);
this.onToggleMarkdownClicked = this.onToggleMarkdownClicked.bind(this);