ref(chat) Convert components to TS
This commit is contained in:
parent
baf5aa14e8
commit
576d3ed8a7
|
@ -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 } />
|
|
@ -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 <></>;
|
||||
}
|
||||
|
||||
/**
|
|
@ -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>
|
||||
);
|
|
@ -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>
|
|
@ -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);
|
|
@ -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';
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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
|
||||
};
|
|
@ -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
|
||||
|
||||
};
|
||||
}
|
||||
|
|
@ -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')) {
|
|
@ -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';
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
// @flow
|
||||
|
||||
import React, { useEffect, useState } from 'react';
|
||||
|
||||
import { isIosMobileBrowser } from '../../../base/environment/utils';
|
|
@ -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';
|
||||
|
|
|
@ -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>
|
||||
));
|
||||
|
Loading…
Reference in New Issue