Convert PhoneNumbers to TS
Signed-off-by: Šimon Brandner <simon.bra.ag@gmail.com>pull/21833/head
parent
a2ecf18096
commit
39f92c4ddc
|
@ -16,16 +16,17 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import { _t } from "../../../../languageHandler";
|
import { _t } from "../../../../languageHandler";
|
||||||
import { MatrixClientPeg } from "../../../../MatrixClientPeg";
|
import { MatrixClientPeg } from "../../../../MatrixClientPeg";
|
||||||
import Field from "../../elements/Field";
|
import Field from "../../elements/Field";
|
||||||
import AccessibleButton from "../../elements/AccessibleButton";
|
import AccessibleButton from "../../elements/AccessibleButton";
|
||||||
import AddThreepid from "../../../../AddThreepid";
|
import AddThreepid from "../../../../AddThreepid";
|
||||||
import CountryDropdown from "../../auth/CountryDropdown";
|
import CountryDropdown from "../../auth/CountryDropdown";
|
||||||
import * as sdk from '../../../../index';
|
|
||||||
import Modal from '../../../../Modal';
|
import Modal from '../../../../Modal';
|
||||||
import { replaceableComponent } from "../../../../utils/replaceableComponent";
|
import { replaceableComponent } from "../../../../utils/replaceableComponent";
|
||||||
|
import { IThreepid, ThreepidMedium } from "matrix-js-sdk/src/@types/threepids";
|
||||||
|
import ErrorDialog from "../../dialogs/ErrorDialog";
|
||||||
|
import { PhoneNumberCountryDefinition } from "../../../../phonenumber";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
TODO: Improve the UX for everything in here.
|
TODO: Improve the UX for everything in here.
|
||||||
|
@ -34,42 +35,45 @@ This is a copy/paste of EmailAddresses, mostly.
|
||||||
|
|
||||||
// TODO: Combine EmailAddresses and PhoneNumbers to be 3pid agnostic
|
// TODO: Combine EmailAddresses and PhoneNumbers to be 3pid agnostic
|
||||||
|
|
||||||
export class ExistingPhoneNumber extends React.Component {
|
interface IExistingPhoneNumberProps {
|
||||||
static propTypes = {
|
msisdn: IThreepid;
|
||||||
msisdn: PropTypes.object.isRequired,
|
onRemoved: (phoneNumber: IThreepid) => void;
|
||||||
onRemoved: PropTypes.func.isRequired,
|
}
|
||||||
};
|
|
||||||
|
|
||||||
constructor() {
|
interface IExistingPhoneNumberState {
|
||||||
super();
|
verifyRemove: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ExistingPhoneNumber extends React.Component<IExistingPhoneNumberProps, IExistingPhoneNumberState> {
|
||||||
|
constructor(props: IExistingPhoneNumberProps) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
verifyRemove: false,
|
verifyRemove: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
_onRemove = (e) => {
|
private onRemove = (e: React.MouseEvent): void => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
this.setState({ verifyRemove: true });
|
this.setState({ verifyRemove: true });
|
||||||
};
|
};
|
||||||
|
|
||||||
_onDontRemove = (e) => {
|
private onDontRemove = (e: React.MouseEvent): void => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
this.setState({ verifyRemove: false });
|
this.setState({ verifyRemove: false });
|
||||||
};
|
};
|
||||||
|
|
||||||
_onActuallyRemove = (e) => {
|
private onActuallyRemove = (e: React.MouseEvent): void => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
MatrixClientPeg.get().deleteThreePid(this.props.msisdn.medium, this.props.msisdn.address).then(() => {
|
MatrixClientPeg.get().deleteThreePid(this.props.msisdn.medium, this.props.msisdn.address).then(() => {
|
||||||
return this.props.onRemoved(this.props.msisdn);
|
return this.props.onRemoved(this.props.msisdn);
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
|
||||||
console.error("Unable to remove contact information: " + err);
|
console.error("Unable to remove contact information: " + err);
|
||||||
Modal.createTrackedDialog('Remove 3pid failed', '', ErrorDialog, {
|
Modal.createTrackedDialog('Remove 3pid failed', '', ErrorDialog, {
|
||||||
title: _t("Unable to remove contact information"),
|
title: _t("Unable to remove contact information"),
|
||||||
|
@ -78,7 +82,7 @@ export class ExistingPhoneNumber extends React.Component {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
public render(): JSX.Element {
|
||||||
if (this.state.verifyRemove) {
|
if (this.state.verifyRemove) {
|
||||||
return (
|
return (
|
||||||
<div className="mx_ExistingPhoneNumber">
|
<div className="mx_ExistingPhoneNumber">
|
||||||
|
@ -86,14 +90,14 @@ export class ExistingPhoneNumber extends React.Component {
|
||||||
{ _t("Remove %(phone)s?", { phone: this.props.msisdn.address }) }
|
{ _t("Remove %(phone)s?", { phone: this.props.msisdn.address }) }
|
||||||
</span>
|
</span>
|
||||||
<AccessibleButton
|
<AccessibleButton
|
||||||
onClick={this._onActuallyRemove}
|
onClick={this.onActuallyRemove}
|
||||||
kind="danger_sm"
|
kind="danger_sm"
|
||||||
className="mx_ExistingPhoneNumber_confirmBtn"
|
className="mx_ExistingPhoneNumber_confirmBtn"
|
||||||
>
|
>
|
||||||
{ _t("Remove") }
|
{ _t("Remove") }
|
||||||
</AccessibleButton>
|
</AccessibleButton>
|
||||||
<AccessibleButton
|
<AccessibleButton
|
||||||
onClick={this._onDontRemove}
|
onClick={this.onDontRemove}
|
||||||
kind="link_sm"
|
kind="link_sm"
|
||||||
className="mx_ExistingPhoneNumber_confirmBtn"
|
className="mx_ExistingPhoneNumber_confirmBtn"
|
||||||
>
|
>
|
||||||
|
@ -106,7 +110,7 @@ export class ExistingPhoneNumber extends React.Component {
|
||||||
return (
|
return (
|
||||||
<div className="mx_ExistingPhoneNumber">
|
<div className="mx_ExistingPhoneNumber">
|
||||||
<span className="mx_ExistingPhoneNumber_address">+{ this.props.msisdn.address }</span>
|
<span className="mx_ExistingPhoneNumber_address">+{ this.props.msisdn.address }</span>
|
||||||
<AccessibleButton onClick={this._onRemove} kind="danger_sm">
|
<AccessibleButton onClick={this.onRemove} kind="danger_sm">
|
||||||
{ _t("Remove") }
|
{ _t("Remove") }
|
||||||
</AccessibleButton>
|
</AccessibleButton>
|
||||||
</div>
|
</div>
|
||||||
|
@ -114,19 +118,30 @@ export class ExistingPhoneNumber extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@replaceableComponent("views.settings.account.PhoneNumbers")
|
interface IProps {
|
||||||
export default class PhoneNumbers extends React.Component {
|
msisdns: IThreepid[];
|
||||||
static propTypes = {
|
onMsisdnsChange: (phoneNumbers: Partial<IThreepid>[]) => void;
|
||||||
msisdns: PropTypes.array.isRequired,
|
}
|
||||||
onMsisdnsChange: PropTypes.func.isRequired,
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(props) {
|
interface IState {
|
||||||
|
verifying: boolean;
|
||||||
|
verifyError: string;
|
||||||
|
verifyMsisdn: string;
|
||||||
|
addTask: any; // FIXME: When AddThreepid is TSfied
|
||||||
|
continueDisabled: boolean;
|
||||||
|
phoneCountry: string;
|
||||||
|
newPhoneNumber: string;
|
||||||
|
newPhoneNumberCode: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@replaceableComponent("views.settings.account.PhoneNumbers")
|
||||||
|
export default class PhoneNumbers extends React.Component<IProps, IState> {
|
||||||
|
constructor(props: IProps) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
verifying: false,
|
verifying: false,
|
||||||
verifyError: false,
|
verifyError: null,
|
||||||
verifyMsisdn: "",
|
verifyMsisdn: "",
|
||||||
addTask: null,
|
addTask: null,
|
||||||
continueDisabled: false,
|
continueDisabled: false,
|
||||||
|
@ -136,30 +151,29 @@ export default class PhoneNumbers extends React.Component {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
_onRemoved = (address) => {
|
private onRemoved = (address: IThreepid): void => {
|
||||||
const msisdns = this.props.msisdns.filter((e) => e !== address);
|
const msisdns = this.props.msisdns.filter((e) => e !== address);
|
||||||
this.props.onMsisdnsChange(msisdns);
|
this.props.onMsisdnsChange(msisdns);
|
||||||
};
|
};
|
||||||
|
|
||||||
_onChangeNewPhoneNumber = (e) => {
|
private onChangeNewPhoneNumber = (e: React.ChangeEvent<HTMLInputElement>): void => {
|
||||||
this.setState({
|
this.setState({
|
||||||
newPhoneNumber: e.target.value,
|
newPhoneNumber: e.target.value,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
_onChangeNewPhoneNumberCode = (e) => {
|
private onChangeNewPhoneNumberCode = (e: React.ChangeEvent<HTMLInputElement>): void => {
|
||||||
this.setState({
|
this.setState({
|
||||||
newPhoneNumberCode: e.target.value,
|
newPhoneNumberCode: e.target.value,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
_onAddClick = (e) => {
|
private onAddClick = (e: React.MouseEvent | React.FormEvent): void => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
if (!this.state.newPhoneNumber) return;
|
if (!this.state.newPhoneNumber) return;
|
||||||
|
|
||||||
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
|
||||||
const phoneNumber = this.state.newPhoneNumber;
|
const phoneNumber = this.state.newPhoneNumber;
|
||||||
const phoneCountry = this.state.phoneCountry;
|
const phoneCountry = this.state.phoneCountry;
|
||||||
|
|
||||||
|
@ -178,7 +192,7 @@ export default class PhoneNumbers extends React.Component {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
_onContinueClick = (e) => {
|
private onContinueClick = (e: React.MouseEvent | React.FormEvent): void => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
|
@ -190,7 +204,7 @@ export default class PhoneNumbers extends React.Component {
|
||||||
if (finished) {
|
if (finished) {
|
||||||
const msisdns = [
|
const msisdns = [
|
||||||
...this.props.msisdns,
|
...this.props.msisdns,
|
||||||
{ address, medium: "msisdn" },
|
{ address, medium: ThreepidMedium.Phone },
|
||||||
];
|
];
|
||||||
this.props.onMsisdnsChange(msisdns);
|
this.props.onMsisdnsChange(msisdns);
|
||||||
newPhoneNumber = "";
|
newPhoneNumber = "";
|
||||||
|
@ -207,7 +221,6 @@ export default class PhoneNumbers extends React.Component {
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
this.setState({ continueDisabled: false });
|
this.setState({ continueDisabled: false });
|
||||||
if (err.errcode !== 'M_THREEPID_AUTH_FAILED') {
|
if (err.errcode !== 'M_THREEPID_AUTH_FAILED') {
|
||||||
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
|
||||||
console.error("Unable to verify phone number: " + err);
|
console.error("Unable to verify phone number: " + err);
|
||||||
Modal.createTrackedDialog('Unable to verify phone number', '', ErrorDialog, {
|
Modal.createTrackedDialog('Unable to verify phone number', '', ErrorDialog, {
|
||||||
title: _t("Unable to verify phone number."),
|
title: _t("Unable to verify phone number."),
|
||||||
|
@ -219,17 +232,17 @@ export default class PhoneNumbers extends React.Component {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
_onCountryChanged = (e) => {
|
private onCountryChanged = (country: PhoneNumberCountryDefinition): void => {
|
||||||
this.setState({ phoneCountry: e.iso2 });
|
this.setState({ phoneCountry: country.iso2 });
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
public render(): JSX.Element {
|
||||||
const existingPhoneElements = this.props.msisdns.map((p) => {
|
const existingPhoneElements = this.props.msisdns.map((p) => {
|
||||||
return <ExistingPhoneNumber msisdn={p} onRemoved={this._onRemoved} key={p.address} />;
|
return <ExistingPhoneNumber msisdn={p} onRemoved={this.onRemoved} key={p.address} />;
|
||||||
});
|
});
|
||||||
|
|
||||||
let addVerifySection = (
|
let addVerifySection = (
|
||||||
<AccessibleButton onClick={this._onAddClick} kind="primary">
|
<AccessibleButton onClick={this.onAddClick} kind="primary">
|
||||||
{ _t("Add") }
|
{ _t("Add") }
|
||||||
</AccessibleButton>
|
</AccessibleButton>
|
||||||
);
|
);
|
||||||
|
@ -243,17 +256,17 @@ export default class PhoneNumbers extends React.Component {
|
||||||
<br />
|
<br />
|
||||||
{ this.state.verifyError }
|
{ this.state.verifyError }
|
||||||
</div>
|
</div>
|
||||||
<form onSubmit={this._onContinueClick} autoComplete="off" noValidate={true}>
|
<form onSubmit={this.onContinueClick} autoComplete="off" noValidate={true}>
|
||||||
<Field
|
<Field
|
||||||
type="text"
|
type="text"
|
||||||
label={_t("Verification code")}
|
label={_t("Verification code")}
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
disabled={this.state.continueDisabled}
|
disabled={this.state.continueDisabled}
|
||||||
value={this.state.newPhoneNumberCode}
|
value={this.state.newPhoneNumberCode}
|
||||||
onChange={this._onChangeNewPhoneNumberCode}
|
onChange={this.onChangeNewPhoneNumberCode}
|
||||||
/>
|
/>
|
||||||
<AccessibleButton
|
<AccessibleButton
|
||||||
onClick={this._onContinueClick}
|
onClick={this.onContinueClick}
|
||||||
kind="primary"
|
kind="primary"
|
||||||
disabled={this.state.continueDisabled}
|
disabled={this.state.continueDisabled}
|
||||||
>
|
>
|
||||||
|
@ -264,7 +277,7 @@ export default class PhoneNumbers extends React.Component {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const phoneCountry = <CountryDropdown onOptionChange={this._onCountryChanged}
|
const phoneCountry = <CountryDropdown onOptionChange={this.onCountryChanged}
|
||||||
className="mx_PhoneNumbers_country"
|
className="mx_PhoneNumbers_country"
|
||||||
value={this.state.phoneCountry}
|
value={this.state.phoneCountry}
|
||||||
disabled={this.state.verifying}
|
disabled={this.state.verifying}
|
||||||
|
@ -275,7 +288,7 @@ export default class PhoneNumbers extends React.Component {
|
||||||
return (
|
return (
|
||||||
<div className="mx_PhoneNumbers">
|
<div className="mx_PhoneNumbers">
|
||||||
{ existingPhoneElements }
|
{ existingPhoneElements }
|
||||||
<form onSubmit={this._onAddClick} autoComplete="off" noValidate={true} className="mx_PhoneNumbers_new">
|
<form onSubmit={this.onAddClick} autoComplete="off" noValidate={true} className="mx_PhoneNumbers_new">
|
||||||
<div className="mx_PhoneNumbers_input">
|
<div className="mx_PhoneNumbers_input">
|
||||||
<Field
|
<Field
|
||||||
type="text"
|
type="text"
|
||||||
|
@ -284,7 +297,7 @@ export default class PhoneNumbers extends React.Component {
|
||||||
disabled={this.state.verifying}
|
disabled={this.state.verifying}
|
||||||
prefixComponent={phoneCountry}
|
prefixComponent={phoneCountry}
|
||||||
value={this.state.newPhoneNumber}
|
value={this.state.newPhoneNumber}
|
||||||
onChange={this._onChangeNewPhoneNumber}
|
onChange={this.onChangeNewPhoneNumber}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
Loading…
Reference in New Issue