Merge pull request #6412 from matrix-org/gsouqet/ts-migration-1

This commit is contained in:
Germain 2021-07-21 08:36:08 +01:00 committed by GitHub
commit ae60692e88
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 96 additions and 90 deletions

View file

@ -15,8 +15,10 @@ limitations under the License.
*/ */
import React from 'react'; import React from 'react';
import * as sdk from '../../../../index';
import PropTypes from 'prop-types'; import BaseDialog from "../../../../components/views/dialogs/BaseDialog";
import Spinner from "../../../../components/views/elements/Spinner";
import DialogButtons from "../../../../components/views/elements/DialogButtons";
import dis from "../../../../dispatcher/dispatcher"; import dis from "../../../../dispatcher/dispatcher";
import { _t } from '../../../../languageHandler'; import { _t } from '../../../../languageHandler';
@ -24,46 +26,44 @@ import SettingsStore from "../../../../settings/SettingsStore";
import EventIndexPeg from "../../../../indexing/EventIndexPeg"; import EventIndexPeg from "../../../../indexing/EventIndexPeg";
import { Action } from "../../../../dispatcher/actions"; import { Action } from "../../../../dispatcher/actions";
import { SettingLevel } from "../../../../settings/SettingLevel"; import { SettingLevel } from "../../../../settings/SettingLevel";
interface IProps {
onFinished: (success: boolean) => void;
}
interface IState {
disabling: boolean;
}
/* /*
* Allows the user to disable the Event Index. * Allows the user to disable the Event Index.
*/ */
export default class DisableEventIndexDialog extends React.Component { export default class DisableEventIndexDialog extends React.Component<IProps, IState> {
static propTypes = { constructor(props: IProps) {
onFinished: PropTypes.func.isRequired,
}
constructor(props) {
super(props); super(props);
this.state = { this.state = {
disabling: false, disabling: false,
}; };
} }
_onDisable = async () => { private onDisable = async (): Promise<void> => {
this.setState({ this.setState({
disabling: true, disabling: true,
}); });
await SettingsStore.setValue('enableEventIndexing', null, SettingLevel.DEVICE, false); await SettingsStore.setValue('enableEventIndexing', null, SettingLevel.DEVICE, false);
await EventIndexPeg.deleteEventIndex(); await EventIndexPeg.deleteEventIndex();
this.props.onFinished(); this.props.onFinished(true);
dis.fire(Action.ViewUserSettings); dis.fire(Action.ViewUserSettings);
} };
render() {
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
const Spinner = sdk.getComponent('elements.Spinner');
const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
public render(): React.ReactNode {
return ( return (
<BaseDialog onFinished={this.props.onFinished} title={_t("Are you sure?")}> <BaseDialog onFinished={this.props.onFinished} title={_t("Are you sure?")}>
{ _t("If disabled, messages from encrypted rooms won't appear in search results.") } { _t("If disabled, messages from encrypted rooms won't appear in search results.") }
{ this.state.disabling ? <Spinner /> : <div /> } { this.state.disabling ? <Spinner /> : <div /> }
<DialogButtons <DialogButtons
primaryButton={_t('Disable')} primaryButton={_t('Disable')}
onPrimaryButtonClick={this._onDisable} onPrimaryButtonClick={this.onDisable}
primaryButtonClass="danger" primaryButtonClass="danger"
cancelButtonClass="warning" cancelButtonClass="warning"
onCancel={this.props.onFinished} onCancel={this.props.onFinished}

View file

@ -134,8 +134,9 @@ export default class ManageEventIndexDialog extends React.Component<IProps, ISta
} }
private onDisable = async () => { private onDisable = async () => {
Modal.createTrackedDialogAsync("Disable message search", "Disable message search", const DisableEventIndexDialog = (await import("./DisableEventIndexDialog")).default;
import("./DisableEventIndexDialog"), Modal.createTrackedDialog("Disable message search", "Disable message search",
DisableEventIndexDialog,
null, null, /* priority = */ false, /* static = */ true, null, null, /* priority = */ false, /* static = */ true,
); );
}; };

View file

@ -19,7 +19,7 @@ import { replaceableComponent } from "../../../utils/replaceableComponent";
@replaceableComponent("views.auth.AuthBody") @replaceableComponent("views.auth.AuthBody")
export default class AuthBody extends React.PureComponent { export default class AuthBody extends React.PureComponent {
render() { public render(): React.ReactNode {
return <div className="mx_AuthBody"> return <div className="mx_AuthBody">
{ this.props.children } { this.props.children }
</div>; </div>;

View file

@ -22,7 +22,7 @@ import { replaceableComponent } from "../../../utils/replaceableComponent";
@replaceableComponent("views.auth.AuthFooter") @replaceableComponent("views.auth.AuthFooter")
export default class AuthFooter extends React.Component { export default class AuthFooter extends React.Component {
render() { public render(): React.ReactNode {
return ( return (
<div className="mx_AuthFooter"> <div className="mx_AuthFooter">
<a href="https://matrix.org" target="_blank" rel="noreferrer noopener">{ _t("powered by Matrix") }</a> <a href="https://matrix.org" target="_blank" rel="noreferrer noopener">{ _t("powered by Matrix") }</a>

View file

@ -16,20 +16,17 @@ limitations under the License.
*/ */
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types';
import * as sdk from '../../../index';
import { replaceableComponent } from "../../../utils/replaceableComponent"; import { replaceableComponent } from "../../../utils/replaceableComponent";
import AuthHeaderLogo from "./AuthHeaderLogo";
import LanguageSelector from "./LanguageSelector";
interface IProps {
disableLanguageSelector?: boolean;
}
@replaceableComponent("views.auth.AuthHeader") @replaceableComponent("views.auth.AuthHeader")
export default class AuthHeader extends React.Component { export default class AuthHeader extends React.Component<IProps> {
static propTypes = { public render(): React.ReactNode {
disableLanguageSelector: PropTypes.bool,
};
render() {
const AuthHeaderLogo = sdk.getComponent('auth.AuthHeaderLogo');
const LanguageSelector = sdk.getComponent('views.auth.LanguageSelector');
return ( return (
<div className="mx_AuthHeader"> <div className="mx_AuthHeader">
<AuthHeaderLogo /> <AuthHeaderLogo />

View file

@ -19,7 +19,7 @@ import { replaceableComponent } from "../../../utils/replaceableComponent";
@replaceableComponent("views.auth.AuthHeaderLogo") @replaceableComponent("views.auth.AuthHeaderLogo")
export default class AuthHeaderLogo extends React.PureComponent { export default class AuthHeaderLogo extends React.PureComponent {
render() { public render(): React.ReactNode {
return <div className="mx_AuthHeaderLogo"> return <div className="mx_AuthHeaderLogo">
Matrix Matrix
</div>; </div>;

View file

@ -17,14 +17,12 @@ limitations under the License.
*/ */
import React from 'react'; import React from 'react';
import * as sdk from '../../../index';
import { replaceableComponent } from "../../../utils/replaceableComponent"; import { replaceableComponent } from "../../../utils/replaceableComponent";
import AuthFooter from "./AuthFooter";
@replaceableComponent("views.auth.AuthPage") @replaceableComponent("views.auth.AuthPage")
export default class AuthPage extends React.PureComponent { export default class AuthPage extends React.PureComponent {
render() { public render(): React.ReactNode {
const AuthFooter = sdk.getComponent('auth.AuthFooter');
return ( return (
<div className="mx_AuthPage"> <div className="mx_AuthPage">
<div className="mx_AuthPage_modal"> <div className="mx_AuthPage_modal">

View file

@ -19,7 +19,7 @@ import { replaceableComponent } from "../../../utils/replaceableComponent";
@replaceableComponent("views.auth.CompleteSecurityBody") @replaceableComponent("views.auth.CompleteSecurityBody")
export default class CompleteSecurityBody extends React.PureComponent { export default class CompleteSecurityBody extends React.PureComponent {
render() { public render(): React.ReactNode {
return <div className="mx_CompleteSecurityBody"> return <div className="mx_CompleteSecurityBody">
{ this.props.children } { this.props.children }
</div>; </div>;

View file

@ -15,21 +15,19 @@ limitations under the License.
*/ */
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types';
import * as sdk from '../../../index'; import { COUNTRIES, getEmojiFlag, PhoneNumberCountryDefinition } from '../../../phonenumber';
import { COUNTRIES, getEmojiFlag } from '../../../phonenumber';
import SdkConfig from "../../../SdkConfig"; import SdkConfig from "../../../SdkConfig";
import { _t } from "../../../languageHandler"; import { _t } from "../../../languageHandler";
import { replaceableComponent } from "../../../utils/replaceableComponent"; import { replaceableComponent } from "../../../utils/replaceableComponent";
import Dropdown from "../elements/Dropdown";
const COUNTRIES_BY_ISO2 = {}; const COUNTRIES_BY_ISO2 = {};
for (const c of COUNTRIES) { for (const c of COUNTRIES) {
COUNTRIES_BY_ISO2[c.iso2] = c; COUNTRIES_BY_ISO2[c.iso2] = c;
} }
function countryMatchesSearchQuery(query, country) { function countryMatchesSearchQuery(query: string, country: PhoneNumberCountryDefinition): boolean {
// Remove '+' if present (when searching for a prefix) // Remove '+' if present (when searching for a prefix)
if (query[0] === '+') { if (query[0] === '+') {
query = query.slice(1); query = query.slice(1);
@ -41,15 +39,26 @@ function countryMatchesSearchQuery(query, country) {
return false; return false;
} }
@replaceableComponent("views.auth.CountryDropdown") interface IProps {
export default class CountryDropdown extends React.Component { value?: string;
constructor(props) { onOptionChange: (country: PhoneNumberCountryDefinition) => void;
super(props); isSmall: boolean; // if isSmall, show +44 in the selected value
this._onSearchChange = this._onSearchChange.bind(this); showPrefix: boolean;
this._onOptionChange = this._onOptionChange.bind(this); className?: string;
this._getShortOption = this._getShortOption.bind(this); disabled?: boolean;
}
let defaultCountry = COUNTRIES[0]; interface IState {
searchQuery: string;
defaultCountry: PhoneNumberCountryDefinition;
}
@replaceableComponent("views.auth.CountryDropdown")
export default class CountryDropdown extends React.Component<IProps, IState> {
constructor(props: IProps) {
super(props);
let defaultCountry: PhoneNumberCountryDefinition = COUNTRIES[0];
const defaultCountryCode = SdkConfig.get()["defaultCountryCode"]; const defaultCountryCode = SdkConfig.get()["defaultCountryCode"];
if (defaultCountryCode) { if (defaultCountryCode) {
const country = COUNTRIES.find(c => c.iso2 === defaultCountryCode.toUpperCase()); const country = COUNTRIES.find(c => c.iso2 === defaultCountryCode.toUpperCase());
@ -62,7 +71,7 @@ export default class CountryDropdown extends React.Component {
}; };
} }
componentDidMount() { public componentDidMount(): void {
if (!this.props.value) { if (!this.props.value) {
// If no value is given, we start with the default // If no value is given, we start with the default
// country selected, but our parent component // country selected, but our parent component
@ -71,21 +80,21 @@ export default class CountryDropdown extends React.Component {
} }
} }
_onSearchChange(search) { private onSearchChange = (search: string): void => {
this.setState({ this.setState({
searchQuery: search, searchQuery: search,
}); });
} };
_onOptionChange(iso2) { private onOptionChange = (iso2: string): void => {
this.props.onOptionChange(COUNTRIES_BY_ISO2[iso2]); this.props.onOptionChange(COUNTRIES_BY_ISO2[iso2]);
} };
_flagImgForIso2(iso2) { private flagImgForIso2(iso2: string): React.ReactNode {
return <div className="mx_Dropdown_option_emoji">{ getEmojiFlag(iso2) }</div>; return <div className="mx_Dropdown_option_emoji">{ getEmojiFlag(iso2) }</div>;
} }
_getShortOption(iso2) { private getShortOption = (iso2: string): React.ReactNode => {
if (!this.props.isSmall) { if (!this.props.isSmall) {
return undefined; return undefined;
} }
@ -94,14 +103,12 @@ export default class CountryDropdown extends React.Component {
countryPrefix = '+' + COUNTRIES_BY_ISO2[iso2].prefix; countryPrefix = '+' + COUNTRIES_BY_ISO2[iso2].prefix;
} }
return <span className="mx_CountryDropdown_shortOption"> return <span className="mx_CountryDropdown_shortOption">
{ this._flagImgForIso2(iso2) } { this.flagImgForIso2(iso2) }
{ countryPrefix } { countryPrefix }
</span>; </span>;
} };
render() {
const Dropdown = sdk.getComponent('elements.Dropdown');
public render(): React.ReactNode {
let displayedCountries; let displayedCountries;
if (this.state.searchQuery) { if (this.state.searchQuery) {
displayedCountries = COUNTRIES.filter( displayedCountries = COUNTRIES.filter(
@ -124,7 +131,7 @@ export default class CountryDropdown extends React.Component {
const options = displayedCountries.map((country) => { const options = displayedCountries.map((country) => {
return <div className="mx_CountryDropdown_option" key={country.iso2}> return <div className="mx_CountryDropdown_option" key={country.iso2}>
{ this._flagImgForIso2(country.iso2) } { this.flagImgForIso2(country.iso2) }
{ _t(country.name) } (+{ country.prefix }) { _t(country.name) } (+{ country.prefix })
</div>; </div>;
}); });
@ -136,10 +143,10 @@ export default class CountryDropdown extends React.Component {
return <Dropdown return <Dropdown
id="mx_CountryDropdown" id="mx_CountryDropdown"
className={this.props.className + " mx_CountryDropdown"} className={this.props.className + " mx_CountryDropdown"}
onOptionChange={this._onOptionChange} onOptionChange={this.onOptionChange}
onSearchChange={this._onSearchChange} onSearchChange={this.onSearchChange}
menuWidth={298} menuWidth={298}
getShortOption={this._getShortOption} getShortOption={this.getShortOption}
value={value} value={value}
searchEnabled={true} searchEnabled={true}
disabled={this.props.disabled} disabled={this.props.disabled}
@ -149,13 +156,3 @@ export default class CountryDropdown extends React.Component {
</Dropdown>; </Dropdown>;
} }
} }
CountryDropdown.propTypes = {
className: PropTypes.string,
isSmall: PropTypes.bool,
// if isSmall, show +44 in the selected value
showPrefix: PropTypes.bool,
onOptionChange: PropTypes.func.isRequired,
value: PropTypes.string,
disabled: PropTypes.bool,
};

View file

@ -18,21 +18,23 @@ import SdkConfig from "../../../SdkConfig";
import { getCurrentLanguage } from "../../../languageHandler"; import { getCurrentLanguage } from "../../../languageHandler";
import SettingsStore from "../../../settings/SettingsStore"; import SettingsStore from "../../../settings/SettingsStore";
import PlatformPeg from "../../../PlatformPeg"; import PlatformPeg from "../../../PlatformPeg";
import * as sdk from '../../../index';
import React from 'react'; import React from 'react';
import { SettingLevel } from "../../../settings/SettingLevel"; import { SettingLevel } from "../../../settings/SettingLevel";
import LanguageDropdown from "../elements/LanguageDropdown";
function onChange(newLang) { function onChange(newLang: string): void {
if (getCurrentLanguage() !== newLang) { if (getCurrentLanguage() !== newLang) {
SettingsStore.setValue("language", null, SettingLevel.DEVICE, newLang); SettingsStore.setValue("language", null, SettingLevel.DEVICE, newLang);
PlatformPeg.get().reload(); PlatformPeg.get().reload();
} }
} }
export default function LanguageSelector({ disabled }) { interface IProps {
if (SdkConfig.get()['disable_login_language_selector']) return <div />; disabled?: boolean;
}
const LanguageDropdown = sdk.getComponent('views.elements.LanguageDropdown'); export default function LanguageSelector({ disabled }: IProps): JSX.Element {
if (SdkConfig.get()['disable_login_language_selector']) return <div />;
return <LanguageDropdown return <LanguageDropdown
className="mx_AuthBody_language" className="mx_AuthBody_language"
onOptionChange={onChange} onOptionChange={onChange}

View file

@ -17,7 +17,7 @@ limitations under the License.
import React from 'react'; import React from 'react';
import classNames from "classnames"; import classNames from "classnames";
import * as sdk from '../../../index'; import * as sdk from "../../../index";
import SdkConfig from '../../../SdkConfig'; import SdkConfig from '../../../SdkConfig';
import AuthPage from "./AuthPage"; import AuthPage from "./AuthPage";
import { _td } from "../../../languageHandler"; import { _td } from "../../../languageHandler";
@ -25,21 +25,26 @@ import SettingsStore from "../../../settings/SettingsStore";
import { UIFeature } from "../../../settings/UIFeature"; import { UIFeature } from "../../../settings/UIFeature";
import CountlyAnalytics from "../../../CountlyAnalytics"; import CountlyAnalytics from "../../../CountlyAnalytics";
import { replaceableComponent } from "../../../utils/replaceableComponent"; import { replaceableComponent } from "../../../utils/replaceableComponent";
import LanguageSelector from "./LanguageSelector";
// translatable strings for Welcome pages // translatable strings for Welcome pages
_td("Sign in with SSO"); _td("Sign in with SSO");
interface IProps {
}
@replaceableComponent("views.auth.Welcome") @replaceableComponent("views.auth.Welcome")
export default class Welcome extends React.PureComponent { export default class Welcome extends React.PureComponent<IProps> {
constructor(props) { constructor(props: IProps) {
super(props); super(props);
CountlyAnalytics.instance.track("onboarding_welcome"); CountlyAnalytics.instance.track("onboarding_welcome");
} }
render() { public render(): React.ReactNode {
const EmbeddedPage = sdk.getComponent('structures.EmbeddedPage'); // FIXME: Using an import will result in wrench-element-tests failures
const LanguageSelector = sdk.getComponent('auth.LanguageSelector'); const EmbeddedPage = sdk.getComponent("structures.EmbeddedPage");
const pagesConfig = SdkConfig.get().embeddedPages; const pagesConfig = SdkConfig.get().embeddedPages;
let pageUrl = null; let pageUrl = null;

View file

@ -42,7 +42,13 @@ export const getEmojiFlag = (countryCode: string) => {
return String.fromCodePoint(...countryCode.split('').map(l => UNICODE_BASE + l.charCodeAt(0))); return String.fromCodePoint(...countryCode.split('').map(l => UNICODE_BASE + l.charCodeAt(0)));
}; };
export const COUNTRIES = [ export interface PhoneNumberCountryDefinition {
iso2: string;
name: string;
prefix: string;
}
export const COUNTRIES: PhoneNumberCountryDefinition[] = [
{ {
"iso2": "GB", "iso2": "GB",
"name": _td("United Kingdom"), "name": _td("United Kingdom"),