Parcourir la source

feat(api) expose event for mouse movements inside the iframe

j8
Tudor-Ovidiu Avram il y a 3 ans
Parent
révision
7f04767566

+ 5
- 0
config.js Voir le fichier

@@ -792,6 +792,11 @@ var config = {
792 792
      websocketKeepAliveUrl
793 793
      */
794 794
 
795
+    /**
796
+     * Default interval (milliseconds) for triggering mouseMoved iframe API event
797
+     */
798
+    mouseMoveCallbackInterval: 1000,
799
+
795 800
     /**
796 801
         Use this array to configure which notifications will be shown to the user
797 802
         The items correspond to the title or description key of that notification

+ 77
- 0
modules/API/API.js Voir le fichier

@@ -572,6 +572,44 @@ function toggleScreenSharing(enable) {
572 572
     }
573 573
 }
574 574
 
575
+/**
576
+ * Removes sensitive data from a mouse event.
577
+ *
578
+ * @param {MouseEvent} event - The mouse event to sanitize.
579
+ * @returns {Object}
580
+ */
581
+function sanitizeMouseEvent(event: MouseEvent) {
582
+    const {
583
+        clientX,
584
+        clientY,
585
+        movementX,
586
+        movementY,
587
+        offsetX,
588
+        offsetY,
589
+        pageX,
590
+        pageY,
591
+        x,
592
+        y,
593
+        screenX,
594
+        screenY
595
+    } = event;
596
+
597
+    return {
598
+        clientX,
599
+        clientY,
600
+        movementX,
601
+        movementY,
602
+        offsetX,
603
+        offsetY,
604
+        pageX,
605
+        pageY,
606
+        x,
607
+        y,
608
+        screenX,
609
+        screenY
610
+    };
611
+}
612
+
575 613
 /**
576 614
  * Implements API class that communicates with external API class and provides
577 615
  * interface to access Jitsi Meet features by external applications that embed
@@ -675,6 +713,45 @@ class API {
675 713
         });
676 714
     }
677 715
 
716
+    /**
717
+     * Notify external application (if API is enabled) that the mouse has entered inside the iframe.
718
+     *
719
+     * @param {MouseEvent} event - The mousemove event.
720
+     * @returns {void}
721
+     */
722
+    notifyMouseEnter(event: MouseEvent) {
723
+        this._sendEvent({
724
+            name: 'mouse-enter',
725
+            event: sanitizeMouseEvent(event)
726
+        });
727
+    }
728
+
729
+    /**
730
+     * Notify external application (if API is enabled) that the mouse has entered inside the iframe.
731
+     *
732
+     * @param {MouseEvent} event - The mousemove event.
733
+     * @returns {void}
734
+     */
735
+    notifyMouseLeave(event: MouseEvent) {
736
+        this._sendEvent({
737
+            name: 'mouse-leave',
738
+            event: sanitizeMouseEvent(event)
739
+        });
740
+    }
741
+
742
+    /**
743
+     * Notify external application (if API is enabled) that the mouse has moved inside the iframe.
744
+     *
745
+     * @param {MouseEvent} event - The mousemove event.
746
+     * @returns {void}
747
+     */
748
+    notifyMouseMove(event: MouseEvent) {
749
+        this._sendEvent({
750
+            name: 'mouse-move',
751
+            event: sanitizeMouseEvent(event)
752
+        });
753
+    }
754
+
678 755
     /**
679 756
      * Notify external application that the video quality setting has changed.
680 757
      *

+ 3
- 0
modules/API/external/external_api.js Voir le fichier

@@ -84,6 +84,9 @@ const events = {
84 84
     'incoming-message': 'incomingMessage',
85 85
     'log': 'log',
86 86
     'mic-error': 'micError',
87
+    'mouse-enter': 'mouseEnter',
88
+    'mouse-leave': 'mouseLeave',
89
+    'mouse-move': 'mouseMove',
87 90
     'outgoing-message': 'outgoingMessage',
88 91
     'participant-joined': 'participantJoined',
89 92
     'participant-kicked-out': 'participantKickedOut',

+ 1
- 0
react/features/base/config/configWhitelist.js Voir le fichier

@@ -140,6 +140,7 @@ export default [
140 140
     'liveStreamingEnabled',
141 141
     'localRecording',
142 142
     'maxFullResolutionParticipants',
143
+    'mouseMoveCallbackInterval',
143 144
     'notifications',
144 145
     'openSharedDocumentOnJoin',
145 146
     'opusMaxAverageBitrate',

+ 63
- 2
react/features/conference/components/web/Conference.js Voir le fichier

@@ -85,6 +85,11 @@ type Props = AbstractProps & {
85 85
      */
86 86
     _layoutClassName: string,
87 87
 
88
+    /**
89
+     * The config specified interval for triggering mouseMoved iframe api events
90
+     */
91
+    _mouseMoveCallbackInterval: number,
92
+
88 93
     /**
89 94
      * Name for this conference room.
90 95
      */
@@ -104,7 +109,11 @@ type Props = AbstractProps & {
104 109
  */
105 110
 class Conference extends AbstractConference<Props, *> {
106 111
     _onFullScreenChange: Function;
112
+    _onMouseEnter: Function;
113
+    _onMouseLeave: Function;
114
+    _onMouseMove: Function;
107 115
     _onShowToolbar: Function;
116
+    _originalOnMouseMove: Function;
108 117
     _originalOnShowToolbar: Function;
109 118
     _setBackground: Function;
110 119
 
@@ -117,9 +126,13 @@ class Conference extends AbstractConference<Props, *> {
117 126
     constructor(props) {
118 127
         super(props);
119 128
 
129
+        const { _mouseMoveCallbackInterval } = props;
130
+
120 131
         // Throttle and bind this component's mousemove handler to prevent it
121 132
         // from firing too often.
122 133
         this._originalOnShowToolbar = this._onShowToolbar;
134
+        this._originalOnMouseMove = this._onMouseMove;
135
+
123 136
         this._onShowToolbar = _.throttle(
124 137
             () => this._originalOnShowToolbar(),
125 138
             100,
@@ -128,6 +141,14 @@ class Conference extends AbstractConference<Props, *> {
128 141
                 trailing: false
129 142
             });
130 143
 
144
+        this._onMouseMove = _.throttle(
145
+            event => this._originalOnMouseMove(event),
146
+            _mouseMoveCallbackInterval,
147
+            {
148
+                leading: true,
149
+                trailing: false
150
+            });
151
+
131 152
         // Bind event handler so it is only bound once for every instance.
132 153
         this._onFullScreenChange = this._onFullScreenChange.bind(this);
133 154
         this._setBackground = this._setBackground.bind(this);
@@ -192,7 +213,11 @@ class Conference extends AbstractConference<Props, *> {
192 213
         } = this.props;
193 214
 
194 215
         return (
195
-            <div id = 'layout_wrapper'>
216
+            <div
217
+                id = 'layout_wrapper'
218
+                onMouseEnter = { this._onMouseEnter }
219
+                onMouseLeave = { this._onMouseLeave }
220
+                onMouseMove = { this._onMouseMove } >
196 221
                 <div
197 222
                     className = { _layoutClassName }
198 223
                     id = 'videoconference_page'
@@ -262,6 +287,39 @@ class Conference extends AbstractConference<Props, *> {
262 287
         this.props.dispatch(fullScreenChanged(APP.UI.isFullScreen()));
263 288
     }
264 289
 
290
+    /**
291
+     * Triggers iframe API mouseEnter event.
292
+     *
293
+     * @param {MouseEvent} event - The mouse event.
294
+     * @private
295
+     * @returns {void}
296
+     */
297
+    _onMouseEnter(event) {
298
+        APP.API.notifyMouseEnter(event);
299
+    }
300
+
301
+    /**
302
+     * Triggers iframe API mouseLeave event.
303
+     *
304
+     * @param {MouseEvent} event - The mouse event.
305
+     * @private
306
+     * @returns {void}
307
+     */
308
+    _onMouseLeave(event) {
309
+        APP.API.notifyMouseLeave(event);
310
+    }
311
+
312
+    /**
313
+     * Triggers iframe API mouseMove event.
314
+     *
315
+     * @param {MouseEvent} event - The mouse event.
316
+     * @private
317
+     * @returns {void}
318
+     */
319
+    _onMouseMove(event) {
320
+        APP.API.notifyMouseMove(event);
321
+    }
322
+
265 323
     /**
266 324
      * Displays the toolbar.
267 325
      *
@@ -305,12 +363,15 @@ class Conference extends AbstractConference<Props, *> {
305 363
  * @returns {Props}
306 364
  */
307 365
 function _mapStateToProps(state) {
366
+    const { backgroundAlpha, mouseMoveCallbackInterval } = state['features/base/config'];
367
+
308 368
     return {
309 369
         ...abstractMapStateToProps(state),
310
-        _backgroundAlpha: state['features/base/config'].backgroundAlpha,
370
+        _backgroundAlpha: backgroundAlpha,
311 371
         _isLobbyScreenVisible: state['features/base/dialog']?.component === LobbyScreen,
312 372
         _isParticipantsPaneVisible: getParticipantsPaneOpen(state),
313 373
         _layoutClassName: LAYOUT_CLASSNAMES[getCurrentLayout(state)],
374
+        _mouseMoveCallbackInterval: mouseMoveCallbackInterval,
314 375
         _roomName: getConferenceNameForTitle(state),
315 376
         _showPrejoin: isPrejoinPageVisible(state)
316 377
     };

Chargement…
Annuler
Enregistrer