"Fossies" - the Fresh Open Source Software Archive 
Member "jitsi-meet-7307/react/features/reactions/components/web/ReactionsMenu.tsx" (30 May 2023, 8087 Bytes) of package /linux/misc/jitsi-meet-7307.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) TSX (TypeScript with React) source code syntax highlighting (style:
standard) with prefixed line numbers.
Alternatively you can here
view or
download the uninterpreted source code file.
See also the last
Fossies "Diffs" side-by-side code changes report for "ReactionsMenu.tsx":
jitsi-meet_8319_vs_jitsi-meet_8615.
1 import React, { useCallback, useEffect } from 'react';
2 import { useTranslation } from 'react-i18next';
3 import { connect } from 'react-redux';
4 import { makeStyles } from 'tss-react/mui';
5
6 import { createReactionMenuEvent, createToolbarEvent } from '../../../analytics/AnalyticsEvents';
7 import { sendAnalytics } from '../../../analytics/functions';
8 import { IReduxState, IStore } from '../../../app/types';
9 import { raiseHand } from '../../../base/participants/actions';
10 import { getLocalParticipant, hasRaisedHand } from '../../../base/participants/functions';
11 import GifsMenu from '../../../gifs/components/web/GifsMenu';
12 import GifsMenuButton from '../../../gifs/components/web/GifsMenuButton';
13 import { isGifEnabled, isGifsMenuOpen } from '../../../gifs/functions';
14 import { dockToolbox } from '../../../toolbox/actions.web';
15 import { addReactionToBuffer } from '../../actions.any';
16 import { toggleReactionsMenuVisibility } from '../../actions.web';
17 import {
18 GIFS_MENU_HEIGHT_IN_OVERFLOW_MENU,
19 RAISE_HAND_ROW_HEIGHT, REACTIONS,
20 REACTIONS_MENU_HEIGHT_DRAWER,
21 REACTIONS_MENU_HEIGHT_IN_OVERFLOW_MENU
22 } from '../../constants';
23 import { IReactionsMenuParent } from '../../types';
24
25 import ReactionButton from './ReactionButton';
26
27 interface IProps {
28
29 /**
30 * Docks the toolbox.
31 */
32 _dockToolbox: Function;
33
34 /**
35 * Whether or not the GIF feature is enabled.
36 */
37 _isGifEnabled: boolean;
38
39 /**
40 * Whether or not the GIF menu is visible.
41 */
42 _isGifMenuVisible: boolean;
43
44 /**
45 * The ID of the local participant.
46 */
47 _localParticipantID?: string;
48
49 /**
50 * Whether or not the local participant's hand is raised.
51 */
52 _raisedHand: boolean;
53
54 /**
55 * The Redux Dispatch function.
56 */
57 dispatch: IStore['dispatch'];
58
59 /**
60 * Indicates the parent of the reactions menu.
61 */
62 parent: IReactionsMenuParent;
63
64 /**
65 * Whether to show the raised hand button.
66 */
67 showRaisedHand?: boolean;
68 }
69
70 const useStyles = makeStyles<IProps>()((theme, props: IProps) => {
71 const { parent, showRaisedHand, _isGifMenuVisible } = props;
72 let reactionsMenuHeight = REACTIONS_MENU_HEIGHT_DRAWER;
73
74 if (parent === IReactionsMenuParent.OverflowDrawer || parent === IReactionsMenuParent.OverflowMenu) {
75 if (parent === IReactionsMenuParent.OverflowMenu) {
76 reactionsMenuHeight = REACTIONS_MENU_HEIGHT_IN_OVERFLOW_MENU;
77
78 if (_isGifMenuVisible) {
79 reactionsMenuHeight += GIFS_MENU_HEIGHT_IN_OVERFLOW_MENU;
80 }
81 }
82 if (!showRaisedHand) {
83 reactionsMenuHeight -= RAISE_HAND_ROW_HEIGHT;
84 }
85 }
86
87 return {
88 reactionsMenuInOverflowMenu: {
89 '&.reactions-menu': {
90 '&.with-gif': {
91 width: 'inherit'
92 },
93 '.reactions-row': {
94 '.toolbox-icon': {
95 width: '24px',
96 height: '24px',
97
98 'span.emoji': {
99 width: '24px',
100 height: '24px',
101 lineHeight: '24px',
102 fontSize: '16px'
103 }
104 }
105 },
106 '.raise-hand-row': {
107 '.toolbox-icon': {
108 height: '32px'
109 }
110 }
111 }
112 },
113 overflow: {
114 width: 'auto',
115 paddingBottom: 'max(env(safe-area-inset-bottom, 0), 16px)',
116 backgroundColor: theme.palette.ui01,
117 boxShadow: 'none',
118 borderRadius: 0,
119 position: 'relative',
120 boxSizing: 'border-box',
121 height: `${reactionsMenuHeight}px`
122 }
123 };
124 });
125
126 const _getReactionButtons = (dispatch: IStore['dispatch'], t: Function) => {
127 let modifierKey = 'Alt';
128
129 if (window.navigator?.platform) {
130 if (window.navigator.platform.indexOf('Mac') !== -1) {
131 modifierKey = '⌥';
132 }
133 }
134
135 return Object.keys(REACTIONS).map(key => {
136 /**
137 * Sends reaction message.
138 *
139 * @returns {void}
140 */
141 function doSendReaction() {
142 dispatch(addReactionToBuffer(key));
143 sendAnalytics(createReactionMenuEvent(key));
144 }
145
146 return (<ReactionButton
147 accessibilityLabel = { t(`toolbar.accessibilityLabel.${key}`) }
148 icon = { REACTIONS[key].emoji }
149 key = { key }
150 // eslint-disable-next-line react/jsx-no-bind
151 onClick = { doSendReaction }
152 toggled = { false }
153 tooltip = { `${t(`toolbar.${key}`)} (${modifierKey} + ${REACTIONS[key].shortcutChar})` } />);
154 });
155 };
156
157 const ReactionsMenu = (props: IProps) => {
158 const {
159 _dockToolbox,
160 _isGifEnabled,
161 _isGifMenuVisible,
162 _raisedHand,
163 dispatch,
164 parent,
165 showRaisedHand = false
166 } = props;
167 const isInOverflowMenu
168 = parent === IReactionsMenuParent.OverflowDrawer || parent === IReactionsMenuParent.OverflowMenu;
169 const { classes, cx } = useStyles(props);
170 const { t } = useTranslation();
171
172 useEffect(() => {
173 _dockToolbox(true);
174
175 return () => {
176 _dockToolbox(false);
177 };
178 }, []);
179
180 const _doToggleRaiseHand = useCallback(() => {
181 dispatch(raiseHand(!_raisedHand));
182 }, [ _raisedHand ]);
183
184 const _onToolbarToggleRaiseHand = useCallback(() => {
185 sendAnalytics(createToolbarEvent(
186 'raise.hand',
187 { enable: !_raisedHand }));
188 _doToggleRaiseHand();
189 dispatch(toggleReactionsMenuVisibility());
190 }, [ _raisedHand ]);
191
192 const buttons = _getReactionButtons(dispatch, t);
193
194 if (_isGifEnabled) {
195 buttons.push(<GifsMenuButton parent = { parent } />);
196 }
197
198 return (
199 <div
200 className = { cx('reactions-menu',
201 parent === IReactionsMenuParent.OverflowMenu && classes.reactionsMenuInOverflowMenu,
202 _isGifEnabled && 'with-gif',
203 isInOverflowMenu && `overflow ${classes.overflow}`) }>
204 {_isGifEnabled && _isGifMenuVisible
205 && <GifsMenu
206 columns = { parent === IReactionsMenuParent.OverflowMenu ? 1 : undefined }
207 parent = { parent } />}
208 <div className = 'reactions-row'>
209 { buttons }
210 </div>
211 {showRaisedHand && (
212 <div className = 'raise-hand-row'>
213 <ReactionButton
214 accessibilityLabel = { t('toolbar.accessibilityLabel.raiseHand') }
215 icon = '✋'
216 key = 'raisehand'
217 label = {
218 `${t(`toolbar.${_raisedHand ? 'lowerYourHand' : 'raiseYourHand'}`)}
219 ${isInOverflowMenu ? '' : ' (R)'}`
220 }
221 onClick = { _onToolbarToggleRaiseHand }
222 toggled = { true } />
223 </div>
224 )}
225 </div>
226 );
227 };
228
229 /**
230 * Function that maps parts of Redux state tree into component props.
231 *
232 * @param {Object} state - Redux state.
233 * @returns {Object}
234 */
235 function mapStateToProps(state: IReduxState) {
236 const localParticipant = getLocalParticipant(state);
237
238 return {
239 _localParticipantID: localParticipant?.id,
240 _isGifEnabled: isGifEnabled(state),
241 _isGifMenuVisible: isGifsMenuOpen(state),
242 _raisedHand: hasRaisedHand(localParticipant)
243 };
244 }
245
246 /**
247 * Function that maps parts of Redux actions into component props.
248 *
249 * @param {Object} dispatch - Redux dispatch.
250 * @returns {Object}
251 */
252 function mapDispatchToProps(dispatch: IStore['dispatch']) {
253 return {
254 dispatch,
255 _dockToolbox: (dock: boolean) => dispatch(dockToolbox(dock))
256 };
257 }
258
259 export default connect(mapStateToProps, mapDispatchToProps)(ReactionsMenu);