|
@@ -142,6 +142,9 @@ function SmallVideo(VideoLayout) {
|
142
|
142
|
// Bind event handlers so they are only bound once for every instance.
|
143
|
143
|
this._onPopoverHover = this._onPopoverHover.bind(this);
|
144
|
144
|
this.updateView = this.updateView.bind(this);
|
|
145
|
+
|
|
146
|
+ this._onContainerClick = this._onContainerClick.bind(this);
|
|
147
|
+ this._onContainerDoubleClick = this._onContainerDoubleClick.bind(this);
|
145
|
148
|
}
|
146
|
149
|
|
147
|
150
|
/**
|
|
@@ -821,12 +824,71 @@ SmallVideo.prototype.updateIndicators = function() {
|
821
|
824
|
};
|
822
|
825
|
|
823
|
826
|
/**
|
824
|
|
- * Pins the participant displayed by this thumbnail or unpins if already pinned.
|
|
827
|
+ * Callback invoked when the thumbnail is double clicked. Will pin the
|
|
828
|
+ * participant if in tile view.
|
|
829
|
+ *
|
|
830
|
+ * @param {MouseEvent} event - The click event to intercept.
|
|
831
|
+ * @private
|
|
832
|
+ * @returns {void}
|
|
833
|
+ */
|
|
834
|
+SmallVideo.prototype._onContainerDoubleClick = function(event) {
|
|
835
|
+ if (this._pinningRequiresDoubleClick() && this._shouldTriggerPin(event)) {
|
|
836
|
+ APP.store.dispatch(pinParticipant(this.id));
|
|
837
|
+ }
|
|
838
|
+};
|
|
839
|
+
|
|
840
|
+/**
|
|
841
|
+ * Callback invoked when the thumbnail is clicked and potentially trigger
|
|
842
|
+ * pinning of the participant.
|
825
|
843
|
*
|
|
844
|
+ * @param {MouseEvent} event - The click event to intercept.
|
826
|
845
|
* @private
|
827
|
846
|
* @returns {void}
|
828
|
847
|
*/
|
829
|
|
-SmallVideo.prototype._togglePin = function() {
|
|
848
|
+SmallVideo.prototype._onContainerClick = function(event) {
|
|
849
|
+ const triggerPin = this._shouldTriggerPin(event)
|
|
850
|
+ && !this._pinningRequiresDoubleClick();
|
|
851
|
+
|
|
852
|
+ if (event.stopPropagation && triggerPin) {
|
|
853
|
+ event.stopPropagation();
|
|
854
|
+ event.preventDefault();
|
|
855
|
+ }
|
|
856
|
+
|
|
857
|
+ if (triggerPin) {
|
|
858
|
+ this.togglePin();
|
|
859
|
+ }
|
|
860
|
+
|
|
861
|
+ return false;
|
|
862
|
+};
|
|
863
|
+
|
|
864
|
+/**
|
|
865
|
+ * Returns whether or not a click event is targeted at certain elements which
|
|
866
|
+ * should not trigger a pin.
|
|
867
|
+ *
|
|
868
|
+ * @param {MouseEvent} event - The click event to intercept.
|
|
869
|
+ * @private
|
|
870
|
+ * @returns {boolean}
|
|
871
|
+ */
|
|
872
|
+SmallVideo.prototype._shouldTriggerPin = function(event) {
|
|
873
|
+ // TODO Checking the classes is a workround to allow events to bubble into
|
|
874
|
+ // the DisplayName component if it was clicked. React's synthetic events
|
|
875
|
+ // will fire after jQuery handlers execute, so stop propogation at this
|
|
876
|
+ // point will prevent DisplayName from getting click events. This workaround
|
|
877
|
+ // should be removeable once LocalVideo is a React Component because then
|
|
878
|
+ // the components share the same eventing system.
|
|
879
|
+ const $source = $(event.target || event.srcElement);
|
|
880
|
+
|
|
881
|
+ return $source.parents('.displayNameContainer').length === 0
|
|
882
|
+ && $source.parents('.popover').length === 0
|
|
883
|
+ && !event.target.classList.contains('popover');
|
|
884
|
+};
|
|
885
|
+
|
|
886
|
+/**
|
|
887
|
+ * Pins the participant displayed by this thumbnail or unpins if already pinned.
|
|
888
|
+ *
|
|
889
|
+ * @returns {void}
|
|
890
|
+ */
|
|
891
|
+SmallVideo.prototype.togglePin = function() {
|
830
|
892
|
const pinnedParticipant
|
831
|
893
|
= getPinnedParticipant(APP.store.getState()) || {};
|
832
|
894
|
const participantIdToPin
|
|
@@ -836,6 +898,17 @@ SmallVideo.prototype._togglePin = function() {
|
836
|
898
|
APP.store.dispatch(pinParticipant(participantIdToPin));
|
837
|
899
|
};
|
838
|
900
|
|
|
901
|
+/**
|
|
902
|
+ * Returns whether or not clicking to pin the participant needs to be a double
|
|
903
|
+ * click instead of a single click.
|
|
904
|
+ *
|
|
905
|
+ * @private
|
|
906
|
+ * @returns {boolean}
|
|
907
|
+ */
|
|
908
|
+SmallVideo.prototype._pinningRequiresDoubleClick = function() {
|
|
909
|
+ return shouldDisplayTileView(APP.store.getState());
|
|
910
|
+};
|
|
911
|
+
|
839
|
912
|
/**
|
840
|
913
|
* Removes the React element responsible for showing connection status, dominant
|
841
|
914
|
* speaker, and raised hand icons.
|