Last active
October 1, 2020 06:28
-
-
Save a-gu/9cc1b4caf6440cb2b918c13c72e0d0ce to your computer and use it in GitHub Desktop.
Userscript for a better experience using Zoom web conferencing in a web browser
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Better Browser Zoom | |
// @version 0.6 | |
// @description Userscript for a better experience using Zoom web conferencing in a web browser | |
// @author Andrew Gu | |
// @updateURL https://gist.githubusercontent.com/a-gu/9cc1b4caf6440cb2b918c13c72e0d0ce/raw/better_browser_zoom.user.js | |
// @grant unsafeWindow | |
// @grant GM_addStyle | |
// @grant GM_setValue | |
// @grant GM_getValue | |
// @grant GM_notification | |
// @match https://*.zoom.us/* | |
// @run-at document-idle | |
// ==/UserScript== | |
(function() { | |
'use strict'; | |
GM_addStyle(` | |
.bbz-link { | |
color: #0e71eb; | |
font-size: 3em; | |
font-weight: bold; | |
transition: transform 0.5s ease; | |
} | |
.bbz-link:not(:hover):not(:focus) { | |
animation: 2s ease infinite attention; | |
} | |
.bbz-link:hover, | |
.bbz-link:focus { | |
transform: scale(1.1) rotate(0); | |
} | |
.bbz-autofill-join-name { | |
margin: 0.5em 0; | |
} | |
@keyframes attention { | |
40% { transform: scale(1) rotate(0); } | |
50%, 60% { transform: scale(1.1) rotate(1.5deg); } | |
75% { transform: scale(0.95) rotate(-1.5deg); } | |
} | |
`) | |
let browserJoinLink = function () { | |
if (!/^Launch Meeting\b/.test(document.querySelector('title').innerText)) { return } | |
let observer = new MutationObserver(function () { | |
let uiContainer = document.querySelector('#zoom-ui-frame') | |
if (!uiContainer) { return } | |
// determine action URL and label | |
let actionURL = atob(unsafeWindow.launchBase64).match(/\u001a.(.+?)"/)[1] | |
let actionText = '' | |
if (/\/start$/.test(actionURL)) { | |
actionText = 'Start From Your Browser' | |
} else if (/^[^?&]+\/join\/[^\/]+(\?|$)/.test(actionURL)) { | |
actionText = 'Join From Your Browser' | |
} else { | |
console.warn('Unknown launchURL', actionURL) | |
observer.disconnect() | |
return | |
} | |
// generate UI | |
let webJoinAnchor = document.createElement('a') | |
webJoinAnchor.href = actionURL | |
webJoinAnchor.innerText = actionText | |
webJoinAnchor.classList.add('bbz-link') | |
uiContainer.prepend(webJoinAnchor) | |
observer.disconnect() | |
}) | |
observer.observe(document.body, { | |
attributes: true, | |
attributeFilter: [ 'id' ], | |
childList: true, | |
subtree: true | |
}) | |
} | |
browserJoinLink() | |
let autofillJoinName = function () { | |
let nameInput = document.querySelector('input#inputname') | |
if (!nameInput) { return false } | |
let autofillName | |
let rememberedName = function (type, key, value) { | |
let store = JSON.parse(GM_getValue(`bbz-autofill-join-name-${type}`, '{}')) | |
let now = (new Date()).getTime() | |
// set new values | |
if (value) { store[key] = { value: value, expiry: now + 365*24*3600e3 } } | |
// remove expired stores | |
for (let filterKey in store) { | |
if (store[key].expiry < now) { | |
delete store[key] | |
} | |
} | |
// persist modified store | |
GM_setValue(`bbz-autofill-join-name-${type}`, JSON.stringify(store)) | |
// return requested value | |
if (key in store) { return store[key].value } | |
} | |
// load remembered name | |
let accountIDs = Array.from(document.scripts).map(script => script.innerText.match(/var userId *= *'([^']+)' *;/)).filter(x => !!x) | |
let rememberIDs = { | |
'meeting': document.querySelector('input#meeting_number').value, | |
'account': accountIDs.length ? accountIDs[0][1] : null, | |
'global': 'global' | |
} | |
autofillName = autofillName || rememberedName('meeting', rememberIDs.meeting) | |
autofillName = autofillName || rememberedName('account', rememberIDs.account) | |
autofillName = autofillName || rememberedName('global', 'global') | |
// autofill loaded name | |
if (autofillName) { nameInput.value = autofillName } | |
// generate UI | |
let rememberOption = document.createElement('div') | |
rememberOption.classList.add('bbz-autofill-join-name') | |
rememberOption.appendChild(document.createTextNode('Remember name for ')) | |
let rememberSelect = document.createElement('select') | |
rememberOption.appendChild(rememberSelect) | |
let rememberLabels = { 'meeting': 'this meeting', 'account': 'this account', 'global': 'everything' } | |
Object.keys(rememberLabels).forEach(type => { | |
let option = document.createElement('option') | |
option.setAttribute('value', type) | |
option.innerText = rememberLabels[type] | |
rememberSelect.appendChild(option) | |
}) | |
nameInput.parentNode.appendChild(rememberOption) | |
// save name on join | |
let saveName = () => { | |
if (rememberSelect.value in rememberLabels) { | |
rememberedName(rememberSelect.value, rememberIDs[rememberSelect.value], nameInput.value) | |
} | |
} | |
document.querySelector('button#joinBtn').addEventListener('click', saveName) | |
nameInput.closest('form').addEventListener('submit', saveName) | |
} | |
autofillJoinName() | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment