Merge branch 'develop' into johannes/find-myself
This commit is contained in:
commit
d0e9331f07
612 changed files with 3608 additions and 2769 deletions
|
@ -43,7 +43,7 @@ export default class Clock extends React.Component<Props> {
|
|||
return currentFloor !== nextFloor;
|
||||
}
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
return (
|
||||
<span aria-live={this.props["aria-live"]} role={this.props.role} className="mx_Clock">
|
||||
{this.props.formatFn(this.props.seconds)}
|
||||
|
|
|
@ -31,7 +31,7 @@ interface IState {
|
|||
* A clock which shows a clip's maximum duration.
|
||||
*/
|
||||
export default class DurationClock extends React.PureComponent<IProps, IState> {
|
||||
public constructor(props) {
|
||||
public constructor(props: IProps) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
|
@ -48,7 +48,7 @@ export default class DurationClock extends React.PureComponent<IProps, IState> {
|
|||
this.setState({ durationSeconds: time[1] });
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
return <Clock seconds={this.state.durationSeconds} />;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,12 +34,12 @@ interface IState {
|
|||
*/
|
||||
export default class LiveRecordingClock extends React.PureComponent<IProps, IState> {
|
||||
private seconds = 0;
|
||||
private scheduledUpdate = new MarkedExecution(
|
||||
private scheduledUpdate: MarkedExecution = new MarkedExecution(
|
||||
() => this.updateClock(),
|
||||
() => requestAnimationFrame(() => this.scheduledUpdate.trigger()),
|
||||
);
|
||||
|
||||
public constructor(props) {
|
||||
public constructor(props: IProps) {
|
||||
super(props);
|
||||
this.state = {
|
||||
seconds: 0,
|
||||
|
@ -59,7 +59,7 @@ export default class LiveRecordingClock extends React.PureComponent<IProps, ISta
|
|||
});
|
||||
}
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
return <Clock seconds={this.state.seconds} aria-live="off" />;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,12 +39,12 @@ export default class LiveRecordingWaveform extends React.PureComponent<IProps, I
|
|||
};
|
||||
|
||||
private waveform: number[] = [];
|
||||
private scheduledUpdate = new MarkedExecution(
|
||||
private scheduledUpdate: MarkedExecution = new MarkedExecution(
|
||||
() => this.updateWaveform(),
|
||||
() => requestAnimationFrame(() => this.scheduledUpdate.trigger()),
|
||||
);
|
||||
|
||||
public constructor(props) {
|
||||
public constructor(props: IProps) {
|
||||
super(props);
|
||||
this.state = {
|
||||
waveform: arraySeed(0, RECORDING_PLAYBACK_SAMPLES),
|
||||
|
@ -63,7 +63,7 @@ export default class LiveRecordingWaveform extends React.PureComponent<IProps, I
|
|||
this.setState({ waveform: this.waveform });
|
||||
}
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
return <Waveform relHeights={this.state.waveform} />;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ interface IProps extends Omit<React.ComponentProps<typeof AccessibleTooltipButto
|
|||
* to be displayed in reference to a recording.
|
||||
*/
|
||||
export default class PlayPauseButton extends React.PureComponent<IProps> {
|
||||
public constructor(props) {
|
||||
public constructor(props: IProps) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ interface IState {
|
|||
* A clock for a playback of a recording.
|
||||
*/
|
||||
export default class PlaybackClock extends React.PureComponent<IProps, IState> {
|
||||
public constructor(props) {
|
||||
public constructor(props: IProps) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
|
@ -65,7 +65,7 @@ export default class PlaybackClock extends React.PureComponent<IProps, IState> {
|
|||
this.setState({ seconds: time[0], durationSeconds: time[1] });
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
let seconds = this.state.seconds;
|
||||
if (this.state.playbackPhase === PlaybackState.Stopped) {
|
||||
if (Number.isFinite(this.props.defaultDisplaySeconds)) {
|
||||
|
|
|
@ -34,7 +34,7 @@ interface IState {
|
|||
* A waveform which shows the waveform of a previously recorded recording
|
||||
*/
|
||||
export default class PlaybackWaveform extends React.PureComponent<IProps, IState> {
|
||||
public constructor(props) {
|
||||
public constructor(props: IProps) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
|
@ -61,7 +61,7 @@ export default class PlaybackWaveform extends React.PureComponent<IProps, IState
|
|||
this.setState({ progress });
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
return <Waveform relHeights={this.state.heights} progress={this.state.progress} />;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ export default class SeekBar extends React.PureComponent<IProps, IState> {
|
|||
// We use an animation frame request to avoid overly spamming prop updates, even if we aren't
|
||||
// really using anything demanding on the CSS front.
|
||||
|
||||
private animationFrameFn = new MarkedExecution(
|
||||
private animationFrameFn: MarkedExecution = new MarkedExecution(
|
||||
() => this.doUpdate(),
|
||||
() => requestAnimationFrame(() => this.animationFrameFn.trigger()),
|
||||
);
|
||||
|
|
|
@ -41,7 +41,7 @@ export default class Waveform extends React.PureComponent<IProps, IState> {
|
|||
progress: 1,
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
return (
|
||||
<div className="mx_Waveform">
|
||||
{this.props.relHeights.map((h, i) => {
|
||||
|
|
|
@ -122,7 +122,7 @@ export default class CaptchaForm extends React.Component<ICaptchaFormProps, ICap
|
|||
}
|
||||
}
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
let error = null;
|
||||
if (this.state.errorText) {
|
||||
error = <div className="error">{this.state.errorText}</div>;
|
||||
|
|
|
@ -21,7 +21,7 @@ import SdkConfig from "../../../SdkConfig";
|
|||
import { _t } from "../../../languageHandler";
|
||||
import Dropdown from "../elements/Dropdown";
|
||||
|
||||
const COUNTRIES_BY_ISO2 = {};
|
||||
const COUNTRIES_BY_ISO2: Record<string, PhoneNumberCountryDefinition> = {};
|
||||
for (const c of COUNTRIES) {
|
||||
COUNTRIES_BY_ISO2[c.iso2] = c;
|
||||
}
|
||||
|
|
|
@ -74,7 +74,7 @@ class EmailField extends PureComponent<IProps> {
|
|||
return result;
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
return (
|
||||
<Field
|
||||
id={this.props.id}
|
||||
|
|
|
@ -100,7 +100,7 @@ interface IPasswordAuthEntryState {
|
|||
export class PasswordAuthEntry extends React.Component<IAuthEntryProps, IPasswordAuthEntryState> {
|
||||
public static LOGIN_TYPE = AuthType.Password;
|
||||
|
||||
public constructor(props) {
|
||||
public constructor(props: IAuthEntryProps) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
|
@ -136,7 +136,7 @@ export class PasswordAuthEntry extends React.Component<IAuthEntryProps, IPasswor
|
|||
});
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
const passwordBoxClass = classNames({
|
||||
error: this.props.errorText,
|
||||
});
|
||||
|
@ -207,7 +207,7 @@ export class RecaptchaAuthEntry extends React.Component<IRecaptchaAuthEntryProps
|
|||
});
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
if (this.props.busy) {
|
||||
return <Spinner />;
|
||||
}
|
||||
|
@ -264,7 +264,7 @@ interface ITermsAuthEntryState {
|
|||
export class TermsAuthEntry extends React.Component<ITermsAuthEntryProps, ITermsAuthEntryState> {
|
||||
public static LOGIN_TYPE = AuthType.Terms;
|
||||
|
||||
public constructor(props) {
|
||||
public constructor(props: ITermsAuthEntryProps) {
|
||||
super(props);
|
||||
|
||||
// example stageParams:
|
||||
|
@ -288,8 +288,12 @@ export class TermsAuthEntry extends React.Component<ITermsAuthEntryProps, ITerms
|
|||
|
||||
const allPolicies = this.props.stageParams.policies || {};
|
||||
const prefLang = SettingsStore.getValue("language");
|
||||
const initToggles = {};
|
||||
const pickedPolicies = [];
|
||||
const initToggles: Record<string, boolean> = {};
|
||||
const pickedPolicies: {
|
||||
id: string;
|
||||
name: string;
|
||||
url: string;
|
||||
}[] = [];
|
||||
for (const policyId of Object.keys(allPolicies)) {
|
||||
const policy = allPolicies[policyId];
|
||||
|
||||
|
@ -325,7 +329,7 @@ export class TermsAuthEntry extends React.Component<ITermsAuthEntryProps, ITerms
|
|||
}
|
||||
|
||||
private togglePolicy(policyId: string): void {
|
||||
const newToggles = {};
|
||||
const newToggles: Record<string, boolean> = {};
|
||||
for (const policy of this.state.policies) {
|
||||
let checked = this.state.toggledPolicies[policy.id];
|
||||
if (policy.id === policyId) checked = !checked;
|
||||
|
@ -349,7 +353,7 @@ export class TermsAuthEntry extends React.Component<ITermsAuthEntryProps, ITerms
|
|||
}
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
if (this.props.busy) {
|
||||
return <Spinner />;
|
||||
}
|
||||
|
@ -438,7 +442,7 @@ export class EmailIdentityAuthEntry extends React.Component<
|
|||
this.props.onPhaseChange(DEFAULT_PHASE);
|
||||
}
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
let errorSection;
|
||||
// ignore the error when errcode is M_UNAUTHORIZED as we expect that error until the link is clicked.
|
||||
if (this.props.errorText && this.props.errorCode !== "M_UNAUTHORIZED") {
|
||||
|
@ -484,7 +488,7 @@ export class EmailIdentityAuthEntry extends React.Component<
|
|||
{
|
||||
a: (text: string) => (
|
||||
<Fragment>
|
||||
<AccessibleButton kind="link_inline" onClick={() => null} disabled>
|
||||
<AccessibleButton kind="link_inline" onClick={null} disabled>
|
||||
{text} <Spinner w={14} h={14} />
|
||||
</AccessibleButton>
|
||||
</Fragment>
|
||||
|
@ -555,7 +559,7 @@ export class MsisdnAuthEntry extends React.Component<IMsisdnAuthEntryProps, IMsi
|
|||
private sid: string;
|
||||
private msisdn: string;
|
||||
|
||||
public constructor(props) {
|
||||
public constructor(props: IMsisdnAuthEntryProps) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
|
@ -646,7 +650,7 @@ export class MsisdnAuthEntry extends React.Component<IMsisdnAuthEntryProps, IMsi
|
|||
}
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
if (this.state.requestingToken) {
|
||||
return <Spinner />;
|
||||
} else {
|
||||
|
@ -729,7 +733,7 @@ export class RegistrationTokenAuthEntry extends React.Component<IAuthEntryProps,
|
|||
});
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
const registrationTokenBoxClass = classNames({
|
||||
error: this.props.errorText,
|
||||
});
|
||||
|
@ -853,7 +857,7 @@ export class SSOAuthEntry extends React.Component<ISSOAuthEntryProps, ISSOAuthEn
|
|||
this.props.submitAuthDict({});
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
let continueButton = null;
|
||||
const cancelButton = (
|
||||
<AccessibleButton
|
||||
|
@ -908,7 +912,7 @@ export class FallbackAuthEntry extends React.Component<IAuthEntryProps> {
|
|||
private popupWindow: Window;
|
||||
private fallbackButton = createRef<HTMLButtonElement>();
|
||||
|
||||
public constructor(props) {
|
||||
public constructor(props: IAuthEntryProps) {
|
||||
super(props);
|
||||
|
||||
// we have to make the user click a button, as browsers will block
|
||||
|
@ -948,7 +952,7 @@ export class FallbackAuthEntry extends React.Component<IAuthEntryProps> {
|
|||
}
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
let errorSection;
|
||||
if (this.props.errorText) {
|
||||
errorSection = (
|
||||
|
|
|
@ -75,7 +75,7 @@ interface IState {
|
|||
* This uses the unstable feature of MSC3906: https://github.com/matrix-org/matrix-spec-proposals/pull/3906
|
||||
*/
|
||||
export default class LoginWithQR extends React.Component<IProps, IState> {
|
||||
public constructor(props) {
|
||||
public constructor(props: IProps) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
|
@ -229,7 +229,7 @@ export default class LoginWithQR extends React.Component<IProps, IState> {
|
|||
}
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
return (
|
||||
<LoginWithQRFlow
|
||||
onClick={this.onClick}
|
||||
|
|
|
@ -41,7 +41,7 @@ interface IProps {
|
|||
* This uses the unstable feature of MSC3906: https://github.com/matrix-org/matrix-spec-proposals/pull/3906
|
||||
*/
|
||||
export default class LoginWithQRFlow extends React.Component<IProps> {
|
||||
public constructor(props) {
|
||||
public constructor(props: IProps) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
|
@ -69,7 +69,7 @@ export default class LoginWithQRFlow extends React.Component<IProps> {
|
|||
);
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
let title = "";
|
||||
let titleIcon: JSX.Element | undefined;
|
||||
let main: JSX.Element | undefined;
|
||||
|
@ -184,7 +184,11 @@ export default class LoginWithQRFlow extends React.Component<IProps> {
|
|||
<p>{_t("Scan the QR code below with your device that's signed out.")}</p>
|
||||
<ol>
|
||||
<li>{_t("Start at the sign in screen")}</li>
|
||||
<li>{_t("Select 'Scan QR code'")}</li>
|
||||
<li>
|
||||
{_t("Select '%(scanQRCode)s'", {
|
||||
scanQRCode: _t("Scan QR code"),
|
||||
})}
|
||||
</li>
|
||||
<li>{_t("Review and approve the sign in")}</li>
|
||||
</ol>
|
||||
{code}
|
||||
|
|
|
@ -30,8 +30,8 @@ interface IProps extends Omit<IInputProps, "onValidate"> {
|
|||
labelRequired?: string;
|
||||
labelInvalid?: string;
|
||||
|
||||
onChange(ev: React.FormEvent<HTMLElement>);
|
||||
onValidate?(result: IValidationResult);
|
||||
onChange(ev: React.FormEvent<HTMLElement>): void;
|
||||
onValidate?(result: IValidationResult): void;
|
||||
}
|
||||
|
||||
class PassphraseConfirmField extends PureComponent<IProps> {
|
||||
|
@ -65,7 +65,7 @@ class PassphraseConfirmField extends PureComponent<IProps> {
|
|||
return result;
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
return (
|
||||
<Field
|
||||
id={this.props.id}
|
||||
|
|
|
@ -36,8 +36,8 @@ interface IProps extends Omit<IInputProps, "onValidate"> {
|
|||
labelStrongPassword?: string;
|
||||
labelAllowedButUnsafe?: string;
|
||||
|
||||
onChange(ev: React.FormEvent<HTMLElement>);
|
||||
onValidate?(result: IValidationResult);
|
||||
onChange(ev: React.FormEvent<HTMLElement>): void;
|
||||
onValidate?(result: IValidationResult): void;
|
||||
}
|
||||
|
||||
class PassphraseField extends PureComponent<IProps> {
|
||||
|
@ -102,7 +102,7 @@ class PassphraseField extends PureComponent<IProps> {
|
|||
return result;
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
return (
|
||||
<Field
|
||||
id={this.props.id}
|
||||
|
|
|
@ -14,17 +14,18 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import React, { SyntheticEvent } from "react";
|
||||
import classNames from "classnames";
|
||||
|
||||
import { _t } from "../../../languageHandler";
|
||||
import SdkConfig from "../../../SdkConfig";
|
||||
import { ValidatedServerConfig } from "../../../utils/ValidatedServerConfig";
|
||||
import AccessibleButton from "../elements/AccessibleButton";
|
||||
import withValidation, { IValidationResult } from "../elements/Validation";
|
||||
import AccessibleButton, { ButtonEvent } from "../elements/AccessibleButton";
|
||||
import withValidation, { IFieldState, IValidationResult } from "../elements/Validation";
|
||||
import Field from "../elements/Field";
|
||||
import CountryDropdown from "./CountryDropdown";
|
||||
import EmailField from "./EmailField";
|
||||
import { PhoneNumberCountryDefinition } from "../../../phonenumber";
|
||||
|
||||
// For validating phone numbers without country codes
|
||||
const PHONE_NUMBER_REGEX = /^[0-9()\-\s]*$/;
|
||||
|
@ -51,7 +52,7 @@ interface IProps {
|
|||
interface IState {
|
||||
fieldValid: Partial<Record<LoginField, boolean>>;
|
||||
loginType: LoginField.Email | LoginField.MatrixId | LoginField.Phone;
|
||||
password: "";
|
||||
password: string;
|
||||
}
|
||||
|
||||
const enum LoginField {
|
||||
|
@ -66,6 +67,10 @@ const enum LoginField {
|
|||
* The email/username/phone fields are fully-controlled, the password field is not.
|
||||
*/
|
||||
export default class PasswordLogin extends React.PureComponent<IProps, IState> {
|
||||
private [LoginField.Email]: Field;
|
||||
private [LoginField.Phone]: Field;
|
||||
private [LoginField.MatrixId]: Field;
|
||||
|
||||
public static defaultProps = {
|
||||
onUsernameChanged: function () {},
|
||||
onUsernameBlur: function () {},
|
||||
|
@ -75,7 +80,7 @@ export default class PasswordLogin extends React.PureComponent<IProps, IState> {
|
|||
disableSubmit: false,
|
||||
};
|
||||
|
||||
public constructor(props) {
|
||||
public constructor(props: IProps) {
|
||||
super(props);
|
||||
this.state = {
|
||||
// Field error codes by field ID
|
||||
|
@ -85,13 +90,13 @@ export default class PasswordLogin extends React.PureComponent<IProps, IState> {
|
|||
};
|
||||
}
|
||||
|
||||
private onForgotPasswordClick = (ev): void => {
|
||||
private onForgotPasswordClick = (ev: ButtonEvent): void => {
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
this.props.onForgotPasswordClick();
|
||||
};
|
||||
|
||||
private onSubmitForm = async (ev): Promise<void> => {
|
||||
private onSubmitForm = async (ev: SyntheticEvent): Promise<void> => {
|
||||
ev.preventDefault();
|
||||
|
||||
const allFieldsValid = await this.verifyFieldsBeforeSubmit();
|
||||
|
@ -99,47 +104,40 @@ export default class PasswordLogin extends React.PureComponent<IProps, IState> {
|
|||
return;
|
||||
}
|
||||
|
||||
let username = ""; // XXX: Synapse breaks if you send null here:
|
||||
let phoneCountry = null;
|
||||
let phoneNumber = null;
|
||||
|
||||
switch (this.state.loginType) {
|
||||
case LoginField.Email:
|
||||
case LoginField.MatrixId:
|
||||
username = this.props.username;
|
||||
this.props.onSubmit(this.props.username, undefined, undefined, this.state.password);
|
||||
break;
|
||||
case LoginField.Phone:
|
||||
phoneCountry = this.props.phoneCountry;
|
||||
phoneNumber = this.props.phoneNumber;
|
||||
this.props.onSubmit(undefined, this.props.phoneCountry, this.props.phoneNumber, this.state.password);
|
||||
break;
|
||||
}
|
||||
|
||||
this.props.onSubmit(username, phoneCountry, phoneNumber, this.state.password);
|
||||
};
|
||||
|
||||
private onUsernameChanged = (ev): void => {
|
||||
private onUsernameChanged = (ev: React.ChangeEvent<HTMLInputElement>): void => {
|
||||
this.props.onUsernameChanged(ev.target.value);
|
||||
};
|
||||
|
||||
private onUsernameBlur = (ev): void => {
|
||||
private onUsernameBlur = (ev: React.FocusEvent<HTMLInputElement>): void => {
|
||||
this.props.onUsernameBlur(ev.target.value);
|
||||
};
|
||||
|
||||
private onLoginTypeChange = (ev): void => {
|
||||
const loginType = ev.target.value;
|
||||
private onLoginTypeChange = (ev: React.ChangeEvent<HTMLSelectElement>): void => {
|
||||
const loginType = ev.target.value as IState["loginType"];
|
||||
this.setState({ loginType });
|
||||
this.props.onUsernameChanged(""); // Reset because email and username use the same state
|
||||
};
|
||||
|
||||
private onPhoneCountryChanged = (country): void => {
|
||||
private onPhoneCountryChanged = (country: PhoneNumberCountryDefinition): void => {
|
||||
this.props.onPhoneCountryChanged(country.iso2);
|
||||
};
|
||||
|
||||
private onPhoneNumberChanged = (ev): void => {
|
||||
private onPhoneNumberChanged = (ev: React.ChangeEvent<HTMLInputElement>): void => {
|
||||
this.props.onPhoneNumberChanged(ev.target.value);
|
||||
};
|
||||
|
||||
private onPasswordChanged = (ev): void => {
|
||||
private onPasswordChanged = (ev: React.ChangeEvent<HTMLInputElement>): void => {
|
||||
this.setState({ password: ev.target.value });
|
||||
};
|
||||
|
||||
|
@ -151,7 +149,7 @@ export default class PasswordLogin extends React.PureComponent<IProps, IState> {
|
|||
activeElement.blur();
|
||||
}
|
||||
|
||||
const fieldIDsInDisplayOrder = [this.state.loginType, LoginField.Password];
|
||||
const fieldIDsInDisplayOrder: LoginField[] = [this.state.loginType, LoginField.Password];
|
||||
|
||||
// Run all fields with stricter validation that no longer allows empty
|
||||
// values for required fields.
|
||||
|
@ -221,7 +219,7 @@ export default class PasswordLogin extends React.PureComponent<IProps, IState> {
|
|||
],
|
||||
});
|
||||
|
||||
private onUsernameValidate = async (fieldState): Promise<IValidationResult> => {
|
||||
private onUsernameValidate = async (fieldState: IFieldState): Promise<IValidationResult> => {
|
||||
const result = await this.validateUsernameRules(fieldState);
|
||||
this.markFieldValid(LoginField.MatrixId, result.valid);
|
||||
return result;
|
||||
|
@ -248,7 +246,7 @@ export default class PasswordLogin extends React.PureComponent<IProps, IState> {
|
|||
],
|
||||
});
|
||||
|
||||
private onPhoneNumberValidate = async (fieldState): Promise<IValidationResult> => {
|
||||
private onPhoneNumberValidate = async (fieldState: IFieldState): Promise<IValidationResult> => {
|
||||
const result = await this.validatePhoneNumberRules(fieldState);
|
||||
this.markFieldValid(LoginField.Password, result.valid);
|
||||
return result;
|
||||
|
@ -266,7 +264,7 @@ export default class PasswordLogin extends React.PureComponent<IProps, IState> {
|
|||
],
|
||||
});
|
||||
|
||||
private onPasswordValidate = async (fieldState): Promise<IValidationResult> => {
|
||||
private onPasswordValidate = async (fieldState: IFieldState): Promise<IValidationResult> => {
|
||||
const result = await this.validatePasswordRules(fieldState);
|
||||
this.markFieldValid(LoginField.Password, result.valid);
|
||||
return result;
|
||||
|
@ -369,7 +367,7 @@ export default class PasswordLogin extends React.PureComponent<IProps, IState> {
|
|||
}
|
||||
}
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
let forgotPasswordJsx;
|
||||
|
||||
if (this.props.onForgotPasswordClick) {
|
||||
|
|
|
@ -15,18 +15,18 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import React, { BaseSyntheticEvent } from "react";
|
||||
import { MatrixClient } from "matrix-js-sdk/src/client";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { MatrixError } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import * as Email from "../../../email";
|
||||
import { looksValid as phoneNumberLooksValid } from "../../../phonenumber";
|
||||
import { looksValid as phoneNumberLooksValid, PhoneNumberCountryDefinition } from "../../../phonenumber";
|
||||
import Modal from "../../../Modal";
|
||||
import { _t, _td } from "../../../languageHandler";
|
||||
import SdkConfig from "../../../SdkConfig";
|
||||
import { SAFE_LOCALPART_REGEX } from "../../../Registration";
|
||||
import withValidation, { IValidationResult } from "../elements/Validation";
|
||||
import withValidation, { IFieldState, IValidationResult } from "../elements/Validation";
|
||||
import { ValidatedServerConfig } from "../../../utils/ValidatedServerConfig";
|
||||
import EmailField from "./EmailField";
|
||||
import PassphraseField from "./PassphraseField";
|
||||
|
@ -95,12 +95,18 @@ interface IState {
|
|||
* A pure UI component which displays a registration form.
|
||||
*/
|
||||
export default class RegistrationForm extends React.PureComponent<IProps, IState> {
|
||||
private [RegistrationField.Email]: Field;
|
||||
private [RegistrationField.Password]: Field;
|
||||
private [RegistrationField.PasswordConfirm]: Field;
|
||||
private [RegistrationField.Username]: Field;
|
||||
private [RegistrationField.PhoneNumber]: Field;
|
||||
|
||||
public static defaultProps = {
|
||||
onValidationChange: logger.error,
|
||||
canSubmit: true,
|
||||
};
|
||||
|
||||
public constructor(props) {
|
||||
public constructor(props: IProps) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
|
@ -115,7 +121,9 @@ export default class RegistrationForm extends React.PureComponent<IProps, IState
|
|||
};
|
||||
}
|
||||
|
||||
private onSubmit = async (ev): Promise<void> => {
|
||||
private onSubmit = async (
|
||||
ev: BaseSyntheticEvent<Event, EventTarget & HTMLFormElement, EventTarget & HTMLFormElement>,
|
||||
): Promise<void> => {
|
||||
ev.preventDefault();
|
||||
ev.persist();
|
||||
|
||||
|
@ -152,7 +160,9 @@ export default class RegistrationForm extends React.PureComponent<IProps, IState
|
|||
}
|
||||
};
|
||||
|
||||
private doSubmit(ev): void {
|
||||
private doSubmit(
|
||||
ev: BaseSyntheticEvent<Event, EventTarget & HTMLFormElement, EventTarget & HTMLFormElement>,
|
||||
): void {
|
||||
PosthogAnalytics.instance.setAuthenticationType("Password");
|
||||
|
||||
const email = this.state.email.trim();
|
||||
|
@ -248,7 +258,7 @@ export default class RegistrationForm extends React.PureComponent<IProps, IState
|
|||
});
|
||||
}
|
||||
|
||||
private onEmailChange = (ev): void => {
|
||||
private onEmailChange = (ev: React.ChangeEvent<HTMLInputElement>): void => {
|
||||
this.setState({
|
||||
email: ev.target.value.trim(),
|
||||
});
|
||||
|
@ -277,7 +287,7 @@ export default class RegistrationForm extends React.PureComponent<IProps, IState
|
|||
],
|
||||
});
|
||||
|
||||
private onPasswordChange = (ev): void => {
|
||||
private onPasswordChange = (ev: React.ChangeEvent<HTMLInputElement>): void => {
|
||||
this.setState({
|
||||
password: ev.target.value,
|
||||
});
|
||||
|
@ -287,7 +297,7 @@ export default class RegistrationForm extends React.PureComponent<IProps, IState
|
|||
this.markFieldValid(RegistrationField.Password, result.valid);
|
||||
};
|
||||
|
||||
private onPasswordConfirmChange = (ev): void => {
|
||||
private onPasswordConfirmChange = (ev: React.ChangeEvent<HTMLInputElement>): void => {
|
||||
this.setState({
|
||||
passwordConfirm: ev.target.value,
|
||||
});
|
||||
|
@ -297,19 +307,19 @@ export default class RegistrationForm extends React.PureComponent<IProps, IState
|
|||
this.markFieldValid(RegistrationField.PasswordConfirm, result.valid);
|
||||
};
|
||||
|
||||
private onPhoneCountryChange = (newVal): void => {
|
||||
private onPhoneCountryChange = (newVal: PhoneNumberCountryDefinition): void => {
|
||||
this.setState({
|
||||
phoneCountry: newVal.iso2,
|
||||
});
|
||||
};
|
||||
|
||||
private onPhoneNumberChange = (ev): void => {
|
||||
private onPhoneNumberChange = (ev: React.ChangeEvent<HTMLInputElement>): void => {
|
||||
this.setState({
|
||||
phoneNumber: ev.target.value,
|
||||
});
|
||||
};
|
||||
|
||||
private onPhoneNumberValidate = async (fieldState): Promise<IValidationResult> => {
|
||||
private onPhoneNumberValidate = async (fieldState: IFieldState): Promise<IValidationResult> => {
|
||||
const result = await this.validatePhoneNumberRules(fieldState);
|
||||
this.markFieldValid(RegistrationField.PhoneNumber, result.valid);
|
||||
return result;
|
||||
|
@ -334,13 +344,13 @@ export default class RegistrationForm extends React.PureComponent<IProps, IState
|
|||
],
|
||||
});
|
||||
|
||||
private onUsernameChange = (ev): void => {
|
||||
private onUsernameChange = (ev: React.ChangeEvent<HTMLInputElement>): void => {
|
||||
this.setState({
|
||||
username: ev.target.value,
|
||||
});
|
||||
};
|
||||
|
||||
private onUsernameValidate = async (fieldState): Promise<IValidationResult> => {
|
||||
private onUsernameValidate = async (fieldState: IFieldState): Promise<IValidationResult> => {
|
||||
const result = await this.validateUsernameRules(fieldState);
|
||||
this.markFieldValid(RegistrationField.Username, result.valid);
|
||||
return result;
|
||||
|
@ -524,7 +534,7 @@ export default class RegistrationForm extends React.PureComponent<IProps, IState
|
|||
);
|
||||
}
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
const registerButton = (
|
||||
<input className="mx_Login_submit" type="submit" value={_t("Register")} disabled={!this.props.canSubmit} />
|
||||
);
|
||||
|
|
|
@ -48,7 +48,7 @@ interface IProps {
|
|||
tabIndex?: number;
|
||||
}
|
||||
|
||||
const calculateUrls = (url: string, urls: string[], lowBandwidth: boolean): string[] => {
|
||||
const calculateUrls = (url?: string, urls?: string[], lowBandwidth = false): string[] => {
|
||||
// work out the full set of urls to try to load. This is formed like so:
|
||||
// imageUrls: [ props.url, ...props.urls ]
|
||||
|
||||
|
@ -66,7 +66,7 @@ const calculateUrls = (url: string, urls: string[], lowBandwidth: boolean): stri
|
|||
return Array.from(new Set(_urls));
|
||||
};
|
||||
|
||||
const useImageUrl = ({ url, urls }): [string, () => void] => {
|
||||
const useImageUrl = ({ url, urls }: { url?: string; urls?: string[] }): [string, () => void] => {
|
||||
// Since this is a hot code path and the settings store can be slow, we
|
||||
// use the cached lowBandwidth value from the room context if it exists
|
||||
const roomContext = useContext(RoomContext);
|
||||
|
|
|
@ -109,7 +109,7 @@ export default function MemberAvatar({
|
|||
}
|
||||
|
||||
export class LegacyMemberAvatar extends React.Component<IProps> {
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
return <MemberAvatar {...this.props}>{this.props.children}</MemberAvatar>;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -135,7 +135,7 @@ export default class RoomAvatar extends React.Component<IProps, IState> {
|
|||
return this.props.room?.roomId || this.props.oobData?.roomId;
|
||||
}
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
const { room, oobData, viewAvatarOnClick, onClick, className, ...otherProps } = this.props;
|
||||
const roomName = room?.name ?? oobData.name;
|
||||
|
||||
|
|
|
@ -91,7 +91,7 @@ const BetaCard: React.FC<IProps> = ({ title: titleOverride, featureId }) => {
|
|||
);
|
||||
}
|
||||
|
||||
let refreshWarning: string;
|
||||
let refreshWarning: string | undefined;
|
||||
if (requiresRefresh) {
|
||||
const brand = SdkConfig.get().brand;
|
||||
refreshWarning = value
|
||||
|
|
|
@ -34,7 +34,7 @@ interface IState {
|
|||
export default class DialpadContextMenu extends React.Component<IProps, IState> {
|
||||
private numberEntryFieldRef: React.RefObject<Field> = createRef();
|
||||
|
||||
public constructor(props) {
|
||||
public constructor(props: IProps) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
|
@ -58,18 +58,18 @@ export default class DialpadContextMenu extends React.Component<IProps, IState>
|
|||
this.props.onFinished();
|
||||
};
|
||||
|
||||
public onKeyDown = (ev): void => {
|
||||
public onKeyDown = (ev: React.KeyboardEvent): void => {
|
||||
// Prevent Backspace and Delete keys from functioning in the entry field
|
||||
if (ev.code === "Backspace" || ev.code === "Delete") {
|
||||
ev.preventDefault();
|
||||
}
|
||||
};
|
||||
|
||||
public onChange = (ev): void => {
|
||||
public onChange = (ev: React.ChangeEvent<HTMLInputElement>): void => {
|
||||
this.setState({ value: ev.target.value });
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
return (
|
||||
<ContextMenu {...this.props}>
|
||||
<div className="mx_DialPadContextMenuWrapper">
|
||||
|
|
|
@ -47,7 +47,7 @@ export default class GenericElementContextMenu extends React.Component<IProps> {
|
|||
}
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
return <div>{this.props.element}</div>;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ interface IProps {
|
|||
}
|
||||
|
||||
export default class GenericTextContextMenu extends React.Component<IProps> {
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
return (
|
||||
<div className="mx_Tooltip mx_Tooltip_visible" style={{ display: "block" }}>
|
||||
{this.props.message}
|
||||
|
|
|
@ -26,7 +26,7 @@ interface IProps extends IContextMenuProps {
|
|||
}
|
||||
|
||||
export default class LegacyCallContextMenu extends React.Component<IProps> {
|
||||
public constructor(props) {
|
||||
public constructor(props: IProps) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,7 @@ export default class LegacyCallContextMenu extends React.Component<IProps> {
|
|||
this.props.onFinished();
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
const holdUnholdCaption = this.props.call.isRemoteOnHold() ? _t("Resume") : _t("Hold");
|
||||
const handler = this.props.call.isRemoteOnHold() ? this.onUnholdClick : this.onHoldClick;
|
||||
|
||||
|
|
|
@ -376,7 +376,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
|
|||
this.closeMenu();
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
const cli = MatrixClientPeg.get();
|
||||
const me = cli.getUserId();
|
||||
const { mxEvent, rightClick, link, eventTileOps, reactions, collapseReplyChain, ...other } = this.props;
|
||||
|
|
|
@ -48,7 +48,7 @@ export default class AskInviteAnywayDialog extends React.Component<IProps> {
|
|||
this.props.onFinished(false);
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
const errorList = this.props.unknownProfileUsers.map((address) => (
|
||||
<li key={address.userId}>
|
||||
{address.userId}: {address.errorText}
|
||||
|
|
|
@ -88,7 +88,7 @@ export default class BaseDialog extends React.Component<IProps> {
|
|||
fixedWidth: true,
|
||||
};
|
||||
|
||||
public constructor(props) {
|
||||
public constructor(props: IProps) {
|
||||
super(props);
|
||||
|
||||
this.matrixClient = MatrixClientPeg.get();
|
||||
|
@ -115,7 +115,7 @@ export default class BaseDialog extends React.Component<IProps> {
|
|||
this.props.onFinished(false);
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
let cancelButton;
|
||||
if (this.props.hasCancel) {
|
||||
cancelButton = (
|
||||
|
@ -132,7 +132,7 @@ export default class BaseDialog extends React.Component<IProps> {
|
|||
headerImage = <img className="mx_Dialog_titleImage" src={this.props.headerImage} alt="" />;
|
||||
}
|
||||
|
||||
const lockProps = {
|
||||
const lockProps: Record<string, any> = {
|
||||
"onKeyDown": this.onKeyDown,
|
||||
"role": "dialog",
|
||||
// This should point to a node describing the dialog.
|
||||
|
|
|
@ -54,7 +54,7 @@ interface IState {
|
|||
export default class BugReportDialog extends React.Component<IProps, IState> {
|
||||
private unmounted: boolean;
|
||||
|
||||
public constructor(props) {
|
||||
public constructor(props: IProps) {
|
||||
super(props);
|
||||
this.state = {
|
||||
sendLogs: true,
|
||||
|
@ -180,7 +180,7 @@ export default class BugReportDialog extends React.Component<IProps, IState> {
|
|||
this.setState({ downloadProgress });
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
let error = null;
|
||||
if (this.state.err) {
|
||||
error = <div className="error">{this.state.err}</div>;
|
||||
|
|
|
@ -21,6 +21,7 @@ import { RoomMember } from "matrix-js-sdk/src/models/room-member";
|
|||
import { Room } from "matrix-js-sdk/src/models/room";
|
||||
import { EventTimeline } from "matrix-js-sdk/src/models/event-timeline";
|
||||
import { EventType } from "matrix-js-sdk/src/@types/event";
|
||||
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
|
||||
|
||||
import { _t } from "../../../languageHandler";
|
||||
import dis from "../../../dispatcher/dispatcher";
|
||||
|
@ -42,7 +43,7 @@ const BulkRedactDialog: React.FC<IBulkRedactDialogProps> = (props) => {
|
|||
const [keepStateEvents, setKeepStateEvents] = useState(true);
|
||||
|
||||
let timeline = room.getLiveTimeline();
|
||||
let eventsToRedact = [];
|
||||
let eventsToRedact: MatrixEvent[] = [];
|
||||
while (timeline) {
|
||||
eventsToRedact = [
|
||||
...eventsToRedact,
|
||||
|
|
|
@ -27,16 +27,26 @@ interface IProps {
|
|||
onFinished: (success: boolean) => void;
|
||||
}
|
||||
|
||||
const REPOS = ["vector-im/element-web", "matrix-org/matrix-react-sdk", "matrix-org/matrix-js-sdk"];
|
||||
type State = Partial<Record<typeof REPOS[number], null | string | Commit[]>>;
|
||||
|
||||
export default class ChangelogDialog extends React.Component<IProps> {
|
||||
public constructor(props) {
|
||||
interface Commit {
|
||||
sha: string;
|
||||
html_url: string;
|
||||
commit: {
|
||||
message: string;
|
||||
};
|
||||
}
|
||||
|
||||
const REPOS = ["vector-im/element-web", "matrix-org/matrix-react-sdk", "matrix-org/matrix-js-sdk"] as const;
|
||||
|
||||
export default class ChangelogDialog extends React.Component<IProps, State> {
|
||||
public constructor(props: IProps) {
|
||||
super(props);
|
||||
|
||||
this.state = {};
|
||||
}
|
||||
|
||||
private async fetchChanges(repo: string, oldVersion: string, newVersion: string): Promise<void> {
|
||||
private async fetchChanges(repo: typeof REPOS[number], oldVersion: string, newVersion: string): Promise<void> {
|
||||
const url = `https://riot.im/github/repos/${repo}/compare/${oldVersion}...${newVersion}`;
|
||||
|
||||
try {
|
||||
|
@ -66,7 +76,7 @@ export default class ChangelogDialog extends React.Component<IProps> {
|
|||
}
|
||||
}
|
||||
|
||||
private elementsForCommit(commit): JSX.Element {
|
||||
private elementsForCommit(commit: Commit): JSX.Element {
|
||||
return (
|
||||
<li key={commit.sha} className="mx_ChangelogDialog_li">
|
||||
<a href={commit.html_url} target="_blank" rel="noreferrer noopener">
|
||||
|
@ -76,7 +86,7 @@ export default class ChangelogDialog extends React.Component<IProps> {
|
|||
);
|
||||
}
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
const logs = REPOS.map((repo) => {
|
||||
let content;
|
||||
if (this.state[repo] == null) {
|
||||
|
@ -86,7 +96,7 @@ export default class ChangelogDialog extends React.Component<IProps> {
|
|||
msg: this.state[repo],
|
||||
});
|
||||
} else {
|
||||
content = this.state[repo].map(this.elementsForCommit);
|
||||
content = (this.state[repo] as Commit[]).map(this.elementsForCommit);
|
||||
}
|
||||
return (
|
||||
<div key={repo}>
|
||||
|
|
|
@ -45,7 +45,7 @@ interface IState {
|
|||
* To avoid this, we keep the dialog open as long as /redact is in progress.
|
||||
*/
|
||||
export default class ConfirmAndWaitRedactDialog extends React.PureComponent<IProps, IState> {
|
||||
public constructor(props) {
|
||||
public constructor(props: IProps) {
|
||||
super(props);
|
||||
this.state = {
|
||||
isRedacting: false,
|
||||
|
@ -72,7 +72,7 @@ export default class ConfirmAndWaitRedactDialog extends React.PureComponent<IPro
|
|||
}
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
if (this.state.isRedacting) {
|
||||
if (this.state.redactionErrorCode) {
|
||||
const code = this.state.redactionErrorCode;
|
||||
|
|
|
@ -33,7 +33,7 @@ interface IProps {
|
|||
* A dialog for confirming a redaction.
|
||||
*/
|
||||
export default class ConfirmRedactDialog extends React.Component<IProps> {
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
return (
|
||||
<TextInputDialog
|
||||
onFinished={this.props.onFinished}
|
||||
|
|
|
@ -83,7 +83,7 @@ export default class ConfirmUserActionDialog extends React.Component<IProps, ISt
|
|||
});
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
const confirmButtonClass = this.props.danger ? "danger" : "";
|
||||
|
||||
let reasonBox;
|
||||
|
|
|
@ -33,7 +33,7 @@ export default class ConfirmWipeDeviceDialog extends React.Component<IProps> {
|
|||
this.props.onFinished(false);
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
return (
|
||||
<BaseDialog
|
||||
className="mx_ConfirmWipeDeviceDialog"
|
||||
|
|
|
@ -62,7 +62,7 @@ export default class CreateRoomDialog extends React.Component<IProps, IState> {
|
|||
private nameField = createRef<Field>();
|
||||
private aliasField = createRef<RoomAliasField>();
|
||||
|
||||
public constructor(props) {
|
||||
public constructor(props: IProps) {
|
||||
super(props);
|
||||
|
||||
this.supportsRestricted = !!this.props.parentSpace;
|
||||
|
@ -216,7 +216,7 @@ export default class CreateRoomDialog extends React.Component<IProps, IState> {
|
|||
],
|
||||
});
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
const isVideoRoom = this.props.type === RoomType.ElementVideo;
|
||||
|
||||
let aliasField: JSX.Element;
|
||||
|
|
|
@ -21,7 +21,7 @@ import { logger } from "matrix-js-sdk/src/logger";
|
|||
|
||||
import { _t } from "../../../languageHandler";
|
||||
import BaseDialog from "./BaseDialog";
|
||||
import AccessibleButton from "../elements/AccessibleButton";
|
||||
import AccessibleButton, { ButtonEvent } from "../elements/AccessibleButton";
|
||||
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
||||
import { BetaPill } from "../beta/BetaCard";
|
||||
import Field from "../elements/Field";
|
||||
|
@ -54,7 +54,7 @@ const CreateSubspaceDialog: React.FC<IProps> = ({ space, onAddExistingSpaceClick
|
|||
}
|
||||
const [joinRule, setJoinRule] = useState<JoinRule>(defaultJoinRule);
|
||||
|
||||
const onCreateSubspaceClick = async (e): Promise<void> => {
|
||||
const onCreateSubspaceClick = async (e: ButtonEvent): Promise<void> => {
|
||||
e.preventDefault();
|
||||
if (busy) return;
|
||||
|
||||
|
|
|
@ -28,6 +28,16 @@ import BaseDialog from "./BaseDialog";
|
|||
import defaultDispatcher from "../../../dispatcher/dispatcher";
|
||||
import { Action } from "../../../dispatcher/actions";
|
||||
|
||||
type DialogAesthetics = Partial<{
|
||||
[x in AuthType]: {
|
||||
[x: number]: {
|
||||
body: string;
|
||||
continueText?: string;
|
||||
continueKind?: string;
|
||||
};
|
||||
};
|
||||
}>;
|
||||
|
||||
interface IProps {
|
||||
onFinished: (success: boolean) => void;
|
||||
}
|
||||
|
@ -46,7 +56,7 @@ interface IState {
|
|||
}
|
||||
|
||||
export default class DeactivateAccountDialog extends React.Component<IProps, IState> {
|
||||
public constructor(props) {
|
||||
public constructor(props: IProps) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
|
@ -65,7 +75,7 @@ export default class DeactivateAccountDialog extends React.Component<IProps, ISt
|
|||
this.initAuth(/* shouldErase= */ false);
|
||||
}
|
||||
|
||||
private onStagePhaseChange = (stage: AuthType, phase: string): void => {
|
||||
private onStagePhaseChange = (stage: AuthType, phase: number): void => {
|
||||
const dialogAesthetics = {
|
||||
[SSOAuthEntry.PHASE_PREAUTH]: {
|
||||
body: _t("Confirm your account deactivation by using Single Sign On to prove your identity."),
|
||||
|
@ -80,7 +90,7 @@ export default class DeactivateAccountDialog extends React.Component<IProps, ISt
|
|||
};
|
||||
|
||||
// This is the same as aestheticsForStagePhases in InteractiveAuthDialog minus the `title`
|
||||
const DEACTIVATE_AESTHETICS = {
|
||||
const DEACTIVATE_AESTHETICS: DialogAesthetics = {
|
||||
[SSOAuthEntry.LOGIN_TYPE]: dialogAesthetics,
|
||||
[SSOAuthEntry.UNSTABLE_LOGIN_TYPE]: dialogAesthetics,
|
||||
[PasswordAuthEntry.LOGIN_TYPE]: {
|
||||
|
@ -96,9 +106,9 @@ export default class DeactivateAccountDialog extends React.Component<IProps, ISt
|
|||
let continueKind = null;
|
||||
if (aesthetics) {
|
||||
const phaseAesthetics = aesthetics[phase];
|
||||
if (phaseAesthetics && phaseAesthetics.body) bodyText = phaseAesthetics.body;
|
||||
if (phaseAesthetics && phaseAesthetics.continueText) continueText = phaseAesthetics.continueText;
|
||||
if (phaseAesthetics && phaseAesthetics.continueKind) continueKind = phaseAesthetics.continueKind;
|
||||
if (phaseAesthetics?.body) bodyText = phaseAesthetics.body;
|
||||
if (phaseAesthetics?.continueText) continueText = phaseAesthetics.continueText;
|
||||
if (phaseAesthetics?.continueKind) continueKind = phaseAesthetics.continueKind;
|
||||
}
|
||||
this.setState({ bodyText, continueText, continueKind });
|
||||
};
|
||||
|
@ -172,7 +182,7 @@ export default class DeactivateAccountDialog extends React.Component<IProps, ISt
|
|||
});
|
||||
}
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
let error = null;
|
||||
if (this.state.errStr) {
|
||||
error = <div className="error">{this.state.errStr}</div>;
|
||||
|
|
|
@ -91,7 +91,7 @@ const DevtoolsDialog: React.FC<IProps> = ({ roomId, onFinished }) => {
|
|||
<BaseTool onBack={onBack}>
|
||||
{Object.entries(Tools).map(([category, tools]) => (
|
||||
<div key={category}>
|
||||
<h3>{_t(categoryLabels[category])}</h3>
|
||||
<h3>{_t(categoryLabels[category as unknown as Category])}</h3>
|
||||
{tools.map(([label, tool]) => {
|
||||
const onClick = (): void => {
|
||||
setTool([label, tool]);
|
||||
|
|
|
@ -67,7 +67,7 @@ export default class EndPollDialog extends React.Component<IProps> {
|
|||
this.props.onFinished(endPoll);
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
return (
|
||||
<QuestionDialog
|
||||
title={_t("End Poll")}
|
||||
|
|
|
@ -46,16 +46,13 @@ interface IState {
|
|||
export default class ErrorDialog extends React.Component<IProps, IState> {
|
||||
public static defaultProps = {
|
||||
focus: true,
|
||||
title: null,
|
||||
description: null,
|
||||
button: null,
|
||||
};
|
||||
|
||||
private onClick = (): void => {
|
||||
this.props.onFinished(true);
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
return (
|
||||
<BaseDialog
|
||||
className="mx_ErrorDialog"
|
||||
|
|
|
@ -25,7 +25,14 @@ import DialogButtons from "../elements/DialogButtons";
|
|||
import Field from "../elements/Field";
|
||||
import StyledRadioGroup from "../elements/StyledRadioGroup";
|
||||
import StyledCheckbox from "../elements/StyledCheckbox";
|
||||
import { ExportFormat, ExportType, textForFormat, textForType } from "../../../utils/exportUtils/exportUtils";
|
||||
import {
|
||||
ExportFormat,
|
||||
ExportFormatKey,
|
||||
ExportType,
|
||||
ExportTypeKey,
|
||||
textForFormat,
|
||||
textForType,
|
||||
} from "../../../utils/exportUtils/exportUtils";
|
||||
import withValidation, { IFieldState, IValidationResult } from "../elements/Validation";
|
||||
import HTMLExporter from "../../../utils/exportUtils/HtmlExport";
|
||||
import JSONExporter from "../../../utils/exportUtils/JSONExport";
|
||||
|
@ -237,15 +244,15 @@ const ExportDialog: React.FC<IProps> = ({ room, onFinished }) => {
|
|||
setExporter(null);
|
||||
};
|
||||
|
||||
const exportFormatOptions = Object.keys(ExportFormat).map((format) => ({
|
||||
value: ExportFormat[format],
|
||||
label: textForFormat(ExportFormat[format]),
|
||||
const exportFormatOptions = Object.values(ExportFormat).map((format) => ({
|
||||
value: format,
|
||||
label: textForFormat(format),
|
||||
}));
|
||||
|
||||
const exportTypeOptions = Object.keys(ExportType).map((type) => {
|
||||
const exportTypeOptions = Object.values(ExportType).map((type) => {
|
||||
return (
|
||||
<option key={type} value={ExportType[type]}>
|
||||
{textForType(ExportType[type])}
|
||||
<option key={ExportType[type]} value={type}>
|
||||
{textForType(type)}
|
||||
</option>
|
||||
);
|
||||
});
|
||||
|
@ -332,7 +339,7 @@ const ExportDialog: React.FC<IProps> = ({ room, onFinished }) => {
|
|||
<StyledRadioGroup
|
||||
name="exportFormat"
|
||||
value={exportFormat}
|
||||
onChange={(key) => setExportFormat(ExportFormat[key])}
|
||||
onChange={(key: ExportFormatKey) => setExportFormat(ExportFormat[key])}
|
||||
definitions={exportFormatOptions}
|
||||
/>
|
||||
</>
|
||||
|
@ -347,7 +354,7 @@ const ExportDialog: React.FC<IProps> = ({ room, onFinished }) => {
|
|||
element="select"
|
||||
value={exportType}
|
||||
onChange={(e) => {
|
||||
setExportType(ExportType[e.target.value]);
|
||||
setExportType(ExportType[e.target.value as ExportTypeKey]);
|
||||
}}
|
||||
>
|
||||
{exportTypeOptions}
|
||||
|
|
|
@ -97,7 +97,7 @@ const FeedbackDialog: React.FC<IProps> = (props: IProps) => {
|
|||
);
|
||||
}
|
||||
|
||||
let bugReports = null;
|
||||
let bugReports: JSX.Element | null = null;
|
||||
if (rageshakeUrl) {
|
||||
bugReports = (
|
||||
<p className="mx_FeedbackDialog_section_microcopy">
|
||||
|
|
|
@ -243,7 +243,7 @@ const ForwardDialog: React.FC<IProps> = ({ matrixClient: cli, event, permalinkCr
|
|||
}
|
||||
|
||||
const [truncateAt, setTruncateAt] = useState(20);
|
||||
function overflowTile(overflowCount, totalCount): JSX.Element {
|
||||
function overflowTile(overflowCount: number, totalCount: number): JSX.Element {
|
||||
const text = _t("and %(count)s others...", { count: overflowCount });
|
||||
return (
|
||||
<EntityTile
|
||||
|
|
|
@ -155,7 +155,7 @@ export default class HostSignupDialog extends React.PureComponent<IProps, IState
|
|||
});
|
||||
}
|
||||
|
||||
private onAccountDetailsDialogFinished = async (result): Promise<void> => {
|
||||
private onAccountDetailsDialogFinished = async (result: boolean): Promise<void> => {
|
||||
if (result) {
|
||||
return this.sendAccountDetails();
|
||||
}
|
||||
|
|
|
@ -256,7 +256,7 @@ export default class IncomingSasDialog extends React.Component<IProps, IState> {
|
|||
return <VerificationCancelled onDone={this.onCancelClick} />;
|
||||
}
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
let body;
|
||||
switch (this.state.phase) {
|
||||
case PHASE_START:
|
||||
|
|
|
@ -44,7 +44,7 @@ export default class InfoDialog extends React.Component<IProps> {
|
|||
this.props.onFinished();
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
return (
|
||||
<BaseDialog
|
||||
className="mx_InfoDialog"
|
||||
|
|
|
@ -35,7 +35,7 @@ export default class IntegrationsDisabledDialog extends React.Component<IProps>
|
|||
dis.fire(Action.ViewUserSettings);
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
return (
|
||||
<BaseDialog
|
||||
className="mx_IntegrationsDisabledDialog"
|
||||
|
@ -44,7 +44,11 @@ export default class IntegrationsDisabledDialog extends React.Component<IProps>
|
|||
title={_t("Integrations are disabled")}
|
||||
>
|
||||
<div className="mx_IntegrationsDisabledDialog_content">
|
||||
<p>{_t("Enable 'Manage Integrations' in Settings to do this.")}</p>
|
||||
<p>
|
||||
{_t("Enable '%(manageIntegrations)s' in Settings to do this.", {
|
||||
manageIntegrations: _t("Manage integrations"),
|
||||
})}
|
||||
</p>
|
||||
</div>
|
||||
<DialogButtons
|
||||
primaryButton={_t("Settings")}
|
||||
|
|
|
@ -29,7 +29,7 @@ export default class IntegrationsImpossibleDialog extends React.Component<IProps
|
|||
this.props.onFinished();
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
const brand = SdkConfig.get().brand;
|
||||
|
||||
return (
|
||||
|
|
|
@ -18,7 +18,7 @@ limitations under the License.
|
|||
|
||||
import React from "react";
|
||||
import { MatrixClient } from "matrix-js-sdk/src/client";
|
||||
import { IAuthData } from "matrix-js-sdk/src/interactive-auth";
|
||||
import { AuthType, IAuthData } from "matrix-js-sdk/src/interactive-auth";
|
||||
|
||||
import { _t } from "../../../languageHandler";
|
||||
import AccessibleButton from "../elements/AccessibleButton";
|
||||
|
@ -27,8 +27,8 @@ import { SSOAuthEntry } from "../auth/InteractiveAuthEntryComponents";
|
|||
import BaseDialog from "./BaseDialog";
|
||||
import { IDialogProps } from "./IDialogProps";
|
||||
|
||||
interface IDialogAesthetics {
|
||||
[x: string]: {
|
||||
type DialogAesthetics = Partial<{
|
||||
[x in AuthType]: {
|
||||
[x: number]: {
|
||||
title: string;
|
||||
body: string;
|
||||
|
@ -36,7 +36,7 @@ interface IDialogAesthetics {
|
|||
continueKind: string;
|
||||
};
|
||||
};
|
||||
}
|
||||
}>;
|
||||
|
||||
export interface InteractiveAuthDialogProps extends IDialogProps {
|
||||
// matrix client to use for UI auth requests
|
||||
|
@ -71,15 +71,15 @@ export interface InteractiveAuthDialogProps extends IDialogProps {
|
|||
// }
|
||||
//
|
||||
// Default is defined in _getDefaultDialogAesthetics()
|
||||
aestheticsForStagePhases?: IDialogAesthetics;
|
||||
aestheticsForStagePhases?: DialogAesthetics;
|
||||
}
|
||||
|
||||
interface IState {
|
||||
authError: Error;
|
||||
|
||||
// See _onUpdateStagePhase()
|
||||
uiaStage: number | string;
|
||||
uiaStagePhase: number | string;
|
||||
uiaStage: AuthType | null;
|
||||
uiaStagePhase: number | null;
|
||||
}
|
||||
|
||||
export default class InteractiveAuthDialog extends React.Component<InteractiveAuthDialogProps, IState> {
|
||||
|
@ -95,7 +95,7 @@ export default class InteractiveAuthDialog extends React.Component<InteractiveAu
|
|||
};
|
||||
}
|
||||
|
||||
private getDefaultDialogAesthetics(): IDialogAesthetics {
|
||||
private getDefaultDialogAesthetics(): DialogAesthetics {
|
||||
const ssoAesthetics = {
|
||||
[SSOAuthEntry.PHASE_PREAUTH]: {
|
||||
title: _t("Use Single Sign On to continue"),
|
||||
|
@ -125,13 +125,13 @@ export default class InteractiveAuthDialog extends React.Component<InteractiveAu
|
|||
this.props.onFinished(false, null);
|
||||
} else {
|
||||
this.setState({
|
||||
authError: result,
|
||||
authError: result as Error,
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private onUpdateStagePhase = (newStage: string | number, newPhase: string | number): void => {
|
||||
private onUpdateStagePhase = (newStage: AuthType, newPhase: number): void => {
|
||||
// We copy the stage and stage phase params into state for title selection in render()
|
||||
this.setState({ uiaStage: newStage, uiaStagePhase: newPhase });
|
||||
};
|
||||
|
@ -140,7 +140,7 @@ export default class InteractiveAuthDialog extends React.Component<InteractiveAu
|
|||
this.props.onFinished(false);
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
// Let's pick a title, body, and other params text that we'll show to the user. The order
|
||||
// is most specific first, so stagePhase > our props > defaults.
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { createRef, ReactNode } from "react";
|
||||
import React, { createRef, ReactNode, SyntheticEvent } from "react";
|
||||
import classNames from "classnames";
|
||||
import { RoomMember } from "matrix-js-sdk/src/models/room-member";
|
||||
import { Room } from "matrix-js-sdk/src/models/room";
|
||||
|
@ -92,7 +92,7 @@ enum TabId {
|
|||
}
|
||||
|
||||
class DMUserTile extends React.PureComponent<IDMUserTileProps> {
|
||||
private onRemove = (e): void => {
|
||||
private onRemove = (e: ButtonEvent): void => {
|
||||
// Stop the browser from highlighting text
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
@ -100,7 +100,7 @@ class DMUserTile extends React.PureComponent<IDMUserTileProps> {
|
|||
this.props.onRemove(this.props.member);
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
const avatarSize = 20;
|
||||
const avatar = <SearchResultAvatar user={this.props.member} size={avatarSize} />;
|
||||
|
||||
|
@ -139,7 +139,7 @@ interface IDMRoomTileProps {
|
|||
}
|
||||
|
||||
class DMRoomTile extends React.PureComponent<IDMRoomTileProps> {
|
||||
private onClick = (e): void => {
|
||||
private onClick = (e: ButtonEvent): void => {
|
||||
// Stop the browser from highlighting text
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
@ -187,7 +187,7 @@ class DMRoomTile extends React.PureComponent<IDMRoomTileProps> {
|
|||
return result;
|
||||
}
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
let timestamp = null;
|
||||
if (this.props.lastActiveTs) {
|
||||
const humanTs = humanizeTime(this.props.lastActiveTs);
|
||||
|
@ -271,6 +271,10 @@ interface InviteRoomProps extends BaseProps {
|
|||
roomId: string;
|
||||
}
|
||||
|
||||
function isRoomInvite(props: Props): props is InviteRoomProps {
|
||||
return props.kind === KIND_INVITE;
|
||||
}
|
||||
|
||||
interface InviteCallProps extends BaseProps {
|
||||
kind: typeof KIND_CALL_TRANSFER;
|
||||
|
||||
|
@ -311,7 +315,7 @@ export default class InviteDialog extends React.PureComponent<Props, IInviteDial
|
|||
private numberEntryFieldRef: React.RefObject<Field> = createRef();
|
||||
private unmounted = false;
|
||||
|
||||
public constructor(props) {
|
||||
public constructor(props: Props) {
|
||||
super(props);
|
||||
|
||||
if (props.kind === KIND_INVITE && !props.roomId) {
|
||||
|
@ -321,7 +325,7 @@ export default class InviteDialog extends React.PureComponent<Props, IInviteDial
|
|||
}
|
||||
|
||||
const alreadyInvited = new Set([MatrixClientPeg.get().getUserId(), SdkConfig.get("welcome_user_id")]);
|
||||
if (props.roomId) {
|
||||
if (isRoomInvite(props)) {
|
||||
const room = MatrixClientPeg.get().getRoom(props.roomId);
|
||||
if (!room) throw new Error("Room ID given to InviteDialog does not look like a room");
|
||||
room.getMembersWithMembership("invite").forEach((m) => alreadyInvited.add(m.userId));
|
||||
|
@ -361,7 +365,7 @@ export default class InviteDialog extends React.PureComponent<Props, IInviteDial
|
|||
this.unmounted = true;
|
||||
}
|
||||
|
||||
private onConsultFirstChange = (ev): void => {
|
||||
private onConsultFirstChange = (ev: React.ChangeEvent<HTMLInputElement>): void => {
|
||||
this.setState({ consultFirst: ev.target.checked });
|
||||
};
|
||||
|
||||
|
@ -538,11 +542,11 @@ export default class InviteDialog extends React.PureComponent<Props, IInviteDial
|
|||
this.props.onFinished(true);
|
||||
};
|
||||
|
||||
private onKeyDown = (e): void => {
|
||||
private onKeyDown = (e: React.KeyboardEvent<HTMLInputElement>): void => {
|
||||
if (this.state.busy) return;
|
||||
|
||||
let handled = false;
|
||||
const value = e.target.value.trim();
|
||||
const value = e.currentTarget.value.trim();
|
||||
const action = getKeyBindingsManager().getAccessibilityAction(e);
|
||||
|
||||
switch (action) {
|
||||
|
@ -692,7 +696,7 @@ export default class InviteDialog extends React.PureComponent<Props, IInviteDial
|
|||
}
|
||||
};
|
||||
|
||||
private updateFilter = (e): void => {
|
||||
private updateFilter = (e: React.ChangeEvent<HTMLInputElement>): void => {
|
||||
const term = e.target.value;
|
||||
this.setState({ filterText: term });
|
||||
|
||||
|
@ -750,7 +754,7 @@ export default class InviteDialog extends React.PureComponent<Props, IInviteDial
|
|||
}
|
||||
};
|
||||
|
||||
private onPaste = async (e): Promise<void> => {
|
||||
private onPaste = async (e: React.ClipboardEvent): Promise<void> => {
|
||||
if (this.state.filterText) {
|
||||
// if the user has already typed something, just let them
|
||||
// paste normally.
|
||||
|
@ -825,7 +829,7 @@ export default class InviteDialog extends React.PureComponent<Props, IInviteDial
|
|||
this.setState({ targets: [...this.state.targets, ...toAdd] });
|
||||
};
|
||||
|
||||
private onClickInputArea = (e): void => {
|
||||
private onClickInputArea = (e: React.MouseEvent): void => {
|
||||
// Stop the browser from highlighting text
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
@ -835,7 +839,7 @@ export default class InviteDialog extends React.PureComponent<Props, IInviteDial
|
|||
}
|
||||
};
|
||||
|
||||
private onUseDefaultIdentityServerClick = (e): void => {
|
||||
private onUseDefaultIdentityServerClick = (e: ButtonEvent): void => {
|
||||
e.preventDefault();
|
||||
|
||||
// Update the IS in account data. Actually using it may trigger terms.
|
||||
|
@ -844,7 +848,7 @@ export default class InviteDialog extends React.PureComponent<Props, IInviteDial
|
|||
this.setState({ canUseIdentityServer: true, tryingIdentityServer: false });
|
||||
};
|
||||
|
||||
private onManageSettingsClick = (e): void => {
|
||||
private onManageSettingsClick = (e: ButtonEvent): void => {
|
||||
e.preventDefault();
|
||||
dis.fire(Action.ViewUserSettings);
|
||||
this.props.onFinished(false);
|
||||
|
@ -864,8 +868,8 @@ export default class InviteDialog extends React.PureComponent<Props, IInviteDial
|
|||
// Mix in the server results if we have any, but only if we're searching. We track the additional
|
||||
// members separately because we want to filter sourceMembers but trust the mixin arrays to have
|
||||
// the right members in them.
|
||||
let priorityAdditionalMembers = []; // Shows up before our own suggestions, higher quality
|
||||
let otherAdditionalMembers = []; // Shows up after our own suggestions, lower quality
|
||||
let priorityAdditionalMembers: Result[] = []; // Shows up before our own suggestions, higher quality
|
||||
let otherAdditionalMembers: Result[] = []; // Shows up after our own suggestions, lower quality
|
||||
const hasMixins = this.state.serverResultsMixin || this.state.threepidResultsMixin;
|
||||
if (this.state.filterText && hasMixins && kind === "suggestions") {
|
||||
// We don't want to duplicate members though, so just exclude anyone we've already seen.
|
||||
|
@ -1030,12 +1034,12 @@ export default class InviteDialog extends React.PureComponent<Props, IInviteDial
|
|||
}
|
||||
}
|
||||
|
||||
private onDialFormSubmit = (ev): void => {
|
||||
private onDialFormSubmit = (ev: SyntheticEvent): void => {
|
||||
ev.preventDefault();
|
||||
this.transferCall();
|
||||
};
|
||||
|
||||
private onDialChange = (ev): void => {
|
||||
private onDialChange = (ev: React.ChangeEvent<HTMLInputElement>): void => {
|
||||
this.setState({ dialPadValue: ev.currentTarget.value });
|
||||
};
|
||||
|
||||
|
@ -1066,9 +1070,9 @@ export default class InviteDialog extends React.PureComponent<Props, IInviteDial
|
|||
this.setState({ currentTabId: tabId });
|
||||
};
|
||||
|
||||
private async onLinkClick(e): Promise<void> {
|
||||
private async onLinkClick(e: React.MouseEvent<HTMLAnchorElement>): Promise<void> {
|
||||
e.preventDefault();
|
||||
selectText(e.target);
|
||||
selectText(e.currentTarget);
|
||||
}
|
||||
|
||||
private get screenName(): ScreenName {
|
||||
|
@ -1078,7 +1082,7 @@ export default class InviteDialog extends React.PureComponent<Props, IInviteDial
|
|||
}
|
||||
}
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
let spinner = null;
|
||||
if (this.state.busy) {
|
||||
spinner = <Spinner w={20} h={20} />;
|
||||
|
|
|
@ -45,7 +45,7 @@ export default class LogoutDialog extends React.Component<IProps, IState> {
|
|||
onFinished: function () {},
|
||||
};
|
||||
|
||||
public constructor(props) {
|
||||
public constructor(props: IProps) {
|
||||
super(props);
|
||||
|
||||
const cli = MatrixClientPeg.get();
|
||||
|
@ -127,7 +127,7 @@ export default class LogoutDialog extends React.Component<IProps, IState> {
|
|||
this.props.onFinished(true);
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
if (this.state.shouldLoadBackupStatus) {
|
||||
const description = (
|
||||
<div>
|
||||
|
|
|
@ -40,7 +40,7 @@ export default class ManualDeviceKeyVerificationDialog extends React.Component<I
|
|||
this.props.onFinished(confirm);
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
let text;
|
||||
if (MatrixClientPeg.get().getUserId() === this.props.userId) {
|
||||
text = _t("Confirm by comparing the following with the User Settings in your other session:");
|
||||
|
|
|
@ -121,8 +121,8 @@ export default class MessageEditHistoryDialog extends React.PureComponent<IProps
|
|||
}
|
||||
|
||||
private renderEdits(): JSX.Element[] {
|
||||
const nodes = [];
|
||||
let lastEvent;
|
||||
const nodes: JSX.Element[] = [];
|
||||
let lastEvent: MatrixEvent;
|
||||
let allEvents = this.state.events;
|
||||
// append original event when we've done last pagination
|
||||
if (this.state.originalEvent && !this.state.nextBatch) {
|
||||
|
@ -152,7 +152,7 @@ export default class MessageEditHistoryDialog extends React.PureComponent<IProps
|
|||
return nodes;
|
||||
}
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
let content;
|
||||
if (this.state.error) {
|
||||
const { error } = this.state;
|
||||
|
|
|
@ -65,7 +65,7 @@ export default class ModalWidgetDialog extends React.PureComponent<IProps, IStat
|
|||
disabledButtonIds: (this.props.widgetDefinition.buttons || []).filter((b) => b.disabled).map((b) => b.id),
|
||||
};
|
||||
|
||||
public constructor(props) {
|
||||
public constructor(props: IProps) {
|
||||
super(props);
|
||||
|
||||
this.widget = new ElementWidget({
|
||||
|
@ -124,7 +124,7 @@ export default class ModalWidgetDialog extends React.PureComponent<IProps, IStat
|
|||
this.state.messaging.transport.reply(ev.detail, {} as IWidgetApiAcknowledgeResponseData);
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
const templated = this.widget.getCompleteUrl({
|
||||
widgetRoomId: this.props.widgetRoomId,
|
||||
currentUserId: MatrixClientPeg.get().getUserId(),
|
||||
|
|
|
@ -58,7 +58,7 @@ export default class QuestionDialog extends React.Component<IQuestionDialogProps
|
|||
this.props.onFinished(false);
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
let primaryButtonClass = "";
|
||||
if (this.props.danger) {
|
||||
primaryButtonClass = "danger";
|
||||
|
|
|
@ -15,7 +15,7 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import * as React from "react";
|
||||
import { useRef, useState } from "react";
|
||||
import { SyntheticEvent, useRef, useState } from "react";
|
||||
|
||||
import { _t, _td } from "../../../languageHandler";
|
||||
import { IDialogProps } from "./IDialogProps";
|
||||
|
@ -32,7 +32,7 @@ const RegistrationEmailPromptDialog: React.FC<IProps> = ({ onFinished }) => {
|
|||
const [email, setEmail] = useState("");
|
||||
const fieldRef = useRef<Field>();
|
||||
|
||||
const onSubmit = async (e): Promise<void> => {
|
||||
const onSubmit = async (e: SyntheticEvent): Promise<void> => {
|
||||
e.preventDefault();
|
||||
if (email) {
|
||||
const valid = await fieldRef.current.validate({});
|
||||
|
|
|
@ -15,7 +15,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import React, { ChangeEvent } from "react";
|
||||
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
|
||||
|
@ -189,7 +189,7 @@ export default class ReportEventDialog extends React.Component<IProps, IState> {
|
|||
};
|
||||
|
||||
// The user has written down a freeform description of the abuse.
|
||||
private onReasonChange = ({ target: { value: reason } }): void => {
|
||||
private onReasonChange = ({ target: { value: reason } }: ChangeEvent<HTMLTextAreaElement>): void => {
|
||||
this.setState({ reason });
|
||||
};
|
||||
|
||||
|
@ -273,7 +273,7 @@ export default class ReportEventDialog extends React.Component<IProps, IState> {
|
|||
}
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
let error = null;
|
||||
if (this.state.err) {
|
||||
error = <div className="error">{this.state.err}</div>;
|
||||
|
|
|
@ -33,6 +33,7 @@ import { UIFeature } from "../../../settings/UIFeature";
|
|||
import BaseDialog from "./BaseDialog";
|
||||
import { Action } from "../../../dispatcher/actions";
|
||||
import { VoipRoomSettingsTab } from "../settings/tabs/room/VoipRoomSettingsTab";
|
||||
import { ActionPayload } from "../../../dispatcher/payloads";
|
||||
|
||||
export const ROOM_GENERAL_TAB = "ROOM_GENERAL_TAB";
|
||||
export const ROOM_VOIP_TAB = "ROOM_VOIP_TAB";
|
||||
|
@ -74,7 +75,7 @@ export default class RoomSettingsDialog extends React.Component<IProps, IState>
|
|||
MatrixClientPeg.get().removeListener(RoomEvent.Name, this.onRoomName);
|
||||
}
|
||||
|
||||
private onAction = (payload): void => {
|
||||
private onAction = (payload: ActionPayload): void => {
|
||||
// When view changes below us, close the room settings
|
||||
// whilst the modal is open this can only be triggered when someone hits Leave Room
|
||||
if (payload.action === Action.ViewHomePage) {
|
||||
|
@ -180,7 +181,7 @@ export default class RoomSettingsDialog extends React.Component<IProps, IState>
|
|||
return tabs;
|
||||
}
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
const roomName = this.state.roomName;
|
||||
return (
|
||||
<BaseDialog
|
||||
|
|
|
@ -68,7 +68,7 @@ export default class RoomUpgradeDialog extends React.Component<IProps, IState> {
|
|||
});
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
let buttons;
|
||||
if (this.state.busy) {
|
||||
buttons = <Spinner />;
|
||||
|
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { ReactNode } from "react";
|
||||
import React, { ReactNode, SyntheticEvent } from "react";
|
||||
import { EventType } from "matrix-js-sdk/src/@types/event";
|
||||
import { JoinRule } from "matrix-js-sdk/src/@types/partials";
|
||||
|
||||
|
@ -53,7 +53,7 @@ export default class RoomUpgradeWarningDialog extends React.Component<IProps, IS
|
|||
private readonly isPrivate: boolean;
|
||||
private readonly currentVersion: string;
|
||||
|
||||
public constructor(props) {
|
||||
public constructor(props: IProps) {
|
||||
super(props);
|
||||
|
||||
const room = MatrixClientPeg.get().getRoom(this.props.roomId);
|
||||
|
@ -93,14 +93,14 @@ export default class RoomUpgradeWarningDialog extends React.Component<IProps, IS
|
|||
this.setState({ inviteUsersToNewRoom });
|
||||
};
|
||||
|
||||
private openBugReportDialog = (e): void => {
|
||||
private openBugReportDialog = (e: SyntheticEvent): void => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
Modal.createDialog(BugReportDialog, {});
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
const brand = SdkConfig.get().brand;
|
||||
|
||||
let inviteToggle = null;
|
||||
|
|
|
@ -73,7 +73,7 @@ export default abstract class ScrollableBaseModal<
|
|||
protected abstract submit(): void;
|
||||
protected abstract renderContent(): React.ReactNode;
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
return (
|
||||
<MatrixClientContext.Provider value={this.matrixClient}>
|
||||
<FocusLock
|
||||
|
|
|
@ -88,7 +88,7 @@ export default class ServerOfflineDialog extends React.PureComponent<IProps> {
|
|||
});
|
||||
}
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
let timeline = this.renderTimeline().filter((c) => !!c); // remove nulls for next check
|
||||
if (timeline.length === 0) {
|
||||
timeline = [<div key={1}>{_t("You're all caught up.")}</div>];
|
||||
|
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { createRef } from "react";
|
||||
import React, { ChangeEvent, createRef, SyntheticEvent } from "react";
|
||||
import { AutoDiscovery } from "matrix-js-sdk/src/autodiscovery";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
|
||||
|
@ -45,7 +45,7 @@ export default class ServerPickerDialog extends React.PureComponent<IProps, ISta
|
|||
private readonly fieldRef = createRef<Field>();
|
||||
private validatedConf: ValidatedServerConfig;
|
||||
|
||||
public constructor(props) {
|
||||
public constructor(props: IProps) {
|
||||
super(props);
|
||||
|
||||
const config = SdkConfig.get();
|
||||
|
@ -75,7 +75,7 @@ export default class ServerPickerDialog extends React.PureComponent<IProps, ISta
|
|||
this.setState({ defaultChosen: false });
|
||||
};
|
||||
|
||||
private onHomeserverChange = (ev): void => {
|
||||
private onHomeserverChange = (ev: ChangeEvent<HTMLInputElement>): void => {
|
||||
this.setState({ otherHomeserver: ev.target.value });
|
||||
};
|
||||
|
||||
|
@ -149,7 +149,7 @@ export default class ServerPickerDialog extends React.PureComponent<IProps, ISta
|
|||
|
||||
private onHomeserverValidate = (fieldState: IFieldState): Promise<IValidationResult> => this.validate(fieldState);
|
||||
|
||||
private onSubmit = async (ev): Promise<void> => {
|
||||
private onSubmit = async (ev: SyntheticEvent): Promise<void> => {
|
||||
ev.preventDefault();
|
||||
|
||||
const valid = await this.fieldRef.current.validate({ allowEmpty: false });
|
||||
|
@ -163,7 +163,7 @@ export default class ServerPickerDialog extends React.PureComponent<IProps, ISta
|
|||
this.props.onFinished(this.state.defaultChosen ? this.defaultServer : this.validatedConf);
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
let text;
|
||||
if (this.defaultServer.hsName === "matrix.org") {
|
||||
text = _t("Matrix.org is the biggest public homeserver in the world, so it's a good place for many.");
|
||||
|
|
|
@ -22,7 +22,7 @@ import DialogButtons from "../elements/DialogButtons";
|
|||
import { IDialogProps } from "./IDialogProps";
|
||||
|
||||
export default class SeshatResetDialog extends React.PureComponent<IDialogProps> {
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
return (
|
||||
<BaseDialog
|
||||
hasCancel={true}
|
||||
|
|
|
@ -54,7 +54,7 @@ export default class SessionRestoreErrorDialog extends React.Component<IProps> {
|
|||
window.location.reload();
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
const brand = SdkConfig.get().brand;
|
||||
|
||||
const clearStorageButton = (
|
||||
|
|
|
@ -138,7 +138,7 @@ export default class SetEmailDialog extends React.Component<IProps, IState> {
|
|||
);
|
||||
}
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
const emailInput = this.state.emailBusy ? (
|
||||
<Spinner />
|
||||
) : (
|
||||
|
|
|
@ -36,12 +36,12 @@ const socials = [
|
|||
{
|
||||
name: "Facebook",
|
||||
img: require("../../../../res/img/social/facebook.png"),
|
||||
url: (url) => `https://www.facebook.com/sharer/sharer.php?u=${url}`,
|
||||
url: (url: String) => `https://www.facebook.com/sharer/sharer.php?u=${url}`,
|
||||
},
|
||||
{
|
||||
name: "Twitter",
|
||||
img: require("../../../../res/img/social/twitter-2.png"),
|
||||
url: (url) => `https://twitter.com/home?status=${url}`,
|
||||
url: (url: string) => `https://twitter.com/home?status=${url}`,
|
||||
},
|
||||
/* // icon missing
|
||||
name: 'Google Plus',
|
||||
|
@ -50,17 +50,17 @@ const socials = [
|
|||
},*/ {
|
||||
name: "LinkedIn",
|
||||
img: require("../../../../res/img/social/linkedin.png"),
|
||||
url: (url) => `https://www.linkedin.com/shareArticle?mini=true&url=${url}`,
|
||||
url: (url: string) => `https://www.linkedin.com/shareArticle?mini=true&url=${url}`,
|
||||
},
|
||||
{
|
||||
name: "Reddit",
|
||||
img: require("../../../../res/img/social/reddit.png"),
|
||||
url: (url) => `https://www.reddit.com/submit?url=${url}`,
|
||||
url: (url: string) => `https://www.reddit.com/submit?url=${url}`,
|
||||
},
|
||||
{
|
||||
name: "email",
|
||||
img: require("../../../../res/img/social/email-1.png"),
|
||||
url: (url) => `mailto:?body=${url}`,
|
||||
url: (url: string) => `mailto:?body=${url}`,
|
||||
},
|
||||
];
|
||||
|
||||
|
@ -71,14 +71,14 @@ interface IProps extends IDialogProps {
|
|||
|
||||
interface IState {
|
||||
linkSpecificEvent: boolean;
|
||||
permalinkCreator: RoomPermalinkCreator;
|
||||
permalinkCreator: RoomPermalinkCreator | null;
|
||||
}
|
||||
|
||||
export default class ShareDialog extends React.PureComponent<IProps, IState> {
|
||||
public constructor(props) {
|
||||
public constructor(props: IProps) {
|
||||
super(props);
|
||||
|
||||
let permalinkCreator: RoomPermalinkCreator = null;
|
||||
let permalinkCreator: RoomPermalinkCreator | null = null;
|
||||
if (props.target instanceof Room) {
|
||||
permalinkCreator = new RoomPermalinkCreator(props.target);
|
||||
permalinkCreator.load();
|
||||
|
@ -91,9 +91,9 @@ export default class ShareDialog extends React.PureComponent<IProps, IState> {
|
|||
};
|
||||
}
|
||||
|
||||
public static onLinkClick(e): void {
|
||||
public static onLinkClick(e: React.MouseEvent): void {
|
||||
e.preventDefault();
|
||||
selectText(e.target);
|
||||
selectText(e.currentTarget);
|
||||
}
|
||||
|
||||
private onLinkSpecificEventCheckboxClick = (): void => {
|
||||
|
@ -108,15 +108,15 @@ export default class ShareDialog extends React.PureComponent<IProps, IState> {
|
|||
if (this.props.target instanceof Room) {
|
||||
if (this.state.linkSpecificEvent) {
|
||||
const events = this.props.target.getLiveTimeline().getEvents();
|
||||
matrixToUrl = this.state.permalinkCreator.forEvent(events[events.length - 1].getId());
|
||||
matrixToUrl = this.state.permalinkCreator!.forEvent(events[events.length - 1].getId()!);
|
||||
} else {
|
||||
matrixToUrl = this.state.permalinkCreator.forShareableRoom();
|
||||
matrixToUrl = this.state.permalinkCreator!.forShareableRoom();
|
||||
}
|
||||
} else if (this.props.target instanceof User || this.props.target instanceof RoomMember) {
|
||||
matrixToUrl = makeUserPermalink(this.props.target.userId);
|
||||
} else if (this.props.target instanceof MatrixEvent) {
|
||||
if (this.state.linkSpecificEvent) {
|
||||
matrixToUrl = this.props.permalinkCreator.forEvent(this.props.target.getId());
|
||||
matrixToUrl = this.props.permalinkCreator.forEvent(this.props.target.getId()!);
|
||||
} else {
|
||||
matrixToUrl = this.props.permalinkCreator.forShareableRoom();
|
||||
}
|
||||
|
@ -124,7 +124,7 @@ export default class ShareDialog extends React.PureComponent<IProps, IState> {
|
|||
return matrixToUrl;
|
||||
}
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
let title;
|
||||
let checkbox;
|
||||
|
||||
|
|
|
@ -17,14 +17,14 @@ limitations under the License.
|
|||
import React from "react";
|
||||
|
||||
import { _t } from "../../../languageHandler";
|
||||
import { CommandCategories, Commands } from "../../../SlashCommands";
|
||||
import { Command, CommandCategories, Commands } from "../../../SlashCommands";
|
||||
import { IDialogProps } from "./IDialogProps";
|
||||
import InfoDialog from "./InfoDialog";
|
||||
|
||||
interface IProps extends IDialogProps {}
|
||||
|
||||
const SlashCommandHelpDialog: React.FC<IProps> = ({ onFinished }) => {
|
||||
const categories = {};
|
||||
const categories: Record<string, Command[]> = {};
|
||||
Commands.forEach((cmd) => {
|
||||
if (!cmd.isEnabled()) return;
|
||||
if (!categories[cmd.category]) {
|
||||
|
|
|
@ -37,7 +37,7 @@ export default class StorageEvictedDialog extends React.Component<IProps> {
|
|||
this.props.onFinished(true);
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
let logRequest;
|
||||
if (SdkConfig.get().bug_report_endpoint_url) {
|
||||
logRequest = _t(
|
||||
|
|
|
@ -21,6 +21,7 @@ import { SERVICE_TYPES } from "matrix-js-sdk/src/service-types";
|
|||
import { _t, pickBestLanguage } from "../../../languageHandler";
|
||||
import DialogButtons from "../elements/DialogButtons";
|
||||
import BaseDialog from "./BaseDialog";
|
||||
import { ServicePolicyPair } from "../../../Terms";
|
||||
|
||||
interface ITermsCheckboxProps {
|
||||
onChange: (url: string, checked: boolean) => void;
|
||||
|
@ -33,7 +34,7 @@ class TermsCheckbox extends React.PureComponent<ITermsCheckboxProps> {
|
|||
this.props.onChange(this.props.url, ev.currentTarget.checked);
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
return <input type="checkbox" onChange={this.onChange} checked={this.props.checked} />;
|
||||
}
|
||||
}
|
||||
|
@ -43,7 +44,7 @@ interface ITermsDialogProps {
|
|||
* Array of [Service, policies] pairs, where policies is the response from the
|
||||
* /terms endpoint for that service
|
||||
*/
|
||||
policiesAndServicePairs: any[];
|
||||
policiesAndServicePairs: ServicePolicyPair[];
|
||||
|
||||
/**
|
||||
* urls that the user has already agreed to
|
||||
|
@ -63,7 +64,7 @@ interface IState {
|
|||
}
|
||||
|
||||
export default class TermsDialog extends React.PureComponent<ITermsDialogProps, IState> {
|
||||
public constructor(props) {
|
||||
public constructor(props: ITermsDialogProps) {
|
||||
super(props);
|
||||
this.state = {
|
||||
// url -> boolean
|
||||
|
@ -125,7 +126,7 @@ export default class TermsDialog extends React.PureComponent<ITermsDialogProps,
|
|||
});
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
const rows = [];
|
||||
for (const policiesAndService of this.props.policiesAndServicePairs) {
|
||||
const parsedBaseUrl = url.parse(policiesAndService.service.baseUrl);
|
||||
|
|
|
@ -106,7 +106,7 @@ export default class TextInputDialog extends React.Component<IProps, IState> {
|
|||
return result;
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
return (
|
||||
<BaseDialog
|
||||
className="mx_TextInputDialog"
|
||||
|
|
|
@ -39,7 +39,7 @@ export default class UploadConfirmDialog extends React.Component<IProps> {
|
|||
totalFiles: 1,
|
||||
};
|
||||
|
||||
public constructor(props) {
|
||||
public constructor(props: IProps) {
|
||||
super(props);
|
||||
|
||||
// Create a fresh `Blob` for previewing (even though `File` already is
|
||||
|
@ -65,7 +65,7 @@ export default class UploadConfirmDialog extends React.Component<IProps> {
|
|||
this.props.onFinished(true, true);
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
let title: string;
|
||||
if (this.props.totalFiles > 1 && this.props.currentIndex !== undefined) {
|
||||
title = _t("Upload files (%(current)s of %(total)s)", {
|
||||
|
|
|
@ -43,7 +43,7 @@ export default class UploadFailureDialog extends React.Component<IProps> {
|
|||
this.props.onFinished(true);
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
let message;
|
||||
let preview;
|
||||
let buttons;
|
||||
|
|
|
@ -50,7 +50,7 @@ interface IState {
|
|||
export default class UserSettingsDialog extends React.Component<IProps, IState> {
|
||||
private settingsWatchers: string[] = [];
|
||||
|
||||
public constructor(props) {
|
||||
public constructor(props: IProps) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
|
@ -210,7 +210,7 @@ export default class UserSettingsDialog extends React.Component<IProps, IState>
|
|||
return tabs;
|
||||
}
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
return (
|
||||
<BaseDialog
|
||||
className="mx_UserSettingsDialog"
|
||||
|
|
|
@ -35,7 +35,7 @@ interface IState {
|
|||
}
|
||||
|
||||
export default class VerificationRequestDialog extends React.Component<IProps, IState> {
|
||||
public constructor(props) {
|
||||
public constructor(props: IProps) {
|
||||
super(props);
|
||||
this.state = {
|
||||
verificationRequest: this.props.verificationRequest,
|
||||
|
@ -47,7 +47,7 @@ export default class VerificationRequestDialog extends React.Component<IProps, I
|
|||
}
|
||||
}
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
const request = this.state.verificationRequest;
|
||||
const otherUserId = request && request.otherUserId;
|
||||
const member = this.props.member || (otherUserId && MatrixClientPeg.get().getUser(otherUserId));
|
||||
|
|
|
@ -33,13 +33,12 @@ interface IProps extends IDialogProps {
|
|||
widgetKind: WidgetKind; // TODO: Refactor into the Widget class
|
||||
}
|
||||
|
||||
interface IBooleanStates {
|
||||
// @ts-ignore - TS wants a string key, but we know better
|
||||
[capability: Capability]: boolean;
|
||||
}
|
||||
type BooleanStates = Partial<{
|
||||
[capability in Capability]: boolean;
|
||||
}>;
|
||||
|
||||
interface IState {
|
||||
booleanStates: IBooleanStates;
|
||||
booleanStates: BooleanStates;
|
||||
rememberSelection: boolean;
|
||||
}
|
||||
|
||||
|
@ -52,7 +51,7 @@ export default class WidgetCapabilitiesPromptDialog extends React.PureComponent<
|
|||
const parsedEvents = WidgetEventCapability.findEventCapabilities(this.props.requestedCapabilities);
|
||||
parsedEvents.forEach((e) => this.eventPermissionsMap.set(e.raw, e));
|
||||
|
||||
const states: IBooleanStates = {};
|
||||
const states: BooleanStates = {};
|
||||
this.props.requestedCapabilities.forEach((c) => (states[c] = true));
|
||||
|
||||
this.state = {
|
||||
|
@ -71,7 +70,7 @@ export default class WidgetCapabilitiesPromptDialog extends React.PureComponent<
|
|||
this.setState({ rememberSelection: newVal });
|
||||
};
|
||||
|
||||
private onSubmit = async (ev): Promise<void> => {
|
||||
private onSubmit = async (): Promise<void> => {
|
||||
this.closeAndTryRemember(
|
||||
Object.entries(this.state.booleanStates)
|
||||
.filter(([_, isSelected]) => isSelected)
|
||||
|
@ -79,7 +78,7 @@ export default class WidgetCapabilitiesPromptDialog extends React.PureComponent<
|
|||
);
|
||||
};
|
||||
|
||||
private onReject = async (ev): Promise<void> => {
|
||||
private onReject = async (): Promise<void> => {
|
||||
this.closeAndTryRemember([]); // nothing was approved
|
||||
};
|
||||
|
||||
|
@ -87,7 +86,7 @@ export default class WidgetCapabilitiesPromptDialog extends React.PureComponent<
|
|||
this.props.onFinished({ approved, remember: this.state.rememberSelection });
|
||||
}
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
// We specifically order the timeline capabilities down to the bottom. The capability text
|
||||
// generation cares strongly about this.
|
||||
const orderedCapabilities = Object.entries(this.state.booleanStates).sort(([capA], [capB]) => {
|
||||
|
|
|
@ -73,7 +73,7 @@ export default class WidgetOpenIDPermissionsDialog extends React.PureComponent<I
|
|||
this.setState({ rememberSelection: newVal });
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
return (
|
||||
<BaseDialog
|
||||
className="mx_WidgetOpenIDPermissionsDialog"
|
||||
|
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { useContext, useMemo, useRef, useState } from "react";
|
||||
import React, { ChangeEvent, useContext, useMemo, useRef, useState } from "react";
|
||||
import { IContent, MatrixEvent } from "matrix-js-sdk/src/models/event";
|
||||
|
||||
import { _t, _td } from "../../../../languageHandler";
|
||||
|
@ -87,7 +87,7 @@ export const EventEditor: React.FC<IEventEditorProps> = ({ fieldDefs, defaultCon
|
|||
type="text"
|
||||
autoComplete="on"
|
||||
value={fieldData[i]}
|
||||
onChange={(ev) =>
|
||||
onChange={(ev: ChangeEvent<HTMLInputElement>) =>
|
||||
setFieldData((data) => {
|
||||
data[i] = ev.target.value;
|
||||
return [...data];
|
||||
|
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { useEffect, useState } from "react";
|
||||
import React, { ChangeEvent, useEffect, useState } from "react";
|
||||
|
||||
import { _t } from "../../../../languageHandler";
|
||||
import Field from "../../elements/Field";
|
||||
|
@ -72,7 +72,7 @@ const FilteredList: React.FC<IProps> = ({ children, query, onChange }) => {
|
|||
type="text"
|
||||
autoComplete="off"
|
||||
value={query}
|
||||
onChange={(ev) => onChange(ev.target.value)}
|
||||
onChange={(ev: ChangeEvent<HTMLInputElement>) => onChange(ev.target.value)}
|
||||
className="mx_TextInputDialog_input mx_DevTools_RoomStateExplorer_query"
|
||||
// force re-render so that autoFocus is applied when this component is re-used
|
||||
key={children?.[0]?.key ?? ""}
|
||||
|
|
|
@ -15,7 +15,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { useContext, useMemo, useState } from "react";
|
||||
import React, { ChangeEvent, useContext, useMemo, useState } from "react";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
|
||||
import { _t } from "../../../../languageHandler";
|
||||
|
@ -74,7 +74,7 @@ const CanEditLevelField: React.FC<ICanEditLevelFieldProps> = ({ setting, roomId,
|
|||
};
|
||||
|
||||
function renderExplicitSettingValues(setting: string, roomId: string): string {
|
||||
const vals = {};
|
||||
const vals: Record<string, number | null> = {};
|
||||
for (const level of LEVEL_ORDER) {
|
||||
try {
|
||||
vals[level] = SettingsStore.getValueAt(level, setting, roomId, true, true);
|
||||
|
@ -283,7 +283,7 @@ const SettingsList: React.FC<ISettingsListProps> = ({ onBack, onView, onEdit })
|
|||
type="text"
|
||||
autoComplete="off"
|
||||
value={query}
|
||||
onChange={(ev) => setQuery(ev.target.value)}
|
||||
onChange={(ev: ChangeEvent<HTMLInputElement>) => setQuery(ev.target.value)}
|
||||
className="mx_TextInputDialog_input mx_DevTools_RoomStateExplorer_query"
|
||||
/>
|
||||
<table>
|
||||
|
|
|
@ -14,26 +14,47 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { MatrixClient } from "matrix-js-sdk/src/client";
|
||||
import { MatrixEvent, Poll } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import { _t } from "../../../../languageHandler";
|
||||
import BaseDialog from "../BaseDialog";
|
||||
import { IDialogProps } from "../IDialogProps";
|
||||
import { PollHistoryList } from "./PollHistoryList";
|
||||
import { getPolls } from "./usePollHistory";
|
||||
import { PollHistoryFilter } from "./types";
|
||||
import { usePolls } from "./usePollHistory";
|
||||
|
||||
type PollHistoryDialogProps = Pick<IDialogProps, "onFinished"> & {
|
||||
roomId: string;
|
||||
matrixClient: MatrixClient;
|
||||
};
|
||||
|
||||
const sortEventsByLatest = (left: MatrixEvent, right: MatrixEvent): number => right.getTs() - left.getTs();
|
||||
const filterPolls =
|
||||
(filter: PollHistoryFilter) =>
|
||||
(poll: Poll): boolean =>
|
||||
(filter === "ACTIVE") !== poll.isEnded;
|
||||
const filterAndSortPolls = (polls: Map<string, Poll>, filter: PollHistoryFilter): MatrixEvent[] => {
|
||||
return [...polls.values()]
|
||||
.filter(filterPolls(filter))
|
||||
.map((poll) => poll.rootEvent)
|
||||
.sort(sortEventsByLatest);
|
||||
};
|
||||
|
||||
export const PollHistoryDialog: React.FC<PollHistoryDialogProps> = ({ roomId, matrixClient, onFinished }) => {
|
||||
const pollStartEvents = getPolls(roomId, matrixClient);
|
||||
const { polls } = usePolls(roomId, matrixClient);
|
||||
const [filter, setFilter] = useState<PollHistoryFilter>("ACTIVE");
|
||||
const [pollStartEvents, setPollStartEvents] = useState(filterAndSortPolls(polls, filter));
|
||||
|
||||
useEffect(() => {
|
||||
setPollStartEvents(filterAndSortPolls(polls, filter));
|
||||
}, [filter, polls]);
|
||||
|
||||
return (
|
||||
<BaseDialog title={_t("Polls history")} onFinished={onFinished}>
|
||||
<div className="mx_PollHistoryDialog_content">
|
||||
<PollHistoryList pollStartEvents={pollStartEvents} />
|
||||
<PollHistoryList pollStartEvents={pollStartEvents} filter={filter} onFilterChange={setFilter} />
|
||||
</div>
|
||||
</BaseDialog>
|
||||
);
|
||||
|
|
|
@ -19,13 +19,26 @@ import { MatrixEvent } from "matrix-js-sdk/src/matrix";
|
|||
|
||||
import PollListItem from "./PollListItem";
|
||||
import { _t } from "../../../../languageHandler";
|
||||
import { FilterTabGroup } from "../../elements/FilterTabGroup";
|
||||
import { PollHistoryFilter } from "./types";
|
||||
|
||||
type PollHistoryListProps = {
|
||||
pollStartEvents: MatrixEvent[];
|
||||
filter: PollHistoryFilter;
|
||||
onFilterChange: (filter: PollHistoryFilter) => void;
|
||||
};
|
||||
export const PollHistoryList: React.FC<PollHistoryListProps> = ({ pollStartEvents }) => {
|
||||
export const PollHistoryList: React.FC<PollHistoryListProps> = ({ pollStartEvents, filter, onFilterChange }) => {
|
||||
return (
|
||||
<div className="mx_PollHistoryList">
|
||||
<FilterTabGroup<PollHistoryFilter>
|
||||
name="PollHistoryDialog_filter"
|
||||
value={filter}
|
||||
onFilterChange={onFilterChange}
|
||||
tabs={[
|
||||
{ id: "ACTIVE", label: "Active polls" },
|
||||
{ id: "ENDED", label: "Past polls" },
|
||||
]}
|
||||
/>
|
||||
{!!pollStartEvents.length ? (
|
||||
<ol className="mx_PollHistoryList_list">
|
||||
{pollStartEvents.map((pollStartEvent) => (
|
||||
|
@ -33,7 +46,11 @@ export const PollHistoryList: React.FC<PollHistoryListProps> = ({ pollStartEvent
|
|||
))}
|
||||
</ol>
|
||||
) : (
|
||||
<span className="mx_PollHistoryList_noResults">{_t("There are no polls in this room")}</span>
|
||||
<span className="mx_PollHistoryList_noResults">
|
||||
{filter === "ACTIVE"
|
||||
? _t("There are no active polls in this room")
|
||||
: _t("There are no past polls in this room")}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
|
22
src/components/views/dialogs/polls/types.ts
Normal file
22
src/components/views/dialogs/polls/types.ts
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Possible values for the "filter" setting in the poll history dialog
|
||||
*
|
||||
* Ended polls have a valid M_POLL_END event
|
||||
*/
|
||||
export type PollHistoryFilter = "ACTIVE" | "ENDED";
|
|
@ -14,27 +14,32 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { M_POLL_START } from "matrix-js-sdk/src/@types/polls";
|
||||
import { MatrixEvent } from "matrix-js-sdk/src/matrix";
|
||||
import { Poll, PollEvent } from "matrix-js-sdk/src/matrix";
|
||||
import { MatrixClient } from "matrix-js-sdk/src/client";
|
||||
|
||||
import { useEventEmitterState } from "../../../../hooks/useEventEmitter";
|
||||
|
||||
/**
|
||||
* Get poll start events in a rooms live timeline
|
||||
* Get poll instances from a room
|
||||
* @param roomId - id of room to retrieve polls for
|
||||
* @param matrixClient - client
|
||||
* @returns {MatrixEvent[]} - array fo poll start events
|
||||
* @returns {Map<string, Poll>} - Map of Poll instances
|
||||
*/
|
||||
export const getPolls = (roomId: string, matrixClient: MatrixClient): MatrixEvent[] => {
|
||||
export const usePolls = (
|
||||
roomId: string,
|
||||
matrixClient: MatrixClient,
|
||||
): {
|
||||
polls: Map<string, Poll>;
|
||||
} => {
|
||||
const room = matrixClient.getRoom(roomId);
|
||||
|
||||
if (!room) {
|
||||
throw new Error("Cannot find room");
|
||||
}
|
||||
|
||||
// @TODO(kerrya) poll history will be actively fetched in PSG-1043
|
||||
// for now, just display polls that are in the current timeline
|
||||
const timelineEvents = room.getLiveTimeline().getEvents();
|
||||
const pollStartEvents = timelineEvents.filter((event) => M_POLL_START.matches(event.getType()));
|
||||
const polls = useEventEmitterState(room, PollEvent.New, () => room.polls);
|
||||
|
||||
return pollStartEvents;
|
||||
// @TODO(kerrya) watch polls for end events, trigger refiltering
|
||||
|
||||
return { polls };
|
||||
};
|
||||
|
|
|
@ -62,7 +62,7 @@ interface IState {
|
|||
export default class AccessSecretStorageDialog extends React.PureComponent<IProps, IState> {
|
||||
private fileUpload = React.createRef<HTMLInputElement>();
|
||||
|
||||
public constructor(props) {
|
||||
public constructor(props: IProps) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
|
@ -268,7 +268,7 @@ export default class AccessSecretStorageDialog extends React.PureComponent<IProp
|
|||
}
|
||||
}
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
const hasPassphrase =
|
||||
this.props.keyInfo &&
|
||||
this.props.keyInfo.passphrase &&
|
||||
|
|
|
@ -33,7 +33,7 @@ export default class ConfirmDestroyCrossSigningDialog extends React.Component<IP
|
|||
this.props.onFinished(false);
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
return (
|
||||
<BaseDialog
|
||||
className="mx_ConfirmDestroyCrossSigningDialog"
|
||||
|
|
|
@ -18,6 +18,7 @@ limitations under the License.
|
|||
import React from "react";
|
||||
import { CrossSigningKeys } from "matrix-js-sdk/src/client";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { UIAFlow } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import { MatrixClientPeg } from "../../../../MatrixClientPeg";
|
||||
import { _t } from "../../../../languageHandler";
|
||||
|
@ -82,7 +83,7 @@ export default class CreateCrossSigningDialog extends React.PureComponent<IProps
|
|||
logger.log("uploadDeviceSigningKeys advertised no flows!");
|
||||
return;
|
||||
}
|
||||
const canUploadKeysWithPasswordOnly = error.data.flows.some((f) => {
|
||||
const canUploadKeysWithPasswordOnly = error.data.flows.some((f: UIAFlow) => {
|
||||
return f.stages.length === 1 && f.stages[0] === "m.login.password";
|
||||
});
|
||||
this.setState({
|
||||
|
@ -167,7 +168,7 @@ export default class CreateCrossSigningDialog extends React.PureComponent<IProps
|
|||
this.props.onFinished(false);
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
let content;
|
||||
if (this.state.error) {
|
||||
content = (
|
||||
|
|
|
@ -15,7 +15,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import React, { ChangeEvent } from "react";
|
||||
import { MatrixClient } from "matrix-js-sdk/src/client";
|
||||
import { IKeyBackupInfo, IKeyBackupRestoreResult } from "matrix-js-sdk/src/crypto/keybackup";
|
||||
import { ISecretStorageKeyInfo } from "matrix-js-sdk/src/crypto/api";
|
||||
|
@ -81,7 +81,7 @@ export default class RestoreKeyBackupDialog extends React.PureComponent<IProps,
|
|||
showSummary: true,
|
||||
};
|
||||
|
||||
public constructor(props) {
|
||||
public constructor(props: IProps) {
|
||||
super(props);
|
||||
this.state = {
|
||||
backupInfo: null,
|
||||
|
@ -117,7 +117,7 @@ export default class RestoreKeyBackupDialog extends React.PureComponent<IProps,
|
|||
});
|
||||
};
|
||||
|
||||
private progressCallback = (data): void => {
|
||||
private progressCallback = (data: IState["progress"]): void => {
|
||||
this.setState({
|
||||
progress: data,
|
||||
});
|
||||
|
@ -128,7 +128,7 @@ export default class RestoreKeyBackupDialog extends React.PureComponent<IProps,
|
|||
accessSecretStorage(async (): Promise<void> => {}, /* forceReset = */ true);
|
||||
};
|
||||
|
||||
private onRecoveryKeyChange = (e): void => {
|
||||
private onRecoveryKeyChange = (e: ChangeEvent<HTMLInputElement>): void => {
|
||||
this.setState({
|
||||
recoveryKey: e.target.value,
|
||||
recoveryKeyValid: MatrixClientPeg.get().isValidRecoveryKey(e.target.value),
|
||||
|
@ -213,7 +213,7 @@ export default class RestoreKeyBackupDialog extends React.PureComponent<IProps,
|
|||
}
|
||||
};
|
||||
|
||||
private onPassPhraseChange = (e): void => {
|
||||
private onPassPhraseChange = (e: ChangeEvent<HTMLInputElement>): void => {
|
||||
this.setState({
|
||||
passPhrase: e.target.value,
|
||||
});
|
||||
|
@ -247,7 +247,7 @@ export default class RestoreKeyBackupDialog extends React.PureComponent<IProps,
|
|||
}
|
||||
}
|
||||
|
||||
private async restoreWithCachedKey(backupInfo): Promise<boolean> {
|
||||
private async restoreWithCachedKey(backupInfo?: IKeyBackupInfo): Promise<boolean> {
|
||||
if (!backupInfo) return false;
|
||||
try {
|
||||
const recoverInfo = await MatrixClientPeg.get().restoreKeyBackupWithCache(
|
||||
|
@ -308,7 +308,7 @@ export default class RestoreKeyBackupDialog extends React.PureComponent<IProps,
|
|||
}
|
||||
}
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
const backupHasPassphrase =
|
||||
this.state.backupInfo &&
|
||||
this.state.backupInfo.auth_data &&
|
||||
|
@ -480,7 +480,7 @@ export default class RestoreKeyBackupDialog extends React.PureComponent<IProps,
|
|||
<div>
|
||||
<p>
|
||||
{_t(
|
||||
"<b>Warning</b>: You should only set up key backup " + "from a trusted computer.",
|
||||
"<b>Warning</b>: you should only set up key backup " + "from a trusted computer.",
|
||||
{},
|
||||
{ b: (sub) => <b>{sub}</b> },
|
||||
)}
|
||||
|
|
|
@ -57,7 +57,7 @@ export default class SetupEncryptionDialog extends React.Component<IProps, IStat
|
|||
this.setState({ icon: iconFromPhase(this.store.phase) });
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
return (
|
||||
<BaseDialog
|
||||
headerImage={this.state.icon}
|
||||
|
|
|
@ -77,7 +77,7 @@ import BaseAvatar from "../../avatars/BaseAvatar";
|
|||
import DecoratedRoomAvatar from "../../avatars/DecoratedRoomAvatar";
|
||||
import { SearchResultAvatar } from "../../avatars/SearchResultAvatar";
|
||||
import { NetworkDropdown } from "../../directory/NetworkDropdown";
|
||||
import AccessibleButton from "../../elements/AccessibleButton";
|
||||
import AccessibleButton, { ButtonEvent } from "../../elements/AccessibleButton";
|
||||
import LabelledCheckbox from "../../elements/LabelledCheckbox";
|
||||
import Spinner from "../../elements/Spinner";
|
||||
import NotificationBadge from "../../rooms/NotificationBadge";
|
||||
|
@ -625,7 +625,7 @@ const SpotlightDialog: React.FC<IProps> = ({ initialText = "", initialFilter = n
|
|||
const showViewButton =
|
||||
clientRoom?.getMyMembership() === "join" || result.publicRoom.world_readable || cli.isGuest();
|
||||
|
||||
const listener = (ev): void => {
|
||||
const listener = (ev: ButtonEvent): void => {
|
||||
const { publicRoom } = result;
|
||||
viewRoom(
|
||||
{
|
||||
|
|
|
@ -73,7 +73,7 @@ export default class AccessibleTooltipButton extends React.PureComponent<IProps,
|
|||
if (ev.relatedTarget) this.showTooltip();
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const { title, tooltip, children, tooltipClassName, forceHide, alignment, onHideTooltip, ...props } =
|
||||
this.props;
|
||||
|
|
|
@ -88,7 +88,7 @@ export default class AppPermission extends React.Component<IProps, IState> {
|
|||
}
|
||||
}
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
const brand = SdkConfig.get().brand;
|
||||
|
||||
const displayName = this.state.roomMember ? this.state.roomMember.name : this.props.creatorUserId;
|
||||
|
|
|
@ -18,7 +18,7 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import url from "url";
|
||||
import React, { ContextType, createRef, MutableRefObject, ReactNode } from "react";
|
||||
import React, { ContextType, createRef, CSSProperties, MutableRefObject, ReactNode } from "react";
|
||||
import classNames from "classnames";
|
||||
import { MatrixCapabilities } from "matrix-widget-api";
|
||||
import { Room, RoomEvent } from "matrix-js-sdk/src/models/room";
|
||||
|
@ -81,7 +81,7 @@ interface IProps {
|
|||
// Is this an instance of a user widget
|
||||
userWidget: boolean;
|
||||
// sets the pointer-events property on the iframe
|
||||
pointerEvents?: string;
|
||||
pointerEvents?: CSSProperties["pointerEvents"];
|
||||
widgetPageTitle?: string;
|
||||
showLayoutButtons?: boolean;
|
||||
// Handle to manually notify the PersistedElement that it needs to move
|
||||
|
@ -544,7 +544,7 @@ export default class AppTile extends React.Component<IProps, IState> {
|
|||
this.setState({ menuDisplayed: false });
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
let appTileBody;
|
||||
|
||||
// Note that there is advice saying allow-scripts shouldn't be used with allow-same-origin
|
||||
|
@ -562,9 +562,9 @@ export default class AppTile extends React.Component<IProps, IState> {
|
|||
"microphone; camera; encrypted-media; autoplay; display-capture; clipboard-write; " + "clipboard-read;";
|
||||
|
||||
const appTileBodyClass = "mx_AppTileBody" + (this.props.miniMode ? "_mini " : " ");
|
||||
const appTileBodyStyles = {};
|
||||
const appTileBodyStyles: CSSProperties = {};
|
||||
if (this.props.pointerEvents) {
|
||||
appTileBodyStyles["pointerEvents"] = this.props.pointerEvents;
|
||||
appTileBodyStyles.pointerEvents = this.props.pointerEvents;
|
||||
}
|
||||
|
||||
const loadingElement = (
|
||||
|
|
|
@ -55,7 +55,7 @@ export class ExistingSource extends React.Component<ExistingSourceIProps> {
|
|||
this.props.onSelect(this.props.source);
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
const thumbnailClasses = classNames({
|
||||
mx_desktopCapturerSourcePicker_source_thumbnail: true,
|
||||
mx_desktopCapturerSourcePicker_source_thumbnail_selected: this.props.selected,
|
||||
|
@ -149,7 +149,7 @@ export default class DesktopCapturerSourcePicker extends React.Component<PickerI
|
|||
return new Tab(type, label, null, <div className="mx_desktopCapturerSourcePicker_tab">{sources}</div>);
|
||||
}
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
const tabs = [
|
||||
this.getTab("screen", _t("Share entire screen")),
|
||||
this.getTab("window", _t("Application window")),
|
||||
|
|
|
@ -25,7 +25,7 @@ interface IProps {
|
|||
}
|
||||
|
||||
export default class DialPadBackspaceButton extends React.PureComponent<IProps> {
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
return (
|
||||
<div className="mx_DialPadBackspaceButtonWrapper">
|
||||
<AccessibleButton
|
||||
|
|
|
@ -71,7 +71,7 @@ export default class DialogButtons extends React.Component<IProps> {
|
|||
this.props.onCancel(event);
|
||||
};
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
let primaryButtonClassName = "mx_Dialog_primary";
|
||||
if (this.props.primaryButtonClass) {
|
||||
primaryButtonClassName += " " + this.props.primaryButtonClass;
|
||||
|
|
|
@ -73,7 +73,7 @@ export default class Draggable extends React.Component<IProps, IState> {
|
|||
});
|
||||
}
|
||||
|
||||
public render(): JSX.Element {
|
||||
public render(): React.ReactNode {
|
||||
return <div className={this.props.className} onMouseDown={this.onMouseDown} />;
|
||||
}
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue