mirror of
https://github.com/jech/galene.git
synced 2024-11-22 16:45:58 +01:00
Add contextual menu in user list.
This commit is contained in:
parent
7cbc516679
commit
997806ec52
3 changed files with 111 additions and 25 deletions
|
@ -1120,7 +1120,6 @@ legend {
|
||||||
transition: all 0.3s;
|
transition: all 0.3s;
|
||||||
background: #ffffff;
|
background: #ffffff;
|
||||||
border-right: 1px solid #dcdcdc;
|
border-right: 1px solid #dcdcdc;
|
||||||
z-index: 1039;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#left-sidebar .galene-header {
|
#left-sidebar .galene-header {
|
||||||
|
@ -1168,7 +1167,6 @@ header .collapse {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
height: calc(100% - 84px);
|
height: calc(100% - 84px);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
z-index: 1;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
display: block;
|
display: block;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
|
@ -1345,3 +1343,17 @@ header .collapse {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:root{
|
||||||
|
--contextualMenuBg: #eee;
|
||||||
|
--contextualMenuShadow: 1px 1px 1px #444; */
|
||||||
|
--contextualMenuRadius: 0px; */
|
||||||
|
--contextualMenuText: black;
|
||||||
|
|
||||||
|
--contextualSubMenuBg: #eee;
|
||||||
|
|
||||||
|
--contextualHover: #ddd;
|
||||||
|
|
||||||
|
--contextualOverflowIcon: #999;
|
||||||
|
--contextualSeperator: #999;
|
||||||
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
<link rel="stylesheet" type="text/css" href="/external/fontawesome/css/solid.min.css"/>
|
<link rel="stylesheet" type="text/css" href="/external/fontawesome/css/solid.min.css"/>
|
||||||
<link rel="stylesheet" type="text/css" href="/external/fontawesome/css/regular.min.css"/>
|
<link rel="stylesheet" type="text/css" href="/external/fontawesome/css/regular.min.css"/>
|
||||||
<link rel="stylesheet" type="text/css" href="/external/toastify/toastify.css"/>
|
<link rel="stylesheet" type="text/css" href="/external/toastify/toastify.css"/>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/external/contextual/contextual.css"/>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
@ -274,6 +275,7 @@
|
||||||
|
|
||||||
<script src="/protocol.js" defer></script>
|
<script src="/protocol.js" defer></script>
|
||||||
<script src="/external/toastify/toastify.js" defer></script>
|
<script src="/external/toastify/toastify.js" defer></script>
|
||||||
|
<script src="/external/contextual/contextual.js"></script>
|
||||||
<script src="/galene.js" defer></script>
|
<script src="/galene.js" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
118
static/galene.js
118
static/galene.js
|
@ -1959,6 +1959,60 @@ function stringCompare(a, b) {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {HTMLElement} elt
|
||||||
|
*/
|
||||||
|
function userMenu(elt) {
|
||||||
|
if(!elt.id.startsWith('user-'))
|
||||||
|
throw new Error('Unexpected id for user menu');
|
||||||
|
let id = elt.id.slice('user-'.length);
|
||||||
|
let user = serverConnection.users[id];
|
||||||
|
if(!user)
|
||||||
|
throw new Error("Couldn't find user")
|
||||||
|
let items = [];
|
||||||
|
if(id === serverConnection.id) {
|
||||||
|
let mydata = serverConnection.users[serverConnection.id].data;
|
||||||
|
if(mydata['raisehand'])
|
||||||
|
items.push({label: 'Lower hand', onClick: () => {
|
||||||
|
serverConnection.userAction(
|
||||||
|
'setdata', serverConnection.id, {'raisehand': null},
|
||||||
|
);
|
||||||
|
}});
|
||||||
|
else
|
||||||
|
items.push({label: 'Raise hand', onClick: () => {
|
||||||
|
serverConnection.userAction(
|
||||||
|
'setdata', serverConnection.id, {'raisehand': true},
|
||||||
|
);
|
||||||
|
}});
|
||||||
|
items.push({label: 'Restart media', onClick: renegotiateStreams});
|
||||||
|
} else {
|
||||||
|
items.push({label: 'Send file', onClick: () => {
|
||||||
|
sendFile(id);
|
||||||
|
}});
|
||||||
|
if(serverConnection.permissions.op) {
|
||||||
|
items.push({type: 'seperator'}); // sic
|
||||||
|
if(user.permissions.present)
|
||||||
|
items.push({label: 'Forbid presenting', onClick: () => {
|
||||||
|
serverConnection.userAction('unpresent', id);
|
||||||
|
}});
|
||||||
|
else
|
||||||
|
items.push({label: 'Allow presenting', onClick: () => {
|
||||||
|
serverConnection.userAction('present', id);
|
||||||
|
}});
|
||||||
|
items.push({label: 'Mute', onClick: () => {
|
||||||
|
serverConnection.userAction('mute', id);
|
||||||
|
}});
|
||||||
|
items.push({label: 'Kick out', onClick: () => {
|
||||||
|
serverConnection.userAction('kick', id);
|
||||||
|
}});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/** @ts-ignore */
|
||||||
|
new Contextual({
|
||||||
|
items: items,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} id
|
* @param {string} id
|
||||||
* @param {user} userinfo
|
* @param {user} userinfo
|
||||||
|
@ -1974,6 +2028,13 @@ function addUser(id, userinfo) {
|
||||||
else
|
else
|
||||||
user.classList.remove('user-status-raisehand');
|
user.classList.remove('user-status-raisehand');
|
||||||
|
|
||||||
|
user.addEventListener('click', function(e) {
|
||||||
|
let elt = e.target;
|
||||||
|
if(!elt || !(elt instanceof HTMLElement))
|
||||||
|
throw new Error("Couldn't find user div");
|
||||||
|
userMenu(elt);
|
||||||
|
});
|
||||||
|
|
||||||
let us = div.children;
|
let us = div.children;
|
||||||
|
|
||||||
if(id === serverConnection.id) {
|
if(id === serverConnection.id) {
|
||||||
|
@ -2342,12 +2403,12 @@ function failFile(f, message) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} username
|
|
||||||
* @param {string} id
|
* @param {string} id
|
||||||
* @param {File} file
|
* @param {File} file
|
||||||
*/
|
*/
|
||||||
function offerFile(username, id, file) {
|
function offerFile(id, file) {
|
||||||
let fileid = newRandomId();
|
let fileid = newRandomId();
|
||||||
|
let username = serverConnection.users[id].username;
|
||||||
let f = new TransferredFile(
|
let f = new TransferredFile(
|
||||||
fileid, id, true, username, file.name, file.type, file.size,
|
fileid, id, true, username, file.name, file.type, file.size,
|
||||||
);
|
);
|
||||||
|
@ -3089,13 +3150,17 @@ commands.subgroups = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function renegotiateStreams() {
|
||||||
|
for(let id in serverConnection.up)
|
||||||
|
serverConnection.up[id].restartIce();
|
||||||
|
for(let id in serverConnection.down)
|
||||||
|
serverConnection.down[id].restartIce();
|
||||||
|
}
|
||||||
|
|
||||||
commands.renegotiate = {
|
commands.renegotiate = {
|
||||||
description: 'renegotiate media streams',
|
description: 'renegotiate media streams',
|
||||||
f: (c, r) => {
|
f: (c, r) => {
|
||||||
for(let id in serverConnection.up)
|
renegotiateStreams();
|
||||||
serverConnection.up[id].restartIce();
|
|
||||||
for(let id in serverConnection.down)
|
|
||||||
serverConnection.down[id].restartIce();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3283,6 +3348,28 @@ commands.unraise = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} id
|
||||||
|
*/
|
||||||
|
function sendFile(id) {
|
||||||
|
let input = document.createElement('input');
|
||||||
|
input.type = 'file';
|
||||||
|
input.onchange = function(e) {
|
||||||
|
if(!(this instanceof HTMLInputElement))
|
||||||
|
throw new Error('Unexpected type for this');
|
||||||
|
let files = input.files;
|
||||||
|
for(let i = 0; i < files.length; i++) {
|
||||||
|
try {
|
||||||
|
offerFile(id, files[i]);
|
||||||
|
} catch(e) {
|
||||||
|
console.error(e);
|
||||||
|
displayError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
input.click();
|
||||||
|
}
|
||||||
|
|
||||||
commands.sendfile = {
|
commands.sendfile = {
|
||||||
parameters: 'user',
|
parameters: 'user',
|
||||||
description: 'send a file (this will disclose your IP address)',
|
description: 'send a file (this will disclose your IP address)',
|
||||||
|
@ -3293,23 +3380,8 @@ commands.sendfile = {
|
||||||
let id = findUserId(p[0]);
|
let id = findUserId(p[0]);
|
||||||
if(!id)
|
if(!id)
|
||||||
throw new Error(`Unknown user ${p[0]}`);
|
throw new Error(`Unknown user ${p[0]}`);
|
||||||
let input = document.createElement('input');
|
sendFile(id);
|
||||||
input.type = 'file';
|
},
|
||||||
input.onchange = function(e) {
|
|
||||||
if(!(this instanceof HTMLInputElement))
|
|
||||||
throw new Error('Unexpected type for this');
|
|
||||||
let files = input.files;
|
|
||||||
for(let i = 0; i < files.length; i++) {
|
|
||||||
try {
|
|
||||||
offerFile(p[i], id, files[i]);
|
|
||||||
} catch(e) {
|
|
||||||
console.error(e);
|
|
||||||
displayError(e);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
input.click();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue