jiti-meet/modules/API/API.js

252 lines
6.4 KiB
JavaScript

/* global APP */
/**
* Implements API class that communicates with external api class
* and provides interface to access Jitsi Meet features by external
* applications that embed Jitsi Meet
*/
/**
* List of the available commands.
* @type {{
* displayName: inputDisplayNameHandler,
* toggleAudio: toggleAudio,
* toggleVideo: toggleVideo,
* toggleFilmStrip: toggleFilmStrip,
* toggleChat: toggleChat,
* toggleContactList: toggleContactList
* }}
*/
var commands = {};
function initCommands() {
commands = {
displayName: APP.UI.inputDisplayNameHandler,
toggleAudio: APP.conference.toggleAudioMuted,
toggleVideo: APP.conference.toggleVideoMuted,
toggleFilmStrip: APP.UI.toggleFilmStrip,
toggleChat: APP.UI.toggleChat,
toggleContactList: APP.UI.toggleContactList
};
}
/**
* Maps the supported events and their status
* (true it the event is enabled and false if it is disabled)
* @type {{
* incomingMessage: boolean,
* outgoingMessage: boolean,
* displayNameChange: boolean,
* participantJoined: boolean,
* participantLeft: boolean
* }}
*/
const events = {
incomingMessage: false,
outgoingMessage:false,
displayNameChange: false,
participantJoined: false,
participantLeft: false
};
/**
* Processes commands from external application.
* @param message the object with the command
*/
function processCommand(message) {
if (message.action != "execute") {
console.error("Unknown action of the message");
return;
}
for (var key in message) {
if(commands[key])
commands[key].apply(null, message[key]);
}
}
/**
* Processes events objects from external applications
* @param event the event
*/
function processEvent(event) {
if (!event.action) {
console.error("Event with no action is received.");
return;
}
var i = 0;
switch(event.action) {
case "add":
for (; i < event.events.length; i++) {
events[event.events[i]] = true;
}
break;
case "remove":
for (; i < event.events.length; i++) {
events[event.events[i]] = false;
}
break;
default:
console.error("Unknown action for event.");
}
}
/**
* Sends message to the external application.
* @param object
*/
function sendMessage(object) {
window.parent.postMessage(JSON.stringify(object), "*");
}
/**
* Processes a message event from the external application
* @param event the message event
*/
function processMessage(event) {
var message;
try {
message = JSON.parse(event.data);
} catch (e) {}
if(!message.type)
return;
switch (message.type) {
case "command":
processCommand(message);
break;
case "event":
processEvent(message);
break;
default:
console.error("Unknown type of the message");
return;
}
}
/**
* Check whether the API should be enabled or not.
* @returns {boolean}
*/
function isEnabled () {
let hash = location.hash;
return hash && hash.indexOf("external") > -1 && window.postMessage;
}
/**
* Checks whether the event is enabled ot not.
* @param name the name of the event.
* @returns {*}
*/
function isEventEnabled (name) {
return events[name];
}
/**
* Sends event object to the external application that has been subscribed
* for that event.
* @param name the name event
* @param object data associated with the event
*/
function triggerEvent (name, object) {
if (isEnabled() && isEventEnabled(name)) {
sendMessage({
type: "event",
action: "result",
event: name,
result: object
});
}
}
export default {
/**
* Initializes the APIConnector. Setups message event listeners that will
* receive information from external applications that embed Jitsi Meet.
* It also sends a message to the external application that APIConnector
* is initialized.
*/
init: function () {
if (!isEnabled()) {
return;
}
initCommands();
if (window.addEventListener) {
window.addEventListener('message', processMessage, false);
} else {
window.attachEvent('onmessage', processMessage);
}
sendMessage({type: "system", loaded: true});
},
/**
* Notify external application (if API is enabled) that message was sent.
* @param {string} body message body
*/
notifySendingChatMessage (body) {
triggerEvent("outgoingMessage", {"message": body});
},
/**
* Notify external application (if API is enabled) that
* message was received.
* @param {string} id user id
* @param {string} nick user nickname
* @param {string} body message body
* @param {number} ts message creation timestamp
*/
notifyReceivedChatMessage (id, nick, body, ts) {
if (APP.conference.isLocalId(id)) {
return;
}
triggerEvent(
"incomingMessage",
{"from": id, "nick": nick, "message": body, "stamp": ts}
);
},
/**
* Notify external application (if API is enabled) that
* user joined the conference.
* @param {string} id user id
*/
notifyUserJoined (id) {
triggerEvent("participantJoined", {id});
},
/**
* Notify external application (if API is enabled) that
* user left the conference.
* @param {string} id user id
*/
notifyUserLeft (id) {
triggerEvent("participantLeft", {id});
},
/**
* Notify external application (if API is enabled) that
* user changed their nickname.
* @param {string} id user id
* @param {string} displayName user nickname
*/
notifyDisplayNameChanged (id, displayName) {
triggerEvent("displayNameChange", {id, displayname: displayName});
},
/**
* Removes the listeners.
*/
dispose: function () {
if (!isEnabled()) {
return;
}
if (window.removeEventListener) {
window.removeEventListener("message", processMessage, false);
} else {
window.detachEvent('onmessage', processMessage);
}
}
};