소스 검색

feat(raised-hand) Change `raisedHand` to a timestamp instead of boole… (#10167)

- this was needed for sorting the raised hand participants in participants pane in
the order they raised their hand also for participants joining late
master
Horatiu Muresan 4 년 전
부모
커밋
4b7a6741fa
No account linked to committer's email address

+ 3
- 2
modules/API/API.js 파일 보기

37
     kickParticipant,
37
     kickParticipant,
38
     raiseHand,
38
     raiseHand,
39
     isParticipantModerator,
39
     isParticipantModerator,
40
-    isLocalParticipantModerator
40
+    isLocalParticipantModerator,
41
+    hasRaisedHand
41
 } from '../../react/features/base/participants';
42
 } from '../../react/features/base/participants';
42
 import { updateSettings } from '../../react/features/base/settings';
43
 import { updateSettings } from '../../react/features/base/settings';
43
 import { isToggleCameraEnabled, toggleCamera } from '../../react/features/base/tracks';
44
 import { isToggleCameraEnabled, toggleCamera } from '../../react/features/base/tracks';
281
             if (!localParticipant) {
282
             if (!localParticipant) {
282
                 return;
283
                 return;
283
             }
284
             }
284
-            const { raisedHand } = localParticipant;
285
+            const raisedHand = hasRaisedHand(localParticipant);
285
 
286
 
286
             sendAnalytics(createApiEvent('raise-hand.toggled'));
287
             sendAnalytics(createApiEvent('raise-hand.toggled'));
287
             APP.store.dispatch(raiseHand(!raisedHand));
288
             APP.store.dispatch(raiseHand(!raisedHand));

+ 3
- 2
react/features/av-moderation/middleware.js 파일 보기

8
 import {
8
 import {
9
     getLocalParticipant,
9
     getLocalParticipant,
10
     getRemoteParticipants,
10
     getRemoteParticipants,
11
+    hasRaisedHand,
11
     isLocalParticipantModerator,
12
     isLocalParticipantModerator,
12
     isParticipantModerator,
13
     isParticipantModerator,
13
     PARTICIPANT_UPDATED,
14
     PARTICIPANT_UPDATED,
134
             if (isLocalParticipantModerator(state)) {
135
             if (isLocalParticipantModerator(state)) {
135
 
136
 
136
                 // this is handled only by moderators
137
                 // this is handled only by moderators
137
-                if (participant.raisedHand) {
138
+                if (hasRaisedHand(participant)) {
138
                     // if participant raises hand show notification
139
                     // if participant raises hand show notification
139
                     !isParticipantApproved(participant.id, MEDIA_TYPE.AUDIO)(state)
140
                     !isParticipantApproved(participant.id, MEDIA_TYPE.AUDIO)(state)
140
                     && dispatch(participantPendingAudio(participant));
141
                     && dispatch(participantPendingAudio(participant));
148
 
149
 
149
                 // this is the granted moderator case
150
                 // this is the granted moderator case
150
                 getRemoteParticipants(state).forEach(p => {
151
                 getRemoteParticipants(state).forEach(p => {
151
-                    p.raisedHand && !isParticipantApproved(p.id, MEDIA_TYPE.AUDIO)(state)
152
+                    hasRaisedHand(p) && !isParticipantApproved(p.id, MEDIA_TYPE.AUDIO)(state)
152
                         && dispatch(participantPendingAudio(p));
153
                         && dispatch(participantPendingAudio(p));
153
                 });
154
                 });
154
             }
155
             }

+ 2
- 2
react/features/base/participants/actions.js 파일 보기

564
  * @param {boolean} enabled - Raise or lower hand.
564
  * @param {boolean} enabled - Raise or lower hand.
565
  * @returns {{
565
  * @returns {{
566
  *     type: LOCAL_PARTICIPANT_RAISE_HAND,
566
  *     type: LOCAL_PARTICIPANT_RAISE_HAND,
567
- *     enabled: boolean
567
+ *     raisedHandTimestamp: number
568
  * }}
568
  * }}
569
  */
569
  */
570
 export function raiseHand(enabled) {
570
 export function raiseHand(enabled) {
571
     return {
571
     return {
572
         type: LOCAL_PARTICIPANT_RAISE_HAND,
572
         type: LOCAL_PARTICIPANT_RAISE_HAND,
573
-        enabled
573
+        raisedHandTimestamp: enabled ? Date.now() : 0
574
     };
574
     };
575
 }
575
 }
576
 
576
 

+ 12
- 2
react/features/base/participants/functions.js 파일 보기

461
  * @param {(Function|Object)} stateful - The (whole) redux state, or redux's
461
  * @param {(Function|Object)} stateful - The (whole) redux state, or redux's
462
  * {@code getState} function to be used to retrieve the state
462
  * {@code getState} function to be used to retrieve the state
463
  * features/base/participants.
463
  * features/base/participants.
464
- * @returns {Array<string>}
464
+ * @returns {Array<Object>}
465
  */
465
  */
466
-export function getRaiseHandsQueue(stateful: Object | Function): Array<string> {
466
+export function getRaiseHandsQueue(stateful: Object | Function): Array<Object> {
467
     const { raisedHandsQueue } = toState(stateful)['features/base/participants'];
467
     const { raisedHandsQueue } = toState(stateful)['features/base/participants'];
468
 
468
 
469
     return raisedHandsQueue;
469
     return raisedHandsQueue;
470
 }
470
 }
471
+
472
+/**
473
+ * Returns whether the given participant has his hand raised or not.
474
+ *
475
+ * @param {Object} participant - The participant.
476
+ * @returns {boolean} - Whether participant has raise hand or not.
477
+ */
478
+export function hasRaisedHand(participant: Object): boolean {
479
+    return Boolean(participant && participant.raisedHandTimestamp);
480
+}

+ 48
- 28
react/features/base/participants/middleware.js 파일 보기

94
         const participant = getLocalParticipant(state);
94
         const participant = getLocalParticipant(state);
95
         const isLocal = participant && participant.id === id;
95
         const isLocal = participant && participant.id === id;
96
 
96
 
97
-        if (isLocal && participant.raisedHand === undefined) {
97
+        if (isLocal && participant.raisedHandTimestamp === undefined) {
98
             // if local was undefined, let's leave it like that
98
             // if local was undefined, let's leave it like that
99
             // avoids sending unnecessary presence updates
99
             // avoids sending unnecessary presence updates
100
             break;
100
             break;
105
                 conference,
105
                 conference,
106
                 id,
106
                 id,
107
                 local: isLocal,
107
                 local: isLocal,
108
-                raisedHand: false
108
+                raisedHandTimestamp: 0
109
             }));
109
             }));
110
         }
110
         }
111
 
111
 
127
     }
127
     }
128
 
128
 
129
     case LOCAL_PARTICIPANT_RAISE_HAND: {
129
     case LOCAL_PARTICIPANT_RAISE_HAND: {
130
-        const { enabled } = action;
130
+        const { raisedHandTimestamp } = action;
131
         const localId = getLocalParticipant(store.getState())?.id;
131
         const localId = getLocalParticipant(store.getState())?.id;
132
 
132
 
133
-        store.dispatch(raiseHandUpdateQueue({
134
-            id: localId,
135
-            raisedHand: enabled
136
-        }));
137
-
138
         store.dispatch(participantUpdated({
133
         store.dispatch(participantUpdated({
139
             // XXX Only the local participant is allowed to update without
134
             // XXX Only the local participant is allowed to update without
140
             // stating the JitsiConference instance (i.e. participant property
135
             // stating the JitsiConference instance (i.e. participant property
144
 
139
 
145
             id: localId,
140
             id: localId,
146
             local: true,
141
             local: true,
147
-            raisedHand: enabled
142
+            raisedHandTimestamp
143
+        }));
144
+
145
+        store.dispatch(raiseHandUpdateQueue({
146
+            id: localId,
147
+            raisedHandTimestamp
148
         }));
148
         }));
149
 
149
 
150
         if (typeof APP !== 'undefined') {
150
         if (typeof APP !== 'undefined') {
151
-            APP.API.notifyRaiseHandUpdated(localId, enabled);
151
+            APP.API.notifyRaiseHandUpdated(localId, raisedHandTimestamp);
152
         }
152
         }
153
 
153
 
154
         break;
154
         break;
177
 
177
 
178
     case RAISE_HAND_UPDATED: {
178
     case RAISE_HAND_UPDATED: {
179
         const { participant } = action;
179
         const { participant } = action;
180
-        const queue = getRaiseHandsQueue(store.getState());
180
+        let queue = getRaiseHandsQueue(store.getState());
181
 
181
 
182
-        if (participant.raisedHand) {
183
-            queue.push(participant.id);
184
-            action.queue = queue;
185
-        } else {
186
-            const filteredQueue = queue.filter(id => id !== participant.id);
182
+        if (participant.raisedHandTimestamp) {
183
+            queue.push({
184
+                id: participant.id,
185
+                raisedHandTimestamp: participant.raisedHandTimestamp
186
+            });
187
 
187
 
188
-            action.queue = filteredQueue;
188
+            // sort the queue before adding to store.
189
+            queue = queue.sort(({ raisedHandTimestamp: a }, { raisedHandTimestamp: b }) => a - b);
190
+        } else {
191
+            // no need to sort on remove value.
192
+            queue = queue.filter(({ id }) => id !== participant.id);
189
         }
193
         }
194
+
195
+        action.queue = queue;
190
         break;
196
         break;
191
     }
197
     }
192
 
198
 
287
                         id: participant.getId(),
293
                         id: participant.getId(),
288
                         features: { 'screen-sharing': true }
294
                         features: { 'screen-sharing': true }
289
                     })),
295
                     })),
290
-                'raisedHand': (participant, value) => _raiseHandUpdated(store, conference, participant.getId(), value),
296
+                'raisedHand': (participant, value) =>
297
+                    _raiseHandUpdated(store, conference, participant.getId(), value),
291
                 'remoteControlSessionStatus': (participant, value) =>
298
                 'remoteControlSessionStatus': (participant, value) =>
292
                     store.dispatch(participantUpdated({
299
                     store.dispatch(participantUpdated({
293
                         conference,
300
                         conference,
320
 
327
 
321
             // We left the conference, the local participant must be updated.
328
             // We left the conference, the local participant must be updated.
322
             _e2eeUpdated(store, conference, localParticipantId, false);
329
             _e2eeUpdated(store, conference, localParticipantId, false);
323
-            _raiseHandUpdated(store, conference, localParticipantId, false);
330
+            _raiseHandUpdated(store, conference, localParticipantId, 0);
324
         }
331
         }
325
     }
332
     }
326
 );
333
 );
451
  */
458
  */
452
 function _participantJoinedOrUpdated(store, next, action) {
459
 function _participantJoinedOrUpdated(store, next, action) {
453
     const { dispatch, getState } = store;
460
     const { dispatch, getState } = store;
454
-    const { participant: { avatarURL, email, id, local, name, raisedHand } } = action;
461
+    const { participant: { avatarURL, email, id, local, name, raisedHandTimestamp } } = action;
455
 
462
 
456
     // Send an external update of the local participant's raised hand state
463
     // Send an external update of the local participant's raised hand state
457
     // if a new raised hand state is defined in the action.
464
     // if a new raised hand state is defined in the action.
458
-    if (typeof raisedHand !== 'undefined') {
465
+    if (typeof raisedHandTimestamp !== 'undefined') {
459
 
466
 
460
         if (local) {
467
         if (local) {
461
             const { conference } = getState()['features/base/conference'];
468
             const { conference } = getState()['features/base/conference'];
469
+            const rHand = parseInt(raisedHandTimestamp, 10);
462
 
470
 
463
             // Send raisedHand signalling only if there is a change
471
             // Send raisedHand signalling only if there is a change
464
-            if (conference && raisedHand !== getLocalParticipant(getState()).raisedHand) {
465
-                conference.setLocalParticipantProperty('raisedHand', raisedHand);
472
+            if (conference && rHand !== getLocalParticipant(getState()).raisedHandTimestamp) {
473
+                conference.setLocalParticipantProperty('raisedHand', rHand);
466
             }
474
             }
467
         }
475
         }
468
     }
476
     }
508
  * @returns {void}
516
  * @returns {void}
509
  */
517
  */
510
 function _raiseHandUpdated({ dispatch, getState }, conference, participantId, newValue) {
518
 function _raiseHandUpdated({ dispatch, getState }, conference, participantId, newValue) {
511
-    const raisedHand = newValue === 'true';
519
+    let raisedHandTimestamp;
520
+
521
+    switch (newValue) {
522
+    case undefined:
523
+    case 'false':
524
+        raisedHandTimestamp = 0;
525
+        break;
526
+    case 'true':
527
+        raisedHandTimestamp = Date.now();
528
+        break;
529
+    default:
530
+        raisedHandTimestamp = parseInt(newValue, 10);
531
+    }
512
     const state = getState();
532
     const state = getState();
513
 
533
 
514
     dispatch(participantUpdated({
534
     dispatch(participantUpdated({
515
         conference,
535
         conference,
516
         id: participantId,
536
         id: participantId,
517
-        raisedHand
537
+        raisedHandTimestamp
518
     }));
538
     }));
519
 
539
 
520
     dispatch(raiseHandUpdateQueue({
540
     dispatch(raiseHandUpdateQueue({
521
         id: participantId,
541
         id: participantId,
522
-        raisedHand
542
+        raisedHandTimestamp
523
     }));
543
     }));
524
 
544
 
525
     if (typeof APP !== 'undefined') {
545
     if (typeof APP !== 'undefined') {
526
-        APP.API.notifyRaiseHandUpdated(participantId, raisedHand);
546
+        APP.API.notifyRaiseHandUpdated(participantId, raisedHandTimestamp);
527
     }
547
     }
528
 
548
 
529
     const isModerator = isLocalParticipantModerator(state);
549
     const isModerator = isLocalParticipantModerator(state);
540
         customActionHandler: () => dispatch(approveParticipant(participantId))
560
         customActionHandler: () => dispatch(approveParticipant(participantId))
541
     } : {};
561
     } : {};
542
 
562
 
543
-    if (raisedHand) {
563
+    if (raisedHandTimestamp) {
544
         dispatch(showNotification({
564
         dispatch(showNotification({
545
             titleKey: 'notify.somebody',
565
             titleKey: 'notify.somebody',
546
             title: getParticipantDisplayName(state, participantId),
566
             title: getParticipantDisplayName(state, participantId),

+ 2
- 2
react/features/filmstrip/components/AbstractRaisedHandIndicator.js 파일 보기

2
 
2
 
3
 import { Component } from 'react';
3
 import { Component } from 'react';
4
 
4
 
5
-import { getParticipantById } from '../../base/participants';
5
+import { getParticipantById, hasRaisedHand } from '../../base/participants';
6
 
6
 
7
 export type Props = {
7
 export type Props = {
8
 
8
 
57
     const participant = getParticipantById(state, ownProps.participantId);
57
     const participant = getParticipantById(state, ownProps.participantId);
58
 
58
 
59
     return {
59
     return {
60
-        _raisedHand: participant && participant.raisedHand
60
+        _raisedHand: hasRaisedHand(participant)
61
     };
61
     };
62
 }
62
 }

+ 2
- 1
react/features/participants-pane/components/native/LobbyParticipantItem.js 파일 보기

5
 import { Button } from 'react-native-paper';
5
 import { Button } from 'react-native-paper';
6
 import { useDispatch } from 'react-redux';
6
 import { useDispatch } from 'react-redux';
7
 
7
 
8
+import { hasRaisedHand } from '../../../base/participants';
8
 import { approveKnockingParticipant } from '../../../lobby/actions.native';
9
 import { approveKnockingParticipant } from '../../../lobby/actions.native';
9
 import { showContextMenuReject } from '../../actions.native';
10
 import { showContextMenuReject } from '../../actions.native';
10
 import { MEDIA_STATE } from '../../constants';
11
 import { MEDIA_STATE } from '../../constants';
35
             onPress = { openContextMenuReject }
36
             onPress = { openContextMenuReject }
36
             participant = { p }
37
             participant = { p }
37
             participantID = { p.id }
38
             participantID = { p.id }
38
-            raisedHand = { p.raisedHand }
39
+            raisedHand = { hasRaisedHand(p) }
39
             videoMediaState = { MEDIA_STATE.NONE }>
40
             videoMediaState = { MEDIA_STATE.NONE }>
40
             <Button
41
             <Button
41
                 children = { t('lobby.admit') }
42
                 children = { t('lobby.admit') }

+ 2
- 1
react/features/participants-pane/components/native/MeetingParticipantItem.js 파일 보기

7
     getLocalParticipant,
7
     getLocalParticipant,
8
     getParticipantByIdOrUndefined,
8
     getParticipantByIdOrUndefined,
9
     getParticipantDisplayName,
9
     getParticipantDisplayName,
10
+    hasRaisedHand,
10
     isParticipantModerator
11
     isParticipantModerator
11
 } from '../../../base/participants';
12
 } from '../../../base/participants';
12
 import { connect } from '../../../base/redux';
13
 import { connect } from '../../../base/redux';
190
         _local: Boolean(participant?.local),
191
         _local: Boolean(participant?.local),
191
         _localVideoOwner: Boolean(ownerId === localParticipantId),
192
         _localVideoOwner: Boolean(ownerId === localParticipantId),
192
         _participantID: participant?.id,
193
         _participantID: participant?.id,
193
-        _raisedHand: Boolean(participant?.raisedHand),
194
+        _raisedHand: hasRaisedHand(participant),
194
         _videoMediaState: videoMediaState
195
         _videoMediaState: videoMediaState
195
     };
196
     };
196
 }
197
 }

+ 2
- 1
react/features/participants-pane/components/web/LobbyParticipantItem.js 파일 보기

3
 import React from 'react';
3
 import React from 'react';
4
 import { useTranslation } from 'react-i18next';
4
 import { useTranslation } from 'react-i18next';
5
 
5
 
6
+import { hasRaisedHand } from '../../../base/participants';
6
 import { ACTION_TRIGGER, MEDIA_STATE } from '../../constants';
7
 import { ACTION_TRIGGER, MEDIA_STATE } from '../../constants';
7
 import { useLobbyActions } from '../../hooks';
8
 import { useLobbyActions } from '../../hooks';
8
 
9
 
45
             openDrawerForParticipant = { openDrawerForParticipant }
46
             openDrawerForParticipant = { openDrawerForParticipant }
46
             overflowDrawer = { overflowDrawer }
47
             overflowDrawer = { overflowDrawer }
47
             participantID = { id }
48
             participantID = { id }
48
-            raisedHand = { p.raisedHand }
49
+            raisedHand = { hasRaisedHand(p) }
49
             videoMediaState = { MEDIA_STATE.NONE }
50
             videoMediaState = { MEDIA_STATE.NONE }
50
             youText = { t('chat.you') }>
51
             youText = { t('chat.you') }>
51
             <ParticipantActionButton
52
             <ParticipantActionButton

+ 2
- 1
react/features/participants-pane/components/web/MeetingParticipantItem.js 파일 보기

9
     getLocalParticipant,
9
     getLocalParticipant,
10
     getParticipantByIdOrUndefined,
10
     getParticipantByIdOrUndefined,
11
     getParticipantDisplayName,
11
     getParticipantDisplayName,
12
+    hasRaisedHand,
12
     isParticipantModerator
13
     isParticipantModerator
13
 } from '../../../base/participants';
14
 } from '../../../base/participants';
14
 import { connect } from '../../../base/redux';
15
 import { connect } from '../../../base/redux';
307
         _participant: participant,
308
         _participant: participant,
308
         _participantID: participant?.id,
309
         _participantID: participant?.id,
309
         _quickActionButtonType,
310
         _quickActionButtonType,
310
-        _raisedHand: Boolean(participant?.raisedHand),
311
+        _raisedHand: hasRaisedHand(participant),
311
         _videoMediaState
312
         _videoMediaState
312
     };
313
     };
