Enable @typescript-eslint/explicit-function-return-type
in /src (#9788)
* Enable `@typescript-eslint/explicit-member-accessibility` on /src * Prettier * Enable `@typescript-eslint/explicit-function-return-type` in /src * Fix types * tsc strict fixes * Delint * Fix test * Fix bad merge
This commit is contained in:
parent
7a36ba0fde
commit
030b7e90bf
683 changed files with 3459 additions and 3013 deletions
|
@ -102,7 +102,7 @@ export default function AccessibleButton<T extends keyof JSX.IntrinsicElements>(
|
|||
onKeyUp,
|
||||
triggerOnMouseDown,
|
||||
...restProps
|
||||
}: IProps<T>) {
|
||||
}: IProps<T>): JSX.Element {
|
||||
const newProps: IAccessibleButtonProps = restProps;
|
||||
if (disabled) {
|
||||
newProps["aria-disabled"] = true;
|
||||
|
|
|
@ -43,7 +43,7 @@ export default class AccessibleTooltipButton extends React.PureComponent<IProps,
|
|||
};
|
||||
}
|
||||
|
||||
public componentDidUpdate(prevProps: Readonly<IProps>) {
|
||||
public componentDidUpdate(prevProps: Readonly<IProps>): void {
|
||||
if (!prevProps.forceHide && this.props.forceHide && this.state.hover) {
|
||||
this.setState({
|
||||
hover: false,
|
||||
|
@ -51,7 +51,7 @@ export default class AccessibleTooltipButton extends React.PureComponent<IProps,
|
|||
}
|
||||
}
|
||||
|
||||
private showTooltip = () => {
|
||||
private showTooltip = (): void => {
|
||||
if (this.props.onHover) this.props.onHover(true);
|
||||
if (this.props.forceHide) return;
|
||||
this.setState({
|
||||
|
@ -59,7 +59,7 @@ export default class AccessibleTooltipButton extends React.PureComponent<IProps,
|
|||
});
|
||||
};
|
||||
|
||||
private hideTooltip = (ev: SyntheticEvent) => {
|
||||
private hideTooltip = (ev: SyntheticEvent): void => {
|
||||
if (this.props.onHover) this.props.onHover(false);
|
||||
this.setState({
|
||||
hover: false,
|
||||
|
@ -67,13 +67,13 @@ export default class AccessibleTooltipButton extends React.PureComponent<IProps,
|
|||
this.props.onHideTooltip?.(ev);
|
||||
};
|
||||
|
||||
private onFocus = (ev: FocusEvent) => {
|
||||
private onFocus = (ev: FocusEvent): void => {
|
||||
// We only show the tooltip if focus arrived here from some other
|
||||
// element, to avoid leaving tooltips hanging around when a modal closes
|
||||
if (ev.relatedTarget) this.showTooltip();
|
||||
};
|
||||
|
||||
public render() {
|
||||
public render(): JSX.Element {
|
||||
// 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() {
|
||||
public render(): JSX.Element {
|
||||
const brand = SdkConfig.get().brand;
|
||||
|
||||
const displayName = this.state.roomMember ? this.state.roomMember.name : this.props.creatorUserId;
|
||||
|
|
|
@ -147,7 +147,7 @@ export default class AppTile extends React.Component<IProps, IState> {
|
|||
this.state = this.getNewState(props);
|
||||
}
|
||||
|
||||
private watchUserReady = () => {
|
||||
private watchUserReady = (): void => {
|
||||
if (OwnProfileStore.instance.isProfileInfoFetched) {
|
||||
return;
|
||||
}
|
||||
|
@ -168,7 +168,7 @@ export default class AppTile extends React.Component<IProps, IState> {
|
|||
return allowed || props.userId === props.creatorUserId;
|
||||
};
|
||||
|
||||
private onUserLeftRoom() {
|
||||
private onUserLeftRoom(): void {
|
||||
const isActiveWidget = ActiveWidgetStore.instance.getWidgetPersistence(
|
||||
this.props.app.id,
|
||||
this.props.app.roomId,
|
||||
|
@ -304,13 +304,13 @@ export default class AppTile extends React.Component<IProps, IState> {
|
|||
OwnProfileStore.instance.removeListener(UPDATE_EVENT, this.onUserReady);
|
||||
}
|
||||
|
||||
private setupSgListeners() {
|
||||
private setupSgListeners(): void {
|
||||
this.sgWidget.on("preparing", this.onWidgetPreparing);
|
||||
// emits when the capabilities have been set up or changed
|
||||
this.sgWidget.on("capabilitiesNotified", this.onWidgetCapabilitiesNotified);
|
||||
}
|
||||
|
||||
private stopSgListeners() {
|
||||
private stopSgListeners(): void {
|
||||
if (!this.sgWidget) return;
|
||||
this.sgWidget.off("preparing", this.onWidgetPreparing);
|
||||
this.sgWidget.off("capabilitiesNotified", this.onWidgetCapabilitiesNotified);
|
||||
|
@ -337,7 +337,7 @@ export default class AppTile extends React.Component<IProps, IState> {
|
|||
});
|
||||
}
|
||||
|
||||
private startMessaging() {
|
||||
private startMessaging(): void {
|
||||
try {
|
||||
this.sgWidget?.startMessaging(this.iframe);
|
||||
} catch (e) {
|
||||
|
@ -490,7 +490,7 @@ export default class AppTile extends React.Component<IProps, IState> {
|
|||
);
|
||||
}
|
||||
|
||||
private reload() {
|
||||
private reload(): void {
|
||||
this.endWidgetActions().then(() => {
|
||||
// reset messaging
|
||||
this.resetWidget(this.props);
|
||||
|
|
|
@ -33,13 +33,13 @@ interface IProps {
|
|||
const CopyableText: React.FC<IProps> = ({ children, getTextToCopy, border = true, className }) => {
|
||||
const [tooltip, setTooltip] = useState<string | undefined>(undefined);
|
||||
|
||||
const onCopyClickInternal = async (e: ButtonEvent) => {
|
||||
const onCopyClickInternal = async (e: ButtonEvent): Promise<void> => {
|
||||
e.preventDefault();
|
||||
const successful = await copyPlaintext(getTextToCopy());
|
||||
setTooltip(successful ? _t("Copied!") : _t("Failed to copy"));
|
||||
};
|
||||
|
||||
const onHideTooltip = () => {
|
||||
const onHideTooltip = (): void => {
|
||||
if (tooltip) {
|
||||
setTooltip(undefined);
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ export class ExistingSource extends React.Component<ExistingSourceIProps> {
|
|||
this.props.onSelect(this.props.source);
|
||||
};
|
||||
|
||||
public render() {
|
||||
public render(): JSX.Element {
|
||||
const thumbnailClasses = classNames({
|
||||
mx_desktopCapturerSourcePicker_source_thumbnail: true,
|
||||
mx_desktopCapturerSourcePicker_source_thumbnail_selected: this.props.selected,
|
||||
|
@ -96,7 +96,7 @@ export default class DesktopCapturerSourcePicker extends React.Component<PickerI
|
|||
};
|
||||
}
|
||||
|
||||
public async componentDidMount() {
|
||||
public async componentDidMount(): Promise<void> {
|
||||
// window.setInterval() first waits and then executes, therefore
|
||||
// we call getDesktopCapturerSources() here without any delay.
|
||||
// Otherwise the dialog would be left empty for some time.
|
||||
|
@ -105,14 +105,14 @@ export default class DesktopCapturerSourcePicker extends React.Component<PickerI
|
|||
});
|
||||
|
||||
// We update the sources every 500ms to get newer thumbnails
|
||||
this.interval = window.setInterval(async () => {
|
||||
this.interval = window.setInterval(async (): Promise<void> => {
|
||||
this.setState({
|
||||
sources: await getDesktopCapturerSources(),
|
||||
});
|
||||
}, 500);
|
||||
}
|
||||
|
||||
public componentWillUnmount() {
|
||||
public componentWillUnmount(): void {
|
||||
clearInterval(this.interval);
|
||||
}
|
||||
|
||||
|
@ -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() {
|
||||
public render(): JSX.Element {
|
||||
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() {
|
||||
public render(): JSX.Element {
|
||||
return (
|
||||
<div className="mx_DialPadBackspaceButtonWrapper">
|
||||
<AccessibleButton
|
||||
|
|
|
@ -73,7 +73,7 @@ export default class Draggable extends React.Component<IProps, IState> {
|
|||
});
|
||||
}
|
||||
|
||||
public render() {
|
||||
public render(): JSX.Element {
|
||||
return <div className={this.props.className} onMouseDown={this.onMouseDown} />;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,17 +39,17 @@ class MenuOption extends React.Component<IMenuOptionProps> {
|
|||
disabled: false,
|
||||
};
|
||||
|
||||
private onMouseEnter = () => {
|
||||
private onMouseEnter = (): void => {
|
||||
this.props.onMouseEnter(this.props.dropdownKey);
|
||||
};
|
||||
|
||||
private onClick = (e: React.MouseEvent) => {
|
||||
private onClick = (e: React.MouseEvent): void => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
this.props.onClick(this.props.dropdownKey);
|
||||
};
|
||||
|
||||
public render() {
|
||||
public render(): JSX.Element {
|
||||
const optClasses = classnames({
|
||||
mx_Dropdown_option: true,
|
||||
mx_Dropdown_option_highlight: this.props.highlighted,
|
||||
|
@ -139,7 +139,7 @@ export default class Dropdown extends React.Component<DropdownProps, IState> {
|
|||
document.addEventListener("click", this.onDocumentClick, false);
|
||||
}
|
||||
|
||||
public componentDidUpdate(prevProps: Readonly<DropdownProps>) {
|
||||
public componentDidUpdate(prevProps: Readonly<DropdownProps>): void {
|
||||
if (objectHasDiff(this.props, prevProps) && this.props.children?.length) {
|
||||
this.reindexChildren(this.props.children);
|
||||
const firstChild = this.props.children[0];
|
||||
|
@ -149,7 +149,7 @@ export default class Dropdown extends React.Component<DropdownProps, IState> {
|
|||
}
|
||||
}
|
||||
|
||||
public componentWillUnmount() {
|
||||
public componentWillUnmount(): void {
|
||||
document.removeEventListener("click", this.onDocumentClick, false);
|
||||
}
|
||||
|
||||
|
@ -160,7 +160,7 @@ export default class Dropdown extends React.Component<DropdownProps, IState> {
|
|||
});
|
||||
}
|
||||
|
||||
private onDocumentClick = (ev: MouseEvent) => {
|
||||
private onDocumentClick = (ev: MouseEvent): void => {
|
||||
// Close the dropdown if the user clicks anywhere that isn't
|
||||
// within our root element
|
||||
if (ev !== this.ignoreEvent) {
|
||||
|
@ -170,7 +170,7 @@ export default class Dropdown extends React.Component<DropdownProps, IState> {
|
|||
}
|
||||
};
|
||||
|
||||
private onRootClick = (ev: MouseEvent) => {
|
||||
private onRootClick = (ev: MouseEvent): void => {
|
||||
// This captures any clicks that happen within our elements,
|
||||
// such that we can then ignore them when they're seen by the
|
||||
// click listener on the document handler, ie. not close the
|
||||
|
@ -180,7 +180,7 @@ export default class Dropdown extends React.Component<DropdownProps, IState> {
|
|||
this.ignoreEvent = ev;
|
||||
};
|
||||
|
||||
private onAccessibleButtonClick = (ev: ButtonEvent) => {
|
||||
private onAccessibleButtonClick = (ev: ButtonEvent): void => {
|
||||
if (this.props.disabled) return;
|
||||
|
||||
const action = getKeyBindingsManager().getAccessibilityAction(ev as React.KeyboardEvent);
|
||||
|
@ -199,7 +199,7 @@ export default class Dropdown extends React.Component<DropdownProps, IState> {
|
|||
}
|
||||
};
|
||||
|
||||
private close() {
|
||||
private close(): void {
|
||||
this.setState({
|
||||
expanded: false,
|
||||
});
|
||||
|
@ -209,12 +209,12 @@ export default class Dropdown extends React.Component<DropdownProps, IState> {
|
|||
}
|
||||
}
|
||||
|
||||
private onMenuOptionClick = (dropdownKey: string) => {
|
||||
private onMenuOptionClick = (dropdownKey: string): void => {
|
||||
this.close();
|
||||
this.props.onOptionChange(dropdownKey);
|
||||
};
|
||||
|
||||
private onKeyDown = (e: React.KeyboardEvent) => {
|
||||
private onKeyDown = (e: React.KeyboardEvent): void => {
|
||||
let handled = true;
|
||||
|
||||
// These keys don't generate keypress events and so needs to be on keyup
|
||||
|
@ -254,7 +254,7 @@ export default class Dropdown extends React.Component<DropdownProps, IState> {
|
|||
}
|
||||
};
|
||||
|
||||
private onInputChange = (e: ChangeEvent<HTMLInputElement>) => {
|
||||
private onInputChange = (e: ChangeEvent<HTMLInputElement>): void => {
|
||||
this.setState({
|
||||
searchQuery: e.currentTarget.value,
|
||||
});
|
||||
|
@ -263,7 +263,7 @@ export default class Dropdown extends React.Component<DropdownProps, IState> {
|
|||
}
|
||||
};
|
||||
|
||||
private collectRoot = (e: HTMLDivElement) => {
|
||||
private collectRoot = (e: HTMLDivElement): void => {
|
||||
if (this.dropdownRootElement) {
|
||||
this.dropdownRootElement.removeEventListener("click", this.onRootClick, false);
|
||||
}
|
||||
|
@ -273,7 +273,7 @@ export default class Dropdown extends React.Component<DropdownProps, IState> {
|
|||
this.dropdownRootElement = e;
|
||||
};
|
||||
|
||||
private setHighlightedOption = (optionKey: string) => {
|
||||
private setHighlightedOption = (optionKey: string): void => {
|
||||
this.setState({
|
||||
highlightedOption: optionKey,
|
||||
});
|
||||
|
@ -291,7 +291,7 @@ export default class Dropdown extends React.Component<DropdownProps, IState> {
|
|||
return keys[index <= 0 ? keys.length - 1 : (index - 1) % keys.length];
|
||||
}
|
||||
|
||||
private scrollIntoView(node: Element) {
|
||||
private scrollIntoView(node: Element): void {
|
||||
if (node) {
|
||||
node.scrollIntoView({
|
||||
block: "nearest",
|
||||
|
@ -300,7 +300,7 @@ export default class Dropdown extends React.Component<DropdownProps, IState> {
|
|||
}
|
||||
}
|
||||
|
||||
private getMenuOptions() {
|
||||
private getMenuOptions(): JSX.Element[] {
|
||||
const options = React.Children.map(this.props.children, (child: ReactElement) => {
|
||||
const highlighted = this.state.highlightedOption === child.key;
|
||||
return (
|
||||
|
@ -327,7 +327,7 @@ export default class Dropdown extends React.Component<DropdownProps, IState> {
|
|||
return options;
|
||||
}
|
||||
|
||||
public render() {
|
||||
public render(): JSX.Element {
|
||||
let currentValue;
|
||||
|
||||
const menuStyle: CSSProperties = {};
|
||||
|
|
|
@ -35,21 +35,21 @@ export class EditableItem extends React.Component<IItemProps, IItemState> {
|
|||
verifyRemove: false,
|
||||
};
|
||||
|
||||
private onRemove = (e) => {
|
||||
private onRemove = (e): void => {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
|
||||
this.setState({ verifyRemove: true });
|
||||
};
|
||||
|
||||
private onDontRemove = (e) => {
|
||||
private onDontRemove = (e): void => {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
|
||||
this.setState({ verifyRemove: false });
|
||||
};
|
||||
|
||||
private onActuallyRemove = (e) => {
|
||||
private onActuallyRemove = (e): void => {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
|
||||
|
@ -57,7 +57,7 @@ export class EditableItem extends React.Component<IItemProps, IItemState> {
|
|||
this.setState({ verifyRemove: false });
|
||||
};
|
||||
|
||||
public render() {
|
||||
public render(): JSX.Element {
|
||||
if (this.state.verifyRemove) {
|
||||
return (
|
||||
<div className="mx_EditableItem">
|
||||
|
@ -105,22 +105,22 @@ interface IProps {
|
|||
}
|
||||
|
||||
export default class EditableItemList<P = {}> extends React.PureComponent<IProps & P> {
|
||||
protected onItemAdded = (e) => {
|
||||
protected onItemAdded = (e): void => {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
|
||||
if (this.props.onItemAdded) this.props.onItemAdded(this.props.newItem);
|
||||
};
|
||||
|
||||
protected onItemRemoved = (index) => {
|
||||
protected onItemRemoved = (index: number): void => {
|
||||
if (this.props.onItemRemoved) this.props.onItemRemoved(index);
|
||||
};
|
||||
|
||||
protected onNewItemChanged = (e) => {
|
||||
protected onNewItemChanged = (e): void => {
|
||||
if (this.props.onNewItemChanged) this.props.onNewItemChanged(e.target.value);
|
||||
};
|
||||
|
||||
protected renderNewItemField() {
|
||||
protected renderNewItemField(): JSX.Element {
|
||||
return (
|
||||
<form
|
||||
onSubmit={this.onItemAdded}
|
||||
|
@ -148,7 +148,7 @@ export default class EditableItemList<P = {}> extends React.PureComponent<IProps
|
|||
);
|
||||
}
|
||||
|
||||
public render() {
|
||||
public render(): JSX.Element {
|
||||
const editableItems = this.props.items.map((item, index) => {
|
||||
if (!this.props.canRemove) {
|
||||
return <li key={item}>{item}</li>;
|
||||
|
|
|
@ -47,12 +47,12 @@ const EffectsOverlay: FunctionComponent<IProps> = ({ roomWidth }) => {
|
|||
};
|
||||
|
||||
useEffect(() => {
|
||||
const resize = () => {
|
||||
const resize = (): void => {
|
||||
if (canvasRef.current && canvasRef.current?.height !== UIStore.instance.windowHeight) {
|
||||
canvasRef.current.height = UIStore.instance.windowHeight;
|
||||
}
|
||||
};
|
||||
const onAction = (payload: { action: string }) => {
|
||||
const onAction = (payload: { action: string }): void => {
|
||||
const actionPrefix = "effects.";
|
||||
if (payload.action.indexOf(actionPrefix) === 0) {
|
||||
const effect = payload.action.slice(actionPrefix.length);
|
||||
|
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { ErrorInfo } from "react";
|
||||
import React, { ErrorInfo, ReactNode } from "react";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
|
||||
import { _t } from "../../../languageHandler";
|
||||
|
@ -73,7 +73,7 @@ export default class ErrorBoundary extends React.PureComponent<{}, IState> {
|
|||
});
|
||||
};
|
||||
|
||||
public render() {
|
||||
public render(): ReactNode {
|
||||
if (this.state.error) {
|
||||
const newIssueUrl = "https://github.com/vector-im/element-web/issues/new/choose";
|
||||
|
||||
|
|
|
@ -149,7 +149,7 @@ export default class EventListSummary extends React.Component<IProps> {
|
|||
* more items in `users` than `this.props.summaryLength`, which is the number of names
|
||||
* included before "and [n] others".
|
||||
*/
|
||||
private renderNameList(users: string[]) {
|
||||
private renderNameList(users: string[]): string {
|
||||
return formatCommaSeparatedList(users, this.props.summaryLength);
|
||||
}
|
||||
|
||||
|
@ -207,7 +207,10 @@ export default class EventListSummary extends React.Component<IProps> {
|
|||
* @param {string[]} transitions the array of transitions to transform.
|
||||
* @returns {object[]} an array of coalesced transitions.
|
||||
*/
|
||||
private static coalesceRepeatedTransitions(transitions: TransitionType[]) {
|
||||
private static coalesceRepeatedTransitions(transitions: TransitionType[]): {
|
||||
transitionType: TransitionType;
|
||||
repeats: number;
|
||||
}[] {
|
||||
const res: {
|
||||
transitionType: TransitionType;
|
||||
repeats: number;
|
||||
|
@ -377,7 +380,7 @@ export default class EventListSummary extends React.Component<IProps> {
|
|||
return res;
|
||||
}
|
||||
|
||||
private static getTransitionSequence(events: IUserEvents[]) {
|
||||
private static getTransitionSequence(events: IUserEvents[]): TransitionType[] {
|
||||
return events.map(EventListSummary.getTransition);
|
||||
}
|
||||
|
||||
|
@ -451,7 +454,10 @@ export default class EventListSummary extends React.Component<IProps> {
|
|||
}
|
||||
}
|
||||
|
||||
public getAggregate(userEvents: Record<string, IUserEvents[]>) {
|
||||
public getAggregate(userEvents: Record<string, IUserEvents[]>): {
|
||||
names: Record<string, string[]>;
|
||||
indices: Record<string, number>;
|
||||
} {
|
||||
// A map of aggregate type to arrays of display names. Each aggregate type
|
||||
// is a comma-delimited string of transitions, e.g. "joined,left,kicked".
|
||||
// The array of display names is the array of users who went through that
|
||||
|
@ -489,7 +495,7 @@ export default class EventListSummary extends React.Component<IProps> {
|
|||
};
|
||||
}
|
||||
|
||||
public render() {
|
||||
public render(): JSX.Element {
|
||||
const eventsToRender = this.props.events;
|
||||
|
||||
// Map user IDs to latest Avatar Member. ES6 Maps are ordered by when the key was created,
|
||||
|
|
|
@ -70,7 +70,7 @@ export default class EventTilePreview extends React.Component<IProps, IState> {
|
|||
};
|
||||
}
|
||||
|
||||
private fakeEvent({ message }: IState) {
|
||||
private fakeEvent({ message }: IState): MatrixEvent {
|
||||
// Fake it till we make it
|
||||
/* eslint-disable quote-props */
|
||||
const rawEvent = {
|
||||
|
@ -111,7 +111,7 @@ export default class EventTilePreview extends React.Component<IProps, IState> {
|
|||
return event;
|
||||
}
|
||||
|
||||
public render() {
|
||||
public render(): JSX.Element {
|
||||
const className = classnames(this.props.className, {
|
||||
mx_IRCLayout: this.props.layout == Layout.IRC,
|
||||
mx_EventTilePreview_loader: !this.props.userId,
|
||||
|
|
|
@ -26,7 +26,7 @@ const VALIDATION_THROTTLE_MS = 200;
|
|||
|
||||
const BASE_ID = "mx_Field";
|
||||
let count = 1;
|
||||
function getId() {
|
||||
function getId(): string {
|
||||
return `${BASE_ID}_${count++}`;
|
||||
}
|
||||
|
||||
|
@ -157,7 +157,7 @@ export default class Field extends React.PureComponent<PropShapes, IState> {
|
|||
this.id = this.props.id || getId();
|
||||
}
|
||||
|
||||
public focus() {
|
||||
public focus(): void {
|
||||
this.inputRef.current?.focus();
|
||||
// programmatic does not fire onFocus handler
|
||||
this.setState({
|
||||
|
@ -165,7 +165,7 @@ export default class Field extends React.PureComponent<PropShapes, IState> {
|
|||
});
|
||||
}
|
||||
|
||||
private onFocus = (ev) => {
|
||||
private onFocus = (ev): void => {
|
||||
this.setState({
|
||||
focused: true,
|
||||
});
|
||||
|
@ -180,7 +180,7 @@ export default class Field extends React.PureComponent<PropShapes, IState> {
|
|||
}
|
||||
};
|
||||
|
||||
private onChange = (ev) => {
|
||||
private onChange = (ev): void => {
|
||||
if (this.props.validateOnChange) {
|
||||
this.validateOnChange();
|
||||
}
|
||||
|
@ -190,7 +190,7 @@ export default class Field extends React.PureComponent<PropShapes, IState> {
|
|||
}
|
||||
};
|
||||
|
||||
private onBlur = (ev) => {
|
||||
private onBlur = (ev): void => {
|
||||
this.setState({
|
||||
focused: false,
|
||||
});
|
||||
|
@ -205,7 +205,7 @@ export default class Field extends React.PureComponent<PropShapes, IState> {
|
|||
}
|
||||
};
|
||||
|
||||
public async validate({ focused, allowEmpty = true }: IValidateOpts) {
|
||||
public async validate({ focused, allowEmpty = true }: IValidateOpts): Promise<boolean> {
|
||||
if (!this.props.onValidate) {
|
||||
return;
|
||||
}
|
||||
|
@ -238,7 +238,7 @@ export default class Field extends React.PureComponent<PropShapes, IState> {
|
|||
return valid;
|
||||
}
|
||||
|
||||
public render() {
|
||||
public render(): JSX.Element {
|
||||
/* eslint @typescript-eslint/no-unused-vars: ["error", { "ignoreRestSiblings": true }] */
|
||||
const {
|
||||
element,
|
||||
|
|
|
@ -42,7 +42,7 @@ export default class IRCTimelineProfileResizer extends React.Component<IProps, I
|
|||
};
|
||||
}
|
||||
|
||||
public componentDidMount() {
|
||||
public componentDidMount(): void {
|
||||
this.setState(
|
||||
{
|
||||
IRCLayoutRoot: document.querySelector(".mx_IRCLayout"),
|
||||
|
@ -76,11 +76,11 @@ export default class IRCTimelineProfileResizer extends React.Component<IProps, I
|
|||
};
|
||||
};
|
||||
|
||||
private updateCSSWidth(newWidth: number) {
|
||||
private updateCSSWidth(newWidth: number): void {
|
||||
this.state.IRCLayoutRoot.style.setProperty("--name-width", newWidth + "px");
|
||||
}
|
||||
|
||||
private onMoueUp = () => {
|
||||
private onMoueUp = (): void => {
|
||||
if (this.props.roomId) {
|
||||
SettingsStore.setValue(
|
||||
"ircDisplayNameWidth",
|
||||
|
@ -91,7 +91,7 @@ export default class IRCTimelineProfileResizer extends React.Component<IProps, I
|
|||
}
|
||||
};
|
||||
|
||||
public render() {
|
||||
public render(): JSX.Element {
|
||||
return <Draggable className="mx_ProfileResizer" dragFunc={this.dragFunc} onMouseUp={this.onMoueUp} />;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -126,7 +126,7 @@ export default class ImageView extends React.Component<IProps, IState> {
|
|||
private animatingLoading = false;
|
||||
private imageIsLoaded = false;
|
||||
|
||||
public componentDidMount() {
|
||||
public componentDidMount(): void {
|
||||
// We have to use addEventListener() because the listener
|
||||
// needs to be passive in order to work with Chromium
|
||||
this.focusLock.current.addEventListener("wheel", this.onWheel, { passive: false });
|
||||
|
@ -136,13 +136,13 @@ export default class ImageView extends React.Component<IProps, IState> {
|
|||
this.image.current.addEventListener("load", this.imageLoaded);
|
||||
}
|
||||
|
||||
public componentWillUnmount() {
|
||||
public componentWillUnmount(): void {
|
||||
this.focusLock.current.removeEventListener("wheel", this.onWheel);
|
||||
window.removeEventListener("resize", this.recalculateZoom);
|
||||
this.image.current.removeEventListener("load", this.imageLoaded);
|
||||
}
|
||||
|
||||
private imageLoaded = () => {
|
||||
private imageLoaded = (): void => {
|
||||
// First, we calculate the zoom, so that the image has the same size as
|
||||
// the thumbnail
|
||||
const { thumbnailInfo } = this.props;
|
||||
|
@ -164,11 +164,11 @@ export default class ImageView extends React.Component<IProps, IState> {
|
|||
this.animatingLoading = false;
|
||||
};
|
||||
|
||||
private recalculateZoom = () => {
|
||||
private recalculateZoom = (): void => {
|
||||
this.setZoomAndRotation();
|
||||
};
|
||||
|
||||
private setZoomAndRotation = (inputRotation?: number) => {
|
||||
private setZoomAndRotation = (inputRotation?: number): void => {
|
||||
const image = this.image.current;
|
||||
const imageWrapper = this.imageWrapper.current;
|
||||
|
||||
|
@ -210,11 +210,11 @@ export default class ImageView extends React.Component<IProps, IState> {
|
|||
});
|
||||
};
|
||||
|
||||
private zoomDelta(delta: number, anchorX?: number, anchorY?: number) {
|
||||
private zoomDelta(delta: number, anchorX?: number, anchorY?: number): void {
|
||||
this.zoom(this.state.zoom + delta, anchorX, anchorY);
|
||||
}
|
||||
|
||||
private zoom(zoomLevel: number, anchorX?: number, anchorY?: number) {
|
||||
private zoom(zoomLevel: number, anchorX?: number, anchorY?: number): void {
|
||||
const oldZoom = this.state.zoom;
|
||||
const maxZoom = this.state.maxZoom === this.state.minZoom ? 2 * this.state.maxZoom : this.state.maxZoom;
|
||||
const newZoom = Math.min(zoomLevel, maxZoom);
|
||||
|
@ -267,7 +267,7 @@ export default class ImageView extends React.Component<IProps, IState> {
|
|||
}
|
||||
}
|
||||
|
||||
private onWheel = (ev: WheelEvent) => {
|
||||
private onWheel = (ev: WheelEvent): void => {
|
||||
if (ev.target === this.image.current) {
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
|
@ -278,15 +278,15 @@ export default class ImageView extends React.Component<IProps, IState> {
|
|||
}
|
||||
};
|
||||
|
||||
private onZoomInClick = () => {
|
||||
private onZoomInClick = (): void => {
|
||||
this.zoomDelta(ZOOM_STEP);
|
||||
};
|
||||
|
||||
private onZoomOutClick = () => {
|
||||
private onZoomOutClick = (): void => {
|
||||
this.zoomDelta(-ZOOM_STEP);
|
||||
};
|
||||
|
||||
private onKeyDown = (ev: KeyboardEvent) => {
|
||||
private onKeyDown = (ev: KeyboardEvent): void => {
|
||||
const action = getKeyBindingsManager().getAccessibilityAction(ev);
|
||||
switch (action) {
|
||||
case KeyBindingAction.Escape:
|
||||
|
@ -297,17 +297,17 @@ export default class ImageView extends React.Component<IProps, IState> {
|
|||
}
|
||||
};
|
||||
|
||||
private onRotateCounterClockwiseClick = () => {
|
||||
private onRotateCounterClockwiseClick = (): void => {
|
||||
const cur = this.state.rotation;
|
||||
this.setZoomAndRotation(cur - 90);
|
||||
};
|
||||
|
||||
private onRotateClockwiseClick = () => {
|
||||
private onRotateClockwiseClick = (): void => {
|
||||
const cur = this.state.rotation;
|
||||
this.setZoomAndRotation(cur + 90);
|
||||
};
|
||||
|
||||
private onDownloadClick = () => {
|
||||
private onDownloadClick = (): void => {
|
||||
const a = document.createElement("a");
|
||||
a.href = this.props.src;
|
||||
a.download = this.props.name;
|
||||
|
@ -316,19 +316,19 @@ export default class ImageView extends React.Component<IProps, IState> {
|
|||
a.click();
|
||||
};
|
||||
|
||||
private onOpenContextMenu = () => {
|
||||
private onOpenContextMenu = (): void => {
|
||||
this.setState({
|
||||
contextMenuDisplayed: true,
|
||||
});
|
||||
};
|
||||
|
||||
private onCloseContextMenu = () => {
|
||||
private onCloseContextMenu = (): void => {
|
||||
this.setState({
|
||||
contextMenuDisplayed: false,
|
||||
});
|
||||
};
|
||||
|
||||
private onPermalinkClicked = (ev: React.MouseEvent) => {
|
||||
private onPermalinkClicked = (ev: React.MouseEvent): void => {
|
||||
// This allows the permalink to be opened in a new tab/window or copied as
|
||||
// matrix.to, but also for it to enable routing within Element when clicked.
|
||||
ev.preventDefault();
|
||||
|
@ -342,7 +342,7 @@ export default class ImageView extends React.Component<IProps, IState> {
|
|||
this.props.onFinished();
|
||||
};
|
||||
|
||||
private onStartMoving = (ev: React.MouseEvent) => {
|
||||
private onStartMoving = (ev: React.MouseEvent): void => {
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
|
||||
|
@ -368,7 +368,7 @@ export default class ImageView extends React.Component<IProps, IState> {
|
|||
this.initY = ev.pageY - this.state.translationY;
|
||||
};
|
||||
|
||||
private onMoving = (ev: React.MouseEvent) => {
|
||||
private onMoving = (ev: React.MouseEvent): void => {
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
|
||||
|
@ -380,7 +380,7 @@ export default class ImageView extends React.Component<IProps, IState> {
|
|||
});
|
||||
};
|
||||
|
||||
private onEndMoving = () => {
|
||||
private onEndMoving = (): void => {
|
||||
// Zoom out if we haven't moved much
|
||||
if (
|
||||
this.state.moving === true &&
|
||||
|
@ -394,7 +394,7 @@ export default class ImageView extends React.Component<IProps, IState> {
|
|||
this.setState({ moving: false });
|
||||
};
|
||||
|
||||
private renderContextMenu() {
|
||||
private renderContextMenu(): JSX.Element {
|
||||
let contextMenu = null;
|
||||
if (this.state.contextMenuDisplayed) {
|
||||
contextMenu = (
|
||||
|
@ -411,7 +411,7 @@ export default class ImageView extends React.Component<IProps, IState> {
|
|||
return <React.Fragment>{contextMenu}</React.Fragment>;
|
||||
}
|
||||
|
||||
public render() {
|
||||
public render(): JSX.Element {
|
||||
const showEventMeta = !!this.props.mxEvent;
|
||||
|
||||
let transitionClassName;
|
||||
|
|
|
@ -39,7 +39,7 @@ export default class InfoTooltip extends React.PureComponent<ITooltipProps> {
|
|||
super(props);
|
||||
}
|
||||
|
||||
public render() {
|
||||
public render(): JSX.Element {
|
||||
const { tooltip, children, tooltipClassName, className, kind } = this.props;
|
||||
const title = _t("Information");
|
||||
const iconClassName =
|
||||
|
|
|
@ -30,7 +30,7 @@ export default class InlineSpinner extends React.PureComponent<IProps> {
|
|||
h: 16,
|
||||
};
|
||||
|
||||
public render() {
|
||||
public render(): JSX.Element {
|
||||
return (
|
||||
<div className="mx_InlineSpinner">
|
||||
<div
|
||||
|
|
|
@ -317,7 +317,7 @@ export default class InteractiveTooltip extends React.Component<IProps, IState>
|
|||
};
|
||||
}
|
||||
|
||||
public componentDidUpdate() {
|
||||
public componentDidUpdate(): void {
|
||||
// Whenever this passthrough component updates, also render the tooltip
|
||||
// in a separate DOM tree. This allows the tooltip content to participate
|
||||
// the normal React rendering cycle: when this component re-renders, the
|
||||
|
@ -327,7 +327,7 @@ export default class InteractiveTooltip extends React.Component<IProps, IState>
|
|||
this.renderTooltip();
|
||||
}
|
||||
|
||||
public componentWillUnmount() {
|
||||
public componentWillUnmount(): void {
|
||||
document.removeEventListener("mousemove", this.onMouseMove);
|
||||
}
|
||||
|
||||
|
@ -340,7 +340,7 @@ export default class InteractiveTooltip extends React.Component<IProps, IState>
|
|||
});
|
||||
};
|
||||
|
||||
private collectTarget = (element: HTMLElement) => {
|
||||
private collectTarget = (element: HTMLElement): void => {
|
||||
this.target = element;
|
||||
};
|
||||
|
||||
|
@ -376,7 +376,7 @@ export default class InteractiveTooltip extends React.Component<IProps, IState>
|
|||
return this.props.direction === Direction.Left || this.props.direction === Direction.Right;
|
||||
}
|
||||
|
||||
private onMouseMove = (ev: MouseEvent) => {
|
||||
private onMouseMove = (ev: MouseEvent): void => {
|
||||
const { clientX: x, clientY: y } = ev;
|
||||
const { contentRect } = this.state;
|
||||
const targetRect = this.target.getBoundingClientRect();
|
||||
|
@ -408,7 +408,7 @@ export default class InteractiveTooltip extends React.Component<IProps, IState>
|
|||
document.addEventListener("mousemove", this.onMouseMove);
|
||||
}
|
||||
|
||||
public hideTooltip() {
|
||||
public hideTooltip(): void {
|
||||
this.setState({
|
||||
visible: false,
|
||||
});
|
||||
|
@ -416,7 +416,7 @@ export default class InteractiveTooltip extends React.Component<IProps, IState>
|
|||
document.removeEventListener("mousemove", this.onMouseMove);
|
||||
}
|
||||
|
||||
private renderTooltip() {
|
||||
private renderTooltip(): JSX.Element {
|
||||
const { contentRect, visible } = this.state;
|
||||
if (!visible) {
|
||||
ReactDOM.unmountComponentAtNode(getOrCreateContainer());
|
||||
|
@ -486,7 +486,7 @@ export default class InteractiveTooltip extends React.Component<IProps, IState>
|
|||
ReactDOM.render(tooltip, getOrCreateContainer());
|
||||
}
|
||||
|
||||
public render() {
|
||||
public render(): ReactNode {
|
||||
return this.props.children({
|
||||
ref: this.collectTarget,
|
||||
onMouseOver: this.onTargetMouseOver,
|
||||
|
|
|
@ -39,13 +39,13 @@ export default class InviteReason extends React.PureComponent<IProps, IState> {
|
|||
};
|
||||
}
|
||||
|
||||
public onViewClick = () => {
|
||||
public onViewClick = (): void => {
|
||||
this.setState({
|
||||
hidden: false,
|
||||
});
|
||||
};
|
||||
|
||||
public render() {
|
||||
public render(): JSX.Element {
|
||||
const classes = classNames({
|
||||
mx_InviteReason: true,
|
||||
mx_InviteReason_hidden: this.state.hidden,
|
||||
|
|
|
@ -29,7 +29,7 @@ interface IProps {
|
|||
onChange(value: JoinRule): void;
|
||||
}
|
||||
|
||||
const JoinRuleDropdown = ({
|
||||
const JoinRuleDropdown: React.FC<IProps> = ({
|
||||
label,
|
||||
labelInvite,
|
||||
labelPublic,
|
||||
|
@ -37,7 +37,7 @@ const JoinRuleDropdown = ({
|
|||
value,
|
||||
width = 448,
|
||||
onChange,
|
||||
}: IProps) => {
|
||||
}) => {
|
||||
const options = [
|
||||
<div key={JoinRule.Invite} className="mx_JoinRuleDropdown_invite">
|
||||
{labelInvite}
|
||||
|
|
|
@ -41,7 +41,7 @@ interface IProps {
|
|||
}
|
||||
|
||||
export default class LabelledToggleSwitch extends React.PureComponent<IProps> {
|
||||
public render() {
|
||||
public render(): JSX.Element {
|
||||
// This is a minimal version of a SettingsFlag
|
||||
const { label, caption } = this.props;
|
||||
let firstPart = (
|
||||
|
|
|
@ -23,7 +23,9 @@ import { _t } from "../../../languageHandler";
|
|||
import Spinner from "./Spinner";
|
||||
import Dropdown from "./Dropdown";
|
||||
|
||||
function languageMatchesSearchQuery(query, language) {
|
||||
type Languages = Awaited<ReturnType<typeof languageHandler.getAllLanguagesFromJson>>;
|
||||
|
||||
function languageMatchesSearchQuery(query: string, language: Languages[0]): boolean {
|
||||
if (language.label.toUpperCase().includes(query.toUpperCase())) return true;
|
||||
if (language.value.toUpperCase() === query.toUpperCase()) return true;
|
||||
return false;
|
||||
|
@ -38,7 +40,7 @@ interface IProps {
|
|||
|
||||
interface IState {
|
||||
searchQuery: string;
|
||||
langs: Awaited<ReturnType<typeof languageHandler.getAllLanguagesFromJson>>;
|
||||
langs: Languages;
|
||||
}
|
||||
|
||||
export default class LanguageDropdown extends React.Component<IProps, IState> {
|
||||
|
|
|
@ -27,7 +27,7 @@ export interface LearnMoreProps extends IAccessibleButtonProps {
|
|||
}
|
||||
|
||||
const LearnMore: React.FC<LearnMoreProps> = ({ title, description, ...rest }) => {
|
||||
const onClick = () => {
|
||||
const onClick = (): void => {
|
||||
Modal.createDialog(InfoDialog, {
|
||||
title,
|
||||
description,
|
||||
|
|
|
@ -38,11 +38,11 @@ export default class Measured extends React.PureComponent<IProps> {
|
|||
this.instanceId = Measured.instanceCount++;
|
||||
}
|
||||
|
||||
public componentDidMount() {
|
||||
public componentDidMount(): void {
|
||||
UIStore.instance.on(`Measured${this.instanceId}`, this.onResize);
|
||||
}
|
||||
|
||||
public componentDidUpdate(prevProps: Readonly<IProps>) {
|
||||
public componentDidUpdate(prevProps: Readonly<IProps>): void {
|
||||
const previous = prevProps.sensor;
|
||||
const current = this.props.sensor;
|
||||
if (previous === current) return;
|
||||
|
@ -54,17 +54,17 @@ export default class Measured extends React.PureComponent<IProps> {
|
|||
}
|
||||
}
|
||||
|
||||
public componentWillUnmount() {
|
||||
public componentWillUnmount(): void {
|
||||
UIStore.instance.off(`Measured${this.instanceId}`, this.onResize);
|
||||
UIStore.instance.stopTrackingElementDimensions(`Measured${this.instanceId}`);
|
||||
}
|
||||
|
||||
private onResize = (type: UI_EVENTS, entry: ResizeObserverEntry) => {
|
||||
private onResize = (type: UI_EVENTS, entry: ResizeObserverEntry): void => {
|
||||
if (type !== UI_EVENTS.Resize) return;
|
||||
this.props.onMeasurement(entry.contentRect.width <= this.props.breakpoint);
|
||||
};
|
||||
|
||||
public render() {
|
||||
public render(): JSX.Element {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -77,7 +77,7 @@ const MiniAvatarUploader: React.FC<IProps> = ({
|
|||
chromeFileInputFix(ev);
|
||||
onClick?.(ev);
|
||||
}}
|
||||
onChange={async (ev) => {
|
||||
onChange={async (ev): Promise<void> => {
|
||||
if (!ev.target.files?.length) return;
|
||||
setBusy(true);
|
||||
const file = ev.target.files[0];
|
||||
|
|
|
@ -23,7 +23,7 @@ import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
|||
import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
||||
import { ActionPayload } from "../../../dispatcher/payloads";
|
||||
|
||||
export const getPersistKey = (appId: string) => "widget_" + appId;
|
||||
export const getPersistKey = (appId: string): string => "widget_" + appId;
|
||||
|
||||
// Shamelessly ripped off Modal.js. There's probably a better way
|
||||
// of doing reusable widgets like dialog boxes & menus where we go and
|
||||
|
@ -106,7 +106,7 @@ export default class PersistedElement extends React.Component<IProps> {
|
|||
}
|
||||
}
|
||||
|
||||
public static isMounted(persistKey) {
|
||||
public static isMounted(persistKey: string): boolean {
|
||||
return Boolean(getContainer("mx_persistedElement_" + persistKey));
|
||||
}
|
||||
|
||||
|
|
|
@ -158,7 +158,7 @@ export default class Pill extends React.Component<IProps, IState> {
|
|||
this.load();
|
||||
}
|
||||
|
||||
public componentDidUpdate(prevProps: Readonly<IProps>) {
|
||||
public componentDidUpdate(prevProps: Readonly<IProps>): void {
|
||||
if (objectHasDiff(this.props, prevProps)) {
|
||||
this.load();
|
||||
}
|
||||
|
|
|
@ -99,7 +99,7 @@ export default class PollCreateDialog extends ScrollableBaseModal<IProps, IState
|
|||
this.state = props.editingMxEvent ? editingInitialState(props.editingMxEvent) : creatingInitialState();
|
||||
}
|
||||
|
||||
private checkCanSubmit() {
|
||||
private checkCanSubmit(): void {
|
||||
this.setState({
|
||||
canSubmit:
|
||||
!this.state.busy &&
|
||||
|
@ -108,23 +108,23 @@ export default class PollCreateDialog extends ScrollableBaseModal<IProps, IState
|
|||
});
|
||||
}
|
||||
|
||||
private onQuestionChange = (e: ChangeEvent<HTMLInputElement>) => {
|
||||
private onQuestionChange = (e: ChangeEvent<HTMLInputElement>): void => {
|
||||
this.setState({ question: e.target.value }, () => this.checkCanSubmit());
|
||||
};
|
||||
|
||||
private onOptionChange = (i: number, e: ChangeEvent<HTMLInputElement>) => {
|
||||
private onOptionChange = (i: number, e: ChangeEvent<HTMLInputElement>): void => {
|
||||
const newOptions = arrayFastClone(this.state.options);
|
||||
newOptions[i] = e.target.value;
|
||||
this.setState({ options: newOptions }, () => this.checkCanSubmit());
|
||||
};
|
||||
|
||||
private onOptionRemove = (i: number) => {
|
||||
private onOptionRemove = (i: number): void => {
|
||||
const newOptions = arrayFastClone(this.state.options);
|
||||
newOptions.splice(i, 1);
|
||||
this.setState({ options: newOptions }, () => this.checkCanSubmit());
|
||||
};
|
||||
|
||||
private onOptionAdd = () => {
|
||||
private onOptionAdd = (): void => {
|
||||
const newOptions = arrayFastClone(this.state.options);
|
||||
newOptions.push("");
|
||||
this.setState({ options: newOptions, autoFocusTarget: FocusTarget.NewOption }, () => {
|
||||
|
@ -256,7 +256,7 @@ export default class PollCreateDialog extends ScrollableBaseModal<IProps, IState
|
|||
);
|
||||
}
|
||||
|
||||
public onPollTypeChange = (e: ChangeEvent<HTMLSelectElement>) => {
|
||||
public onPollTypeChange = (e: ChangeEvent<HTMLSelectElement>): void => {
|
||||
this.setState({
|
||||
kind: M_POLL_KIND_DISCLOSED.matches(e.target.value) ? M_POLL_KIND_DISCLOSED : M_POLL_KIND_UNDISCLOSED,
|
||||
});
|
||||
|
|
|
@ -73,11 +73,11 @@ export default class PowerSelector extends React.Component<IProps, IState> {
|
|||
};
|
||||
}
|
||||
|
||||
public componentDidMount() {
|
||||
public componentDidMount(): void {
|
||||
this.initStateFromProps();
|
||||
}
|
||||
|
||||
public componentDidUpdate(prevProps: Readonly<IProps>) {
|
||||
public componentDidUpdate(prevProps: Readonly<IProps>): void {
|
||||
if (objectHasDiff(this.props, prevProps)) {
|
||||
this.initStateFromProps();
|
||||
}
|
||||
|
|
|
@ -98,21 +98,21 @@ export default class ReplyChain extends React.Component<IProps, IState> {
|
|||
return MatrixClientPeg.get();
|
||||
}
|
||||
|
||||
public componentDidMount() {
|
||||
public componentDidMount(): void {
|
||||
this.initialize();
|
||||
this.trySetExpandableQuotes();
|
||||
}
|
||||
|
||||
public componentDidUpdate() {
|
||||
public componentDidUpdate(): void {
|
||||
this.props.onHeightChanged();
|
||||
this.trySetExpandableQuotes();
|
||||
}
|
||||
|
||||
public componentWillUnmount() {
|
||||
public componentWillUnmount(): void {
|
||||
this.unmounted = true;
|
||||
}
|
||||
|
||||
private trySetExpandableQuotes() {
|
||||
private trySetExpandableQuotes(): void {
|
||||
if (this.props.isQuoteExpanded === undefined && this.blockquoteRef.current) {
|
||||
const el: HTMLElement | null = this.blockquoteRef.current.querySelector(".mx_EventTile_body");
|
||||
if (el) {
|
||||
|
@ -199,7 +199,7 @@ export default class ReplyChain extends React.Component<IProps, IState> {
|
|||
return getUserNameColorClass(ev.getSender()).replace("Username", "ReplyChain");
|
||||
}
|
||||
|
||||
public render() {
|
||||
public render(): JSX.Element {
|
||||
let header = null;
|
||||
if (this.state.err) {
|
||||
header = (
|
||||
|
|
|
@ -17,7 +17,7 @@ limitations under the License.
|
|||
import React, { createRef, KeyboardEventHandler } from "react";
|
||||
|
||||
import { _t } from "../../../languageHandler";
|
||||
import withValidation from "./Validation";
|
||||
import withValidation, { IFieldState, IValidationResult } from "./Validation";
|
||||
import Field, { IValidateOpts } from "./Field";
|
||||
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
||||
|
||||
|
@ -60,7 +60,12 @@ export default class RoomAliasField extends React.PureComponent<IProps, IState>
|
|||
return hashAlias;
|
||||
}
|
||||
|
||||
private get domainProps() {
|
||||
private get domainProps(): {
|
||||
prefix: JSX.Element;
|
||||
postfix: JSX.Element;
|
||||
value: string;
|
||||
maxlength: number;
|
||||
} {
|
||||
const { domain } = this.props;
|
||||
const prefix = <span>#</span>;
|
||||
const postfix = domain ? <span title={`:${domain}`}>{`:${domain}`}</span> : <span />;
|
||||
|
@ -72,7 +77,7 @@ export default class RoomAliasField extends React.PureComponent<IProps, IState>
|
|||
return { prefix, postfix, value, maxlength };
|
||||
}
|
||||
|
||||
public render() {
|
||||
public render(): JSX.Element {
|
||||
const { prefix, postfix, value, maxlength } = this.domainProps;
|
||||
return (
|
||||
<Field
|
||||
|
@ -93,13 +98,11 @@ export default class RoomAliasField extends React.PureComponent<IProps, IState>
|
|||
);
|
||||
}
|
||||
|
||||
private onChange = (ev) => {
|
||||
if (this.props.onChange) {
|
||||
this.props.onChange(this.asFullAlias(ev.target.value));
|
||||
}
|
||||
private onChange = (ev: React.ChangeEvent<HTMLInputElement>): void => {
|
||||
this.props.onChange?.(this.asFullAlias(ev.target.value));
|
||||
};
|
||||
|
||||
private onValidate = async (fieldState) => {
|
||||
private onValidate = async (fieldState: IFieldState): Promise<IValidationResult> => {
|
||||
const result = await this.validationRules(fieldState);
|
||||
this.setState({ isValid: result.valid });
|
||||
return result;
|
||||
|
@ -109,7 +112,7 @@ export default class RoomAliasField extends React.PureComponent<IProps, IState>
|
|||
rules: [
|
||||
{
|
||||
key: "hasDomain",
|
||||
test: async ({ value }) => {
|
||||
test: async ({ value }): Promise<boolean> => {
|
||||
// Ignore if we have passed domain
|
||||
if (!value || this.props.domain) {
|
||||
return true;
|
||||
|
@ -124,7 +127,7 @@ export default class RoomAliasField extends React.PureComponent<IProps, IState>
|
|||
},
|
||||
{
|
||||
key: "hasLocalpart",
|
||||
test: async ({ value }) => {
|
||||
test: async ({ value }): Promise<boolean> => {
|
||||
if (!value || this.props.domain) {
|
||||
return true;
|
||||
}
|
||||
|
@ -144,7 +147,7 @@ export default class RoomAliasField extends React.PureComponent<IProps, IState>
|
|||
},
|
||||
{
|
||||
key: "safeLocalpart",
|
||||
test: async ({ value }) => {
|
||||
test: async ({ value }): Promise<boolean> => {
|
||||
if (!value) {
|
||||
return true;
|
||||
}
|
||||
|
@ -174,7 +177,7 @@ export default class RoomAliasField extends React.PureComponent<IProps, IState>
|
|||
? {
|
||||
key: "matches",
|
||||
final: true,
|
||||
test: async ({ value }) => {
|
||||
test: async ({ value }): Promise<boolean> => {
|
||||
if (!value) {
|
||||
return true;
|
||||
}
|
||||
|
@ -192,7 +195,7 @@ export default class RoomAliasField extends React.PureComponent<IProps, IState>
|
|||
: {
|
||||
key: "taken",
|
||||
final: true,
|
||||
test: async ({ value }) => {
|
||||
test: async ({ value }): Promise<boolean> => {
|
||||
if (!value) {
|
||||
return true;
|
||||
}
|
||||
|
@ -218,15 +221,15 @@ export default class RoomAliasField extends React.PureComponent<IProps, IState>
|
|||
],
|
||||
});
|
||||
|
||||
public get isValid() {
|
||||
public get isValid(): boolean {
|
||||
return this.state.isValid;
|
||||
}
|
||||
|
||||
public validate(options: IValidateOpts) {
|
||||
public validate(options: IValidateOpts): Promise<boolean> {
|
||||
return this.fieldRef.current?.validate(options);
|
||||
}
|
||||
|
||||
public focus() {
|
||||
public focus(): void {
|
||||
this.fieldRef.current?.focus();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
|||
|
||||
const DEFAULT_NUM_FACES = 5;
|
||||
|
||||
const isKnownMember = (member: RoomMember) => !!DMRoomMap.shared().getDMRoomsForUserId(member.userId)?.length;
|
||||
const isKnownMember = (member: RoomMember): boolean => !!DMRoomMap.shared().getDMRoomsForUserId(member.userId)?.length;
|
||||
|
||||
interface IProps extends HTMLAttributes<HTMLSpanElement> {
|
||||
room: Room;
|
||||
|
|
|
@ -37,7 +37,7 @@ interface IProps extends React.HTMLProps<HTMLDivElement> {
|
|||
room?: Room;
|
||||
}
|
||||
|
||||
export default function RoomTopic({ room, ...props }: IProps) {
|
||||
export default function RoomTopic({ room, ...props }: IProps): JSX.Element {
|
||||
const client = useContext(MatrixClientContext);
|
||||
const ref = useRef<HTMLDivElement>();
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ interface ISSOButtonProps extends Omit<IProps, "flow"> {
|
|||
mini?: boolean;
|
||||
}
|
||||
|
||||
const getIcon = (brand: IdentityProviderBrand | string) => {
|
||||
const getIcon = (brand: IdentityProviderBrand | string): string | null => {
|
||||
switch (brand) {
|
||||
case IdentityProviderBrand.Apple:
|
||||
return require(`../../../../res/img/element-icons/brands/apple.svg`).default;
|
||||
|
@ -83,7 +83,7 @@ const SSOButton: React.FC<ISSOButtonProps> = ({
|
|||
}) => {
|
||||
const label = idp ? _t("Continue with %(provider)s", { provider: idp.name }) : _t("Sign in with single sign-on");
|
||||
|
||||
const onClick = () => {
|
||||
const onClick = (): void => {
|
||||
const authenticationType = getAuthenticationType(idp?.brand ?? "");
|
||||
PosthogAnalytics.instance.setAuthenticationType(authenticationType);
|
||||
PlatformPeg.get().startSingleSignOn(matrixClient, loginType, fragmentAfterLogin, idp?.id);
|
||||
|
|
|
@ -35,7 +35,7 @@ interface IProps {
|
|||
kind: WarningKind;
|
||||
}
|
||||
|
||||
export default function SearchWarning({ isRoomEncrypted, kind }: IProps) {
|
||||
export default function SearchWarning({ isRoomEncrypted, kind }: IProps): JSX.Element {
|
||||
if (!isRoomEncrypted) return null;
|
||||
if (EventIndexPeg.get()) return null;
|
||||
|
||||
|
|
|
@ -36,11 +36,11 @@ const showPickerDialog = (
|
|||
title: string,
|
||||
serverConfig: ValidatedServerConfig,
|
||||
onFinished: (config: ValidatedServerConfig) => void,
|
||||
) => {
|
||||
): void => {
|
||||
Modal.createDialog(ServerPickerDialog, { title, serverConfig, onFinished });
|
||||
};
|
||||
|
||||
const onHelpClick = () => {
|
||||
const onHelpClick = (): void => {
|
||||
const brand = SdkConfig.get().brand;
|
||||
Modal.createDialog(
|
||||
InfoDialog,
|
||||
|
@ -60,12 +60,12 @@ const onHelpClick = () => {
|
|||
);
|
||||
};
|
||||
|
||||
const ServerPicker = ({ title, dialogTitle, serverConfig, onServerConfigChange }: IProps) => {
|
||||
const ServerPicker: React.FC<IProps> = ({ title, dialogTitle, serverConfig, onServerConfigChange }) => {
|
||||
const disableCustomUrls = SdkConfig.get("disable_custom_urls");
|
||||
|
||||
let editBtn;
|
||||
if (!disableCustomUrls && onServerConfigChange) {
|
||||
const onClick = () => {
|
||||
const onClick = (): void => {
|
||||
showPickerDialog(dialogTitle, serverConfig, (config?: ValidatedServerConfig) => {
|
||||
if (config) {
|
||||
onServerConfigChange(config);
|
||||
|
|
|
@ -56,17 +56,17 @@ export default class SettingsFlag extends React.Component<IProps, IState> {
|
|||
};
|
||||
}
|
||||
|
||||
private onChange = async (checked: boolean) => {
|
||||
private onChange = async (checked: boolean): Promise<void> => {
|
||||
await this.save(checked);
|
||||
this.setState({ value: checked });
|
||||
if (this.props.onChange) this.props.onChange(checked);
|
||||
};
|
||||
|
||||
private checkBoxOnChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
private checkBoxOnChange = (e: React.ChangeEvent<HTMLInputElement>): void => {
|
||||
this.onChange(e.target.checked);
|
||||
};
|
||||
|
||||
private save = async (val?: boolean) => {
|
||||
private save = async (val?: boolean): Promise<void> => {
|
||||
await SettingsStore.setValue(
|
||||
this.props.name,
|
||||
this.props.roomId,
|
||||
|
@ -75,7 +75,7 @@ export default class SettingsFlag extends React.Component<IProps, IState> {
|
|||
);
|
||||
};
|
||||
|
||||
public render() {
|
||||
public render(): JSX.Element {
|
||||
const canChange = SettingsStore.canSetValue(this.props.name, this.props.roomId, this.props.level);
|
||||
|
||||
if (!canChange && this.props.hideIfCannotSet) return null;
|
||||
|
|
|
@ -108,7 +108,7 @@ export default class Slider extends React.Component<IProps> {
|
|||
);
|
||||
}
|
||||
|
||||
public onClick(event: React.MouseEvent) {
|
||||
public onClick(event: React.MouseEvent): void {
|
||||
const width = (event.target as HTMLElement).clientWidth;
|
||||
// nativeEvent is safe to use because https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/offsetX
|
||||
// is supported by all modern browsers
|
||||
|
|
|
@ -21,8 +21,10 @@ import PlatformPeg from "../../../PlatformPeg";
|
|||
import SettingsStore from "../../../settings/SettingsStore";
|
||||
import { _t } from "../../../languageHandler";
|
||||
import Spinner from "./Spinner";
|
||||
import * as languageHandler from "../../../languageHandler";
|
||||
|
||||
function languageMatchesSearchQuery(query, language) {
|
||||
type Languages = Awaited<ReturnType<typeof languageHandler.getAllLanguagesFromJson>>;
|
||||
function languageMatchesSearchQuery(query: string, language: Languages[0]): boolean {
|
||||
if (language.label.toUpperCase().includes(query.toUpperCase())) return true;
|
||||
if (language.value.toUpperCase() === query.toUpperCase()) return true;
|
||||
return false;
|
||||
|
@ -36,7 +38,7 @@ interface SpellCheckLanguagesDropdownIProps {
|
|||
|
||||
interface SpellCheckLanguagesDropdownIState {
|
||||
searchQuery: string;
|
||||
languages: any;
|
||||
languages: Languages;
|
||||
}
|
||||
|
||||
export default class SpellCheckLanguagesDropdown extends React.Component<
|
||||
|
@ -53,7 +55,7 @@ export default class SpellCheckLanguagesDropdown extends React.Component<
|
|||
};
|
||||
}
|
||||
|
||||
public componentDidMount() {
|
||||
public componentDidMount(): void {
|
||||
const plaf = PlatformPeg.get();
|
||||
if (plaf) {
|
||||
plaf.getAvailableSpellCheckLanguages()
|
||||
|
@ -63,7 +65,7 @@ export default class SpellCheckLanguagesDropdown extends React.Component<
|
|||
if (a > b) return 1;
|
||||
return 0;
|
||||
});
|
||||
const langs = [];
|
||||
const langs: Languages = [];
|
||||
languages.forEach((language) => {
|
||||
langs.push({
|
||||
label: language,
|
||||
|
@ -73,16 +75,23 @@ export default class SpellCheckLanguagesDropdown extends React.Component<
|
|||
this.setState({ languages: langs });
|
||||
})
|
||||
.catch((e) => {
|
||||
this.setState({ languages: ["en"] });
|
||||
this.setState({
|
||||
languages: [
|
||||
{
|
||||
value: "en",
|
||||
label: "English",
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private onSearchChange(searchQuery: string) {
|
||||
private onSearchChange(searchQuery: string): void {
|
||||
this.setState({ searchQuery });
|
||||
}
|
||||
|
||||
public render() {
|
||||
public render(): JSX.Element {
|
||||
if (this.state.languages === null) {
|
||||
return <Spinner />;
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ export default class Spinner extends React.PureComponent<IProps> {
|
|||
h: 32,
|
||||
};
|
||||
|
||||
public render() {
|
||||
public render(): JSX.Element {
|
||||
const { w, h, message } = this.props;
|
||||
return (
|
||||
<div className="mx_Spinner">
|
||||
|
|
|
@ -44,7 +44,7 @@ export default class StyledCheckbox extends React.PureComponent<IProps, IState>
|
|||
this.id = this.props.id || "checkbox_" + randomString(10);
|
||||
}
|
||||
|
||||
public render() {
|
||||
public render(): JSX.Element {
|
||||
/* eslint @typescript-eslint/no-unused-vars: ["error", { "ignoreRestSiblings": true }] */
|
||||
const { children, className, kind = CheckboxStyle.Solid, inputRef, ...otherProps } = this.props;
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ export default class StyledRadioButton extends React.PureComponent<IProps, IStat
|
|||
childrenInLabel: true,
|
||||
};
|
||||
|
||||
public render() {
|
||||
public render(): JSX.Element {
|
||||
const { children, className, disabled, outlined, childrenInLabel, inputRef, ...otherProps } = this.props;
|
||||
const _className = classnames("mx_StyledRadioButton", className, {
|
||||
mx_StyledRadioButton_disabled: disabled,
|
||||
|
|
|
@ -46,8 +46,8 @@ function StyledRadioGroup<T extends string>({
|
|||
outlined,
|
||||
disabled,
|
||||
onChange,
|
||||
}: IProps<T>) {
|
||||
const _onChange = (e) => {
|
||||
}: IProps<T>): JSX.Element {
|
||||
const _onChange = (e): void => {
|
||||
onChange(e.target.value);
|
||||
};
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ interface IProps {
|
|||
disabled?: boolean;
|
||||
}
|
||||
|
||||
export const Tag = ({ icon, label, onDeleteClick, disabled = false }: IProps) => {
|
||||
export const Tag: React.FC<IProps> = ({ icon, label, onDeleteClick, disabled = false }) => {
|
||||
return (
|
||||
<div className="mx_Tag">
|
||||
{icon?.()}
|
||||
|
|
|
@ -47,11 +47,11 @@ export default class TagComposer extends React.PureComponent<IProps, IState> {
|
|||
};
|
||||
}
|
||||
|
||||
private onInputChange = (ev: ChangeEvent<HTMLInputElement>) => {
|
||||
private onInputChange = (ev: ChangeEvent<HTMLInputElement>): void => {
|
||||
this.setState({ newTag: ev.target.value });
|
||||
};
|
||||
|
||||
private onAdd = (ev: FormEvent) => {
|
||||
private onAdd = (ev: FormEvent): void => {
|
||||
ev.preventDefault();
|
||||
if (!this.state.newTag) return;
|
||||
|
||||
|
@ -59,13 +59,13 @@ export default class TagComposer extends React.PureComponent<IProps, IState> {
|
|||
this.setState({ newTag: "" });
|
||||
};
|
||||
|
||||
private onRemove(tag: string) {
|
||||
private onRemove(tag: string): void {
|
||||
// We probably don't need to proxy this, but for
|
||||
// sanity of `this` we'll do so anyways.
|
||||
this.props.onRemove(tag);
|
||||
}
|
||||
|
||||
public render() {
|
||||
public render(): JSX.Element {
|
||||
return (
|
||||
<div className="mx_TagComposer">
|
||||
<form className="mx_TagComposer_input" onSubmit={this.onAdd}>
|
||||
|
|
|
@ -38,8 +38,8 @@ interface IProps {
|
|||
}
|
||||
|
||||
// Controlled Toggle Switch element, written with Accessibility in mind
|
||||
export default ({ checked, disabled = false, title, tooltip, onChange, ...props }: IProps) => {
|
||||
const _onClick = () => {
|
||||
export default ({ checked, disabled = false, title, tooltip, onChange, ...props }: IProps): JSX.Element => {
|
||||
const _onClick = (): void => {
|
||||
if (disabled) return;
|
||||
onChange(!checked);
|
||||
};
|
||||
|
|
|
@ -81,7 +81,7 @@ export default class Tooltip extends React.PureComponent<ITooltipProps, State> {
|
|||
}
|
||||
}
|
||||
|
||||
public componentDidMount() {
|
||||
public componentDidMount(): void {
|
||||
window.addEventListener("scroll", this.updatePosition, {
|
||||
passive: true,
|
||||
capture: true,
|
||||
|
@ -92,14 +92,14 @@ export default class Tooltip extends React.PureComponent<ITooltipProps, State> {
|
|||
this.updatePosition();
|
||||
}
|
||||
|
||||
public componentDidUpdate(prevProps) {
|
||||
public componentDidUpdate(prevProps): void {
|
||||
if (objectHasDiff(prevProps, this.props)) {
|
||||
this.updatePosition();
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the wrapper element, as the tooltip has finished using it
|
||||
public componentWillUnmount() {
|
||||
public componentWillUnmount(): void {
|
||||
window.removeEventListener("scroll", this.updatePosition, {
|
||||
capture: true,
|
||||
});
|
||||
|
@ -174,7 +174,7 @@ export default class Tooltip extends React.PureComponent<ITooltipProps, State> {
|
|||
this.setState(style);
|
||||
};
|
||||
|
||||
public render() {
|
||||
public render(): JSX.Element {
|
||||
const tooltipClasses = classNames("mx_Tooltip", this.props.tooltipClassName, {
|
||||
mx_Tooltip_visible: this.props.visible,
|
||||
mx_Tooltip_invisible: !this.props.visible,
|
||||
|
|
|
@ -28,7 +28,7 @@ export default class TooltipButton extends React.Component<IProps> {
|
|||
super(props);
|
||||
}
|
||||
|
||||
public render() {
|
||||
public render(): JSX.Element {
|
||||
return (
|
||||
<TooltipTarget
|
||||
className="mx_TooltipButton_container"
|
||||
|
|
|
@ -70,7 +70,7 @@ export default class TruncatedList extends React.Component<IProps> {
|
|||
}
|
||||
}
|
||||
|
||||
public render() {
|
||||
public render(): JSX.Element {
|
||||
let overflowNode = null;
|
||||
|
||||
const totalChildren = this.getChildCount();
|
||||
|
|
|
@ -29,7 +29,7 @@ interface Props {
|
|||
|
||||
const TIMEOUT = 1500;
|
||||
|
||||
export function UseCaseSelection({ onFinished }: Props) {
|
||||
export function UseCaseSelection({ onFinished }: Props): JSX.Element {
|
||||
const [selection, setSelected] = useState<UseCase | null>(null);
|
||||
|
||||
// Call onFinished 1.5s after `selection` becomes truthy, to give time for the animation to run
|
||||
|
|
|
@ -27,7 +27,7 @@ interface Props {
|
|||
onClick: (useCase: UseCase) => void;
|
||||
}
|
||||
|
||||
export function UseCaseSelectionButton({ useCase, onClick, selected }: Props) {
|
||||
export function UseCaseSelectionButton({ useCase, onClick, selected }: Props): JSX.Element {
|
||||
let label: string;
|
||||
switch (useCase) {
|
||||
case UseCase.PersonalMessaging:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue