mirror of
https://github.com/jech/galene.git
synced 2024-12-23 15:55:47 +01:00
264 lines
9.6 KiB
JavaScript
264 lines
9.6 KiB
JavaScript
|
'use strict';
|
||
|
let galeneKeys = {
|
||
|
from : null,
|
||
|
focusAgain : function() {
|
||
|
if ( galeneKeys.from ) {
|
||
|
galeneKeys.from.focus();
|
||
|
//galeneKeys.from = null;
|
||
|
}
|
||
|
else {
|
||
|
document.body.focus();
|
||
|
}
|
||
|
},
|
||
|
leave : function (event) {
|
||
|
if ( event.target.classList.contains('first') ) {
|
||
|
if ( event.shiftKey ) {
|
||
|
let cm = document.querySelector('.contextualMenu');
|
||
|
if ( cm ) {
|
||
|
cm.remove();
|
||
|
setTimeout(galeneKeys.focusAgain, 20);
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if ( event.target.classList.contains('last') ) {
|
||
|
if ( ! event.shiftKey ) {
|
||
|
let cm = document.querySelector('.contextualMenu');
|
||
|
if ( cm ) {
|
||
|
cm.remove();
|
||
|
setTimeout(galeneKeys.focusAgain, 20);
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if ( event.key === 'Escape' )
|
||
|
setTimeout(galeneKeys.focusAgain, 20);
|
||
|
},
|
||
|
setTabindexContextMenu : function (target) {
|
||
|
let context = document.querySelectorAll('.contextualMenuItemTitle');
|
||
|
if ( context && context.length) {
|
||
|
context.forEach( c => {
|
||
|
let btn = document.createElement('button');
|
||
|
btn.classList.add('contextualMenuItemTitle');
|
||
|
btn.classList.add('contextualJs');
|
||
|
btn.textContent = c.textContent;
|
||
|
btn.addEventListener('click', galeneKeys.menuClick);
|
||
|
c.replaceWith(btn);
|
||
|
});
|
||
|
context = document.querySelectorAll('.contextualMenuItemTitle');
|
||
|
context[0].classList.add('first');
|
||
|
let last = context.length - 1;
|
||
|
context[last].classList.add('last');
|
||
|
galeneKeys.from = target;
|
||
|
context[0].focus();
|
||
|
let pos = target.getBoundingClientRect();
|
||
|
|
||
|
let contextParent = document.querySelector('.contextualMenu');
|
||
|
contextParent.style.top = pos.top+20+'px';
|
||
|
// the following work only if the display with is enough we may have to correct this.
|
||
|
let x = 180;
|
||
|
let w = window.innerWidth;
|
||
|
if ( x + 200 > window.innerWidth ) {
|
||
|
x = w - 205;
|
||
|
}
|
||
|
contextParent.style.left = x+'px';
|
||
|
|
||
|
let menu = document.querySelector('ul.contextualMenu');
|
||
|
} else {
|
||
|
// Enter pressed
|
||
|
galeneKeys.focusAgain();
|
||
|
}
|
||
|
},
|
||
|
menuClick : function(e) {
|
||
|
galeneKeys.focusAgain();
|
||
|
},
|
||
|
processKey : function (event) {
|
||
|
let target = event.target;
|
||
|
let key = event.key;
|
||
|
switch(key) {
|
||
|
case 'Tab':
|
||
|
if ( document.activeElement.classList.contains('contextualMenuItemTitle') ) {
|
||
|
galeneKeys.leave(event);
|
||
|
return;
|
||
|
}
|
||
|
if ( document.activeElement.id === 'sideBarCollapse')
|
||
|
return;
|
||
|
break;
|
||
|
case 'Escape':
|
||
|
let dialog = document.querySelector('dialog');
|
||
|
if ( dialog ) {
|
||
|
let open = dialog.getAttribute('open');
|
||
|
if ( open == '' ) {
|
||
|
dialog.close();
|
||
|
galeneKeys.focusAgain();
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
let cm = document.querySelector('.contextualMenu');
|
||
|
if ( cm ) {
|
||
|
cm.remove();
|
||
|
galeneKeys.leave(event);
|
||
|
return;
|
||
|
}
|
||
|
// if the setting are open close them
|
||
|
let sidebar = document.querySelector('#sidebarnav[open]');
|
||
|
if ( sidebar ) {
|
||
|
event.preventDefault();
|
||
|
sidebar.removeAttribute('open');
|
||
|
return;
|
||
|
}
|
||
|
// check if we are within the chat
|
||
|
let active = document.activeElement;
|
||
|
let chat = document.querySelector('#left:not(.invisible)');
|
||
|
if ( chat ) {
|
||
|
event.preventDefault();
|
||
|
chat.classList.add('invisible');
|
||
|
let showChat = document.querySelector('#show-chat');
|
||
|
showChat.classList.remove('invisible');
|
||
|
return;
|
||
|
}
|
||
|
// finally close possibly the user list
|
||
|
let userList = document.querySelector('#left-sidebar:not(.active)');
|
||
|
if ( userList ) {
|
||
|
event.preventDefault();
|
||
|
document.querySelector('#left-sidebar').classList.add('active');
|
||
|
return;
|
||
|
}
|
||
|
break;
|
||
|
case 'Enter':
|
||
|
case ' ':
|
||
|
if ( target.classList.contains('volume-mute') ) {
|
||
|
let state =
|
||
|
target.click();
|
||
|
if ( translate && translate.translateList ) {
|
||
|
translate.setVolumeAria();
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
}
|
||
|
switch(target.nodeName) {
|
||
|
case 'INPUT':
|
||
|
let type = target.getAttribute('type');
|
||
|
if ( type && type === 'submit' ) {
|
||
|
return;
|
||
|
}
|
||
|
case 'TEXTAREA':
|
||
|
case 'SELECT':
|
||
|
return;
|
||
|
break;
|
||
|
}
|
||
|
let usercont = null;
|
||
|
switch(key) {
|
||
|
case 'u':
|
||
|
event.preventDefault();
|
||
|
usercont = document.querySelector('#left-sidebar');
|
||
|
if ( !usercont.classList.contains('active')) {
|
||
|
/* focus first user */
|
||
|
let user = document.querySelector('#users .user-p');
|
||
|
if ( user )
|
||
|
user.focus();
|
||
|
} else {
|
||
|
usercont.classList.remove('active');
|
||
|
}
|
||
|
break;
|
||
|
case 'r':
|
||
|
/* raise hand */
|
||
|
let me = document.querySelector('#left-sidebar #users .user-p');
|
||
|
if ( me ) {
|
||
|
if (me.classList.contains('user-status-raisehand') )
|
||
|
me.classList.remove('user-status-raisehand');
|
||
|
else
|
||
|
me.classList.add('user-status-raisehand');
|
||
|
}
|
||
|
break;
|
||
|
case 'm':
|
||
|
let localMute = getSettings().localMute;
|
||
|
localMute = !localMute;
|
||
|
setLocalMute(localMute, true);
|
||
|
break;
|
||
|
case 'c':
|
||
|
/* Chat */
|
||
|
event.preventDefault();
|
||
|
let chat = document.querySelector('#left:not(.invisible)');
|
||
|
if (!chat) {
|
||
|
setVisibility('left', true);
|
||
|
setVisibility('show-chat', false);
|
||
|
resizePeers();
|
||
|
chat = document.querySelector('#left:not(.invisible) textarea');
|
||
|
}
|
||
|
if (chat)
|
||
|
chat.focus();
|
||
|
break;
|
||
|
}
|
||
|
},
|
||
|
userClick : function (e) {
|
||
|
galeneKeys.from = e.target;
|
||
|
setTimeout(galeneKeys.setTabindexContextMenu,20, e.target);
|
||
|
},
|
||
|
addClickListener : function (mutationList) {
|
||
|
for (const mutation of mutationList) {
|
||
|
if (mutation.type === "childList") {
|
||
|
if (mutation && mutation.addedNodes) {
|
||
|
let idx = mutation.addedNodes.length -1;
|
||
|
if (idx >= 0) {
|
||
|
mutation.addedNodes[idx].addEventListener('click', galeneKeys.userClick);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
focusInput : function() {
|
||
|
let input = document.querySelector('#input');
|
||
|
input.focus();
|
||
|
},
|
||
|
collapseSidebar : function(e) {
|
||
|
let sidebar = document.querySelector('#left-sidebar.active');
|
||
|
if ( !sidebar ) {
|
||
|
// focus the first user-p button done but no outline!
|
||
|
//let user = document.querySelector('.user-p');
|
||
|
let userP = document.querySelector('.user-p');
|
||
|
if (userP)
|
||
|
userP.focus();
|
||
|
}
|
||
|
},
|
||
|
setSr : function (sr, toast) {
|
||
|
sr.textContent = toast.textContent;
|
||
|
},
|
||
|
resetSr : function(sr) {
|
||
|
sr.textContent = '';
|
||
|
},
|
||
|
setSrText : function() {
|
||
|
let toast = document.querySelector('.toastify');
|
||
|
let sr = document.querySelector('#srSpeak');
|
||
|
if ( toast ) {
|
||
|
setTimeout(galeneKeys.setSr, 50, sr, toast);
|
||
|
setTimeout(galeneKeys.resetSr, 4000, sr);
|
||
|
}
|
||
|
},
|
||
|
init : function () {
|
||
|
// add mutation oberver
|
||
|
let toObserve = document.querySelector('#users');
|
||
|
if ( toObserve ) {
|
||
|
const observer = new MutationObserver(galeneKeys.addClickListener);
|
||
|
observer.observe(toObserve, {childList:true, subtree:false});
|
||
|
}
|
||
|
const popup = new MutationObserver(galeneKeys.setSrText);
|
||
|
popup.observe(document.body, {childList: true,subtree: false});
|
||
|
|
||
|
// add event listener to the show-chat button
|
||
|
let showChat = document.querySelector('#show-chat');
|
||
|
if ( showChat ) {
|
||
|
showChat.addEventListener('click',galeneKeys.focusInput);
|
||
|
}
|
||
|
let left = document.querySelector('#sidebarCollapse');
|
||
|
if ( left ) {
|
||
|
left.addEventListener('click', galeneKeys.collapseSidebar);
|
||
|
}
|
||
|
},
|
||
|
};
|
||
|
document.addEventListener('keydown', galeneKeys.processKey);
|
||
|
document.addEventListener('DOMContentLoaded', galeneKeys.init);
|
||
|
|