feat(reactions) Added Reactions (#9465)

* Created desktop reactions menu

Moved raise hand functionality to reactions menu

* Added reactions to chat

* Added animations

* Added reactions to the web mobile version

Redesigned the overflow menu. Added the reactions menu and reactions animations

* Make toolbar visible on animation start

* Bug fix

* Cleanup

* Fixed overflow menu desktop

* Revert mobile menu changes

* Removed unused CSS

* Fixed iOS safari issue

* Fixed overflow issue on mobile

* Added keyboard shortcuts for reactions

* Disabled double tap zoom on reaction buttons

* Refactored actions

* Updated option symbol for keyboard shortcuts

* Actions refactor

* Refactor

* Fixed linting errors

* Updated BottomSheet

* Added reactions on native

* Code cleanup

* Code review refactor

* Color fix

* Hide reactions on one participant

* Removed console log

* Lang fix

* Update schortcuts
This commit is contained in:
robertpin
2021-07-13 09:50:08 +03:00
committed by GitHub
parent 8db3a341b3
commit 601ee219e7
50 changed files with 2233 additions and 363 deletions

View File

@@ -1,17 +1,15 @@
// @flow
import React, { PureComponent } from 'react';
import { TouchableOpacity, View } from 'react-native';
import Collapsible from 'react-native-collapsible';
import { ColorSchemeRegistry } from '../../../base/color-scheme';
import { BottomSheet, hideDialog, isDialogOpen } from '../../../base/dialog';
import { IconDragHandle } from '../../../base/icons';
import { connect } from '../../../base/redux';
import { StyleType } from '../../../base/styles';
import { SharedDocumentButton } from '../../../etherpad';
import { InviteButton } from '../../../invite';
import { AudioRouteButton } from '../../../mobile/audio-mode';
import { ReactionMenu } from '../../../reactions/components';
import { LiveStreamButton, RecordButton } from '../../../recording';
import SecurityDialogButton from '../../../security/components/security-dialog/SecurityDialogButton';
import { SharedVideoButton } from '../../../shared-video/components';
@@ -23,11 +21,8 @@ import MuteEveryoneButton from '../MuteEveryoneButton';
import MuteEveryonesVideoButton from '../MuteEveryonesVideoButton';
import AudioOnlyButton from './AudioOnlyButton';
import MoreOptionsButton from './MoreOptionsButton';
import RaiseHandButton from './RaiseHandButton';
import ScreenSharingButton from './ScreenSharingButton.js';
import ToggleCameraButton from './ToggleCameraButton';
import styles from './styles';
/**
* The type of the React {@code Component} props of {@link OverflowMenu}.
@@ -65,12 +60,7 @@ type State = {
/**
* True if the bottom scheet is scrolled to the top.
*/
scrolledToTop: boolean,
/**
* True if the 'more' button set needas to be rendered.
*/
showMore: boolean
scrolledToTop: boolean
}
/**
@@ -96,15 +86,12 @@ class OverflowMenu extends PureComponent<Props, State> {
super(props);
this.state = {
scrolledToTop: true,
showMore: false
scrolledToTop: true
};
// Bind event handlers so they are only bound once per instance.
this._onCancel = this._onCancel.bind(this);
this._onSwipe = this._onSwipe.bind(this);
this._onToggleMenu = this._onToggleMenu.bind(this);
this._renderMenuExpandToggle = this._renderMenuExpandToggle.bind(this);
this._renderReactionMenu = this._renderReactionMenu.bind(this);
}
/**
@@ -115,7 +102,6 @@ class OverflowMenu extends PureComponent<Props, State> {
*/
render() {
const { _bottomSheetStyles, _width } = this.props;
const { showMore } = this.state;
const toolbarButtons = getMovableButtons(_width);
const buttonProps = {
@@ -124,63 +110,45 @@ class OverflowMenu extends PureComponent<Props, State> {
styles: _bottomSheetStyles.buttons
};
const moreOptionsButtonProps = {
...buttonProps,
afterClick: this._onToggleMenu,
visible: !showMore
const topButtonProps = {
afterClick: this._onCancel,
showLabel: true,
styles: {
..._bottomSheetStyles.buttons,
style: {
..._bottomSheetStyles.buttons.style,
borderTopLeftRadius: 16,
borderTopRightRadius: 16,
paddingTop: 16
}
}
};
return (
<BottomSheet
onCancel = { this._onCancel }
onSwipe = { this._onSwipe }
renderHeader = { this._renderMenuExpandToggle }>
<AudioRouteButton { ...buttonProps } />
renderFooter = { toolbarButtons.has('raisehand')
? null
: this._renderReactionMenu }>
<AudioRouteButton { ...topButtonProps } />
{!toolbarButtons.has('invite') && <InviteButton { ...buttonProps } />}
<AudioOnlyButton { ...buttonProps } />
{!toolbarButtons.has('raisehand') && <RaiseHandButton { ...buttonProps } />}
<SecurityDialogButton { ...buttonProps } />
<ScreenSharingButton { ...buttonProps } />
<MoreOptionsButton { ...moreOptionsButtonProps } />
<Collapsible collapsed = { !showMore }>
{!toolbarButtons.has('togglecamera') && <ToggleCameraButton { ...buttonProps } />}
{!toolbarButtons.has('tileview') && <TileViewButton { ...buttonProps } />}
<RecordButton { ...buttonProps } />
<LiveStreamButton { ...buttonProps } />
<SharedVideoButton { ...buttonProps } />
<ClosedCaptionButton { ...buttonProps } />
<SharedDocumentButton { ...buttonProps } />
<MuteEveryoneButton { ...buttonProps } />
<MuteEveryonesVideoButton { ...buttonProps } />
<HelpButton { ...buttonProps } />
</Collapsible>
{!toolbarButtons.has('togglecamera') && <ToggleCameraButton { ...buttonProps } />}
{!toolbarButtons.has('tileview') && <TileViewButton { ...buttonProps } />}
<RecordButton { ...buttonProps } />
<LiveStreamButton { ...buttonProps } />
<SharedVideoButton { ...buttonProps } />
<ClosedCaptionButton { ...buttonProps } />
<SharedDocumentButton { ...buttonProps } />
<MuteEveryoneButton { ...buttonProps } />
<MuteEveryonesVideoButton { ...buttonProps } />
<HelpButton { ...buttonProps } />
</BottomSheet>
);
}
_renderMenuExpandToggle: () => React$Element<any>;
/**
* Function to render the menu toggle in the bottom sheet header area.
*
* @returns {React$Element}
*/
_renderMenuExpandToggle() {
return (
<View
style = { [
this.props._bottomSheetStyles.sheet,
styles.expandMenuContainer
] }>
<TouchableOpacity onPress = { this._onToggleMenu }>
{ /* $FlowFixMe */ }
<IconDragHandle
fill = { this.props._bottomSheetStyles.buttons.iconStyle.color } />
</TouchableOpacity>
</View>
);
}
_onCancel: () => boolean;
/**
@@ -199,45 +167,17 @@ class OverflowMenu extends PureComponent<Props, State> {
return false;
}
_onSwipe: string => void;
_renderReactionMenu: () => React$Element<any>;
/**
* Callback to be invoked when swipe gesture is detected on the menu. Returns true
* if the swipe gesture is handled by the menu, false otherwise.
* Functoin to render the reaction menu as the footer of the bottom sheet.
*
* @param {string} direction - Direction of 'up' or 'down'.
* @returns {boolean}
* @returns {React$Element}
*/
_onSwipe(direction) {
const { showMore } = this.state;
switch (direction) {
case 'up':
!showMore && this.setState({
showMore: true
});
return !showMore;
case 'down':
showMore && this.setState({
showMore: false
});
return showMore;
}
}
_onToggleMenu: () => void;
/**
* Callback to be invoked when the expand menu button is pressed.
*
* @returns {void}
*/
_onToggleMenu() {
this.setState({
showMore: !this.state.showMore
});
_renderReactionMenu() {
return (<ReactionMenu
onCancel = { this._onCancel }
overflowMenu = { true } />);
}
}