Move from browser-request to fetch (#9345)

This commit is contained in:
Michael Telatynski 2022-10-12 18:59:07 +01:00 committed by GitHub
parent ae883bb94b
commit 8b54be6f48
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
50 changed files with 1474 additions and 607 deletions

View file

@ -17,7 +17,6 @@ limitations under the License.
*/
import React from 'react';
import request from 'browser-request';
import sanitizeHtml from 'sanitize-html';
import classnames from 'classnames';
import { logger } from "matrix-js-sdk/src/logger";
@ -61,6 +60,37 @@ export default class EmbeddedPage extends React.PureComponent<IProps, IState> {
return sanitizeHtml(_t(s));
}
private async fetchEmbed() {
let res: Response;
try {
res = await fetch(this.props.url, { method: "GET" });
} catch (err) {
if (this.unmounted) return;
logger.warn(`Error loading page: ${err}`);
this.setState({ page: _t("Couldn't load page") });
return;
}
if (this.unmounted) return;
if (!res.ok) {
logger.warn(`Error loading page: ${res.status}`);
this.setState({ page: _t("Couldn't load page") });
return;
}
let body = (await res.text()).replace(/_t\(['"]([\s\S]*?)['"]\)/mg, (match, g1) => this.translate(g1));
if (this.props.replaceMap) {
Object.keys(this.props.replaceMap).forEach(key => {
body = body.split(key).join(this.props.replaceMap[key]);
});
}
this.setState({ page: body });
}
public componentDidMount(): void {
this.unmounted = false;
@ -68,34 +98,10 @@ export default class EmbeddedPage extends React.PureComponent<IProps, IState> {
return;
}
// we use request() to inline the page into the react component
// We use fetch to inline the page into the react component
// so that it can inherit CSS and theming easily rather than mess around
// with iframes and trying to synchronise document.stylesheets.
request(
{ method: "GET", url: this.props.url },
(err, response, body) => {
if (this.unmounted) {
return;
}
if (err || response.status < 200 || response.status >= 300) {
logger.warn(`Error loading page: ${err}`);
this.setState({ page: _t("Couldn't load page") });
return;
}
body = body.replace(/_t\(['"]([\s\S]*?)['"]\)/mg, (match, g1) => this.translate(g1));
if (this.props.replaceMap) {
Object.keys(this.props.replaceMap).forEach(key => {
body = body.split(key).join(this.props.replaceMap[key]);
});
}
this.setState({ page: body });
},
);
this.fetchEmbed();
this.dispatcherRef = dis.register(this.onAction);
}

View file

@ -1362,7 +1362,7 @@ class TimelinePanel extends React.Component<IProps, IState> {
if (this.unmounted) return;
this.setState({ timelineLoading: false });
logger.error(`Error loading timeline panel at ${this.props.timelineSet.room?.roomId}/${eventId}: ${error}`);
logger.error(`Error loading timeline panel at ${this.props.timelineSet.room?.roomId}/${eventId}`, error);
let onFinished: () => void;

View file

@ -17,7 +17,7 @@ limitations under the License.
import React from 'react';
import { Room } from "matrix-js-sdk/src/models/room";
import filesize from "filesize";
import { IAbortablePromise, IEventRelation } from 'matrix-js-sdk/src/matrix';
import { IEventRelation } from 'matrix-js-sdk/src/matrix';
import { Optional } from "matrix-events-sdk";
import ContentMessages from '../../ContentMessages';
@ -26,8 +26,7 @@ import { _t } from '../../languageHandler';
import { Action } from "../../dispatcher/actions";
import ProgressBar from "../views/elements/ProgressBar";
import AccessibleButton, { ButtonEvent } from "../views/elements/AccessibleButton";
import { IUpload } from "../../models/IUpload";
import MatrixClientContext from "../../contexts/MatrixClientContext";
import { RoomUpload } from "../../models/RoomUpload";
import { ActionPayload } from '../../dispatcher/payloads';
import { UploadPayload } from "../../dispatcher/payloads/UploadPayload";
@ -38,7 +37,7 @@ interface IProps {
interface IState {
currentFile?: string;
currentPromise?: IAbortablePromise<any>;
currentUpload?: RoomUpload;
currentLoaded?: number;
currentTotal?: number;
countFiles: number;
@ -55,8 +54,6 @@ function isUploadPayload(payload: ActionPayload): payload is UploadPayload {
}
export default class UploadBar extends React.PureComponent<IProps, IState> {
static contextType = MatrixClientContext;
private dispatcherRef: Optional<string>;
private mounted = false;
@ -78,7 +75,7 @@ export default class UploadBar extends React.PureComponent<IProps, IState> {
dis.unregister(this.dispatcherRef!);
}
private getUploadsInRoom(): IUpload[] {
private getUploadsInRoom(): RoomUpload[] {
const uploads = ContentMessages.sharedInstance().getCurrentUploads(this.props.relation);
return uploads.filter(u => u.roomId === this.props.room.roomId);
}
@ -86,8 +83,8 @@ export default class UploadBar extends React.PureComponent<IProps, IState> {
private calculateState(): IState {
const [currentUpload, ...otherUploads] = this.getUploadsInRoom();
return {
currentUpload,
currentFile: currentUpload?.fileName,
currentPromise: currentUpload?.promise,
currentLoaded: currentUpload?.loaded,
currentTotal: currentUpload?.total,
countFiles: otherUploads.length + 1,
@ -103,7 +100,7 @@ export default class UploadBar extends React.PureComponent<IProps, IState> {
private onCancelClick = (ev: ButtonEvent) => {
ev.preventDefault();
ContentMessages.sharedInstance().cancelUpload(this.state.currentPromise!, this.context);
ContentMessages.sharedInstance().cancelUpload(this.state.currentUpload!);
};
render() {

View file

@ -15,7 +15,7 @@ limitations under the License.
*/
import React, { ReactNode } from 'react';
import { MatrixError } from "matrix-js-sdk/src/http-api";
import { ConnectionError, MatrixError } from "matrix-js-sdk/src/http-api";
import classNames from "classnames";
import { logger } from "matrix-js-sdk/src/logger";
@ -453,7 +453,7 @@ export default class LoginComponent extends React.PureComponent<IProps, IState>
let errorText: ReactNode = _t("There was a problem communicating with the homeserver, " +
"please try again later.") + (errCode ? " (" + errCode + ")" : "");
if (err["cors"] === 'rejected') { // browser-request specific error field
if (err instanceof ConnectionError) {
if (window.location.protocol === 'https:' &&
(this.props.serverConfig.hsUrl.startsWith("http:") ||
!this.props.serverConfig.hsUrl.startsWith("http"))

View file

@ -16,7 +16,6 @@ Copyright 2019 Michael Telatynski <7t3chguy@gmail.com>
*/
import React from 'react';
import request from 'browser-request';
import { _t } from '../../../languageHandler';
import QuestionDialog from "./QuestionDialog";
@ -37,22 +36,33 @@ export default class ChangelogDialog extends React.Component<IProps> {
this.state = {};
}
private async fetchChanges(repo: string, oldVersion: string, newVersion: string): Promise<void> {
const url = `https://riot.im/github/repos/${repo}/compare/${oldVersion}...${newVersion}`;
try {
const res = await fetch(url);
if (!res.ok) {
this.setState({ [repo]: res.statusText });
return;
}
const body = await res.json();
this.setState({ [repo]: body.commits });
} catch (err) {
this.setState({ [repo]: err.message });
}
}
public componentDidMount() {
const version = this.props.newVersion.split('-');
const version2 = this.props.version.split('-');
if (version == null || version2 == null) return;
// parse versions of form: [vectorversion]-react-[react-sdk-version]-js-[js-sdk-version]
for (let i=0; i<REPOS.length; i++) {
for (let i = 0; i < REPOS.length; i++) {
const oldVersion = version2[2*i];
const newVersion = version[2*i];
const url = `https://riot.im/github/repos/${REPOS[i]}/compare/${oldVersion}...${newVersion}`;
request(url, (err, response, body) => {
if (response.statusCode < 200 || response.statusCode >= 300) {
this.setState({ [REPOS[i]]: response.statusText });
return;
}
this.setState({ [REPOS[i]]: JSON.parse(body).commits });
});
this.fetchChanges(REPOS[i], oldVersion, newVersion);
}
}

View file

@ -654,12 +654,7 @@ export default class InviteDialog extends React.PureComponent<Props, IInviteDial
const token = await authClient.getAccessToken();
if (term !== this.state.filterText) return; // abandon hope
const lookup = await MatrixClientPeg.get().lookupThreePid(
'email',
term,
undefined, // callback
token,
);
const lookup = await MatrixClientPeg.get().lookupThreePid('email', term, token);
if (term !== this.state.filterText) return; // abandon hope
if (!lookup || !lookup.mxid) {

View file

@ -15,7 +15,7 @@ limitations under the License.
*/
import React from 'react';
import { MatrixClient } from 'matrix-js-sdk/src/matrix';
import { MatrixClient, Method } from 'matrix-js-sdk/src/matrix';
import { logger } from 'matrix-js-sdk/src/logger';
import { _t } from '../../../languageHandler';
@ -33,17 +33,10 @@ import { SettingLevel } from "../../../settings/SettingLevel";
* @throws if the proxy server is unreachable or not configured to the given homeserver
*/
async function syncHealthCheck(cli: MatrixClient): Promise<void> {
const controller = new AbortController();
const id = setTimeout(() => controller.abort(), 10 * 1000); // 10s
const url = cli.http.getUrl("/sync", {}, "/_matrix/client/unstable/org.matrix.msc3575");
const res = await fetch(url, {
signal: controller.signal,
method: "POST",
await cli.http.authedRequest(Method.Post, "/sync", undefined, undefined, {
localTimeoutMs: 10 * 1000, // 10s
prefix: "/_matrix/client/unstable/org.matrix.msc3575",
});
clearTimeout(id);
if (res.status != 200) {
throw new Error(`syncHealthCheck: server returned HTTP ${res.status}`);
}
logger.info("server natively support sliding sync OK");
}

View file

@ -74,7 +74,7 @@ const MiniAvatarUploader: React.FC<IProps> = ({
if (!ev.target.files?.length) return;
setBusy(true);
const file = ev.target.files[0];
const uri = await cli.uploadContent(file);
const { content_uri: uri } = await cli.uploadContent(file);
await setAvatarUrl(uri);
setBusy(false);
}}

View file

@ -134,7 +134,7 @@ export default class RoomProfileSettings extends React.Component<IProps, IState>
}
if (this.state.avatarFile) {
const uri = await client.uploadContent(this.state.avatarFile);
const { content_uri: uri } = await client.uploadContent(this.state.avatarFile);
await client.sendStateEvent(this.props.roomId, 'm.room.avatar', { url: uri }, '');
newState.avatarUrl = mediaFromMxc(uri).getSquareThumbnailHttp(96);
newState.originalAvatarUrl = newState.avatarUrl;

View file

@ -148,7 +148,6 @@ export default class RoomPreviewBar extends React.Component<IProps, IState> {
const result = await MatrixClientPeg.get().lookupThreePid(
'email',
this.props.invitedEmail,
undefined /* callback */,
identityAccessToken,
);
this.setState({ invitedEmailMxid: result.mxid });

View file

@ -115,13 +115,13 @@ export default class ChangeAvatar extends React.Component<IProps, IState> {
this.setState({
phase: Phases.Uploading,
});
const httpPromise = MatrixClientPeg.get().uploadContent(file).then((url) => {
const httpPromise = MatrixClientPeg.get().uploadContent(file).then(({ content_uri: url }) => {
newUrl = url;
if (this.props.room) {
return MatrixClientPeg.get().sendStateEvent(
this.props.room.roomId,
'm.room.avatar',
{ url: url },
{ url },
'',
);
} else {

View file

@ -111,7 +111,7 @@ export default class ProfileSettings extends React.Component<{}, IState> {
logger.log(
`Uploading new avatar, ${this.state.avatarFile.name} of type ${this.state.avatarFile.type},` +
` (${this.state.avatarFile.size}) bytes`);
const uri = await client.uploadContent(this.state.avatarFile);
const { content_uri: uri } = await client.uploadContent(this.state.avatarFile);
await client.setAvatarUrl(uri);
newState.avatarUrl = mediaFromMxc(uri).getSquareThumbnailHttp(96);
newState.originalAvatarUrl = newState.avatarUrl;