Added details to context menu, recordings bug fixes.

Ylian Saint-Hilaire committed May 5, 2020 at 14:19 UTC 3470c81b345e463a26f0bc5f9783816d9124e983
4 files changed +86 -53
meshdesktopmultiplex.js
+25 -21
@@ -720,28 +720,32 @@ function CreateDesktopMultiplexor(parent, domain, nodeid, func) {
720
721 // If there is a recording quota, remove any old recordings if needed
722 function cleanUpRecordings() {
723 - if (domain.sessionrecording && ((typeof domain.sessionrecording.maxrecordings == 'number') || (typeof domain.sessionrecording.maxrecordingsizemegabytes == 'number'))) {
724 - var recPath = null, fs = require('fs');
725 - if (domain.sessionrecording.filepath) { recPath = domain.sessionrecording.filepath; } else { recPath = parent.parent.recordpath; }
726 - fs.readdir(recPath, function (err, files) {
727 - if ((err != null) || (files == null)) return;
728 - var recfiles = [];
729 - for (var i in files) {
730 - if (files[i].endsWith('.mcrec')) {
731 - var j = files[i].indexOf('-');
732 - if (j > 0) { recfiles.push({ n: files[i], r: files[i].substring(j + 1), s: fs.statSync(parent.parent.path.join(recPath, files[i])).size }); }
723 + if ((parent.cleanUpRecordingsActive !== true) && domain.sessionrecording && ((typeof domain.sessionrecording.maxrecordings == 'number') || (typeof domain.sessionrecording.maxrecordingsizemegabytes == 'number'))) {
724 + parent.cleanUpRecordingsActive = true;
725 + setTimeout(function () {
726 + var recPath = null, fs = require('fs');
727 + if (domain.sessionrecording.filepath) { recPath = domain.sessionrecording.filepath; } else { recPath = parent.parent.recordpath; }
728 + fs.readdir(recPath, function (err, files) {
729 + if ((err != null) || (files == null)) { delete parent.cleanUpRecordingsActive; return; }
730 + var recfiles = [];
731 + for (var i in files) {
732 + if (files[i].endsWith('.mcrec')) {
733 + var j = files[i].indexOf('-');
734 + if (j > 0) { recfiles.push({ n: files[i], r: files[i].substring(j + 1), s: fs.statSync(parent.parent.path.join(recPath, files[i])).size }); }
735 + }
736 }
734 - }
735 - recfiles.sort(function (a, b) { if (a.r < b.r) return 1; if (a.r > b.r) return -1; return 0; });
736 - var totalFiles = 0, totalSize = 0;
737 - for (var i in recfiles) {
738 - var overQuota = false;
739 - if ((typeof domain.sessionrecording.maxrecordings == 'number') && (totalFiles >= domain.sessionrecording.maxrecordings)) { overQuota = true; }
740 - else if ((typeof domain.sessionrecording.maxrecordingsizemegabytes == 'number') && (totalSize >= (domain.sessionrecording.maxrecordingsizemegabytes * 1048576))) { overQuota = true; }
741 - if (overQuota) { fs.unlinkSync(parent.parent.path.join(recPath, recfiles[i].n)); }
742 - totalFiles++;
743 - totalSize += recfiles[i].s;
744 - }
737 + recfiles.sort(function (a, b) { if (a.r < b.r) return 1; if (a.r > b.r) return -1; return 0; });
738 + var totalFiles = 0, totalSize = 0;
739 + for (var i in recfiles) {
740 + var overQuota = false;
741 + if ((typeof domain.sessionrecording.maxrecordings == 'number') && (totalFiles >= domain.sessionrecording.maxrecordings)) { overQuota = true; }
742 + else if ((typeof domain.sessionrecording.maxrecordingsizemegabytes == 'number') && (totalSize >= (domain.sessionrecording.maxrecordingsizemegabytes * 1048576))) { overQuota = true; }
743 + if (overQuota) { fs.unlinkSync(parent.parent.path.join(recPath, recfiles[i].n)); }
744 + totalFiles++;
745 + totalSize += recfiles[i].s;
746 + }
747 + delete parent.cleanUpRecordingsActive;
748 + });
749 });
750 }
751 }
meshrelay.js
+30 -22
@@ -527,29 +527,37 @@ module.exports.CreateMeshRelay = function (parent, ws, req, domain, user, cookie
527
528 // If there is a recording quota, remove any old recordings if needed
529 function cleanUpRecordings() {
530 - if (domain.sessionrecording && ((typeof domain.sessionrecording.maxrecordings == 'number') || (typeof domain.sessionrecording.maxrecordingsizemegabytes == 'number'))) {
531 - var recPath = null, fs = require('fs');
532 - if (domain.sessionrecording.filepath) { recPath = domain.sessionrecording.filepath; } else { recPath = parent.parent.recordpath; }
533 - fs.readdir(recPath, function (err, files) {
534 - if ((err != null) || (files == null)) return;
535 - var recfiles = [];
536 - for (var i in files) {
537 - if (files[i].endsWith('.mcrec')) {
538 - var j = files[i].indexOf('-');
539 - if (j > 0) { recfiles.push({ n: files[i], r: files[i].substring(j + 1), s: fs.statSync(parent.parent.path.join(recPath, files[i])).size }); }
530 + if ((parent.cleanUpRecordingsActive !== true) && domain.sessionrecording && ((typeof domain.sessionrecording.maxrecordings == 'number') || (typeof domain.sessionrecording.maxrecordingsizemegabytes == 'number'))) {
531 + parent.cleanUpRecordingsActive = true;
532 + setTimeout(function () {
533 + var recPath = null, fs = require('fs');
534 + if (domain.sessionrecording.filepath) { recPath = domain.sessionrecording.filepath; } else { recPath = parent.parent.recordpath; }
535 + fs.readdir(recPath, function (err, files) {
536 + if ((err != null) || (files == null)) { delete parent.cleanUpRecordingsActive; return; }
537 + var recfiles = [];
538 + for (var i in files) {
539 + if (files[i].endsWith('.mcrec')) {
540 + var j = files[i].indexOf('-');
541 + if (j > 0) {
542 + var size = null;
543 + try { size = fs.statSync(parent.parent.path.join(recPath, files[i])).size } catch (ex) { }
544 + if (size != null) { recfiles.push({ n: files[i], r: files[i].substring(j + 1), s: size }); }
545 + }
546 + }
547 }
541 - }
542 - recfiles.sort(function (a, b) { if (a.r < b.r) return 1; if (a.r > b.r) return -1; return 0; });
543 - var totalFiles = 0, totalSize = 0;
544 - for (var i in recfiles) {
545 - var overQuota = false;
546 - if ((typeof domain.sessionrecording.maxrecordings == 'number') && (totalFiles >= domain.sessionrecording.maxrecordings)) { overQuota = true; }
547 - else if ((typeof domain.sessionrecording.maxrecordingsizemegabytes == 'number') && (totalSize >= (domain.sessionrecording.maxrecordingsizemegabytes * 1048576))) { overQuota = true; }
548 - if (overQuota) { fs.unlinkSync(parent.parent.path.join(recPath, recfiles[i].n)); }
549 - totalFiles++;
550 - totalSize += recfiles[i].s;
551 - }
552 - });
548 + recfiles.sort(function (a, b) { if (a.r < b.r) return 1; if (a.r > b.r) return -1; return 0; });
549 + var totalFiles = 0, totalSize = 0;
550 + for (var i in recfiles) {
551 + var overQuota = false;
552 + if ((typeof domain.sessionrecording.maxrecordings == 'number') && (totalFiles >= domain.sessionrecording.maxrecordings)) { overQuota = true; }
553 + else if ((typeof domain.sessionrecording.maxrecordingsizemegabytes == 'number') && (totalSize >= (domain.sessionrecording.maxrecordingsizemegabytes * 1048576))) { overQuota = true; }
554 + if (overQuota) { fs.unlinkSync(parent.parent.path.join(recPath, recfiles[i].n)); }
555 + totalFiles++;
556 + totalSize += recfiles[i].s;
557 + }
558 + delete parent.cleanUpRecordingsActive;
559 + });
560 + }, 500);
561 }
562 }
563
translate/translate.json
+4 -2
@@ -8017,7 +8017,8 @@
8017 "ru": "Детали",
8018 "zh-chs": "細節",
8019 "xloc": [
8020 - "default.handlebars->container->topbar->1->1->MainSubMenuSpan->MainSubMenu->1->0->MainDevInfo"
8020 + "default.handlebars->container->topbar->1->1->MainSubMenuSpan->MainSubMenu->1->0->MainDevInfo",
8021 + "default.handlebars->contextMenu->cxdetails"
8022 ]
8023 },
8024 {
@@ -20105,7 +20106,8 @@
20106 "zh-chs": "外掛程式",
20107 "xloc": [
20108 "default.handlebars->container->topbar->1->1->MainSubMenuSpan->MainSubMenu->1->0->MainDevPlugins",
20108 - "default.handlebars->container->topbar->1->1->ServerSubMenuSpan->ServerSubMenu->1->0->ServerPlugins"
20109 + "default.handlebars->container->topbar->1->1->ServerSubMenuSpan->ServerSubMenu->1->0->ServerPlugins",
20110 + "default.handlebars->contextMenu->cxplugins"
20111 ]
20112 },
20113 {
views/default.handlebars
+27 -8
@@ -44,9 +44,11 @@
44 <div id="cxterminal" class="cmtext" onclick="cmaction(2,event)">Terminal</div>
45 <div id="cxfiles" class="cmtext" onclick="cmaction(4,event)">Files</div>
46 <div id="cxevents" class="cmtext" onclick="cmaction(5,event)">Events</div>
47 - <div id="cxconsole" class="cmtext" onclick="cmaction(6,event)">Console</div>
47 + <div id="cxdetails" class="cmtext" onclick="cmaction(6,event)">Details</div>
48 + <div id="cxconsole" class="cmtext" onclick="cmaction(7,event)">Console</div>
49 + <div id="cxplugins" class="cmtext" onclick="cmaction(8,event)" style="display:none">Plugins</div>
50 <hr id="cxmgroupsplit" />
49 - <div id="cxmdesktop" class="cmtext" onclick="cmaction(7,event)" style="display:none">Multi-Desktop</div>
51 + <div id="cxmdesktop" class="cmtext" onclick="cmaction(9,event)" style="display:none">Multi-Desktop</div>
52 </div>
53 <div id="meshContextMenu" class="contextMenu noselect" style="display:none;min-width:0px">
54 <div id="cxselectall" class="cmtext" onclick="cmmeshaction(1,event)">Select All</div>
@@ -4165,9 +4167,9 @@
4167 function cmaction(action,event) {
4168 var nodeid = contextelement.children[1].attributes.onclick.value;
4169 nodeid = nodeid.substring(12, nodeid.length - 18);
4168 - if (action == 7) { Q('viewselect').value = 3; Q('viewselect').onchange(); Q('autoConnectDesktopCheckbox').checked = true; Q('autoConnectDesktopCheckbox').onclick(); } // Multi-Desktop
4169 - if ((action > 0) && (action < 7)) {
4170 - var panel = [0, 10, 12, 11, 13, 16, 15][action]; // (invalid), General, Desktop, Terminal, Files, Events, Console
4170 + if (action == 9) { Q('viewselect').value = 3; Q('viewselect').onchange(); Q('autoConnectDesktopCheckbox').checked = true; Q('autoConnectDesktopCheckbox').onclick(); } // Multi-Desktop
4171 + if ((action > 0) && (action < 9)) {
4172 + var panel = [0, 10, 12, 11, 13, 16, 17, 15, 19][action]; // (invalid), General, Desktop, Terminal, Files, Events, Console, Plugin
4173 if (event && (event.shiftKey == true)) {
4174 // Open the device in a different tab
4175 window.open(window.location.origin + '?node=' + nodeid.split('/')[2] + '&viewmode=' + panel + '&hide=16', 'meshcentral:' + nodeid);
@@ -11136,6 +11138,10 @@
11138
11139 var p52recordings = null;
11140 function updateRecordings() {
11141 + // Save the list of currently checked recordings
11142 + var checkedRecordings = [], elements = document.getElementsByClassName('RecordingCheckbox');
11143 + for (var i=0;i<elements.length;i++) { if (elements[i].checked) { checkedRecordings.push(elements[i].value); } }
11144 +
11145 // Display the users using the sorted list
11146 var x = '<table class=p3usersTable cellpadding=0 cellspacing=0>', addHeader = true;
11147 x += '<th>' + "Session" + '<th style=width:110px>' + nobreak("Start Time") + '<th style=width:110px>' + "Duration" + '<th style=width:110px>' + "Size";
@@ -11149,6 +11155,11 @@
11155 }
11156 x += '</table>';
11157 QH('p52recordings', x);
11158 +
11159 + // Re-check recordings
11160 + elements = document.getElementsByClassName('RecordingCheckbox');
11161 + for (var i=0;i<elements.length;i++) { elements[i].checked = ((checkedRecordings.indexOf(elements[i].value) >= 0)); }
11162 + p52updateInfo();
11163 }
11164
11165 function addRecordingHtml(i, rec) {
@@ -11184,7 +11195,8 @@
11195 if (rec.present == 1) { icon = 'm1'; actions = '<div style=cursor:pointer;float:right><a href=recordings.ashx?file=' + encodeURIComponent(rec.filename) + ' download><img src=images/link4.png height=10 width=10 title="Download Recording" download></a>&nbsp;</div>'; }
11196 var x = '<tr tabindex=0 onmouseover=userMouseHover2(this,1) onmouseout=userMouseHover2(this,0) onkeypress="if (event.key==\'Enter\') showRecordingDialog(event,\'' + i + '\')"><td style=cursor:pointer>';
11197 x += '<div class=bar style=width:100%>';
11187 - x += '<div class=baricon><input class=RecordingCheckbox value=' + i + ' onclick=p52updateInfo() type=checkbox></div>';
11198 + //x += '<div class=baricon><input class=RecordingCheckbox value="' + encodeURIComponent(rec.filename) + '" onclick=p52updateInfo() type=checkbox></div>';
11199 + x += '<div></div>';
11200 x += '<div class=baricon onclick=showRecordingDialog(event,"' + i + '")><div class=' + icon + '></div></div>';
11201 x += '<div class=g1 onclick=showRecordingDialog(event,"' + i + '")></div><div class=g2 onclick=showRecordingDialog("' + i + '")></div>';
11202 x += '<div onclick=showRecordingDialog(event,"' + i + '")>' + actions + '<div style=font-size:16px>' + sessionName + '</div></div></div><td style=text-align:center>' + sessionStartStr + '<td style=text-align:center>' + sessionLengthStr + '<td style=text-align:center>' + sessionSize;
@@ -11195,7 +11207,6 @@
11207 if (xxdialogMode) return;
11208 if ((event.target.tagName == 'IMG') || (event.target.tagName == 'A')) return;
11209 var rec = p52recordings[i];
11198 - //console.log(rec);
11210 var x = '';
11211 if (rec.protocol) {
11212 var protocolStr = "Unknown";
@@ -11220,7 +11231,15 @@
11231
11232 function refreshRecodings() { meshserver.send({ action: 'recordings', limit: 1000 }); }
11233 function openRecodringPlayer() { if (!xxdialogMode) window.open(window.location.origin + '{{{domainurl}}}player.htm', 'meshcentral-deskplayer'); }
11223 - function p52updateInfo() { }
11234 + function p52updateInfo() {
11235 + var elements = document.getElementsByClassName('RecordingCheckbox'), checkcount = 0;
11236 + for (var i=0;i<elements.length;i++) { if (elements[i].checked === true) { checkcount++; } }
11237 + if (checkcount > 0) {
11238 +
11239 + } else {
11240 +
11241 + }
11242 + }
11243
11244 //
11245 // FILE SELECTOR, DIALOG 3