Skip to content

Commit

Permalink
ref(toolbar) Move getButtons to functions (#13502)
Browse files Browse the repository at this point in the history
Move visible logic inside each button
Move click functionality inside each button
Extract getButtons function from Toolbox components to functions file
  • Loading branch information
robertpin authored Jun 29, 2023
1 parent 699b797 commit 2d80147
Show file tree
Hide file tree
Showing 21 changed files with 637 additions and 726 deletions.
22 changes: 22 additions & 0 deletions react/features/chat/components/web/ChatButton.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import React from 'react';
import { connect } from 'react-redux';

import { createToolbarEvent } from '../../../analytics/AnalyticsEvents';
import { sendAnalytics } from '../../../analytics/functions';
import { IReduxState } from '../../../app/types';
import { translate } from '../../../base/i18n/functions';
import { IconMessage } from '../../../base/icons/svg';
import AbstractButton, { IProps as AbstractButtonProps } from '../../../base/toolbox/components/AbstractButton';
import { closeOverflowMenuIfOpen } from '../../../toolbox/actions.web';
import { toggleChat } from '../../actions.web';

import ChatCounter from './ChatCounter';

Expand Down Expand Up @@ -59,6 +63,24 @@ class ChatButton extends AbstractButton<IProps> {
</div>
);
}

/**
* Handles clicking the button, and toggles the chat.
*
* @private
* @returns {void}
*/
_handleClick() {
const { dispatch } = this.props;

sendAnalytics(createToolbarEvent(
'toggle.chat',
{
enable: !this.props._chatOpen
}));
dispatch(closeOverflowMenuIfOpen());
dispatch(toggleChat());
}
}

/**
Expand Down
17 changes: 16 additions & 1 deletion react/features/embed-meeting/components/EmbedMeetingButton.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ import { connect } from 'react-redux';

import { createToolbarEvent } from '../../analytics/AnalyticsEvents';
import { sendAnalytics } from '../../analytics/functions';
import { IReduxState } from '../../app/types';
import { openDialog } from '../../base/dialog/actions';
import { isMobileBrowser } from '../../base/environment/utils';
import { translate } from '../../base/i18n/functions';
import { IconCode } from '../../base/icons/svg';
import AbstractButton, { IProps as AbstractButtonProps } from '../../base/toolbox/components/AbstractButton';
import { isVpaasMeeting } from '../../jaas/functions';

import EmbedMeetingDialog from './EmbedMeetingDialog';

Expand All @@ -32,4 +35,16 @@ class EmbedMeetingButton extends AbstractButton<AbstractButtonProps> {
}
}

export default translate(connect()(EmbedMeetingButton));
/**
* Function that maps parts of Redux state tree into component props.
*
* @param {Object} state - Redux state.
* @returns {Object}
*/
const mapStateToProps = (state: IReduxState) => {
return {
visible: !isVpaasMeeting(state) && !isMobileBrowser()
};
};

export default translate(connect(mapStateToProps)(EmbedMeetingButton));
5 changes: 4 additions & 1 deletion react/features/feedback/components/FeedbackButton.web.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,11 @@ class FeedbackButton extends AbstractButton<IProps> {
}

