Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/spreed.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDaniel Calviño Sánchez <danxuliu@gmail.com>2021-09-29 01:30:23 +0300
committerDaniel Calviño Sánchez <danxuliu@gmail.com>2021-10-01 09:22:19 +0300
commit6a88f679af3785044b6f83320b115805417144fb (patch)
tree1e211ccff0d389af4463fb120e6764a6361b2956 /src
parentb9be9ae1b1dba86f7c7dbec927438800cd3636f0 (diff)
Extract common emitter code to mixin
The EmitterMixin is not a Vue mixin but a raw JavaScript mixin, so it is stored in "src/utils" rather than in "mixins". The emitter code was almost the same in all classes, except that some classes allowed triggering events without parameters and others did not. The mixin uses the most generic code, that is, the one that also allows triggering events without parameters. Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/utils/EmitterMixin.js108
-rw-r--r--src/utils/webrtc/MediaDevicesManager.js42
-rw-r--r--src/utils/webrtc/analyzers/CallAnalyzer.js43
-rw-r--r--src/utils/webrtc/analyzers/ParticipantAnalyzer.js41
-rw-r--r--src/utils/webrtc/analyzers/PeerConnectionAnalyzer.js43
-rw-r--r--src/utils/webrtc/models/CallParticipantCollection.js43
-rw-r--r--src/utils/webrtc/models/CallParticipantModel.js47
-rw-r--r--src/utils/webrtc/models/LocalCallParticipantModel.js46
-rw-r--r--src/utils/webrtc/models/LocalMediaModel.js42
9 files changed, 152 insertions, 303 deletions
diff --git a/src/utils/EmitterMixin.js b/src/utils/EmitterMixin.js
new file mode 100644
index 000000000..f75ba2a03
--- /dev/null
+++ b/src/utils/EmitterMixin.js
@@ -0,0 +1,108 @@
+/**
+ *
+ * @copyright Copyright (c) 2021, Daniel Calviño Sánchez (danxuliu@gmail.com)
+ *
+ * @license AGPL-3.0-or-later
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/**
+ * Emitter of events.
+ *
+ * The mixin can be inherited calling "EmitterMixin.apply(Inheriter.prototype)";
+ * "_superEmitterMixin()" must be called from the constructor. Inheriters of the
+ * mixin can trigger events calling "_trigger('eventName', [arguments])".
+ *
+ * Clients of the emitter can subscribe to events calling "on('eventName',
+ * eventHandler)", and desubscribe calling "off('eventName', eventHandler)". The
+ * event handler should be defined as "eventHandler(emitter, argument0,
+ * argument1...)". The same subscribed event handler must be provided to
+ * desubscribe it, so an inline function would not work (a function stored in a
+ * variable and probably bound to a specific object may need to be used
+ * instead).
+ */
+export default (function() {
+
+ /**
+ * Mixin constructor.
+ *
+ * Adds mixin attributes to objects inheriting the mixin.
+ *
+ * This must be called in their constructor by classes inheriting the mixin.
+ */
+ function _superEmitterMixin() {
+ this._handlers = []
+ }
+
+ /**
+ * @param {string} event the name of the event
+ * @param {Function} handler the handler function to register
+ */
+ function on(event, handler) {
+ if (!Object.prototype.hasOwnProperty.call(this._handlers, event)) {
+ this._handlers[event] = [handler]
+ } else {
+ this._handlers[event].push(handler)
+ }
+ }
+
+ /**
+ * @param {string} event the name of the event
+ * @param {Function} handler the handler function to deregister
+ */
+ function off(event, handler) {
+ const handlers = this._handlers[event]
+ if (!handlers) {
+ return
+ }
+
+ const index = handlers.indexOf(handler)
+ if (index !== -1) {
+ handlers.splice(index, 1)
+ }
+ }
+
+ /**
+ * @param {string} event the name of the event
+ * @param {Array} args the arguments of the event
+ */
+ function _trigger(event, args) {
+ let handlers = this._handlers[event]
+ if (!handlers) {
+ return
+ }
+
+ if (!args) {
+ args = []
+ }
+
+ args.unshift(this)
+
+ handlers = handlers.slice(0)
+ for (let i = 0; i < handlers.length; i++) {
+ const handler = handlers[i]
+ handler.apply(handler, args)
+ }
+ }
+
+ return function() {
+ // Add methods to the prototype from the functions defined above
+ this._superEmitterMixin = _superEmitterMixin
+ this.on = on
+ this.off = off
+ this._trigger = _trigger
+ }
+})()
diff --git a/src/utils/webrtc/MediaDevicesManager.js b/src/utils/webrtc/MediaDevicesManager.js
index f39e37b87..cc41d075f 100644
--- a/src/utils/webrtc/MediaDevicesManager.js
+++ b/src/utils/webrtc/MediaDevicesManager.js
@@ -20,6 +20,7 @@
*/
import BrowserStorage from '../../services/BrowserStorage'
+import EmitterMixin from '../EmitterMixin'
/**
* Special string to set null device ids in local storage (as only strings are
@@ -74,6 +75,8 @@ const LOCAL_STORAGE_NULL_DEVICE_ID = 'local-storage-null-device-id'
* (in that case the fallback devices will not be taken into account).
*/
export default function MediaDevicesManager() {
+ this._superEmitterMixin()
+
this.attributes = {
devices: [],
@@ -81,8 +84,6 @@ export default function MediaDevicesManager() {
videoInputId: undefined,
}
- this._handlers = []
-
this._enabledCount = 0
this._knownDevices = {}
@@ -135,41 +136,6 @@ MediaDevicesManager.prototype = {
}
},
- on(event, handler) {
- if (!Object.prototype.hasOwnProperty.call(this._handlers, event)) {
- this._handlers[event] = [handler]
- } else {
- this._handlers[event].push(handler)
- }
- },
-
- off(event, handler) {
- const handlers = this._handlers[event]
- if (!handlers) {
- return
- }
-
- const index = handlers.indexOf(handler)
- if (index !== -1) {
- handlers.splice(index, 1)
- }
- },
-
- _trigger(event, args) {
- let handlers = this._handlers[event]
- if (!handlers) {
- return
- }
-
- args.unshift(this)
-
- handlers = handlers.slice(0)
- for (let i = 0; i < handlers.length; i++) {
- const handler = handlers[i]
- handler.apply(handler, args)
- }
- },
-
/**
* Returns whether getting user media and enumerating media devices is
* supported or not.
@@ -501,3 +467,5 @@ MediaDevicesManager.prototype = {
}
},
}
+
+EmitterMixin.apply(MediaDevicesManager.prototype)
diff --git a/src/utils/webrtc/analyzers/CallAnalyzer.js b/src/utils/webrtc/analyzers/CallAnalyzer.js
index 689fb5d7d..b41e39ac0 100644
--- a/src/utils/webrtc/analyzers/CallAnalyzer.js
+++ b/src/utils/webrtc/analyzers/CallAnalyzer.js
@@ -19,6 +19,8 @@
*
*/
+import EmitterMixin from '../../EmitterMixin'
+
import {
ParticipantAnalyzer,
} from './ParticipantAnalyzer'
@@ -50,14 +52,14 @@ import {
* for the remote participants.
*/
export default function CallAnalyzer(localMediaModel, localCallParticipantModel, callParticipantCollection) {
+ this._superEmitterMixin()
+
this.attributes = {
senderConnectionQualityAudio: null,
senderConnectionQualityVideo: null,
senderConnectionQualityScreen: null,
}
- this._handlers = []
-
this._localMediaModel = localMediaModel
this._localCallParticipantModel = localCallParticipantModel
this._callParticipantCollection = callParticipantCollection
@@ -87,41 +89,6 @@ CallAnalyzer.prototype = {
this._trigger('change:' + key, [value])
},
- on(event, handler) {
- if (!Object.prototype.hasOwnProperty.call(this._handlers, event)) {
- this._handlers[event] = [handler]
- } else {
- this._handlers[event].push(handler)
- }
- },
-
- off(event, handler) {
- const handlers = this._handlers[event]
- if (!handlers) {
- return
- }
-
- const index = handlers.indexOf(handler)
- if (index !== -1) {
- handlers.splice(index, 1)
- }
- },
-
- _trigger(event, args) {
- let handlers = this._handlers[event]
- if (!handlers) {
- return
- }
-
- args.unshift(this)
-
- handlers = handlers.slice(0)
- for (let i = 0; i < handlers.length; i++) {
- const handler = handlers[i]
- handler.apply(handler, args)
- }
- },
-
destroy() {
if (this._localParticipantAnalyzer) {
this._localParticipantAnalyzer.off('change:senderConnectionQualityAudio', this._handleSenderConnectionQualityAudioChangeBound)
@@ -145,3 +112,5 @@ CallAnalyzer.prototype = {
},
}
+
+EmitterMixin.apply(CallAnalyzer.prototype)
diff --git a/src/utils/webrtc/analyzers/ParticipantAnalyzer.js b/src/utils/webrtc/analyzers/ParticipantAnalyzer.js
index 865fa26d4..390aadd97 100644
--- a/src/utils/webrtc/analyzers/ParticipantAnalyzer.js
+++ b/src/utils/webrtc/analyzers/ParticipantAnalyzer.js
@@ -19,6 +19,8 @@
*
*/
+import EmitterMixin from '../../EmitterMixin'
+
import {
PEER_DIRECTION,
PeerConnectionAnalyzer,
@@ -57,7 +59,7 @@ import {
* to stop the analysis.
*/
function ParticipantAnalyzer() {
- this._handlers = []
+ this._superEmitterMixin()
this._localMediaModel = null
this._localCallParticipantModel = null
@@ -83,41 +85,6 @@ function ParticipantAnalyzer() {
}
ParticipantAnalyzer.prototype = {
- on(event, handler) {
- if (!Object.prototype.hasOwnProperty.call(this._handlers, event)) {
- this._handlers[event] = [handler]
- } else {
- this._handlers[event].push(handler)
- }
- },
-
- off(event, handler) {
- const handlers = this._handlers[event]
- if (!handlers) {
- return
- }
-
- const index = handlers.indexOf(handler)
- if (index !== -1) {
- handlers.splice(index, 1)
- }
- },
-
- _trigger(event, args) {
- let handlers = this._handlers[event]
- if (!handlers) {
- return
- }
-
- args.unshift(this)
-
- handlers = handlers.slice(0)
- for (let i = 0; i < handlers.length; i++) {
- const handler = handlers[i]
- handler.apply(handler, args)
- }
- },
-
destroy() {
if (this._localCallParticipantModel) {
this._localCallParticipantModel.off('change:peer', this._handlePeerChangeBound)
@@ -350,6 +317,8 @@ ParticipantAnalyzer.prototype = {
}
+EmitterMixin.apply(ParticipantAnalyzer.prototype)
+
export {
ParticipantAnalyzer,
}
diff --git a/src/utils/webrtc/analyzers/PeerConnectionAnalyzer.js b/src/utils/webrtc/analyzers/PeerConnectionAnalyzer.js
index 6d89c63d2..557551b87 100644
--- a/src/utils/webrtc/analyzers/PeerConnectionAnalyzer.js
+++ b/src/utils/webrtc/analyzers/PeerConnectionAnalyzer.js
@@ -19,6 +19,8 @@
*
*/
+import EmitterMixin from '../../EmitterMixin'
+
import {
STAT_VALUE_TYPE,
AverageStatValue,
@@ -72,6 +74,8 @@ const PEER_DIRECTION = {
* not be enough.
*/
function PeerConnectionAnalyzer() {
+ this._superEmitterMixin()
+
this._packets = {
audio: new AverageStatValue(5, STAT_VALUE_TYPE.CUMULATIVE),
video: new AverageStatValue(5, STAT_VALUE_TYPE.CUMULATIVE),
@@ -128,8 +132,6 @@ function PeerConnectionAnalyzer() {
video: true,
}
- this._handlers = []
-
this._peerConnection = null
this._peerDirection = null
@@ -146,41 +148,6 @@ function PeerConnectionAnalyzer() {
}
PeerConnectionAnalyzer.prototype = {
- on(event, handler) {
- if (!Object.prototype.hasOwnProperty.call(this._handlers, event)) {
- this._handlers[event] = [handler]
- } else {
- this._handlers[event].push(handler)
- }
- },
-
- off(event, handler) {
- const handlers = this._handlers[event]
- if (!handlers) {
- return
- }
-
- const index = handlers.indexOf(handler)
- if (index !== -1) {
- handlers.splice(index, 1)
- }
- },
-
- _trigger(event, args) {
- let handlers = this._handlers[event]
- if (!handlers) {
- return
- }
-
- args.unshift(this)
-
- handlers = handlers.slice(0)
- for (let i = 0; i < handlers.length; i++) {
- const handler = handlers[i]
- handler.apply(handler, args)
- }
- },
-
getConnectionQualityAudio() {
return this._connectionQuality.audio
},
@@ -748,6 +715,8 @@ PeerConnectionAnalyzer.prototype = {
}
+EmitterMixin.apply(PeerConnectionAnalyzer.prototype)
+
export {
CONNECTION_QUALITY,
PEER_DIRECTION,
diff --git a/src/utils/webrtc/models/CallParticipantCollection.js b/src/utils/webrtc/models/CallParticipantCollection.js
index 879339a07..1fce98f9c 100644
--- a/src/utils/webrtc/models/CallParticipantCollection.js
+++ b/src/utils/webrtc/models/CallParticipantCollection.js
@@ -19,6 +19,8 @@
*
*/
+import EmitterMixin from '../../EmitterMixin'
+
import CallParticipantModel from './CallParticipantModel'
/**
@@ -26,49 +28,14 @@ import CallParticipantModel from './CallParticipantModel'
*/
export default function CallParticipantCollection() {
- this.callParticipantModels = []
+ this._superEmitterMixin()
- this._handlers = []
+ this.callParticipantModels = []
}
CallParticipantCollection.prototype = {
- on(event, handler) {
- if (!Object.prototype.hasOwnProperty.call(this._handlers, event)) {
- this._handlers[event] = [handler]
- } else {
- this._handlers[event].push(handler)
- }
- },
-
- off(event, handler) {
- const handlers = this._handlers[event]
- if (!handlers) {
- return
- }
-
- const index = handlers.indexOf(handler)
- if (index !== -1) {
- handlers.splice(index, 1)
- }
- },
-
- _trigger(event, args) {
- let handlers = this._handlers[event]
- if (!handlers) {
- return
- }
-
- args.unshift(this)
-
- handlers = handlers.slice(0)
- for (let i = 0; i < handlers.length; i++) {
- const handler = handlers[i]
- handler.apply(handler, args)
- }
- },
-
add(options) {
const callParticipantModel = new CallParticipantModel(options)
this.callParticipantModels.push(callParticipantModel)
@@ -102,3 +69,5 @@ CallParticipantCollection.prototype = {
},
}
+
+EmitterMixin.apply(CallParticipantCollection.prototype)
diff --git a/src/utils/webrtc/models/CallParticipantModel.js b/src/utils/webrtc/models/CallParticipantModel.js
index 101a97f9b..f10c47aa7 100644
--- a/src/utils/webrtc/models/CallParticipantModel.js
+++ b/src/utils/webrtc/models/CallParticipantModel.js
@@ -21,6 +21,8 @@
import attachMediaStream from 'attachmediastream'
+import EmitterMixin from '../../EmitterMixin'
+
export const ConnectionState = {
NEW: 'new',
CHECKING: 'checking',
@@ -40,6 +42,8 @@ export const ConnectionState = {
*/
export default function CallParticipantModel(options) {
+ this._superEmitterMixin()
+
this.attributes = {
peerId: null,
nextcloudSessionId: null,
@@ -65,8 +69,6 @@ export default function CallParticipantModel(options) {
},
}
- this._handlers = []
-
this.set('peerId', options.peerId)
this._webRtc = options.webRtc
@@ -115,45 +117,6 @@ CallParticipantModel.prototype = {
this._trigger('change:' + key, [value])
},
- on(event, handler) {
- if (!Object.prototype.hasOwnProperty.call(this._handlers, event)) {
- this._handlers[event] = [handler]
- } else {
- this._handlers[event].push(handler)
- }
- },
-
- off(event, handler) {
- const handlers = this._handlers[event]
- if (!handlers) {
- return
- }
-
- const index = handlers.indexOf(handler)
- if (index !== -1) {
- handlers.splice(index, 1)
- }
- },
-
- _trigger(event, args) {
- let handlers = this._handlers[event]
- if (!handlers) {
- return
- }
-
- if (!args) {
- args = []
- }
-
- args.unshift(this)
-
- handlers = handlers.slice(0)
- for (let i = 0; i < handlers.length; i++) {
- const handler = handlers[i]
- handler.apply(handler, args)
- }
- },
-
_handlePeerStreamAdded(peer) {
if (this.get('peer') === peer) {
this.set('stream', this.get('peer').stream || null)
@@ -385,3 +348,5 @@ CallParticipantModel.prototype = {
},
}
+
+EmitterMixin.apply(CallParticipantModel.prototype)
diff --git a/src/utils/webrtc/models/LocalCallParticipantModel.js b/src/utils/webrtc/models/LocalCallParticipantModel.js
index f678da597..112a51624 100644
--- a/src/utils/webrtc/models/LocalCallParticipantModel.js
+++ b/src/utils/webrtc/models/LocalCallParticipantModel.js
@@ -19,6 +19,7 @@
*
*/
+import EmitterMixin from '../../EmitterMixin'
import store from '../../../store/index.js'
import { ConnectionState } from './CallParticipantModel'
@@ -28,6 +29,8 @@ import { ConnectionState } from './CallParticipantModel'
*/
export default function LocalCallParticipantModel() {
+ this._superEmitterMixin()
+
this.attributes = {
peerId: null,
peer: null,
@@ -36,8 +39,6 @@ export default function LocalCallParticipantModel() {
connectionState: null,
}
- this._handlers = []
-
this._handleForcedMuteBound = this._handleForcedMute.bind(this)
this._handleExtendedIceConnectionStateChangeBound = this._handleExtendedIceConnectionStateChange.bind(this)
@@ -55,45 +56,6 @@ LocalCallParticipantModel.prototype = {
this._trigger('change:' + key, [value])
},
- on(event, handler) {
- if (!Object.prototype.hasOwnProperty.call(this._handlers, event)) {
- this._handlers[event] = [handler]
- } else {
- this._handlers[event].push(handler)
- }
- },
-
- off(event, handler) {
- const handlers = this._handlers[event]
- if (!handlers) {
- return
- }
-
- const index = handlers.indexOf(handler)
- if (index !== -1) {
- handlers.splice(index, 1)
- }
- },
-
- _trigger(event, args) {
- let handlers = this._handlers[event]
- if (!handlers) {
- return
- }
-
- if (!args) {
- args = []
- }
-
- args.unshift(this)
-
- handlers = handlers.slice(0)
- for (let i = 0; i < handlers.length; i++) {
- const handler = handlers[i]
- handler.apply(handler, args)
- }
- },
-
setWebRtc(webRtc) {
if (this._webRtc) {
this._webRtc.off('forcedMute', this._handleForcedMuteBound)
@@ -193,3 +155,5 @@ LocalCallParticipantModel.prototype = {
},
}
+
+EmitterMixin.apply(LocalCallParticipantModel.prototype)
diff --git a/src/utils/webrtc/models/LocalMediaModel.js b/src/utils/webrtc/models/LocalMediaModel.js
index 9db015ec2..3e04fa7f1 100644
--- a/src/utils/webrtc/models/LocalMediaModel.js
+++ b/src/utils/webrtc/models/LocalMediaModel.js
@@ -19,6 +19,7 @@
*
*/
+import EmitterMixin from '../../EmitterMixin'
import store from '../../../store/index.js'
/**
@@ -26,6 +27,8 @@ import store from '../../../store/index.js'
*/
export default function LocalMediaModel() {
+ this._superEmitterMixin()
+
this.attributes = {
localStreamRequestVideoError: null,
localStream: null,
@@ -42,8 +45,6 @@ export default function LocalMediaModel() {
raisedHand: false,
}
- this._handlers = []
-
this._handleLocalStreamRequestedBound = this._handleLocalStreamRequested.bind(this)
this._handleLocalStreamBound = this._handleLocalStream.bind(this)
this._handleLocalStreamRequestFailedRetryNoVideoBound = this._handleLocalStreamRequestFailedRetryNoVideo.bind(this)
@@ -76,41 +77,6 @@ LocalMediaModel.prototype = {
this._trigger('change:' + key, [value])
},
- on(event, handler) {
- if (!Object.prototype.hasOwnProperty.call(this._handlers, event)) {
- this._handlers[event] = [handler]
- } else {
- this._handlers[event].push(handler)
- }
- },
-
- off(event, handler) {
- const handlers = this._handlers[event]
- if (!handlers) {
- return
- }
-
- const index = handlers.indexOf(handler)
- if (index !== -1) {
- handlers.splice(index, 1)
- }
- },
-
- _trigger(event, args) {
- let handlers = this._handlers[event]
- if (!handlers) {
- return
- }
-
- args.unshift(this)
-
- handlers = handlers.slice(0)
- for (let i = 0; i < handlers.length; i++) {
- const handler = handlers[i]
- handler.apply(handler, args)
- }
- },
-
getWebRtc() {
return this._webRtc
},
@@ -462,3 +428,5 @@ LocalMediaModel.prototype = {
},
}
+
+EmitterMixin.apply(LocalMediaModel.prototype)