From 30f50e5ca65e1bfe90023a614f75560e7a929089 Mon Sep 17 00:00:00 2001 From: Dele Olajide Date: Tue, 20 Jun 2023 21:33:19 +0100 Subject: [PATCH] update galene plugin --- packages/galene/galene-ui.js | 42 +++-- packages/galene/galene.css | 8 +- packages/galene/galene.js | 286 ++++++++++++----------------------- packages/galene/index.html | 2 +- 4 files changed, 136 insertions(+), 202 deletions(-) diff --git a/packages/galene/galene-ui.js b/packages/galene/galene-ui.js index 4c8fa7e..9e38167 100644 --- a/packages/galene/galene-ui.js +++ b/packages/galene/galene-ui.js @@ -2769,6 +2769,8 @@ function formatToken(token, details) { let url = new URL(window.location.href); let params = new URLSearchParams(); params.append('token', token.token); + params.append('room', token.group); // BAO + params.append('username', token.username); // BAO url.search = params.toString(); let foruser = '', by = '', togroup = ''; if(token.username) @@ -3992,19 +3994,24 @@ window.onload = async function() { serverConnection.onchat = addToChatbox; serverConnection.onusermessage = gotUserMessage; serverConnection.onfiletransfer = gotFileTransfer; - - group = urlParam("group") ? "public/" + urlParam("group") : "public"; + + token = urlParam("token"); + group = urlParam("room") ? urlParam("room") : "public"; setTitle(capitalise(group)); addFilters(); - setMediaChoices(false).then(e => reflectSettings()); + setMediaChoices(false).then(e => reflectSettings()); + handleConnection(); } async function handleConnection() { const host = urlParam("host") || location.hostname; + const server = urlParam("server") || location.host; const username = urlParam("username"); + const password = urlParam("password"); + const jid = (username && password) ? username + "@" + host : host; - console.debug("handleConnection", connection, host, username); + console.debug("handleConnection", connection, jid); if (connection) { await serverConnection.connect(connection, host); @@ -4012,9 +4019,9 @@ async function handleConnection() { } else { standalone = true; - connection = new Strophe.Connection((location.protocol == "https:" ? "wss:" : "ws:") + "//" + location.host + "/ws/"); + connection = new Strophe.Connection((location.protocol == "http:" ? "ws:" : "wss:") + "//" + server + "/ws/"); - connection.connect(host, null, async function (status) { + connection.connect(jid, password, async function (status) { console.debug("onload xmpp.connect", status); if (status === Strophe.Status.CONNECTED) { @@ -4044,15 +4051,30 @@ function urlParam (name) { async function amConnected() { console.debug("amConnected"); + const server = urlParam("server") || ((location.protocol == "http:" ? "http:" : "https:") + "//" + location.host + "/galene"); setConnected(true); connectingAgain = false; - const username = urlParam("username") || localStorage.getItem("galene_username") || prompt("Enter username"); - const pw = ""; + let username, credentials; + + if (token) { + username = urlParam("username") || ""; + credentials = {type: 'token', token: token }; + } + else + + if (urlParam("room")) { + username = urlParam("username") || connection.jid.split("@")[0] || ""; + credentials = { + type: 'authServer', + authServer: server + "/auth-server", + location: location.href, + password: urlParam("password") || connection.pass || "" + }; + } try { - await serverConnection.join(group, username, pw); - localStorage.setItem("galene_username", username); + await serverConnection.join(group, username, credentials); } catch(e) { console.error(e); serverConnection.close(); diff --git a/packages/galene/galene.css b/packages/galene/galene.css index 16fd0c9..287b05d 100644 --- a/packages/galene/galene.css +++ b/packages/galene/galene.css @@ -119,7 +119,7 @@ align-items: center; -webkit-box-pack: justify; justify-content: space-between; - background: #610a86; + background: #616a86; /* BAO */ } .navbar { position: relative; @@ -274,7 +274,7 @@ .users-header { height: 3.5rem; padding: 10px; - background: #610a86; + background: #616a86; /* BAO */ font-size: .95rem; font-weight: 500; } @@ -902,7 +902,7 @@ h1 { } .peer-active { - border: 2px solid #610a86; + border: 2px solid #616a86; /* BAO */ } .peer-hidden { @@ -1333,7 +1333,7 @@ header .collapse:hover { } .file-progress { - accent-color: #610a86; + accent-color: #616a86; /* BAO */ margin-left: 10px; margin-right: 10px; } diff --git a/packages/galene/galene.js b/packages/galene/galene.js index 223ce55..1b3f096 100644 --- a/packages/galene/galene.js +++ b/packages/galene/galene.js @@ -27,17 +27,21 @@ _ = converse.env._; __ = _converse.__; - setupStrophePlugins(); + setupStrophePlugins(); + + const domain = location.hostname; + const server = location.host; + const url = (domain == "localhost" || location.protocol == "http:" ? "http://" : "https://") + server + "/galene"; _converse.api.settings.update({ - visible_toolbar_buttons: {call: true}, + visible_toolbar_buttons: {call: false}, galene_head_display_toggle: false, - galene_url: location.protocol + "//" + location.host + "/galene", - galene_host: location.hostname + galene_url: url, + galene_host: domain }); galene_confirm = __('Galene Conference/Webinar?'); - galene_invitation = __('Please join conference with'); + galene_invitation = __('Please join webinar in room at'); galene_tab_invitation = __('Or open in new tab at'); _converse.api.listen.on('messageNotification', function (data) @@ -50,18 +54,20 @@ if (bodyElement) { var body = bodyElement.innerHTML; - var url = _converse.api.settings.get("galene_signature"); + var url = _converse.api.settings.get("galene_url"); var pos = body.indexOf(url + "/"); - + if (pos > -1) { - var group = urlParam ("group", body); + var group = urlParam ("room", body); var host = urlParam ("host", body); var label = galene_invitation; var from = chatbox.getDisplayName().trim(); var avatar = _converse.api.settings.get("notification_icon"); - if (data.chatbox.vcard.attributes.image) avatar = data.chatbox.vcard.attributes.image; + if (data.chatbox.vcard.attributes.image) { + avatar = "data:" + data.chatbox.vcard.attributes.image_type + ";base64," + data.chatbox.vcard.attributes.image; + } var prompt = new Notification(from, { @@ -90,42 +96,46 @@ _converse.api.listen.on('callButtonClicked', function(data) { handleCallRequest(data.model); - }); - + }); + _converse.api.listen.on('getHeadingButtons', (el, buttons) => { buttons.push({'i18n_title': __('Toggle an audio call to ' + el.model.get('jid')), 'i18n_text': __('Call'), 'handler': ev => handleCallRequest(el.model), 'a_class': 'toggle-foo', 'icon_class': 'fa-phone', 'name': 'foo'}); return buttons; - }); + }); _converse.api.listen.on('getToolbarButtons', function(toolbar_el, buttons) { - if (galene_ready) { - console.debug("getToolbarButtons", toolbar_el.model.get("jid")); + if (galene_ready) { let color = "fill:var(--chat-toolbar-btn-color);"; if (toolbar_el.model.get("type") === "chatroom") color = "fill:var(--muc-toolbar-btn-color);"; - + buttons.push(html` - `); } - + return buttons; }); _converse.api.listen.on('connected', async function() { window.connection = _converse.connection; - - const features = await _converse.api.disco.getFeatures(_converse.api.settings.get("galene_host")); + + const server = _converse.api.settings.get("galene_host"); + console.debug("connected", server); + + const features = await _converse.api.disco.getFeatures(server); + console.debug("connected features", features); features.each(feature => { + console.debug("connected feature", feature); const fieldname = feature.get('var'); if (fieldname == "urn:xmpp:sfu:galene:0") { - console.debug("SFU found"); - galene_ready = true; + console.debug("galene SFU found"); + galene_ready = true; } }); @@ -133,7 +143,7 @@ const button = document.querySelector(".plugin-galene"); if (button) button.style.display = 'none'; } - + _converse.connection.addHandler(presence => { /* @@ -205,14 +215,13 @@ return true; }, 'urn:xmpp:rayo:1', 'presence'); - }); _converse.api.listen.on('afterMessageBodyTransformed', function(text) { if (text.indexOf("/galene/") > -1) { const url = text.substring(0); - const group = urlParam ("group", url); + const group = urlParam ("room", url); const host = urlParam ("host", url); if (group && host) { @@ -223,9 +232,8 @@ text.addTemplateResult(0, text.length, html`${link_label} ${group}`); } } - }); + }); - console.debug("galene plugin is ready"); } }); @@ -239,8 +247,11 @@ function terminateCall(model) { const target = model.get('jid'); - const myself = Strophe.getBareJidFromJid(_converse.connection.jid); - console.debug("terminateCall", target, myself); + const myself = Strophe.getBareJidFromJid(_converse.connection.jid); + const callId = Strophe.getNodeFromJid(_converse.connection.rayo.call_resource); + + console.debug("terminateCall", callId, target, myself); + serverConnection.leave("public/" + callId); _converse.connection.rayo.hangup(serverConnection.callHeaders); } @@ -274,8 +285,8 @@ serverConnection.callId = callId; serverConnection.connect(_converse.connection, _converse.api.settings.get("galene_host")); } - } - + } + function urlParam (name, url) { const results = new RegExp('[\\?&]' + name + '=([^&#]*)').exec(url); if (!results) { return undefined; } @@ -300,11 +311,19 @@ { ev.stopPropagation(); ev.preventDefault(); - - const chatView = getChatViewFromElement(ev.currentTarget); - __confirm(galene_confirm, function() { - doVideo(chatView); - }); + + if (galene_ready) { + const toolbar_el = converse.env.utils.ancestor(ev.target, 'converse-chat-toolbar'); + const chatView = _converse.chatboxviews.get(toolbar_el.model.get('jid')); + + if (chatView) { + __confirm(galene_confirm, function() { + doVideo(chatView); + }); + } + } else { + alert("Galene not found"); + } } function clickVideo(ev) @@ -314,23 +333,24 @@ const group = ev.target.getAttribute("data-group"); const host = ev.target.getAttribute("data-host"); + + const chatView = getChatViewFromElement(ev.currentTarget); - if (ev.currentTarget) { - const chatView = getChatViewFromElement(ev.currentTarget); - - if (chatView) { - doLocalVideo(chatView, group, galene_invitation, host); - } + console.debug("clickVideo", ev.target, group, host, chatView); + + if (chatView) { + doLocalVideo(chatView, group, galene_invitation, host); } } function doVideo(view) { - const host = _converse.api.settings.get("galene_host"); - const group = Strophe.getNodeFromJid(view.model.attributes.jid).toLowerCase().replace(/[\\]/g, '') + "-" + Math.random().toString(36).substr(2,9); - const url = _converse.api.settings.get("galene_url") + '/?group=' + group + "&host=" + host; + const isChatBox = view.model.get("type") == "chatbox" + const host = _converse.api.settings.get("galene_host"); + const group = (isChatBox ? "public/" : "") + Strophe.getNodeFromJid(view.model.attributes.jid).toLowerCase().replace(/[\\]/g, '') + "/" + Math.random().toString(36).substr(2,9); + const url = _converse.api.settings.get("galene_url") + '/?room=' + group + "&host=" + host; - console.debug("doVideo", group, url, view); + console.debug("doVideo", isChatBox, group, url, view); view.model.sendMessage({'body': url}); doLocalVideo(view, group, galene_invitation, host); @@ -342,118 +362,16 @@ console.debug("doLocalVideo", view, group, label, host); if (!host) host = _converse.api.settings.get("galene_host"); + const server = _converse.api.settings.get("galene_url"); const isOverlayedDisplay = _converse.api.settings.get("view_mode") === "overlayed"; const headDisplayToggle = isOverlayedDisplay || _converse.api.settings.get("galene_head_display_toggle") === true; const div = view.querySelector(headDisplayToggle ? ".chat-body" : ".box-flyout"); if (div) { - div.innerHTML = ''; - const jid = view.getAttribute("jid"); - if(Array.from(document.querySelectorAll("iframe.galene")).filter(f => f.__jid === jid).length > 0) { - __displayError(__('A webinar is already running in group')); - return; - } - const toggleHandler = function() { - galeneFrame.toggleHideShow(); - }; - const dynamicDisplayManager = new function() { - let __resizeHandler; - let __resizeWatchImpl; - this.start = function() { - const $chatBox = document.querySelector('.converse-chatboxes'); - const $anchor = document.querySelector('#conversejs.conversejs'); - __resizeHandler = function() { - const currentView = _converse.chatboxviews.get(jid) - if (currentView && headDisplayToggle) { - const $head = currentView.querySelector(".chat-head"); - $head.removeEventListener('dblclick', toggleHandler); - $head.addEventListener('dblclick', toggleHandler); - } - const currentDiv = currentView && currentView.querySelector(headDisplayToggle ? ".chat-body" : ".box-flyout"); - let top = currentDiv ? currentDiv.offsetTop : 0; - let left = currentDiv ? currentDiv.offsetLeft : 0; - let width = currentDiv ? currentDiv.offsetWidth : 0; - let height = currentDiv ? currentDiv.offsetHeight : 0; - let current = currentDiv && currentDiv.offsetParent; - while (current && current !== $anchor) { - top += current.offsetTop; - left += current.offsetLeft; - current = current.offsetParent; - } - galeneFrame.style.top = top + "px"; - galeneFrame.style.left = left + "px"; - galeneFrame.style.width = width + "px"; - galeneFrame.style.height = height + "px"; - }; - __resizeWatchImpl = new function() { - let __resizeObserver; - if (isOverlayedDisplay && typeof ResizeObserver === 'function') { - __resizeObserver = new ResizeObserver(function(entries) { - if (entries.length > 0) { - __resizeHandler(); - } - }); - } - const __resizeWatchEvents = ['controlBoxOpened', 'controlBoxClosed', 'chatBoxBlurred', - 'chatBoxFocused', 'chatBoxMinimized', 'chatBoxMaximized', - 'chatBoxViewInitialized', 'chatRoomViewInitialized']; - const __startResize = function() { - galeneFrame.style.pointerEvents = 'none'; - document.addEventListener('mousemove', __deferredResize); - }; - const __endResize = function() { - galeneFrame.style.pointerEvents = ''; - document.removeEventListener('mousemove', __deferredResize); - }; - let timeoutId; - const __deferredResize = function() { - clearTimeout(timeoutId); - timeoutId = setTimeout(__resizeHandler, 0); - }; - this.start = function() { - _converse.api.listen.on('startDiagonalResize', __startResize); - _converse.api.listen.on('startHorizontalResize', __startResize); - _converse.api.listen.on('startVerticalResize', __startResize); - document.addEventListener('mouseup', __endResize); - window.addEventListener('resize', __resizeHandler); - __resizeWatchEvents.forEach(c => _converse.api.listen.on(c, __deferredResize)); - if (__resizeObserver) { - __resizeObserver.observe(div); - __resizeObserver.observe($anchor); - __resizeObserver.observe($chatBox); - } - }; - this.close = function() { - _converse.api.listen.not('startDiagonalResize', __startResize); - _converse.api.listen.not('startHorizontalResize', __startResize); - _converse.api.listen.not('startVerticalResize', __startResize); - document.removeEventListener('mouseup', __endResize); - window.removeEventListener('resize', __resizeHandler); - __resizeWatchEvents.forEach(c => _converse.api.listen.not(c, __deferredResize)); - if (__resizeObserver) { - __resizeObserver.disconnect(); - } - }; - }; - galeneFrame.style.position = "absolute"; - $anchor.appendChild(galeneFrame); - __resizeWatchImpl.start(); - _converse.api.listen.on('chatBoxClosed', closeGalene); - this.triggerChange(); - }; - this.triggerChange = function() { - __resizeHandler(); - }; - this.close = function() { - __resizeWatchImpl.close(); - _converse.api.listen.not('chatBoxClosed', closeGalene); - }; - }; - let galeneFrame = document.createElement('iframe'); let firstTime = true; - let openChatbox = function (view) + let openChatbox = function () { let jid = view.model.get("jid"); let type = view.model.get("type"); @@ -471,62 +389,56 @@ let closeGalene = function(currentModel) { console.debug("doLocalVideo - closeGalene", this); - dynamicDisplayManager.triggerChange(); if (currentModel && currentModel.cid !== chatModel.cid) { return; } - dynamicDisplayManager.close(); galeneFrame.remove(); view.close(); - setTimeout(function() { openChatbox(view) }); + setTimeout(function() { openChatbox() }); } - let galeneIframeCloseHandler = function () - { - console.debug("doLocalVideo - galeneIframeCloseHandler"); - if (!firstTime) // meeting closed and root url is loaded - { - closeGalene(); - } - if (firstTime) firstTime = false; // ignore when galene-meet room url is loaded - }; - galeneFrame.toggleHideShow = function() { - if (galeneFrame.style.display === 'none') { - galeneFrame.show(); - } else { - galeneFrame.hide(); - } - }; - galeneFrame.show = function() { - galeneFrame.style.display = ''; - }; - galeneFrame.hide = function() { - galeneFrame.style.display = 'none'; + let galeneIframeCloseHandler = function () { + console.debug("doLocalVideo - galeneIframeCloseHandler"); + + if (!firstTime) { + closeGalene(); + } + + if (firstTime) { + firstTime = false; // ignore when galene-meet group url is loaded + + galeneFrame.contentWindow.addEventListener("message", function (event) { + if (typeof event.data === 'string') { + let data = JSON.parse(event.data); + let galeneEvent = data['galene_event']; + if ('close' === galeneEvent) { + closeGalene(); + } + } + }, false); + } }; + + const jid = view.model.attributes.jid; + let galeneFrame = document.createElement('iframe'); + galeneFrame.__jid = jid; galeneFrame.addEventListener("load", galeneIframeCloseHandler); - galeneFrame.setAttribute("src", "/community-plugins/packages/galene/index.html?username=" + Strophe.getNodeFromJid(_converse.connection.jid) + "&password=&host=" + host + "&group=" + group); + galeneFrame.setAttribute("src", "./packages/galene/index.html?room=" + group + "&username=" + Strophe.getNodeFromJid(_converse.connection.jid) + "&password=" + _converse.connection.pass + "&host=" + host + "&server=" + server); galeneFrame.setAttribute("class", "galene"); galeneFrame.setAttribute("allow", "microphone; camera;"); galeneFrame.setAttribute("frameborder", "0"); galeneFrame.setAttribute("seamless", "seamless"); galeneFrame.setAttribute("allowfullscreen", "true"); galeneFrame.setAttribute("scrolling", "no"); - galeneFrame.setAttribute("style", "z-index:1049;width:100%;height:100%;"); - dynamicDisplayManager.start(); - - galeneFrame.contentWindow.addEventListener("message", function (event) { - if (typeof event.data === 'string') { - let data = JSON.parse(event.data); - let galeneEvent = data['galene_event']; - if ('close' === galeneEvent) { - closeGalene(); - } - } - }, false); + galeneFrame.setAttribute("style", "width:100%; height:100%; border:none; margin:0; padding:0; overflow:hidden;"); + + div.innerHTML = ""; + div.appendChild(galeneFrame); + } } - + function showStatus(header, status) { let place = document.querySelector('converse-message-form[jid="' + header.caller_id + '"] .chat-textarea, converse-muc-message-form[jid="' + header.caller_id + '"] .chat-textarea'); diff --git a/packages/galene/index.html b/packages/galene/index.html index d4ecab8..1854435 100644 --- a/packages/galene/index.html +++ b/packages/galene/index.html @@ -5,7 +5,7 @@ - +