const mapStateToProps = (state: IReduxState) => {
const { callStatsID } = state['features/base/config'];

return {
_conference: state['features/base/conference'].conference
_conference: state['features/base/conference'].conference,
visible: Boolean(callStatsID)
};
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@ import { connect } from 'react-redux';

import { createToolbarEvent } from '../../../analytics/AnalyticsEvents';
import { sendAnalytics } from '../../../analytics/functions';
import { IReduxState } from '../../../app/types';
import { isMobileBrowser } from '../../../base/environment/utils';
import { translate } from '../../../base/i18n/functions';
import { IconShortcuts } from '../../../base/icons/svg';
import AbstractButton, { IProps as AbstractButtonProps } from '../../../base/toolbox/components/AbstractButton';
import { openSettingsDialog } from '../../../settings/actions';
import { SETTINGS_TABS } from '../../../settings/constants';
import { areKeyboardShortcutsEnabled } from '../../functions';

/**
* Implementation of a button for opening keyboard shortcuts dialog.
Expand All @@ -31,4 +34,16 @@ class KeyboardShortcutsButton extends AbstractButton<AbstractButtonProps> {
}
}

export default translate(connect()(KeyboardShortcutsButton));
/**
* Function that maps parts of Redux state tree into component props.
*
* @param {Object} state - Redux state.
* @returns {Object}
*/
const mapStateToProps = (state: IReduxState) => {
return {
visible: !isMobileBrowser() && areKeyboardShortcutsEnabled(state)
};
};

export default translate(connect(mapStateToProps)(KeyboardShortcutsButton));
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import { IReduxState } from '../../../app/types';
import { translate } from '../../../base/i18n/functions';
import { IconUsers } from '../../../base/icons/svg';
import AbstractButton, { IProps as AbstractButtonProps } from '../../../base/toolbox/components/AbstractButton';
import {
close as closeParticipantsPane,
open as openParticipantsPane
} from '../../../participants-pane/actions.web';

import ParticipantsCounter from './ParticipantsCounter';

Expand Down Expand Up @@ -41,6 +45,22 @@ class ParticipantsPaneButton extends AbstractButton<IProps> {
return this.props._isOpen;
}

/**
* Handles clicking the button, and toggles the participants pane.
*
* @private
* @returns {void}
*/
_handleClick() {
const { dispatch, _isOpen } = this.props;

if (_isOpen) {
dispatch(closeParticipantsPane());
} else {
dispatch(openParticipantsPane());
}
}

/**
* Overrides AbstractButton's {@link Component#render()}.
*
Expand Down
19 changes: 19 additions & 0 deletions react/features/reactions/components/web/RaiseHandButton.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { connect } from 'react-redux';

import { createToolbarEvent } from '../../../analytics/AnalyticsEvents';
import { sendAnalytics } from '../../../analytics/functions';
import { IReduxState } from '../../../app/types';
import { translate } from '../../../base/i18n/functions';
import { IconRaiseHand } from '../../../base/icons/svg';
import { raiseHand } from '../../../base/participants/actions';
import { getLocalParticipant, hasRaisedHand } from '../../../base/participants/functions';
import AbstractButton, { IProps as AbstractButtonProps } from '../../../base/toolbox/components/AbstractButton';

Expand Down Expand Up @@ -40,6 +43,22 @@ class RaiseHandButton extends AbstractButton<IProps> {
_isToggled() {
return this.props.raisedHand;
}

/**
* Handles clicking the button, and toggles the raise hand.
*
* @private
* @returns {void}
*/
_handleClick() {
const { dispatch, raisedHand } = this.props;

sendAnalytics(createToolbarEvent(
'raise.hand',
{ enable: !raisedHand }));

dispatch(raiseHand(!raisedHand));
}
}


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React from 'react';
import { useSelector } from 'react-redux';

import { IReduxState } from '../../../app/types';
import { isMobileBrowser } from '../../../base/environment/utils';
import { IProps as AbstractButtonProps } from '../../../base/toolbox/components/AbstractButton';
import { isReactionsButtonEnabled, isReactionsEnabled } from '../../functions.web';

import RaiseHandButton from './RaiseHandButton';
import ReactionsMenuButton from './ReactionsMenuButton';

const RaiseHandContainerButton = (props: AbstractButtonProps) => {
const reactionsButtonEnabled = useSelector(isReactionsButtonEnabled);
const reactionsEnabled = useSelector(isReactionsEnabled);
const isNarrowLayout = useSelector((state: IReduxState) => state['features/base/responsive-ui'].isNarrowLayout);
const showReactionsAsPartOfRaiseHand
= !reactionsButtonEnabled && reactionsEnabled && !isNarrowLayout && !isMobileBrowser();

return showReactionsAsPartOfRaiseHand
? <ReactionsMenuButton
{ ...props }
showRaiseHand = { true } />
: <RaiseHandButton { ...props } />;
};

export default RaiseHandContainerButton;
68 changes: 46 additions & 22 deletions react/features/reactions/components/web/ReactionsMenuButton.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import React, { ReactElement, useCallback } from 'react';
import React, { ReactElement, useCallback, useMemo } from 'react';
import { WithTranslation } from 'react-i18next';
import { connect } from 'react-redux';
import { connect, useSelector } from 'react-redux';

