浏览代码

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

j8
Tudor-Ovidiu Avram 3 年前
父节点
当前提交
7f04767566

+ 5
- 0
config.js 查看文件

792
      websocketKeepAliveUrl
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
         Use this array to configure which notifications will be shown to the user
801
         Use this array to configure which notifications will be shown to the user
797
         The items correspond to the title or description key of that notification
802
         The items correspond to the title or description key of that notification

+ 77
- 0
modules/API/API.js 查看文件

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
  * Implements API class that communicates with external API class and provides
614
  * Implements API class that communicates with external API class and provides
577
  * interface to access Jitsi Meet features by external applications that embed
615
  * interface to access Jitsi Meet features by external applications that embed
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
      * Notify external application that the video quality setting has changed.
756
      * Notify external application that the video quality setting has changed.
680
      *
757
      *

+ 3
- 0
modules/API/external/external_api.js 查看文件

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

+ 1
- 0
react/features/base/config/configWhitelist.js 查看文件

140
     'liveStreamingEnabled',
140
     'liveStreamingEnabled',
141
     'localRecording',
141
     'localRecording',
142
     'maxFullResolutionParticipants',
142
     'maxFullResolutionParticipants',
143
+    'mouseMoveCallbackInterval',
143
     'notifications',
144
     'notifications',
144
     'openSharedDocumentOnJoin',
145
     'openSharedDocumentOnJoin',
145
     'opusMaxAverageBitrate',
146
     'opusMaxAverageBitrate',

+ 63
- 2
react/features/conference/components/web/Conference.js 查看文件

85
      */
85
      */
86
     _layoutClassName: string,
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
      * Name for this conference room.
94
      * Name for this conference room.
90
      */
95
      */
104
  */
109
  */
105
 class Conference extends AbstractConference<Props, *> {
110
 class Conference extends AbstractConference<Props, *> {
106
     _onFullScreenChange: Function;
111
     _onFullScreenChange: Function;
112
+    _onMouseEnter: Function;
113
+    _onMouseLeave: Function;
114
+    _onMouseMove: Function;
107
     _onShowToolbar: Function;
115
     _onShowToolbar: Function;
116
+    _originalOnMouseMove: Function;
108
     _originalOnShowToolbar: Function;
117
     _originalOnShowToolbar: Function;
109
     _setBackground: Function;
118
     _setBackground: Function;
110
 
119
 
117
     constructor(props) {
126
     constructor(props) {
118
         super(props);
127
         super(props);
119
 
128
 
129
+        const { _mouseMoveCallbackInterval } = props;
130
+
120
         // Throttle and bind this component's mousemove handler to prevent it
131
         // Throttle and bind this component's mousemove handler to prevent it
121
         // from firing too often.
132
         // from firing too often.
122
         this._originalOnShowToolbar = this._onShowToolbar;
133
         this._originalOnShowToolbar = this._onShowToolbar;
134
+        this._originalOnMouseMove = this._onMouseMove;
135
+
123
         this._onShowToolbar = _.throttle(
136
         this._onShowToolbar = _.throttle(
124
             () => this._originalOnShowToolbar(),
137
             () => this._originalOnShowToolbar(),
125
             100,
138
             100,
128
                 trailing: false
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
         // Bind event handler so it is only bound once for every instance.
152
         // Bind event handler so it is only bound once for every instance.
132
         this._onFullScreenChange = this._onFullScreenChange.bind(this);
153
         this._onFullScreenChange = this._onFullScreenChange.bind(this);
133
         this._setBackground = this._setBackground.bind(this);
154
         this._setBackground = this._setBackground.bind(this);
192
         } = this.props;
213
         } = this.props;
193
 
214
 
194
         return (
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
                 <div
221
                 <div
197
                     className = { _layoutClassName }
222
                     className = { _layoutClassName }
198
                     id = 'videoconference_page'
223
                     id = 'videoconference_page'
262
         this.props.dispatch(fullScreenChanged(APP.UI.isFullScreen()));
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
      * Displays the toolbar.
324
      * Displays the toolbar.
267
      *
325
      *
305
  * @returns {Props}
363
  * @returns {Props}
306
  */
364
  */
307
 function _mapStateToProps(state) {
365
 function _mapStateToProps(state) {
366
+    const { backgroundAlpha, mouseMoveCallbackInterval } = state['features/base/config'];
367
+
308
     return {
368
     return {
309
         ...abstractMapStateToProps(state),
369
         ...abstractMapStateToProps(state),
310
-        _backgroundAlpha: state['features/base/config'].backgroundAlpha,
370
+        _backgroundAlpha: backgroundAlpha,
311
         _isLobbyScreenVisible: state['features/base/dialog']?.component === LobbyScreen,
371
         _isLobbyScreenVisible: state['features/base/dialog']?.component === LobbyScreen,
312
         _isParticipantsPaneVisible: getParticipantsPaneOpen(state),
372
         _isParticipantsPaneVisible: getParticipantsPaneOpen(state),
313
         _layoutClassName: LAYOUT_CLASSNAMES[getCurrentLayout(state)],
373
         _layoutClassName: LAYOUT_CLASSNAMES[getCurrentLayout(state)],
374
+        _mouseMoveCallbackInterval: mouseMoveCallbackInterval,
314
         _roomName: getConferenceNameForTitle(state),
375
         _roomName: getConferenceNameForTitle(state),
315
         _showPrejoin: isPrejoinPageVisible(state)
376
         _showPrejoin: isPrejoinPageVisible(state)
316
     };
377
     };

正在加载...
取消
保存