313
 }
314
 }

+ 3
- 7
react/features/participants-pane/functions.js 파일 보기

211
     const { id } = getLocalParticipant(stateful);
211
     const { id } = getLocalParticipant(stateful);
212
     const remoteParticipants = getRemoteParticipantsSorted(stateful);
212
     const remoteParticipants = getRemoteParticipantsSorted(stateful);
213
     const reorderedParticipants = new Set(remoteParticipants);
213
     const reorderedParticipants = new Set(remoteParticipants);
214
-    const raisedHandParticipants = getRaiseHandsQueue(stateful);
214
+    const raisedHandParticipants = getRaiseHandsQueue(stateful).map(({ id: particId }) => particId);
215
     const remoteRaisedHandParticipants = new Set(raisedHandParticipants || []);
215
     const remoteRaisedHandParticipants = new Set(raisedHandParticipants || []);
216
     const dominantSpeaker = getDominantSpeakerParticipant(stateful);
216
     const dominantSpeaker = getDominantSpeakerParticipant(stateful);
217
 
217
 
219
         // Avoid duplicates.
219
         // Avoid duplicates.
220
         if (reorderedParticipants.has(participant)) {
220
         if (reorderedParticipants.has(participant)) {
221
             reorderedParticipants.delete(participant);
221
             reorderedParticipants.delete(participant);
222
-        } else {
223
-            remoteRaisedHandParticipants.delete(participant);
224
         }
222
         }
