Compare commits
1 Commits
jitihouse/
...
rpintilii/
Author | SHA1 | Date |
---|---|---|
robertpin | 576d3ed8a7 |
|
@ -1,80 +1,76 @@
|
||||||
// @flow
|
import React, { Component, ReactNode } from 'react';
|
||||||
|
|
||||||
import React, { Component } from 'react';
|
|
||||||
|
|
||||||
import { NOTIFY_CLICK_MODE } from '../../../toolbox/constants';
|
import { NOTIFY_CLICK_MODE } from '../../../toolbox/constants';
|
||||||
import { combineStyles } from '../../styles';
|
import { combineStyles } from '../../styles/functions.any';
|
||||||
|
|
||||||
import type { Styles } from './AbstractToolboxItem';
|
import type { Styles } from './AbstractToolboxItem';
|
||||||
import ToolboxItem from './ToolboxItem';
|
import ToolboxItem from './ToolboxItem';
|
||||||
|
|
||||||
export type Props = {|
|
export type Props = {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to be called after the click handler has been processed.
|
* Function to be called after the click handler has been processed.
|
||||||
*/
|
*/
|
||||||
afterClick: ?Function,
|
afterClick?: Function;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The button's key.
|
* The button's key.
|
||||||
*/
|
*/
|
||||||
buttonKey?: string,
|
buttonKey?: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether or not the button is displayed in a context menu.
|
* 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
|
* An extra class name to be added at the end of the element's class name
|
||||||
* in order to enable custom styling.
|
* in order to enable custom styling.
|
||||||
*/
|
*/
|
||||||
customClass?: string,
|
customClass?: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extra styles which will be applied in conjunction with `styles` or
|
* Extra styles which will be applied in conjunction with `styles` or
|
||||||
* `toggledStyles` when the button is disabled;.
|
* `toggledStyles` when the button is disabled;.
|
||||||
*/
|
*/
|
||||||
disabledStyles: ?Styles,
|
disabledStyles?: Styles;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* External handler for click action.
|
* External handler for click action.
|
||||||
*/
|
*/
|
||||||
handleClick?: Function,
|
handleClick?: Function;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notify mode for `toolbarButtonClicked` event -
|
* Notify mode for `toolbarButtonClicked` event -
|
||||||
* whether to only notify or to also prevent button click routine.
|
* whether to only notify or to also prevent button click routine.
|
||||||
*/
|
*/
|
||||||
notifyMode?: string,
|
notifyMode?: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether to show the label or not.
|
* Whether to show the label or not.
|
||||||
*/
|
*/
|
||||||
showLabel: boolean,
|
showLabel: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Collection of styles for the button.
|
* Collection of styles for the button.
|
||||||
*/
|
*/
|
||||||
styles: ?Styles,
|
styles?: Styles;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Collection of styles for the button, when in toggled state.
|
* 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.
|
* From which direction the tooltip should appear, relative to the button.
|
||||||
*/
|
*/
|
||||||
tooltipPosition: string,
|
tooltipPosition: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether this button is visible or not.
|
* Whether this button is visible or not.
|
||||||
*/
|
*/
|
||||||
visible: boolean
|
visible: boolean;
|
||||||
|};
|
};
|
||||||
|
|
||||||
declare var APP: Object;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default style for disabled buttons.
|
* Default style for disabled buttons.
|
||||||
|
@ -93,7 +89,7 @@ export const defaultDisabledButtonStyles = {
|
||||||
/**
|
/**
|
||||||
* An abstract implementation of a button.
|
* 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 = {
|
static defaultProps = {
|
||||||
afterClick: undefined,
|
afterClick: undefined,
|
||||||
disabledStyles: defaultDisabledButtonStyles,
|
disabledStyles: defaultDisabledButtonStyles,
|
||||||
|
@ -146,7 +142,9 @@ export default class AbstractButton<P: Props, S: *> extends Component<P, S> {
|
||||||
*
|
*
|
||||||
* @abstract
|
* @abstract
|
||||||
*/
|
*/
|
||||||
tooltip: ?string;
|
get tooltip(): string | undefined {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes a new {@code AbstractButton} instance.
|
* Initializes a new {@code AbstractButton} instance.
|
||||||
|
@ -229,7 +227,7 @@ export default class AbstractButton<P: Props, S: *> extends Component<P, S> {
|
||||||
* @private
|
* @private
|
||||||
* @returns {?Styles}
|
* @returns {?Styles}
|
||||||
*/
|
*/
|
||||||
_getStyles(): ?Styles {
|
_getStyles(): Styles | undefined {
|
||||||
const { disabledStyles, styles, toggledStyles } = this.props;
|
const { disabledStyles, styles, toggledStyles } = this.props;
|
||||||
const buttonStyles
|
const buttonStyles
|
||||||
= (this._isToggled() ? toggledStyles : styles) || styles;
|
= (this._isToggled() ? toggledStyles : styles) || styles;
|
||||||
|
@ -280,11 +278,9 @@ export default class AbstractButton<P: Props, S: *> extends Component<P, S> {
|
||||||
* @returns {?boolean}
|
* @returns {?boolean}
|
||||||
*/
|
*/
|
||||||
_isToggled() {
|
_isToggled() {
|
||||||
return undefined;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_onClick: (*) => void;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles clicking / pressing the button.
|
* Handles clicking / pressing the button.
|
||||||
*
|
*
|
||||||
|
@ -292,7 +288,7 @@ export default class AbstractButton<P: Props, S: *> extends Component<P, S> {
|
||||||
* @private
|
* @private
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
_onClick(e) {
|
_onClick(e: React.MouseEvent<HTMLElement>) {
|
||||||
const { afterClick, handleClick, notifyMode, buttonKey } = this.props;
|
const { afterClick, handleClick, notifyMode, buttonKey } = this.props;
|
||||||
|
|
||||||
if (typeof APP !== 'undefined' && notifyMode) {
|
if (typeof APP !== 'undefined' && notifyMode) {
|
||||||
|
@ -309,9 +305,10 @@ export default class AbstractButton<P: Props, S: *> extends Component<P, S> {
|
||||||
this._handleClick();
|
this._handleClick();
|
||||||
}
|
}
|
||||||
|
|
||||||
afterClick && afterClick(e);
|
afterClick?.(e);
|
||||||
|
|
||||||
// blur after click to release focus from button to allow PTT.
|
// blur after click to release focus from button to allow PTT.
|
||||||
|
// @ts-ignore
|
||||||
e?.currentTarget?.blur && e.currentTarget.blur();
|
e?.currentTarget?.blur && e.currentTarget.blur();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,7 +318,7 @@ export default class AbstractButton<P: Props, S: *> extends Component<P, S> {
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
* @returns {React$Node}
|
* @returns {React$Node}
|
||||||
*/
|
*/
|
||||||
render(): React$Node {
|
render(): ReactNode {
|
||||||
const props = {
|
const props = {
|
||||||
...this.props,
|
...this.props,
|
||||||
accessibilityLabel: this.accessibilityLabel,
|
accessibilityLabel: this.accessibilityLabel,
|
||||||
|
@ -337,6 +334,8 @@ export default class AbstractButton<P: Props, S: *> extends Component<P, S> {
|
||||||
return (
|
return (
|
||||||
<ToolboxItem
|
<ToolboxItem
|
||||||
disabled = { this._isDisabled() }
|
disabled = { this._isDisabled() }
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
onClick = { this._onClick }
|
onClick = { this._onClick }
|
||||||
onKeyDown = { this._onKeyDown }
|
onKeyDown = { this._onKeyDown }
|
||||||
{ ...props } />
|
{ ...props } />
|
|
@ -1,30 +1,29 @@
|
||||||
// @flow
|
import React, { Component, ReactNode } from 'react';
|
||||||
|
import { GestureResponderEvent } from 'react-native';
|
||||||
|
|
||||||
import { Component } from 'react';
|
import { StyleType } from '../../styles/functions.any';
|
||||||
|
|
||||||
import type { StyleType } from '../../styles';
|
|
||||||
|
|
||||||
export type Styles = {
|
export type Styles = {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Style for the item's icon.
|
* Style for the item's icon.
|
||||||
*/
|
*/
|
||||||
iconStyle: StyleType,
|
iconStyle: StyleType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Style for the item's label.
|
* Style for the item's label.
|
||||||
*/
|
*/
|
||||||
labelStyle: StyleType,
|
labelStyle: StyleType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Style for the item itself.
|
* Style for the item itself.
|
||||||
*/
|
*/
|
||||||
style: StyleType,
|
style: StyleType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Color for the item underlay (shows when clicked).
|
* Color for the item underlay (shows when clicked).
|
||||||
*/
|
*/
|
||||||
underlayColor: ?string
|
underlayColor?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Props = {
|
export type Props = {
|
||||||
|
@ -33,76 +32,78 @@ export type Props = {
|
||||||
* A succinct description of what the item does. Used by accessibility
|
* A succinct description of what the item does. Used by accessibility
|
||||||
* tools and torture tests.
|
* tools and torture tests.
|
||||||
*/
|
*/
|
||||||
accessibilityLabel: string,
|
accessibilityLabel: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An extra class name to be added at the end of the element's class name
|
* An extra class name to be added at the end of the element's class name
|
||||||
* in order to enable custom styling.
|
* in order to enable custom styling.
|
||||||
*/
|
*/
|
||||||
customClass?: string,
|
customClass?: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether this item is disabled or not. When disabled, clicking an the item
|
* Whether this item is disabled or not. When disabled, clicking an the item
|
||||||
* has no effect, and it may reflect on its style.
|
* 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}.
|
* A React Element to display at the end of {@code ToolboxItem}.
|
||||||
*/
|
*/
|
||||||
elementAfter?: React$Node,
|
elementAfter?: ReactNode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The icon to render for this {@code ToolboxItem}.
|
* The icon to render for this {@code ToolboxItem}.
|
||||||
*/
|
*/
|
||||||
icon: Object,
|
icon: Function;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The text associated with this item. When `showLabel` is set to
|
* The text associated with this item. When `showLabel` is set to
|
||||||
* {@code true}, it will be displayed alongside the icon.
|
* {@code true}, it will be displayed alongside the icon.
|
||||||
*/
|
*/
|
||||||
label: string,
|
label: string;
|
||||||
|
|
||||||
|
labelProps: any;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* On click handler.
|
* On click handler.
|
||||||
*/
|
*/
|
||||||
onClick: Function,
|
onClick: (e?: React.MouseEvent | GestureResponderEvent) => void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether to show the label or not.
|
* Whether to show the label or not.
|
||||||
*/
|
*/
|
||||||
showLabel: boolean,
|
showLabel: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Collection of styles for the item. Used only on native.
|
* Collection of styles for the item. Used only on native.
|
||||||
*/
|
*/
|
||||||
styles: ?Styles,
|
styles?: Styles;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoked to obtain translated strings.
|
* Invoked to obtain translated strings.
|
||||||
*/
|
*/
|
||||||
t: ?Function,
|
t?: Function;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* True if the item is toggled, false otherwise.
|
* True if the item is toggled, false otherwise.
|
||||||
*/
|
*/
|
||||||
toggled: ?boolean,
|
toggled?: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The text to display in the tooltip. Used only on web.
|
* 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
|
* From which direction the tooltip should appear, relative to the
|
||||||
* item. Used only on web.
|
* item. Used only on web.
|
||||||
*/
|
*/
|
||||||
tooltipPosition: string,
|
tooltipPosition: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether this item is visible or not.
|
* Whether this item is visible or not.
|
||||||
*/
|
*/
|
||||||
visible: boolean
|
visible: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -111,7 +112,7 @@ export type Props = {
|
||||||
*
|
*
|
||||||
* @abstract
|
* @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.
|
* Default values for {@code AbstractToolboxItem} component's properties.
|
||||||
*
|
*
|
||||||
|
@ -147,7 +148,7 @@ export default class AbstractToolboxItem<P : Props> extends Component<P> {
|
||||||
* @protected
|
* @protected
|
||||||
* @returns {?string}
|
* @returns {?string}
|
||||||
*/
|
*/
|
||||||
get label(): ?string {
|
get label(): string | undefined {
|
||||||
return this._maybeTranslateAttribute(this.props.label, this.props.labelProps);
|
return this._maybeTranslateAttribute(this.props.label, this.props.labelProps);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,7 +159,7 @@ export default class AbstractToolboxItem<P : Props> extends Component<P> {
|
||||||
* @protected
|
* @protected
|
||||||
* @returns {?string}
|
* @returns {?string}
|
||||||
*/
|
*/
|
||||||
get tooltip(): ?string {
|
get tooltip(): string | undefined {
|
||||||
return this._maybeTranslateAttribute(this.props.tooltip);
|
return this._maybeTranslateAttribute(this.props.tooltip);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,7 +170,7 @@ export default class AbstractToolboxItem<P : Props> extends Component<P> {
|
||||||
* @protected
|
* @protected
|
||||||
* @returns {?string}
|
* @returns {?string}
|
||||||
*/
|
*/
|
||||||
get accessibilityLabel(): ?string {
|
get accessibilityLabel(): string | undefined {
|
||||||
return this._maybeTranslateAttribute(this.props.accessibilityLabel);
|
return this._maybeTranslateAttribute(this.props.accessibilityLabel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,7 +183,7 @@ export default class AbstractToolboxItem<P : Props> extends Component<P> {
|
||||||
* @private
|
* @private
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
_maybeTranslateAttribute(text, textProps) {
|
_maybeTranslateAttribute(text?: string, textProps?: string) {
|
||||||
const { t } = this.props;
|
const { t } = this.props;
|
||||||
|
|
||||||
if (textProps) {
|
if (textProps) {
|
||||||
|
@ -193,8 +194,6 @@ export default class AbstractToolboxItem<P : Props> extends Component<P> {
|
||||||
return typeof t === 'function' ? t(text) : text;
|
return typeof t === 'function' ? t(text) : text;
|
||||||
}
|
}
|
||||||
|
|
||||||
_onClick: (*) => void;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles clicking/pressing this {@code AbstractToolboxItem} by
|
* Handles clicking/pressing this {@code AbstractToolboxItem} by
|
||||||
* forwarding the event to the {@code onClick} prop of this instance if any.
|
* 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
|
* @protected
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
_onClick(...args) {
|
_onClick(...args: any) {
|
||||||
const { disabled, onClick } = this.props;
|
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() {
|
_renderItem() {
|
||||||
// To be implemented by a subclass.
|
// To be implemented by a subclass.
|
||||||
return null;
|
return <></>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
|
@ -1,12 +1,9 @@
|
||||||
// @flow
|
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Text, TouchableHighlight, View } from 'react-native';
|
import { Text, TouchableHighlight, View } from 'react-native';
|
||||||
|
|
||||||
import { Icon } from '../../icons';
|
import Icon from '../../icons/components/Icon';
|
||||||
|
|
||||||
import AbstractToolboxItem from './AbstractToolboxItem';
|
import AbstractToolboxItem, { Props } from './AbstractToolboxItem';
|
||||||
import type { Props } from './AbstractToolboxItem';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Native implementation of {@code AbstractToolboxItem}.
|
* Native implementation of {@code AbstractToolboxItem}.
|
||||||
|
@ -24,7 +21,7 @@ export default class ToolboxItem extends AbstractToolboxItem<Props> {
|
||||||
return (
|
return (
|
||||||
<Icon
|
<Icon
|
||||||
src = { this.props.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
|
// XXX When using a wrapper View, apply the style to it instead of
|
||||||
// applying it to the TouchableHighlight.
|
// applying it to the TouchableHighlight.
|
||||||
let style = styles && styles.style;
|
let style = styles?.style;
|
||||||
|
|
||||||
if (showLabel) {
|
if (showLabel) {
|
||||||
// XXX TouchableHighlight requires 1 child. If there's a need to
|
// XXX TouchableHighlight requires 1 child. If there's a need to
|
||||||
|
@ -58,7 +55,7 @@ export default class ToolboxItem extends AbstractToolboxItem<Props> {
|
||||||
children = (
|
children = (
|
||||||
<View style = { style }>
|
<View style = { style }>
|
||||||
{ children }
|
{ children }
|
||||||
<Text style = { styles && styles.labelStyle }>
|
<Text style = { styles?.labelStyle }>
|
||||||
{ this.label }
|
{ this.label }
|
||||||
</Text>
|
</Text>
|
||||||
{ elementAfter }
|
{ elementAfter }
|
||||||
|
@ -78,7 +75,7 @@ export default class ToolboxItem extends AbstractToolboxItem<Props> {
|
||||||
disabled = { disabled }
|
disabled = { disabled }
|
||||||
onPress = { onClick }
|
onPress = { onClick }
|
||||||
style = { style }
|
style = { style }
|
||||||
underlayColor = { styles && styles.underlayColor } >
|
underlayColor = { styles?.underlayColor } >
|
||||||
{ children }
|
{ children }
|
||||||
</TouchableHighlight>
|
</TouchableHighlight>
|
||||||
);
|
);
|
|
@ -1,8 +1,8 @@
|
||||||
// @flow
|
|
||||||
|
|
||||||
import React, { Fragment } from 'react';
|
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 { Tooltip } from '../../tooltip';
|
||||||
import ContextMenuItem from '../../ui/components/web/ContextMenuItem';
|
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.
|
* Whether or not the item is displayed in a context menu.
|
||||||
*/
|
*/
|
||||||
contextMenu?: boolean,
|
contextMenu?: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* On key down handler.
|
* 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);
|
this._onKeyPress = this._onKeyPress.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
_onKeyPress: (Object) => void;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles 'Enter' and Space key on the button to trigger onClick for accessibility.
|
* 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
|
* @private
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
_onKeyPress(event) {
|
_onKeyPress(event?: React.KeyboardEvent) {
|
||||||
if (event.key === 'Enter' || event.key === ' ') {
|
if (event?.key === 'Enter' || event?.key === ' ') {
|
||||||
event.preventDefault();
|
event?.preventDefault();
|
||||||
this.props.onClick();
|
this.props.onClick();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,13 +90,13 @@ export default class ToolboxItem extends AbstractToolboxItem<Props> {
|
||||||
|
|
||||||
if (contextMenu) {
|
if (contextMenu) {
|
||||||
return (<ContextMenuItem
|
return (<ContextMenuItem
|
||||||
accessibilityLabel = { this.accessibilityLabel }
|
accessibilityLabel = { this.accessibilityLabel ?? '' }
|
||||||
disabled = { disabled }
|
disabled = { disabled }
|
||||||
icon = { icon }
|
icon = { icon }
|
||||||
onClick = { onClick }
|
onClick = { onClick }
|
||||||
onKeyDown = { onKeyDown }
|
onKeyDown = { onKeyDown }
|
||||||
onKeyPress = { this._onKeyPress }
|
onKeyPress = { this._onKeyPress }
|
||||||
text = { this.label } />);
|
text = { this.label ?? '' } />);
|
||||||
}
|
}
|
||||||
let children = (
|
let children = (
|
||||||
<Fragment>
|
<Fragment>
|
|
@ -1,103 +1,98 @@
|
||||||
// @flow
|
|
||||||
|
|
||||||
import { Component } from 'react';
|
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 { sendMessage, setIsPollsTabFocused } from '../actions';
|
||||||
import { SMALL_WIDTH_THRESHOLD } from '../constants';
|
import { SMALL_WIDTH_THRESHOLD } from '../constants';
|
||||||
|
import { IMessage } from '../reducer';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The type of the React {@code Component} props of {@code AbstractChat}.
|
* 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).
|
* 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.
|
* True if the chat window should be rendered.
|
||||||
*/
|
*/
|
||||||
_isOpen: boolean,
|
_isOpen: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* True if the polls feature is enabled.
|
* True if the polls feature is enabled.
|
||||||
*/
|
*/
|
||||||
_isPollsEnabled: boolean,
|
_isPollsEnabled: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the poll tab is focused or not.
|
* Whether the poll tab is focused or not.
|
||||||
*/
|
*/
|
||||||
_isPollsTabFocused: boolean,
|
_isPollsTabFocused: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All the chat messages in the conference.
|
* All the chat messages in the conference.
|
||||||
*/
|
*/
|
||||||
_messages: Array<Object>,
|
_messages: Array<IMessage>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of unread chat messages.
|
* Number of unread chat messages.
|
||||||
*/
|
*/
|
||||||
_nbUnreadMessages: number,
|
_nbUnreadMessages: number;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of unread poll messages.
|
* Number of unread poll messages.
|
||||||
*/
|
*/
|
||||||
_nbUnreadPolls: number,
|
_nbUnreadPolls: number;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to send a text message.
|
* Function to send a text message.
|
||||||
*
|
*
|
||||||
* @protected
|
* @protected
|
||||||
*/
|
*/
|
||||||
_onSendMessage: Function,
|
_onSendMessage: Function;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to toggle the chat window.
|
||||||
|
*/
|
||||||
|
_onToggleChat: Function;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to display the chat tab.
|
* Function to display the chat tab.
|
||||||
*
|
*
|
||||||
* @protected
|
* @protected
|
||||||
*/
|
*/
|
||||||
_onToggleChatTab: Function,
|
_onToggleChatTab: Function;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to display the polls tab.
|
* Function to display the polls tab.
|
||||||
*
|
*
|
||||||
* @protected
|
* @protected
|
||||||
*/
|
*/
|
||||||
_onTogglePollsTab: Function,
|
_onTogglePollsTab: Function;
|
||||||
|
|
||||||
/**
|
|
||||||
* Function to toggle the chat window.
|
|
||||||
*/
|
|
||||||
_onToggleChat: Function,
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether or not to block chat access with a nickname input form.
|
* Whether or not to block chat access with a nickname input form.
|
||||||
*/
|
*/
|
||||||
_showNamePrompt: boolean,
|
_showNamePrompt: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Redux dispatch function.
|
* The Redux dispatch function.
|
||||||
*/
|
*/
|
||||||
dispatch: Dispatch<any>,
|
dispatch: IStore['dispatch'];
|
||||||
|
}
|
||||||
/**
|
|
||||||
* Function to be used to translate i18n labels.
|
|
||||||
*/
|
|
||||||
t: Function,
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements an abstract chat panel.
|
* 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.
|
* 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.
|
* the new {@code AbstractChat} instance with.
|
||||||
*/
|
*/
|
||||||
constructor(props: P) {
|
constructor(props: P) {
|
||||||
|
@ -109,8 +104,6 @@ export default class AbstractChat<P: Props> extends Component<P> {
|
||||||
this._onTogglePollsTab = this._onTogglePollsTab.bind(this);
|
this._onTogglePollsTab = this._onTogglePollsTab.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
_onSendMessage: (string) => void;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a text message.
|
* Sends a text message.
|
||||||
*
|
*
|
||||||
|
@ -123,8 +116,6 @@ export default class AbstractChat<P: Props> extends Component<P> {
|
||||||
this.props.dispatch(sendMessage(text));
|
this.props.dispatch(sendMessage(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
_onToggleChatTab: () => void;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display the Chat tab.
|
* Display the Chat tab.
|
||||||
*
|
*
|
||||||
|
@ -135,8 +126,6 @@ export default class AbstractChat<P: Props> extends Component<P> {
|
||||||
this.props.dispatch(setIsPollsTabFocused(false));
|
this.props.dispatch(setIsPollsTabFocused(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
_onTogglePollsTab: () => void;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display the Polls tab.
|
* Display the Polls tab.
|
||||||
*
|
*
|
||||||
|
@ -160,7 +149,7 @@ export default class AbstractChat<P: Props> extends Component<P> {
|
||||||
* _showNamePrompt: boolean
|
* _showNamePrompt: boolean
|
||||||
* }}
|
* }}
|
||||||
*/
|
*/
|
||||||
export function _mapStateToProps(state: Object) {
|
export function _mapStateToProps(state: IReduxState) {
|
||||||
const { isOpen, isPollsTabFocused, messages, nbUnreadMessages } = state['features/chat'];
|
const { isOpen, isPollsTabFocused, messages, nbUnreadMessages } = state['features/chat'];
|
||||||
const { nbUnreadPolls } = state['features/polls'];
|
const { nbUnreadPolls } = state['features/polls'];
|
||||||
const _localParticipant = getLocalParticipant(state);
|
const _localParticipant = getLocalParticipant(state);
|
|
@ -9,7 +9,7 @@ import { connect } from '../../../base/redux';
|
||||||
import { TabBarLabelCounter } from '../../../mobile/navigation/components/TabBarLabelCounter';
|
import { TabBarLabelCounter } from '../../../mobile/navigation/components/TabBarLabelCounter';
|
||||||
import { closeChat } from '../../actions.native';
|
import { closeChat } from '../../actions.native';
|
||||||
import AbstractChat, {
|
import AbstractChat, {
|
||||||
type Props as AbstractProps,
|
type IProps as AbstractProps,
|
||||||
_mapStateToProps
|
_mapStateToProps
|
||||||
} from '../AbstractChat';
|
} from '../AbstractChat';
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import React from 'react';
|
import React, { KeyboardEvent } from 'react';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
import { translate } from '../../../base/i18n';
|
import { translate } from '../../../base/i18n/functions';
|
||||||
import { connect } from '../../../base/redux';
|
|
||||||
import Tabs from '../../../base/ui/components/web/Tabs';
|
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 { toggleChat } from '../../actions.web';
|
||||||
import { CHAT_TABS } from '../../constants';
|
import { CHAT_TABS } from '../../constants';
|
||||||
import AbstractChat, {
|
import AbstractChat, {
|
||||||
type Props,
|
IProps,
|
||||||
_mapStateToProps
|
_mapStateToProps
|
||||||
} from '../AbstractChat';
|
} from '../AbstractChat';
|
||||||
|
|
||||||
|
@ -19,11 +19,12 @@ import KeyboardAvoider from './KeyboardAvoider';
|
||||||
import MessageContainer from './MessageContainer';
|
import MessageContainer from './MessageContainer';
|
||||||
import MessageRecipient from './MessageRecipient';
|
import MessageRecipient from './MessageRecipient';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* React Component for holding the chat feature in a side panel that slides in
|
* React Component for holding the chat feature in a side panel that slides in
|
||||||
* and out of view.
|
* 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
|
* 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
|
* @param {Object} props - The read-only properties with which the new
|
||||||
* instance is to be initialized.
|
* instance is to be initialized.
|
||||||
*/
|
*/
|
||||||
constructor(props: Props) {
|
constructor(props: IProps) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this._messageContainerRef = React.createRef();
|
this._messageContainerRef = React.createRef();
|
||||||
|
@ -67,8 +68,7 @@ class Chat extends AbstractChat<Props> {
|
||||||
<ChatHeader
|
<ChatHeader
|
||||||
className = 'chat-header'
|
className = 'chat-header'
|
||||||
id = 'chat-header'
|
id = 'chat-header'
|
||||||
isPollsEnabled = { _isPollsEnabled }
|
isPollsEnabled = { _isPollsEnabled } />
|
||||||
onCancel = { this._onToggleChat } />
|
|
||||||
{ _showNamePrompt
|
{ _showNamePrompt
|
||||||
? <DisplayNameForm isPollsEnabled = { _isPollsEnabled } />
|
? <DisplayNameForm isPollsEnabled = { _isPollsEnabled } />
|
||||||
: this._renderChat() }
|
: this._renderChat() }
|
||||||
|
@ -76,15 +76,13 @@ class Chat extends AbstractChat<Props> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
_onChatTabKeyDown: (KeyboardEvent) => void;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Key press handler for the chat tab.
|
* Key press handler for the chat tab.
|
||||||
*
|
*
|
||||||
* @param {KeyboardEvent} event - The event.
|
* @param {KeyboardEvent} event - The event.
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
_onChatTabKeyDown(event) {
|
_onChatTabKeyDown(event: KeyboardEvent) {
|
||||||
if (event.key === 'Enter' || event.key === ' ') {
|
if (event.key === 'Enter' || event.key === ' ') {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
@ -92,15 +90,13 @@ class Chat extends AbstractChat<Props> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_onEscClick: (KeyboardEvent) => void;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Click handler for the chat sidenav.
|
* Click handler for the chat sidenav.
|
||||||
*
|
*
|
||||||
* @param {KeyboardEvent} event - Esc key click to close the popup.
|
* @param {KeyboardEvent} event - Esc key click to close the popup.
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
_onEscClick(event) {
|
_onEscClick(event: KeyboardEvent) {
|
||||||
if (event.key === 'Escape' && this.props._isOpen) {
|
if (event.key === 'Escape' && this.props._isOpen) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
@ -108,15 +104,13 @@ class Chat extends AbstractChat<Props> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_onPollsTabKeyDown: (KeyboardEvent) => void;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Key press handler for the polls tab.
|
* Key press handler for the polls tab.
|
||||||
*
|
*
|
||||||
* @param {KeyboardEvent} event - The event.
|
* @param {KeyboardEvent} event - The event.
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
_onPollsTabKeyDown(event) {
|
_onPollsTabKeyDown(event: KeyboardEvent) {
|
||||||
if (event.key === 'Enter' || event.key === ' ') {
|
if (event.key === 'Enter' || event.key === ' ') {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
@ -196,10 +190,6 @@ class Chat extends AbstractChat<Props> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
_onSendMessage: (string) => void;
|
|
||||||
|
|
||||||
_onToggleChat: () => void;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toggles the chat window.
|
* Toggles the chat window.
|
||||||
*
|
*
|
||||||
|
@ -208,9 +198,6 @@ class Chat extends AbstractChat<Props> {
|
||||||
_onToggleChat() {
|
_onToggleChat() {
|
||||||
this.props.dispatch(toggleChat());
|
this.props.dispatch(toggleChat());
|
||||||
}
|
}
|
||||||
_onTogglePollsTab: () => void;
|
|
||||||
_onToggleChatTab: () => void;
|
|
||||||
_onChangeTab: (string) => void;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Change selected tab.
|
* Change selected tab.
|
||||||
|
@ -218,7 +205,7 @@ class Chat extends AbstractChat<Props> {
|
||||||
* @param {string} id - Id of the clicked tab.
|
* @param {string} id - Id of the clicked tab.
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
_onChangeTab(id) {
|
_onChangeTab(id: string) {
|
||||||
id === CHAT_TABS.CHAT ? this._onToggleChatTab() : this._onTogglePollsTab();
|
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 { IReduxState } from '../../../app/types';
|
||||||
|
import { translate } from '../../../base/i18n/functions';
|
||||||
import { translate } from '../../../base/i18n';
|
import { IconMessage } from '../../../base/icons/svg';
|
||||||
import { IconMessage } from '../../../base/icons';
|
import AbstractButton, { Props as AbstractButtonProps } from '../../../base/toolbox/components/AbstractButton';
|
||||||
import { connect } from '../../../base/redux';
|
|
||||||
import { AbstractButton, type AbstractButtonProps } from '../../../base/toolbox/components';
|
|
||||||
|
|
||||||
import ChatCounter from './ChatCounter';
|
import ChatCounter from './ChatCounter';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The type of the React {@code Component} props of {@link ChatButton}.
|
* 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.
|
* Whether or not the chat feature is currently displayed.
|
||||||
*/
|
*/
|
||||||
_chatOpen: boolean,
|
_chatOpen: boolean;
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of a button for accessing chat pane.
|
* Implementation of a button for accessing chat pane.
|
||||||
*/
|
*/
|
||||||
class ChatButton extends AbstractButton<Props, *> {
|
class ChatButton extends AbstractButton<IProps, any> {
|
||||||
accessibilityLabel = 'toolbar.accessibilityLabel.chat';
|
accessibilityLabel = 'toolbar.accessibilityLabel.chat';
|
||||||
icon = IconMessage;
|
icon = IconMessage;
|
||||||
label = 'toolbar.openChat';
|
label = 'toolbar.openChat';
|
||||||
|
@ -67,7 +67,7 @@ class ChatButton extends AbstractButton<Props, *> {
|
||||||
* @protected
|
* @protected
|
||||||
* @returns {boReact$Nodeolean}
|
* @returns {boReact$Nodeolean}
|
||||||
*/
|
*/
|
||||||
render(): React$Node {
|
render(): ReactNode {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className = 'toolbar-button-with-badge'
|
className = 'toolbar-button-with-badge'
|
||||||
|
@ -85,7 +85,7 @@ class ChatButton extends AbstractButton<Props, *> {
|
||||||
* @param {Object} state - Redux state.
|
* @param {Object} state - Redux state.
|
||||||
* @returns {Object}
|
* @returns {Object}
|
||||||
*/
|
*/
|
||||||
const mapStateToProps = state => {
|
const mapStateToProps = (state: IReduxState) => {
|
||||||
return {
|
return {
|
||||||
_chatOpen: state['features/chat'].isOpen
|
_chatOpen: state['features/chat'].isOpen
|
||||||
};
|
};
|
|
@ -1,26 +1,25 @@
|
||||||
// @flow
|
|
||||||
|
|
||||||
import React, { Component } from 'react';
|
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 { getUnreadPollCount } from '../../../polls/functions';
|
||||||
import { getUnreadCount } from '../../functions';
|
import { getUnreadCount } from '../../functions';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The type of the React {@code Component} props of {@link ChatCounter}.
|
* The type of the React {@code Component} props of {@link ChatCounter}.
|
||||||
*/
|
*/
|
||||||
type Props = {
|
interface IProps {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The value of to display as a count.
|
* The value of to display as a count.
|
||||||
*/
|
*/
|
||||||
_count: number,
|
_count: number;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* True if the chat window should be rendered.
|
* 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
|
* Implements a React {@link Component} which displays a count of the number of
|
||||||
|
@ -28,7 +27,7 @@ type Props = {
|
||||||
*
|
*
|
||||||
* @augments Component
|
* @augments Component
|
||||||
*/
|
*/
|
||||||
class ChatCounter extends Component<Props> {
|
class ChatCounter extends Component<IProps> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements React's {@link Component#render()}.
|
* Implements React's {@link Component#render()}.
|
||||||
|
@ -61,14 +60,12 @@ class ChatCounter extends Component<Props> {
|
||||||
* _count: number
|
* _count: number
|
||||||
* }}
|
* }}
|
||||||
*/
|
*/
|
||||||
function _mapStateToProps(state) {
|
function _mapStateToProps(state: IReduxState) {
|
||||||
const { isOpen } = state['features/chat'];
|
const { isOpen } = state['features/chat'];
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
||||||
_count: getUnreadCount(state) + getUnreadPollCount(state),
|
_count: getUnreadCount(state) + getUnreadPollCount(state),
|
||||||
_isOpen: isOpen
|
_isOpen: isOpen
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,41 +1,41 @@
|
||||||
// @flow
|
|
||||||
|
|
||||||
import React, { useCallback } from 'react';
|
import React, { useCallback } from 'react';
|
||||||
|
import { WithTranslation } from 'react-i18next';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
import { translate } from '../../../base/i18n';
|
import { translate } from '../../../base/i18n/functions';
|
||||||
import { Icon, IconCloseLarge } from '../../../base/icons';
|
import Icon from '../../../base/icons/components/Icon';
|
||||||
import { connect } from '../../../base/redux';
|
import { IconCloseLarge } from '../../../base/icons/svg';
|
||||||
import { toggleChat } from '../../actions.web';
|
import { toggleChat } from '../../actions.web';
|
||||||
|
|
||||||
type Props = {
|
interface IProps extends WithTranslation {
|
||||||
|
|
||||||
/**
|
|
||||||
* Function to be called when pressing the close button.
|
|
||||||
*/
|
|
||||||
onCancel: Function,
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An optional class name.
|
* An optional class name.
|
||||||
*/
|
*/
|
||||||
className: string,
|
className: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optional id.
|
||||||
|
*/
|
||||||
|
id?: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the polls feature is enabled or not.
|
* 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}.
|
* Custom header of the {@code ChatDialog}.
|
||||||
*
|
*
|
||||||
* @returns {React$Element<any>}
|
* @returns {React$Element<any>}
|
||||||
*/
|
*/
|
||||||
function Header({ onCancel, className, isPollsEnabled, t }: Props) {
|
function Header({ onCancel, className, isPollsEnabled, t }: IProps) {
|
||||||
|
|
||||||
const onKeyPressHandler = useCallback(e => {
|
const onKeyPressHandler = useCallback(e => {
|
||||||
if (onCancel && (e.key === ' ' || e.key === 'Enter')) {
|
if (onCancel && (e.key === ' ' || e.key === 'Enter')) {
|
|
@ -1,11 +1,11 @@
|
||||||
import React, { Component, RefObject } from 'react';
|
import React, { Component, RefObject } from 'react';
|
||||||
import { WithTranslation } from 'react-i18next';
|
import { WithTranslation } from 'react-i18next';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
import { IReduxState, IStore } from '../../../app/types';
|
import { IReduxState, IStore } from '../../../app/types';
|
||||||
import { isMobileBrowser } from '../../../base/environment/utils';
|
import { isMobileBrowser } from '../../../base/environment/utils';
|
||||||
import { translate } from '../../../base/i18n/functions';
|
import { translate } from '../../../base/i18n/functions';
|
||||||
import { IconFaceSmile, IconSend } from '../../../base/icons/svg';
|
import { IconFaceSmile, IconSend } from '../../../base/icons/svg';
|
||||||
import { connect } from '../../../base/redux/functions';
|
|
||||||
import Button from '../../../base/ui/components/web/Button';
|
import Button from '../../../base/ui/components/web/Button';
|
||||||
import Input from '../../../base/ui/components/web/Input';
|
import Input from '../../../base/ui/components/web/Input';
|
||||||
import { areSmileysDisabled } from '../../functions';
|
import { areSmileysDisabled } from '../../functions';
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { WithTranslation } from 'react-i18next';
|
import { WithTranslation } from 'react-i18next';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
import { IStore } from '../../../app/types';
|
import { IStore } from '../../../app/types';
|
||||||
import { translate } from '../../../base/i18n/functions';
|
import { translate } from '../../../base/i18n/functions';
|
||||||
import { connect } from '../../../base/redux/functions';
|
|
||||||
import { updateSettings } from '../../../base/settings/actions';
|
import { updateSettings } from '../../../base/settings/actions';
|
||||||
import Button from '../../../base/ui/components/web/Button';
|
import Button from '../../../base/ui/components/web/Button';
|
||||||
import Input from '../../../base/ui/components/web/Input';
|
import Input from '../../../base/ui/components/web/Input';
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
// @flow
|
|
||||||
|
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
|
|
||||||
import { isIosMobileBrowser } from '../../../base/environment/utils';
|
import { isIosMobileBrowser } from '../../../base/environment/utils';
|
|
@ -1,10 +1,10 @@
|
||||||
import { Theme } from '@mui/material';
|
import { Theme } from '@mui/material';
|
||||||
import { withStyles } from '@mui/styles';
|
import { withStyles } from '@mui/styles';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
import { translate } from '../../../base/i18n/functions';
|
import { translate } from '../../../base/i18n/functions';
|
||||||
import { IconCloseLarge } from '../../../base/icons/svg';
|
import { IconCloseLarge } from '../../../base/icons/svg';
|
||||||
import { connect } from '../../../base/redux/functions';
|
|
||||||
import { withPixelLineHeight } from '../../../base/styles/functions.web';
|
import { withPixelLineHeight } from '../../../base/styles/functions.web';
|
||||||
import Button from '../../../base/ui/components/web/Button';
|
import Button from '../../../base/ui/components/web/Button';
|
||||||
import { BUTTON_TYPES } from '../../../base/ui/constants.any';
|
import { BUTTON_TYPES } from '../../../base/ui/constants.any';
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
// @flow
|
|
||||||
|
|
||||||
import React, { PureComponent } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import Emoji from 'react-emoji-render';
|
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
|
* Callback to invoke when a smiley is selected. The smiley will be passed
|
||||||
* back.
|
* back.
|
||||||
*/
|
*/
|
||||||
onSmileySelect: Function
|
onSmileySelect: Function;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -38,8 +36,6 @@ class SmileysPanel extends PureComponent<Props> {
|
||||||
this._onEscKey = this._onEscKey.bind(this);
|
this._onEscKey = this._onEscKey.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
_onEscKey: (Object) => void;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* KeyPress handler for accessibility.
|
* KeyPress handler for accessibility.
|
||||||
*
|
*
|
||||||
|
@ -47,7 +43,7 @@ class SmileysPanel extends PureComponent<Props> {
|
||||||
*
|
*
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
_onEscKey(e) {
|
_onEscKey(e: React.KeyboardEvent) {
|
||||||
// Escape handling does not work in onKeyPress
|
// Escape handling does not work in onKeyPress
|
||||||
if (e.key === 'Escape') {
|
if (e.key === 'Escape') {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
@ -56,8 +52,6 @@ class SmileysPanel extends PureComponent<Props> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_onKeyPress: (Object) => void;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* KeyPress handler for accessibility.
|
* KeyPress handler for accessibility.
|
||||||
*
|
*
|
||||||
|
@ -65,15 +59,13 @@ class SmileysPanel extends PureComponent<Props> {
|
||||||
*
|
*
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
_onKeyPress(e) {
|
_onKeyPress(e: any) {
|
||||||
if (e.key === ' ') {
|
if (e.key === ' ') {
|
||||||
e.preventDefault();
|
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.
|
* Click handler for to select emoji.
|
||||||
*
|
*
|
||||||
|
@ -81,9 +73,9 @@ class SmileysPanel extends PureComponent<Props> {
|
||||||
*
|
*
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
_onClick(e) {
|
_onClick(e: React.MouseEvent) {
|
||||||
e.preventDefault();
|
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 }>
|
tabIndex = { 0 }>
|
||||||
<Emoji
|
<Emoji
|
||||||
onlyEmojiClassName = 'smiley'
|
onlyEmojiClassName = 'smiley'
|
||||||
text = { smileys[smileyKey] } />
|
text = { smileys[smileyKey as keyof typeof smileys] } />
|
||||||
</div>
|
</div>
|
||||||
));
|
));
|
||||||
|
|
Loading…
Reference in New Issue