ref(chat) Convert components to TS

This commit is contained in:
robertpin 2023-02-06 11:01:55 +02:00
parent baf5aa14e8
commit 576d3ed8a7
15 changed files with 163 additions and 207 deletions

View File

@ -1,80 +1,76 @@
// @flow
import React, { Component } from 'react';
import React, { Component, ReactNode } from 'react';
import { NOTIFY_CLICK_MODE } from '../../../toolbox/constants';
import { combineStyles } from '../../styles';
import { combineStyles } from '../../styles/functions.any';
import type { Styles } from './AbstractToolboxItem';
import ToolboxItem from './ToolboxItem';
export type Props = {|
export type Props = {
/**
* Function to be called after the click handler has been processed.
*/
afterClick: ?Function,
afterClick?: Function;
/**
* The button's key.
*/
buttonKey?: string,
buttonKey?: string;
/**
* Whether or not the button is displayed in a context menu.
*/
contextMenu?: boolean,
contextMenu?: boolean;
/**
* An extra class name to be added at the end of the element's class name
* in order to enable custom styling.
*/
customClass?: string,
customClass?: string;
/**
* Extra styles which will be applied in conjunction with `styles` or
* `toggledStyles` when the button is disabled;.
*/
disabledStyles: ?Styles,
disabledStyles?: Styles;
/**
* External handler for click action.
*/
handleClick?: Function,
handleClick?: Function;
/**
* Notify mode for `toolbarButtonClicked` event -
* whether to only notify or to also prevent button click routine.
*/
notifyMode?: string,
notifyMode?: string;
/**
* Whether to show the label or not.
*/
showLabel: boolean,
showLabel: boolean;
/**
* Collection of styles for the button.
*/
styles: ?Styles,
styles?: Styles;
/**
* Collection of styles for the button, when in toggled state.
*/
toggledStyles: ?Styles,
toggledStyles?: Styles;
/**
* From which direction the tooltip should appear, relative to the button.
*/
tooltipPosition: string,
tooltipPosition: string;
/**
* Whether this button is visible or not.
*/
visible: boolean
|};
declare var APP: Object;
visible: boolean;
};
/**
* Default style for disabled buttons.
@ -93,7 +89,7 @@ export const defaultDisabledButtonStyles = {
/**
* An abstract implementation of a button.
*/
export default class AbstractButton<P: Props, S: *> extends Component<P, S> {
export default class AbstractButton<P extends Props, S> extends Component<P, S> {
static defaultProps = {
afterClick: undefined,
disabledStyles: defaultDisabledButtonStyles,
@ -146,7 +142,9 @@ export default class AbstractButton<P: Props, S: *> extends Component<P, S> {
*
* @abstract
*/
tooltip: ?string;
get tooltip(): string | undefined {
return undefined;
}
/**
* Initializes a new {@code AbstractButton} instance.
@ -229,7 +227,7 @@ export default class AbstractButton<P: Props, S: *> extends Component<P, S> {
* @private
* @returns {?Styles}
*/
_getStyles(): ?Styles {
_getStyles(): Styles | undefined {
const { disabledStyles, styles, toggledStyles } = this.props;
const buttonStyles
= (this._isToggled() ? toggledStyles : styles) || styles;
@ -280,11 +278,9 @@ export default class AbstractButton<P: Props, S: *> extends Component<P, S> {
* @returns {?boolean}
*/
_isToggled() {
return undefined;
return false;
}
_onClick: (*) => void;
/**
* Handles clicking / pressing the button.
*
@ -292,7 +288,7 @@ export default class AbstractButton<P: Props, S: *> extends Component<P, S> {
* @private
* @returns {void}
*/
_onClick(e) {
_onClick(e: React.MouseEvent<HTMLElement>) {
const { afterClick, handleClick, notifyMode, buttonKey } = this.props;
if (typeof APP !== 'undefined' && notifyMode) {
@ -309,9 +305,10 @@ export default class AbstractButton<P: Props, S: *> extends Component<P, S> {
this._handleClick();
}
afterClick && afterClick(e);
afterClick?.(e);
// blur after click to release focus from button to allow PTT.
// @ts-ignore
e?.currentTarget?.blur && e.currentTarget.blur();
}
@ -321,7 +318,7 @@ export default class AbstractButton<P: Props, S: *> extends Component<P, S> {
* @inheritdoc
* @returns {React$Node}
*/
render(): React$Node {
render(): ReactNode {
const props = {
...this.props,
accessibilityLabel: this.accessibilityLabel,
@ -337,6 +334,8 @@ export default class AbstractButton<P: Props, S: *> extends Component<P, S> {
return (
<ToolboxItem
disabled = { this._isDisabled() }
// @ts-ignore
onClick = { this._onClick }
onKeyDown = { this._onKeyDown }
{ ...props } />

View File

@ -1,30 +1,29 @@
// @flow
import React, { Component, ReactNode } from 'react';
import { GestureResponderEvent } from 'react-native';
import { Component } from 'react';
import type { StyleType } from '../../styles';
import { StyleType } from '../../styles/functions.any';
export type Styles = {
/**
* Style for the item's icon.
*/
iconStyle: StyleType,
iconStyle: StyleType;
/**
* Style for the item's label.
*/
labelStyle: StyleType,
labelStyle: StyleType;
/**
* Style for the item itself.
*/
style: StyleType,
style: StyleType;
/**
* Color for the item underlay (shows when clicked).
*/
underlayColor: ?string
underlayColor?: string;
};
export type Props = {
@ -33,76 +32,78 @@ export type Props = {
* A succinct description of what the item does. Used by accessibility
* tools and torture tests.
*/
accessibilityLabel: string,
accessibilityLabel: string;
/**
* An extra class name to be added at the end of the element's class name
* in order to enable custom styling.
*/
customClass?: string,
customClass?: string;
/**
* Whether this item is disabled or not. When disabled, clicking an the item
* has no effect, and it may reflect on its style.
*/
disabled: boolean,
disabled: boolean;
/**
* A React Element to display at the end of {@code ToolboxItem}.
*/
elementAfter?: React$Node,
elementAfter?: ReactNode;
/**
* The icon to render for this {@code ToolboxItem}.
*/
icon: Object,
icon: Function;
/**
* The text associated with this item. When `showLabel` is set to
* {@code true}, it will be displayed alongside the icon.
*/
label: string,
label: string;
labelProps: any;
/**
* On click handler.
*/
onClick: Function,
onClick: (e?: React.MouseEvent | GestureResponderEvent) => void;
/**
* Whether to show the label or not.
*/
showLabel: boolean,
showLabel: boolean;
/**
* Collection of styles for the item. Used only on native.
*/
styles: ?Styles,
styles?: Styles;
/**
* Invoked to obtain translated strings.
*/
t: ?Function,
t?: Function;
/**
* True if the item is toggled, false otherwise.
*/
toggled: ?boolean,
toggled?: boolean;
/**
* The text to display in the tooltip. Used only on web.
*/
tooltip: ?string,
tooltip?: string;
/**
* From which direction the tooltip should appear, relative to the
* item. Used only on web.
*/
tooltipPosition: string,
tooltipPosition: string;
/**
* Whether this item is visible or not.
*/
visible: boolean
visible: boolean;
};
/**
@ -111,7 +112,7 @@ export type Props = {
*
* @abstract
*/
export default class AbstractToolboxItem<P : Props> extends Component<P> {
export default class AbstractToolboxItem<P extends Props> extends Component<P> {
/**
* Default values for {@code AbstractToolboxItem} component's properties.
*
@ -147,7 +148,7 @@ export default class AbstractToolboxItem<P : Props> extends Component<P> {
* @protected
* @returns {?string}
*/
get label(): ?string {
get label(): string | undefined {
return this._maybeTranslateAttribute(this.props.label, this.props.labelProps);
}
@ -158,7 +159,7 @@ export default class AbstractToolboxItem<P : Props> extends Component<P> {
* @protected
* @returns {?string}
*/
get tooltip(): ?string {
get tooltip(): string | undefined {
return this._maybeTranslateAttribute(this.props.tooltip);
}
@ -169,7 +170,7 @@ export default class AbstractToolboxItem<P : Props> extends Component<P> {
* @protected
* @returns {?string}
*/
get accessibilityLabel(): ?string {
get accessibilityLabel(): string | undefined {
return this._maybeTranslateAttribute(this.props.accessibilityLabel);
}
@ -182,7 +183,7 @@ export default class AbstractToolboxItem<P : Props> extends Component<P> {
* @private
* @returns {string}
*/
_maybeTranslateAttribute(text, textProps) {
_maybeTranslateAttribute(text?: string, textProps?: string) {
const { t } = this.props;
if (textProps) {
@ -193,8 +194,6 @@ export default class AbstractToolboxItem<P : Props> extends Component<P> {
return typeof t === 'function' ? t(text) : text;
}
_onClick: (*) => void;
/**
* Handles clicking/pressing this {@code AbstractToolboxItem} by
* forwarding the event to the {@code onClick} prop of this instance if any.
@ -202,10 +201,10 @@ export default class AbstractToolboxItem<P : Props> extends Component<P> {
* @protected
* @returns {void}
*/
_onClick(...args) {
_onClick(...args: any) {
const { disabled, onClick } = this.props;
disabled || (onClick && onClick(...args));
disabled || onClick?.(...args);
}
/**
@ -218,7 +217,7 @@ export default class AbstractToolboxItem<P : Props> extends Component<P> {
*/
_renderItem() {
// To be implemented by a subclass.
return null;
return <></>;
}
/**

View File

@ -1,12 +1,9 @@
// @flow
import React from 'react';
import { Text, TouchableHighlight, View } from 'react-native';
import { Icon } from '../../icons';
import Icon from '../../icons/components/Icon';
import AbstractToolboxItem from './AbstractToolboxItem';
import type { Props } from './AbstractToolboxItem';
import AbstractToolboxItem, { Props } from './AbstractToolboxItem';
/**
* Native implementation of {@code AbstractToolboxItem}.
@ -24,7 +21,7 @@ export default class ToolboxItem extends AbstractToolboxItem<Props> {
return (
<Icon
src = { this.props.icon }
style = { styles && styles.iconStyle } />
style = { styles?.iconStyle } />
);
}
@ -49,7 +46,7 @@ export default class ToolboxItem extends AbstractToolboxItem<Props> {
// XXX When using a wrapper View, apply the style to it instead of
// applying it to the TouchableHighlight.
let style = styles && styles.style;
let style = styles?.style;
if (showLabel) {
// XXX TouchableHighlight requires 1 child. If there's a need to
@ -58,7 +55,7 @@ export default class ToolboxItem extends AbstractToolboxItem<Props> {
children = (
<View style = { style }>
{ children }
<Text style = { styles && styles.labelStyle }>
<Text style = { styles?.labelStyle }>
{ this.label }
</Text>
{ elementAfter }
@ -78,7 +75,7 @@ export default class ToolboxItem extends AbstractToolboxItem<Props> {
disabled = { disabled }
onPress = { onClick }
style = { style }
underlayColor = { styles && styles.underlayColor } >
underlayColor = { styles?.underlayColor } >
{ children }
</TouchableHighlight>
);

View File

@ -1,8 +1,8 @@
// @flow
import React, { Fragment } from 'react';
import { Icon } from '../../icons';
import Icon from '../../icons/components/Icon';
// eslint-disable-next-line lines-around-comment
// @ts-ignore
import { Tooltip } from '../../tooltip';
import ContextMenuItem from '../../ui/components/web/ContextMenuItem';
@ -14,12 +14,12 @@ type Props = AbstractToolboxItemProps & {
/**
* Whether or not the item is displayed in a context menu.
*/
contextMenu?: boolean,
contextMenu?: boolean;
/**
* On key down handler.
*/
onKeyDown: Function
onKeyDown: (e?: React.KeyboardEvent) => void;
};
/**
@ -37,8 +37,6 @@ export default class ToolboxItem extends AbstractToolboxItem<Props> {
this._onKeyPress = this._onKeyPress.bind(this);
}
_onKeyPress: (Object) => void;
/**
* Handles 'Enter' and Space key on the button to trigger onClick for accessibility.
*
@ -46,9 +44,9 @@ export default class ToolboxItem extends AbstractToolboxItem<Props> {
* @private
* @returns {void}
*/
_onKeyPress(event) {
if (event.key === 'Enter' || event.key === ' ') {
event.preventDefault();
_onKeyPress(event?: React.KeyboardEvent) {
if (event?.key === 'Enter' || event?.key === ' ') {
event?.preventDefault();
this.props.onClick();
}
}
@ -92,13 +90,13 @@ export default class ToolboxItem extends AbstractToolboxItem<Props> {
if (contextMenu) {
return (<ContextMenuItem
accessibilityLabel = { this.accessibilityLabel }
accessibilityLabel = { this.accessibilityLabel ?? '' }
disabled = { disabled }
icon = { icon }
onClick = { onClick }
onKeyDown = { onKeyDown }
onKeyPress = { this._onKeyPress }
text = { this.label } />);
text = { this.label ?? '' } />);
}
let children = (
<Fragment>

View File

@ -1,103 +1,98 @@
// @flow
import { Component } from 'react';
import type { Dispatch } from 'redux';
import { WithTranslation } from 'react-i18next';
import { getLocalParticipant } from '../../base/participants';
import { IReduxState, IStore } from '../../app/types';
import { getLocalParticipant } from '../../base/participants/functions';
import { sendMessage, setIsPollsTabFocused } from '../actions';
import { SMALL_WIDTH_THRESHOLD } from '../constants';
import { IMessage } from '../reducer';
/**
* The type of the React {@code Component} props of {@code AbstractChat}.
*/
export type Props = {
export interface IProps extends WithTranslation {
/**
* Whether the chat is opened in a modal or not (computed based on window width).
*/
_isModal: boolean,
_isModal: boolean;
/**
* True if the chat window should be rendered.
*/
_isOpen: boolean,
_isOpen: boolean;
/**
* True if the polls feature is enabled.
*/
_isPollsEnabled: boolean,
_isPollsEnabled: boolean;
/**
* Whether the poll tab is focused or not.
*/
_isPollsTabFocused: boolean,
_isPollsTabFocused: boolean;
/**
* All the chat messages in the conference.
*/
_messages: Array<Object>,
_messages: Array<IMessage>;
/**
* Number of unread chat messages.
*/
_nbUnreadMessages: number,
_nbUnreadMessages: number;
/**
* Number of unread poll messages.
*/
_nbUnreadPolls: number,
_nbUnreadPolls: number;
/**
* Function to send a text message.
*
* @protected
*/
_onSendMessage: Function,
_onSendMessage: Function;
/**
* Function to toggle the chat window.
*/
_onToggleChat: Function;
/**
* Function to display the chat tab.
*
* @protected
*/
_onToggleChatTab: Function,
_onToggleChatTab: Function;
/**
* Function to display the polls tab.
*
* @protected
*/
_onTogglePollsTab: Function,
/**
* Function to toggle the chat window.
*/
_onToggleChat: Function,
_onTogglePollsTab: Function;
/**
* Whether or not to block chat access with a nickname input form.
*/
_showNamePrompt: boolean,
_showNamePrompt: boolean;
/**
* The Redux dispatch function.
*/
dispatch: Dispatch<any>,
/**
* Function to be used to translate i18n labels.
*/
t: Function,
};
dispatch: IStore['dispatch'];
}
/**
* Implements an abstract chat panel.
*/
export default class AbstractChat<P: Props> extends Component<P> {
export default class AbstractChat<P extends IProps> extends Component<P> {
/**
* Initializes a new {@code AbstractChat} instance.
*
* @param {Props} props - The React {@code Component} props to initialize
* @param {IProps} props - The React {@code Component} props to initialize
* the new {@code AbstractChat} instance with.
*/
constructor(props: P) {
@ -109,8 +104,6 @@ export default class AbstractChat<P: Props> extends Component<P> {
this._onTogglePollsTab = this._onTogglePollsTab.bind(this);
}
_onSendMessage: (string) => void;
/**
* Sends a text message.
*
@ -123,8 +116,6 @@ export default class AbstractChat<P: Props> extends Component<P> {
this.props.dispatch(sendMessage(text));
}
_onToggleChatTab: () => void;
/**
* Display the Chat tab.
*
@ -135,8 +126,6 @@ export default class AbstractChat<P: Props> extends Component<P> {
this.props.dispatch(setIsPollsTabFocused(false));
}
_onTogglePollsTab: () => void;
/**
* Display the Polls tab.
*
@ -160,7 +149,7 @@ export default class AbstractChat<P: Props> extends Component<P> {
* _showNamePrompt: boolean
* }}
*/
export function _mapStateToProps(state: Object) {
export function _mapStateToProps(state: IReduxState) {
const { isOpen, isPollsTabFocused, messages, nbUnreadMessages } = state['features/chat'];
const { nbUnreadPolls } = state['features/polls'];
const _localParticipant = getLocalParticipant(state);

View File

@ -9,7 +9,7 @@ import { connect } from '../../../base/redux';
import { TabBarLabelCounter } from '../../../mobile/navigation/components/TabBarLabelCounter';
import { closeChat } from '../../actions.native';
import AbstractChat, {
type Props as AbstractProps,
type IProps as AbstractProps,
_mapStateToProps
} from '../AbstractChat';

View File

@ -1,14 +1,14 @@
import clsx from 'clsx';
import React from 'react';
import React, { KeyboardEvent } from 'react';
import { connect } from 'react-redux';
import { translate } from '../../../base/i18n';
import { connect } from '../../../base/redux';
import { translate } from '../../../base/i18n/functions';
import Tabs from '../../../base/ui/components/web/Tabs';
import { PollsPane } from '../../../polls/components';
import PollsPane from '../../../polls/components/web/PollsPane';
import { toggleChat } from '../../actions.web';
import { CHAT_TABS } from '../../constants';
import AbstractChat, {
type Props,
IProps,
_mapStateToProps
} from '../AbstractChat';
@ -19,11 +19,12 @@ import KeyboardAvoider from './KeyboardAvoider';
import MessageContainer from './MessageContainer';
import MessageRecipient from './MessageRecipient';
/**
* React Component for holding the chat feature in a side panel that slides in
* and out of view.
*/
class Chat extends AbstractChat<Props> {
class Chat extends AbstractChat<IProps> {
/**
* Reference to the React Component for displaying chat messages. Used for
@ -37,7 +38,7 @@ class Chat extends AbstractChat<Props> {
* @param {Object} props - The read-only properties with which the new
* instance is to be initialized.
*/
constructor(props: Props) {
constructor(props: IProps) {
super(props);
this._messageContainerRef = React.createRef();
@ -67,8 +68,7 @@ class Chat extends AbstractChat<Props> {
<ChatHeader
className = 'chat-header'
id = 'chat-header'
isPollsEnabled = { _isPollsEnabled }
onCancel = { this._onToggleChat } />
isPollsEnabled = { _isPollsEnabled } />
{ _showNamePrompt
? <DisplayNameForm isPollsEnabled = { _isPollsEnabled } />
: this._renderChat() }
@ -76,15 +76,13 @@ class Chat extends AbstractChat<Props> {
);
}
_onChatTabKeyDown: (KeyboardEvent) => void;
/**
* Key press handler for the chat tab.
*
* @param {KeyboardEvent} event - The event.
* @returns {void}
*/
_onChatTabKeyDown(event) {
_onChatTabKeyDown(event: KeyboardEvent) {
if (event.key === 'Enter' || event.key === ' ') {
event.preventDefault();
event.stopPropagation();
@ -92,15 +90,13 @@ class Chat extends AbstractChat<Props> {
}
}
_onEscClick: (KeyboardEvent) => void;
/**
* Click handler for the chat sidenav.
*
* @param {KeyboardEvent} event - Esc key click to close the popup.
* @returns {void}
*/
_onEscClick(event) {
_onEscClick(event: KeyboardEvent) {
if (event.key === 'Escape' && this.props._isOpen) {
event.preventDefault();
event.stopPropagation();
@ -108,15 +104,13 @@ class Chat extends AbstractChat<Props> {
}
}
_onPollsTabKeyDown: (KeyboardEvent) => void;
/**
* Key press handler for the polls tab.
*
* @param {KeyboardEvent} event - The event.
* @returns {void}
*/
_onPollsTabKeyDown(event) {
_onPollsTabKeyDown(event: KeyboardEvent) {
if (event.key === 'Enter' || event.key === ' ') {
event.preventDefault();
event.stopPropagation();
@ -196,10 +190,6 @@ class Chat extends AbstractChat<Props> {
);
}
_onSendMessage: (string) => void;
_onToggleChat: () => void;
/**
* Toggles the chat window.
*
@ -208,9 +198,6 @@ class Chat extends AbstractChat<Props> {
_onToggleChat() {
this.props.dispatch(toggleChat());
}
_onTogglePollsTab: () => void;
_onToggleChatTab: () => void;
_onChangeTab: (string) => void;
/**
* Change selected tab.
@ -218,7 +205,7 @@ class Chat extends AbstractChat<Props> {
* @param {string} id - Id of the clicked tab.
* @returns {void}
*/
_onChangeTab(id) {
_onChangeTab(id: string) {
id === CHAT_TABS.CHAT ? this._onToggleChatTab() : this._onTogglePollsTab();
}
}

View File

@ -1,29 +1,29 @@
// @flow
import React, { ReactNode } from 'react';
import { WithTranslation } from 'react-i18next';
import { connect } from 'react-redux';
import React from 'react';
import { translate } from '../../../base/i18n';
import { IconMessage } from '../../../base/icons';
import { connect } from '../../../base/redux';
import { AbstractButton, type AbstractButtonProps } from '../../../base/toolbox/components';
import { IReduxState } from '../../../app/types';
import { translate } from '../../../base/i18n/functions';
import { IconMessage } from '../../../base/icons/svg';
import AbstractButton, { Props as AbstractButtonProps } from '../../../base/toolbox/components/AbstractButton';
import ChatCounter from './ChatCounter';
/**
* The type of the React {@code Component} props of {@link ChatButton}.
*/
type Props = AbstractButtonProps & {
interface IProps extends AbstractButtonProps, WithTranslation {
/**
* Whether or not the chat feature is currently displayed.
*/
_chatOpen: boolean,
};
_chatOpen: boolean;
}
/**
* Implementation of a button for accessing chat pane.
*/
class ChatButton extends AbstractButton<Props, *> {
class ChatButton extends AbstractButton<IProps, any> {
accessibilityLabel = 'toolbar.accessibilityLabel.chat';
icon = IconMessage;
label = 'toolbar.openChat';
@ -67,7 +67,7 @@ class ChatButton extends AbstractButton<Props, *> {
* @protected
* @returns {boReact$Nodeolean}
*/
render(): React$Node {
render(): ReactNode {
return (
<div
className = 'toolbar-button-with-badge'
@ -85,7 +85,7 @@ class ChatButton extends AbstractButton<Props, *> {
* @param {Object} state - Redux state.
* @returns {Object}
*/
const mapStateToProps = state => {
const mapStateToProps = (state: IReduxState) => {
return {
_chatOpen: state['features/chat'].isOpen
};

View File

@ -1,26 +1,25 @@
// @flow
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { connect } from '../../../base/redux';
import { IReduxState } from '../../../app/types';
import { getUnreadPollCount } from '../../../polls/functions';
import { getUnreadCount } from '../../functions';
/**
* The type of the React {@code Component} props of {@link ChatCounter}.
*/
type Props = {
interface IProps {
/**
* The value of to display as a count.
*/
_count: number,
_count: number;
/**
* True if the chat window should be rendered.
*/
_isOpen: boolean
};
_isOpen: boolean;
}
/**
* Implements a React {@link Component} which displays a count of the number of
@ -28,7 +27,7 @@ type Props = {
*
* @augments Component
*/
class ChatCounter extends Component<Props> {
class ChatCounter extends Component<IProps> {
/**
* Implements React's {@link Component#render()}.
@ -61,14 +60,12 @@ class ChatCounter extends Component<Props> {
* _count: number
* }}
*/
function _mapStateToProps(state) {
function _mapStateToProps(state: IReduxState) {
const { isOpen } = state['features/chat'];
return {
_count: getUnreadCount(state) + getUnreadPollCount(state),
_isOpen: isOpen
};
}

View File

@ -1,41 +1,41 @@
// @flow
import React, { useCallback } from 'react';
import { WithTranslation } from 'react-i18next';
import { connect } from 'react-redux';
import { translate } from '../../../base/i18n';
import { Icon, IconCloseLarge } from '../../../base/icons';
import { connect } from '../../../base/redux';
import { translate } from '../../../base/i18n/functions';
import Icon from '../../../base/icons/components/Icon';
import { IconCloseLarge } from '../../../base/icons/svg';
import { toggleChat } from '../../actions.web';
type Props = {
/**
* Function to be called when pressing the close button.
*/
onCancel: Function,
interface IProps extends WithTranslation {
/**
* An optional class name.
*/
className: string,
className: string;
/**
* Optional id.
*/
id?: string;
/**
* Whether the polls feature is enabled or not.
*/
isPollsEnabled: boolean,
isPollsEnabled: boolean;
/**
* Invoked to obtain translated strings.
* Function to be called when pressing the close button.
*/
t: Function
};
onCancel: Function;
}
/**
* Custom header of the {@code ChatDialog}.
*
* @returns {React$Element<any>}
*/
function Header({ onCancel, className, isPollsEnabled, t }: Props) {
function Header({ onCancel, className, isPollsEnabled, t }: IProps) {
const onKeyPressHandler = useCallback(e => {
if (onCancel && (e.key === ' ' || e.key === 'Enter')) {

View File

@ -1,11 +1,11 @@
import React, { Component, RefObject } from 'react';
import { WithTranslation } from 'react-i18next';
import { connect } from 'react-redux';
import { IReduxState, IStore } from '../../../app/types';
import { isMobileBrowser } from '../../../base/environment/utils';
import { translate } from '../../../base/i18n/functions';
import { IconFaceSmile, IconSend } from '../../../base/icons/svg';
import { connect } from '../../../base/redux/functions';
import Button from '../../../base/ui/components/web/Button';
import Input from '../../../base/ui/components/web/Input';
import { areSmileysDisabled } from '../../functions';

View File

@ -1,9 +1,9 @@
import React, { Component } from 'react';
import { WithTranslation } from 'react-i18next';
import { connect } from 'react-redux';
import { IStore } from '../../../app/types';
import { translate } from '../../../base/i18n/functions';
import { connect } from '../../../base/redux/functions';
import { updateSettings } from '../../../base/settings/actions';
import Button from '../../../base/ui/components/web/Button';
import Input from '../../../base/ui/components/web/Input';

View File

@ -1,5 +1,3 @@
// @flow
import React, { useEffect, useState } from 'react';
import { isIosMobileBrowser } from '../../../base/environment/utils';

View File

@ -1,10 +1,10 @@
import { Theme } from '@mui/material';
import { withStyles } from '@mui/styles';
import React from 'react';
import { connect } from 'react-redux';
import { translate } from '../../../base/i18n/functions';
import { IconCloseLarge } from '../../../base/icons/svg';
import { connect } from '../../../base/redux/functions';
import { withPixelLineHeight } from '../../../base/styles/functions.web';
import Button from '../../../base/ui/components/web/Button';
import { BUTTON_TYPES } from '../../../base/ui/constants.any';

View File

@ -1,5 +1,3 @@
// @flow
import React, { PureComponent } from 'react';
import Emoji from 'react-emoji-render';
@ -14,7 +12,7 @@ type Props = {
* Callback to invoke when a smiley is selected. The smiley will be passed
* back.
*/
onSmileySelect: Function
onSmileySelect: Function;
};
/**
@ -38,8 +36,6 @@ class SmileysPanel extends PureComponent<Props> {
this._onEscKey = this._onEscKey.bind(this);
}
_onEscKey: (Object) => void;
/**
* KeyPress handler for accessibility.
*
@ -47,7 +43,7 @@ class SmileysPanel extends PureComponent<Props> {
*
* @returns {void}
*/
_onEscKey(e) {
_onEscKey(e: React.KeyboardEvent) {
// Escape handling does not work in onKeyPress
if (e.key === 'Escape') {
e.preventDefault();
@ -56,8 +52,6 @@ class SmileysPanel extends PureComponent<Props> {
}
}
_onKeyPress: (Object) => void;
/**
* KeyPress handler for accessibility.
*
@ -65,15 +59,13 @@ class SmileysPanel extends PureComponent<Props> {
*
* @returns {void}
*/
_onKeyPress(e) {
_onKeyPress(e: any) {
if (e.key === ' ') {
e.preventDefault();
this.props.onSmileySelect(e.target.id && smileys[e.target.id]);
this.props.onSmileySelect(e.target.id && smileys[e.target.id as keyof typeof smileys]);
}
}
_onClick: (Object) => void;
/**
* Click handler for to select emoji.
*
@ -81,9 +73,9 @@ class SmileysPanel extends PureComponent<Props> {
*
* @returns {void}
*/
_onClick(e) {
_onClick(e: React.MouseEvent) {
e.preventDefault();
this.props.onSmileySelect(e.currentTarget.id && smileys[e.currentTarget.id]);
this.props.onSmileySelect(e.currentTarget.id && smileys[e.currentTarget.id as keyof typeof smileys]);
}
/**
@ -105,7 +97,7 @@ class SmileysPanel extends PureComponent<Props> {
tabIndex = { 0 }>
<Emoji
onlyEmojiClassName = 'smiley'
text = { smileys[smileyKey] } />
text = { smileys[smileyKey as keyof typeof smileys] } />
</div>
));