225
     }
223
     }
226
 
224
 
227
-    // Remove self.
228
-    remoteRaisedHandParticipants.delete(id);
229
-
230
     const dominant = [];
225
     const dominant = [];
226
+    const local = remoteRaisedHandParticipants.has(id) ? [] : [ id ];
231
 
227
 
232
     // Remove dominant speaker.
228
     // Remove dominant speaker.
233
     if (dominantSpeaker && dominantSpeaker.id !== id) {
229
     if (dominantSpeaker && dominantSpeaker.id !== id) {
239
     // Move self and participants with raised hand to the top of the list.
235
     // Move self and participants with raised hand to the top of the list.
240
     return [
236
     return [
241
         ...dominant,
237
         ...dominant,
242
-        id,
238
+        ...local,
243
         ...Array.from(remoteRaisedHandParticipants.keys()),
239
         ...Array.from(remoteRaisedHandParticipants.keys()),
244
         ...Array.from(reorderedParticipants.keys())
240
         ...Array.from(reorderedParticipants.keys())
245
     ];
241
     ];

+ 2
- 1
react/features/reactions/components/native/RaiseHandButton.js 파일 보기

12
 import { translate } from '../../../base/i18n';
12
 import { translate } from '../../../base/i18n';
13
 import {
13
 import {
14
     getLocalParticipant,
14
     getLocalParticipant,
15
+    hasRaisedHand,
15
     raiseHand
16
     raiseHand
16
 } from '../../../base/participants';
17
 } from '../../../base/participants';
17
 import { connect } from '../../../base/redux';
18
 import { connect } from '../../../base/redux';
157
 
158
 
158
     return {
159
     return {
159
         _localParticipant,
160
         _localParticipant,
160
-        _raisedHand: _localParticipant.raisedHand,
161
+        _raisedHand: hasRaisedHand(_localParticipant),
161
         _styles: ColorSchemeRegistry.get(state, 'Toolbox').raiseHandButton
162
         _styles: ColorSchemeRegistry.get(state, 'Toolbox').raiseHandButton
162
     };
163
     };
163
 }
164
 }

+ 2
- 2
react/features/reactions/components/native/ReactionsMenuButton.js 파일 보기

7
 import { translate } from '../../../base/i18n';
7
 import { translate } from '../../../base/i18n';
8
 import { IconRaisedHand } from '../../../base/icons';
8
 import { IconRaisedHand } from '../../../base/icons';
9
 import {
9
 import {
10
-    getLocalParticipant
10
+    getLocalParticipant, hasRaisedHand
11
 } from '../../../base/participants';
11
 } from '../../../base/participants';
12
 import { connect } from '../../../base/redux';
12
 import { connect } from '../../../base/redux';
13
 import { AbstractButton, type AbstractButtonProps } from '../../../base/toolbox/components';
13
 import { AbstractButton, type AbstractButtonProps } from '../../../base/toolbox/components';
81
     const { visible = enabled } = ownProps;
81
     const { visible = enabled } = ownProps;
82
 
82
 
83
     return {
83
     return {
84
-        _raisedHand: _localParticipant.raisedHand,
84
+        _raisedHand: hasRaisedHand(_localParticipant),
85
         _reactionsOpen: isDialogOpen(state, ReactionMenuDialog),
85
         _reactionsOpen: isDialogOpen(state, ReactionMenuDialog),
86
         visible
86
         visible
87
     };
87
     };

+ 5
- 18
react/features/reactions/components/web/ReactionsMenu.js 파일 보기

10
 } from '../../../analytics';
10
 } from '../../../analytics';
11
 import { isMobileBrowser } from '../../../base/environment/utils';
11
 import { isMobileBrowser } from '../../../base/environment/utils';
12
 import { translate } from '../../../base/i18n';
12
 import { translate } from '../../../base/i18n';
13
-import { getLocalParticipant, participantUpdated } from '../../../base/participants';
13
+import { getLocalParticipant, hasRaisedHand, raiseHand } from '../../../base/participants';
14
 import { connect } from '../../../base/redux';
14
 import { connect } from '../../../base/redux';
15
 import { dockToolbox } from '../../../toolbox/actions.web';
15
 import { dockToolbox } from '../../../toolbox/actions.web';
16
 import { addReactionToBuffer } from '../../actions.any';
16
 import { addReactionToBuffer } from '../../actions.any';
123
      * @returns {void}
123
      * @returns {void}
124
      */
124
      */
125
     _doToggleRaiseHand() {
125
     _doToggleRaiseHand() {
126
-        const { _localParticipantID, _raisedHand } = this.props;
127
-        const newRaisedStatus = !_raisedHand;
128
-
129
-        this.props.dispatch(participantUpdated({
130
-            // XXX Only the local participant is allowed to update without
131
-            // stating the JitsiConference instance (i.e. participant property
132
-            // `conference` for a remote participant) because the local
133
-            // participant is uniquely identified by the very fact that there is
134
-            // only one local participant.
135
-
136
-            id: _localParticipantID,
137
-            local: true,
138
-            raisedHand: newRaisedStatus
139
-        }));
140
-
141
-        APP.API.notifyRaiseHandUpdated(_localParticipantID, newRaisedStatus);
126
+        const { _raisedHand } = this.props;
127
+
128
+        this.props.dispatch(raiseHand(!_raisedHand));
142
     }
129
     }
143
 
130
 
