"Fossies" - the Fresh Open Source Software Archive 
Member "jitsi-meet-7319/react/features/video-menu/components/web/RemoteVideoMenuTriggerButton.tsx" (6 Jun 2023, 8069 Bytes) of package /linux/misc/jitsi-meet-7319.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 "RemoteVideoMenuTriggerButton.tsx":
jitsi-meet_8319_vs_jitsi-meet_8615.
1 import React, { useCallback } from 'react';
2 import { useTranslation } from 'react-i18next';
3 import { batch, connect } from 'react-redux';
4 import { makeStyles } from 'tss-react/mui';
5
6 import { IReduxState, IStore } from '../../../app/types';
7 import { isMobileBrowser } from '../../../base/environment/utils';
8 import { IconDotsHorizontal } from '../../../base/icons/svg';
9 import { getLocalParticipant, getParticipantById } from '../../../base/participants/functions';
10 import { IParticipant } from '../../../base/participants/types';
11 import Popover from '../../../base/popover/components/Popover.web';
12 import { setParticipantContextMenuOpen } from '../../../base/responsive-ui/actions';
13 import Button from '../../../base/ui/components/web/Button';
14 import ConnectionIndicatorContent from
15 '../../../connection-indicator/components/web/ConnectionIndicatorContent';
16 import { THUMBNAIL_TYPE } from '../../../filmstrip/constants';
17 import { renderConnectionStatus } from '../../actions.web';
18
19 import FakeParticipantContextMenu from './FakeParticipantContextMenu';
20 import ParticipantContextMenu from './ParticipantContextMenu';
21 import { REMOTE_CONTROL_MENU_STATES } from './RemoteControlButton';
22
23 /**
24 * The type of the React {@code Component} props of
25 * {@link RemoteVideoMenuTriggerButton}.
26 */
27 interface IProps {
28
29 /**
30 * Whether the remote video context menu is disabled.
31 */
32 _disabled: Boolean;
33
34 /**
35 * Shared video local participant owner.
36 */
37 _localVideoOwner?: boolean;
38
39 /**
40 * The position relative to the trigger the remote menu should display
41 * from.
42 */
43 _menuPosition: string;
44
45 /**
46 * Participant reference.
47 */
48 _participant: IParticipant;
49
50 /**
51 * The ID for the participant on which the remote video menu will act.
52 */
53 _participantDisplayName: string;
54
55 /**
56 * The current state of the participant's remote control session.
57 */
58 _remoteControlState?: number;
59
60 /**
61 * Whether the popover should render the Connection Info stats.
62 */
63 _showConnectionInfo: Boolean;
64
65 /**
66 * Whether or not the button should be visible.
67 */
68 buttonVisible: boolean;
69
70 /**
71 * The redux dispatch function.
72 */
73 dispatch: IStore['dispatch'];
74
75 /**
76 * Hides popover.
77 */
78 hidePopover?: Function;
79
80 /**
81 * The ID for the participant on which the remote video menu will act.
82 */
83 participantID: string;
84
85 /**
86 * Whether the popover is visible or not.
87 */
88 popoverVisible?: boolean;
89
90 /**
91 * Shows popover.
92 */
93 showPopover?: Function;
94
95 /**
96 * The type of the thumbnail.
97 */
98 thumbnailType: string;
99 }
100
101 const useStyles = makeStyles()(() => {
102 return {
103 triggerButton: {
104 padding: '3px !important',
105 borderRadius: '4px',
106
107 '& svg': {
108 width: '18px',
109 height: '18px'
110 }
111 },
112
113 contextMenu: {
114 position: 'relative',
115 marginTop: 0,
116 right: 'auto',
117 marginRight: '4px',
118 marginBottom: '4px'
119 }
120 };
121 });
122
123 const RemoteVideoMenuTriggerButton = ({
124 _disabled,
125 _localVideoOwner,
126 _menuPosition,
127 _participant,
128 _participantDisplayName,
129 _remoteControlState,
130 _showConnectionInfo,
131 buttonVisible,
132 dispatch,
133 hidePopover,
134 participantID,
135 popoverVisible,
136 showPopover
137 }: IProps) => {
138 const { classes } = useStyles();
139 const { t } = useTranslation();
140
141 const _onPopoverOpen = useCallback(() => {
142 showPopover?.();
143 dispatch(setParticipantContextMenuOpen(true));
144 }, []);
145
146 const _onPopoverClose = useCallback(() => {
147 hidePopover?.();
148 batch(() => {
149 dispatch(setParticipantContextMenuOpen(false));
150 dispatch(renderConnectionStatus(false));
151 });
152 }, []);
153
154 // eslint-disable-next-line react/no-multi-comp
155 const _renderRemoteVideoMenu = () => {
156 const props = {
157 className: classes.contextMenu,
158 onSelect: _onPopoverClose,
159 participant: _participant,
160 thumbnailMenu: true
161 };
162
163 if (_participant?.fakeParticipant) {
164 return (
165 <FakeParticipantContextMenu
166 { ...props }
167 localVideoOwner = { _localVideoOwner } />
168 );
169 }
170
171 return (
172 <ParticipantContextMenu
173 { ...props }
174 remoteControlState = { _remoteControlState } />
175 );
176 };
177
178 let content;
179
180 if (_showConnectionInfo) {
181 content = <ConnectionIndicatorContent participantId = { participantID } />;
182 } else if (!_disabled) {
183 content = _renderRemoteVideoMenu();
184 }
185
186 if (!content) {
187 return null;
188 }
189
190 const username = _participantDisplayName;
191
192 return (
193 <Popover
194 content = { content }
195 headingLabel = { t('dialog.remoteUserControls', { username }) }
196 id = 'remote-video-menu-trigger'
197 onPopoverClose = { _onPopoverClose }
198 onPopoverOpen = { _onPopoverOpen }
199 position = { _menuPosition }
200 visible = { Boolean(popoverVisible) }>
201 {buttonVisible && !_disabled && (
202 !isMobileBrowser() && <Button
203 accessibilityLabel = { t('dialog.remoteUserControls', { username }) }
204 className = { classes.triggerButton }
205 icon = { IconDotsHorizontal }
206 size = 'small' />
207 )}
208 </Popover>
209 );
210 };
211
212 /**
213 * Maps (parts of) the Redux state to the associated {@code RemoteVideoMenuTriggerButton}'s props.
214 *
215 * @param {Object} state - The Redux state.
216 * @param {Object} ownProps - The own props of the component.
217 * @private
218 * @returns {IProps}
219 */
220 function _mapStateToProps(state: IReduxState, ownProps: Partial<IProps>) {
221 const { participantID, thumbnailType } = ownProps;
222 let _remoteControlState;
223 const localParticipantId = getLocalParticipant(state)?.id;
224 const participant = getParticipantById(state, participantID ?? '');
225 const _participantDisplayName = participant?.name;
226 const _isRemoteControlSessionActive = participant?.remoteControlSessionStatus ?? false;
227 const _supportsRemoteControl = participant?.supportsRemoteControl ?? false;
228 const { active, controller } = state['features/remote-control'];
229 const { requestedParticipant, controlled } = controller;
230 const activeParticipant = requestedParticipant || controlled;
231 const { showConnectionInfo } = state['features/base/connection'];
232 const { remoteVideoMenu } = state['features/base/config'];
233 const { ownerId } = state['features/shared-video'];
234
235 if (_supportsRemoteControl
236 && ((!active && !_isRemoteControlSessionActive) || activeParticipant === participantID)) {
237 if (requestedParticipant === participantID) {
238 _remoteControlState = REMOTE_CONTROL_MENU_STATES.REQUESTING;
239 } else if (controlled) {
240 _remoteControlState = REMOTE_CONTROL_MENU_STATES.STARTED;
241 } else {
242 _remoteControlState = REMOTE_CONTROL_MENU_STATES.NOT_STARTED;
243 }
244 }
245
246 let _menuPosition;
247
248 switch (thumbnailType) {
249 case THUMBNAIL_TYPE.TILE:
250 _menuPosition = 'left-start';
251 break;
252 case THUMBNAIL_TYPE.VERTICAL:
253 _menuPosition = 'left-end';
254 break;
255 case THUMBNAIL_TYPE.HORIZONTAL:
256 _menuPosition = 'top';
257 break;
258 default:
259 _menuPosition = 'auto';
260 }
261
262 return {
263 _disabled: Boolean(remoteVideoMenu?.disabled),
264 _localVideoOwner: Boolean(ownerId === localParticipantId),
265 _menuPosition,
266 _participant: participant ?? { id: '' },
267 _participantDisplayName: _participantDisplayName ?? '',
268 _remoteControlState,
269 _showConnectionInfo: Boolean(showConnectionInfo)
270 };
271 }
272
273 export default connect(_mapStateToProps)(RemoteVideoMenuTriggerButton);