import { createToolbarEvent } from '../../../analytics/AnalyticsEvents';
import { sendAnalytics } from '../../../analytics/functions';
import { IReduxState, IStore } from '../../../app/types';
import { isMobileBrowser } from '../../../base/environment/utils';
import { translate } from '../../../base/i18n/functions';
import { IconArrowUp, IconFaceSmile } from '../../../base/icons/svg';
import { raiseHand } from '../../../base/participants/actions';
import { getLocalParticipant, hasRaisedHand } from '../../../base/participants/functions';
import AbstractButton, { type IProps as AbstractButtonProps } from '../../../base/toolbox/components/AbstractButton';
import ToolboxButtonWithPopup from '../../../base/toolbox/components/web/ToolboxButtonWithPopup';
import { toggleReactionsMenuVisibility } from '../../actions.web';
Expand All @@ -30,6 +34,11 @@ interface IProps extends WithTranslation {
*/
_reactionsButtonEnabled: boolean;

/**
* Whether or not the reactions are enabled.
*/
_reactionsEnabled: boolean;

/**
* The button's key.
*/
Expand All @@ -40,11 +49,6 @@ interface IProps extends WithTranslation {
*/
dispatch: IStore['dispatch'];

/**
* Click handler for raise hand functionality.
*/
handleClick: Function;

/**
* Whether or not it's narrow mode or mobile browser.
*/
Expand All @@ -65,6 +69,11 @@ interface IProps extends WithTranslation {
* The array of reactions to be displayed.
*/
reactionsQueue: Array<IReactionEmojiProps>;

/**
* Whether or not to show the raise hand button.
*/
showRaiseHand?: boolean;
}


Expand All @@ -88,14 +97,15 @@ const ReactionsButton = translate(connect()(ReactionsButtonImpl));
*/
function ReactionsMenuButton({
_reactionsButtonEnabled,
_reactionsEnabled,
_isMobile,
buttonKey,
dispatch,
handleClick,
isOpen,
isNarrow,
notifyMode,
reactionsQueue,
showRaiseHand,
t
}: IProps) {
const toggleReactionsMenu = useCallback(() => {
Expand All @@ -110,26 +120,27 @@ function ReactionsMenuButton({
isOpen && toggleReactionsMenu();
}, [ isOpen, toggleReactionsMenu ]);

const localParticipant = useSelector(getLocalParticipant);
const raisedHand = useMemo(() => hasRaisedHand(localParticipant), [ localParticipant ]);
const handleClick = useCallback(() => {
sendAnalytics(createToolbarEvent(
'raise.hand',
{ enable: !raisedHand }));

dispatch(raiseHand(!raisedHand));
}, [ raisedHand ]);

if (!showRaiseHand && (!_reactionsButtonEnabled || !_reactionsEnabled)) {
return null;
}

const reactionsMenu = (<div className = 'reactions-menu-container'>
<ReactionsMenu parent = { IReactionsMenuParent.Button } />
</div>);

let content: ReactElement | null = null;

if (_reactionsButtonEnabled) {
content = (
<ToolboxButtonWithPopup
ariaLabel = { t('toolbar.accessibilityLabel.reactionsMenu') }
onPopoverClose = { closeReactionsMenu }
onPopoverOpen = { openReactionsMenu }
popoverContent = { reactionsMenu }
trigger = { _isMobile ? 'click' : undefined }
visible = { isOpen }>
<ReactionsButton
buttonKey = { buttonKey }
notifyMode = { notifyMode } />
</ToolboxButtonWithPopup>);
} else {
if (showRaiseHand) {
content = isNarrow
? (
<RaiseHandButton
Expand All @@ -150,6 +161,19 @@ function ReactionsMenuButton({
handleClick = { handleClick }
notifyMode = { notifyMode } />
</ToolboxButtonWithPopup>);
} else {
content = (
<ToolboxButtonWithPopup
ariaLabel = { t('toolbar.accessibilityLabel.reactionsMenu') }
onPopoverClose = { closeReactionsMenu }
onPopoverOpen = { openReactionsMenu }
popoverContent = { reactionsMenu }
trigger = { _isMobile ? 'click' : undefined }
visible = { isOpen }>
<ReactionsButton
buttonKey = { buttonKey }
notifyMode = { notifyMode } />
</ToolboxButtonWithPopup>);
}

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ import { connect } from 'react-redux';
import { IReduxState } from '../../../app/types';
import { translate } from '../../../base/i18n/functions';
import { IconVolumeOff, IconVolumeUp } from '../../../base/icons/svg';
import JitsiMeetJS from '../../../base/lib-jitsi-meet';
import AbstractButton, { IProps as AbstractButtonProps } from '../../../base/toolbox/components/AbstractButton';
import { setOverflowMenuVisible } from '../../../toolbox/actions.web';
import { startAudioScreenShareFlow } from '../../actions.web';
import { isAudioOnlySharing } from '../../functions';
import { isAudioOnlySharing, isScreenAudioSupported } from '../../functions';

interface IProps extends AbstractButtonProps {

Expand Down Expand Up @@ -62,7 +63,8 @@ class ShareAudioButton extends AbstractButton<IProps> {
function _mapStateToProps(state: IReduxState) {

return {
_isAudioOnlySharing: Boolean(isAudioOnlySharing(state))
_isAudioOnlySharing: Boolean(isAudioOnlySharing(state)),
visible: JitsiMeetJS.isDesktopSharingEnabled() && isScreenAudioSupported()
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ import { connect } from 'react-redux';

import { createToolbarEvent } from '../../../analytics/AnalyticsEvents';
import { sendAnalytics } from '../../../analytics/functions';
import { IReduxState } from '../../../app/types';
import { openDialog } from '../../../base/dialog/actions';
import { translate } from '../../../base/i18n/functions';
import { isSpeakerStatsDisabled } from '../../functions';
import AbstractSpeakerStatsButton from '../AbstractSpeakerStatsButton';

import SpeakerStats from './SpeakerStats';
Expand All @@ -28,4 +30,16 @@ class SpeakerStatsButton extends AbstractSpeakerStatsButton {
}
}

export default translate(connect()(SpeakerStatsButton));
/**
* Function that maps parts of Redux state tree into component props.
*
* @param {Object} state - Redux state.
* @returns {Object}
*/
const mapStateToProps = (state: IReduxState) => {
return {
visible: !isSpeakerStatsDisabled(state)
};
};

export default translate(connect(mapStateToProps)(SpeakerStatsButton));
Loading

0 comments on commit 2d80147

Please sign in to comment.