144
     /**
131
     /**
221
     return {
208
     return {
222
         _localParticipantID: localParticipant.id,
209
         _localParticipantID: localParticipant.id,
223
         _isMobile: isMobileBrowser(),
210
         _isMobile: isMobileBrowser(),
224
-        _raisedHand: localParticipant.raisedHand
211
+        _raisedHand: hasRaisedHand(localParticipant)
225
     };
212
     };
226
 }
213
 }
227
 
214
 

+ 2
- 2
react/features/reactions/components/web/ReactionsMenuButton.js 파일 보기

5
 import { isMobileBrowser } from '../../../base/environment/utils';
5
 import { isMobileBrowser } from '../../../base/environment/utils';
6
 import { translate } from '../../../base/i18n';
6
 import { translate } from '../../../base/i18n';
7
 import { IconArrowUp, IconRaisedHand } from '../../../base/icons';
7
 import { IconArrowUp, IconRaisedHand } from '../../../base/icons';
8
-import { getLocalParticipant } from '../../../base/participants';
8
+import { getLocalParticipant, hasRaisedHand } from '../../../base/participants';
9
 import { connect } from '../../../base/redux';
9
 import { connect } from '../../../base/redux';
10
 import { ToolboxButtonWithIcon } from '../../../base/toolbox/components';
10
 import { ToolboxButtonWithIcon } from '../../../base/toolbox/components';
11
 import ToolbarButton from '../../../toolbox/components/web/ToolbarButton';
11
 import ToolbarButton from '../../../toolbox/components/web/ToolbarButton';
138
         isOpen: getReactionsMenuVisibility(state),
138
         isOpen: getReactionsMenuVisibility(state),
139
         isMobile: isMobileBrowser(),
139
         isMobile: isMobileBrowser(),
140
         reactionsQueue: getReactionsQueue(state),
140
         reactionsQueue: getReactionsQueue(state),
141
-        raisedHand: localParticipant?.raisedHand
141
+        raisedHand: hasRaisedHand(localParticipant)
142
     };
142
     };
143
 }
143
 }
144
 
144
 

+ 2
- 1
react/features/toolbox/components/native/RaiseHandButton.js 파일 보기

11
 import { IconRaisedHand } from '../../../base/icons';
11
 import { IconRaisedHand } from '../../../base/icons';
12
 import {
12
 import {
13
     getLocalParticipant,
13
     getLocalParticipant,
14
+    hasRaisedHand,
14
     raiseHand
15
     raiseHand
15
 } from '../../../base/participants';
16
 } from '../../../base/participants';
16
 import { connect } from '../../../base/redux';
17
 import { connect } from '../../../base/redux';
97
 
98
 
98
     return {
99
     return {
99
         _localParticipant,
100
         _localParticipant,
100
-        _raisedHand: _localParticipant.raisedHand,
101
+        _raisedHand: hasRaisedHand(_localParticipant),
101
         visible
102
         visible
102
     };
103
     };
103
 }
104
 }

+ 4
- 6
react/features/toolbox/components/web/Toolbox.js 파일 보기

17
 import JitsiMeetJS from '../../../base/lib-jitsi-meet';
17
 import JitsiMeetJS from '../../../base/lib-jitsi-meet';
18
 import {
18
 import {
19
     getLocalParticipant,
19
     getLocalParticipant,
20
+    hasRaisedHand,
20
     haveParticipantWithScreenSharingFeature,
21
     haveParticipantWithScreenSharingFeature,
21
     raiseHand
22
     raiseHand
22
 } from '../../../base/participants';
23
 } from '../../../base/participants';
488
      * @returns {void}
489
      * @returns {void}
489
      */
490
      */
490
     _doToggleRaiseHand() {
491
     _doToggleRaiseHand() {
491
-        const { _localParticipantID, _raisedHand } = this.props;
492
-        const newRaisedStatus = !_raisedHand;
492
+        const { _raisedHand } = this.props;
493
 
493
 
494
-        this.props.dispatch(raiseHand(newRaisedStatus));
495
-
496
-        APP.API.notifyRaiseHandUpdated(_localParticipantID, newRaisedStatus);
494
+        this.props.dispatch(raiseHand(!_raisedHand));
497
     }
495
     }
498
 
496
 
499
     /**
497
     /**
1338
         _localVideo: localVideo,
1336
         _localVideo: localVideo,
1339
         _overflowMenuVisible: overflowMenuVisible,
1337
         _overflowMenuVisible: overflowMenuVisible,
1340
         _participantsPaneOpen: getParticipantsPaneOpen(state),
1338
         _participantsPaneOpen: getParticipantsPaneOpen(state),
1341
-        _raisedHand: localParticipant?.raisedHand,
1339
+        _raisedHand: hasRaisedHand(localParticipant),
1342
         _reactionsEnabled: isReactionsEnabled(state),
1340
         _reactionsEnabled: isReactionsEnabled(state),
1343
         _screenSharing: isScreenVideoShared(state),
1341
         _screenSharing: isScreenVideoShared(state),
1344
         _tileViewEnabled: shouldDisplayTileView(state),
1342
         _tileViewEnabled: shouldDisplayTileView(state),

Loading…
취소
저장