Added staring a device feature.

This commit is contained in:
Ylian Saint-Hilaire 2020-07-28 15:27:28 -07:00
parent fe4b71dbed
commit 2d677298db
11 changed files with 159 additions and 30 deletions

View File

@ -4219,7 +4219,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
case 'userWebState': {
if (common.validateString(command.state, 1, 10000) == false) break; // Check state size, no more than 10k
command.state = parent.filterUserWebState(command.state); // Filter the state to remove anything bad
if ((command.state == null) || (typeof command.state !== 'object')) break; // If state did not validate correctly, quit here.
if ((command.state == null) || (typeof command.state !== 'string')) { console.log('tt'); break; } // If state did not validate correctly, quit here.
db.Set({ _id: 'ws' + user._id, state: command.state });
parent.parent.DispatchEvent([user._id], obj, { action: 'userWebState', nolog: 1, domain: domain.id, state: command.state });
break;

Binary file not shown.

After

Width:  |  Height:  |  Size: 364 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 542 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 989 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 384 B

File diff suppressed because one or more lines are too long

View File

@ -746,40 +746,48 @@ NoMeshesPanel img {
}
.deviceNotifyDot {
text-align:center;
position:absolute;
right:10px;
top:0px;
width:16px;
height:16px;
}
.deviceNotifyDotSub {
text-align:center;
color:#FFF;
width:16px;
background-color:#00F;
padding:2px;
border-radius:10px;
box-shadow: 2px 2px 10px black;
cursor:pointer;
margin-left:3px;
}
.deviceNotifyDot:hover {
.deviceNotifyDotSub:hover {
background-color:#44F;
}
.deviceNotifySmallDot {
text-align:center;
position:absolute;
right:10px;
top:0px;
width:10px;
height:10px;
}
.deviceNotifySmallDotSub {
text-align:center;
color:#FFF;
width:10px;
padding:2px;
background-color:#00F;
border-radius:10px;
box-shadow: 2px 2px 10px black;
cursor:pointer;
margin-left:2px;
}
.deviceNotifySmallDot:hover {
.deviceNotifySmallDotSub:hover {
background-color:#44F;
}
@ -828,10 +836,14 @@ NoMeshesPanel img {
.deviceBatterySmall11 { background: url(../images/batteries24.png) -140px 0px; }
.deviceNotifyLargeDot {
text-align:center;
position:absolute;
right:10px;
top:140px;
height:40px;
}
.deviceNotifyLargeDotSub {
text-align:center;
width:40px;
height:40px;
color:#FFF;
@ -840,9 +852,10 @@ NoMeshesPanel img {
border-radius:20px;
box-shadow: 2px 2px 10px black;
cursor:pointer;
margin-left:4px;
}
.deviceNotifyLargeDot:hover {
.deviceNotifyLargeDotSub:hover {
background-color:#44F;
}

View File

@ -26719,6 +26719,12 @@
"default.handlebars->container->column_l->p12->termTable->1->1->6->1->1->terminalSettingsButtons"
]
},
{
"en": "Toggle Star",
"xloc": [
"default.handlebars->contextMenu->cxstar"
]
},
{
"cs": "Přepnout režim zobrazení",
"de": "Ansichtsmodus umschalten",
@ -31769,4 +31775,4 @@
]
}
]
}
}

View File

@ -214,29 +214,60 @@
}
.deviceNotifyDot {
text-align:center;
position:absolute;
right:10px;
top:0px;
width:16px;
height:16px;
}
.deviceNotifyDotSub {
text-align:center;
color:#FFF;
width:16px;
background-color:#00F;
padding:2px;
border-radius:10px;
box-shadow: 2px 2px 10px black;
cursor:pointer;
margin-left:3px;
}
.deviceNotifyDot:hover {
.deviceNotifyDotSub:hover {
background-color:#44F;
}
.deviceNotifyLargeDot {
.deviceNotifySmallDot {
position:absolute;
right:10px;
top:0px;
height:10px;
}
.deviceNotifySmallDotSub {
text-align:center;
color:#FFF;
width:10px;
padding:2px;
background-color:#00F;
border-radius:10px;
box-shadow: 2px 2px 10px black;
cursor:pointer;
margin-left:2px;
}
.deviceNotifySmallDotSub:hover {
background-color:#44F;
}
.deviceNotifyLargeDot {
position:absolute;
right:10px;
top:10px;
height:40px;
}
.deviceNotifyLargeDotSub {
text-align:center;
width:40px;
height:40px;
color:#FFF;
@ -245,9 +276,10 @@
border-radius:20px;
box-shadow: 2px 2px 10px black;
cursor:pointer;
margin-left:4px;
}
.deviceNotifyLargeDot:hover {
.deviceNotifyLargeDotSub:hover {
background-color:#44F;
}
@ -485,7 +517,10 @@
</tr>
</table>
<div id=p10general style="overflow-y:scroll;position:absolute;top:55px;bottom:0px;width:100%">
<img id="p10deviceNotify" onclick=showDeviceSessions() class=deviceNotifyLargeDot src=images/icon-relay-notify-40.png width=40 height=40>
<div class="deviceNotifyLargeDot">
<img id="p10deviceStar" class=deviceNotifyDotSub src=images/icon-star-notify-16.png width=16 height=16>
<img id="p10deviceNotify" onclick=showDeviceSessions() class=deviceNotifyLargeDotSub src=images/icon-relay-notify-40.png width=40 height=40>
</div>
<div id="p10deviceBattery" class="deviceBatteryLarge deviceBatteryLarge1"></div>
<div id=p10html style="margin-left:8px;margin-right:8px"></div>
<div id=p10html2></div>
@ -752,6 +787,7 @@
var meshserver = null;
var xdr = null;
var usergroups = null;
var stars = {}; // Devices that have been "stared" by the user.
var serverinfo = null;
var nodes = [];
var meshes = {};
@ -792,6 +828,9 @@
meshserver.onMessage = onMessage;
meshserver.Start();
// Setup stared devices
try { stars = JSON.parse(getstore('stars', '{}')); } catch (ex) { }
// Load desktop settings
var t = localStorage.getItem('desktopsettings');
if (t != null) { desktopsettings = JSON.parse(t); }
@ -1070,11 +1109,17 @@
var webstate = JSON.parse(message.event.state);
for (var i in webstate) { localStorage.setItem(i, webstate[i]); }
// Update stars
if (webstate.stars != null) { stars = JSON.parse(webstate.stars); }
// Update the web page
if ((webstate.loctag != null) && (webstate.loctag != oldLoctag)) {
if (webstate.loctag != null) { args.locale = webstate.loctag; } else { delete args.locale; }
updateDevices();
updateMeshes();
} else if (webstate.stars != null) {
updateDevices();
if (Q('SearchInput').value == '*') { onSearchInputChanged(); }
}
}
break;
@ -1953,6 +1998,9 @@
nodes[d].v = false;
if (nodes[d].users && nodes[d].users.length > 0) { for (var i in nodes[d].users) { if (nodes[d].users[i].toLowerCase().indexOf(userSearch) >= 0) { nodes[d].v = true; } } }
}
} else if (x == '*') {
// Star filter
for (var d in nodes) { nodes[d].v = (stars[nodes[d]._id] == 1); }
} else {
// Device name search
try {
@ -2109,11 +2157,19 @@
if (showRealNames == true && nodes[i].rname != null) name = EscapeHtml(nodes[i].rname);
if (name.length == 0) { name = '<i>' + "None" + '</i>'; }
// Setup device notification
var devNotify = '';
// Add device notification icons
var devNotify = '', devNotifySub = '';
// This device is "starred"
if (stars[nodes[i]._id] == 1) {
devNotifySub += '<img class=deviceNotifyDotSub src=images/icon-star-notify-16.png width=16 height=16>';
}
// This device has session information
if (nodes[i].sessions != null) {
// Sessions are active
if ((nodes[i].sessions.kvm != null) || (nodes[i].sessions.terminal != null) || (nodes[i].sessions.files != null) || (nodes[i].sessions.tcp != null) || (nodes[i].sessions.udp != null)) {
devNotify = '<img class=deviceNotifyDot src=images/icon-relay-notify.png width=16 height=16>';
devNotifySub += '<img class=deviceNotifyDotSub src=images/icon-relay-notify.png width=16 height=16>';
}
// Battery state
@ -2137,6 +2193,9 @@
}
}
// Add any device icons
if (devNotifySub != '') { devNotify += '<div class=deviceNotifyDot>' + devNotifySub + '</div>'; }
// Node
var icon = nodes[i].icon, nodestate = NodeStateStr(nodes[i]);
if ((!nodes[i].conn) || (nodes[i].conn == 0)) { icon += ' gray'; }
@ -2310,6 +2369,7 @@
// Setup session notification
QV('p10deviceNotify', (currentNode.sessions != null) && ((node.sessions.kvm != null) || (node.sessions.terminal != null) || (node.sessions.files != null) || (node.sessions.tcp != null) || (node.sessions.udp != null)));
QV('p10deviceStar', stars[currentNode._id] == 1);
// Device Battery
QV('p10deviceBattery', false);

View File

@ -48,6 +48,7 @@
<div id="cxconsole" class="cmtext" onclick="cmaction(7,event)">Console</div>
<div id="cxplugins" class="cmtext" onclick="cmaction(8,event)" style="display:none">Plugins</div>
<hr id="cxmgroupsplit" />
<div id="cxstar" class="cmtext" onclick="cmaction(10,event)" style="display:none">Toggle Star</div>
<div id="cxmdesktop" class="cmtext" onclick="cmaction(9,event)" style="display:none">Multi-Desktop</div>
</div>
<div id="meshContextMenu" class="contextMenu noselect" style="display:none;min-width:0px">
@ -494,7 +495,10 @@
</td>
<td style=width:20px></td>
<td style=width:200px;vertical-align:top;position:relative valign=top>
<img id="p10deviceNotify" onclick=showDeviceSessions(null,null,event) class=deviceNotifyLargeDot src=images/icon-relay-notify-40.png width=40 height=40>
<div class="deviceNotifyLargeDot">
<img id="p10deviceStar" class=deviceNotifyDotSub src=images/icon-star-notify-16.png width=16 height=16>
<img id="p10deviceNotify" onclick=showDeviceSessions(null,null,event) class=deviceNotifyLargeDotSub src=images/icon-relay-notify-40.png width=40 height=40>
</div>
<div id="p10deviceBattery" class="deviceBatteryLarge deviceBatteryLarge1"></div>
<a href=# onclick=p10showiconselector()><img id=MainComputerImage></a>
<div id=MainComputerState></div>
@ -1217,6 +1221,7 @@
var events = [];
var users = null;
var wssessions = null;
var stars = {}; // Devices that have been "stared" by the user.
var nodeShortIdent = 0;
var desktop;
var desktopsettings = { encoding: 2, showfocus: false, showmouse: true, showcad: true, quality: 40, scaling: 1024, framerate: 50, localkeymap: false };
@ -1309,6 +1314,9 @@
if (nightMode) { QC('body').add('night'); QS('body')['background-color'] = '#000'; }
toggleFullScreen();
// Setup stared devices
try { stars = JSON.parse(getstore('stars', '{}')); } catch (ex) {}
// Setup page visuals
var hide = 0;
var globalHide = parseInt('{{{hide}}}');
@ -2039,6 +2047,9 @@
}
}
// Remove any stars for nodes that don't exist
for (var i in stars) { if (getNodeFromId(i) == null) { delete stars[i]; } }
// If we are currently looking at a node this is now gone, change the view.
if ((currentNode != null) && (IsNodeViewable(currentNode) == false)) { currentNode = null; go(1); }
@ -2461,6 +2472,8 @@
// New user web state, update the web page as needed
try {
if (localStorage != null) {
// TODO: The problem with this "old" values is that if changed from a different tab, the old and new values will be the same.
// So comparing against these values is not a good idea.
var oldShowRealNames = localStorage.getItem('showRealNames');
var oldUiMode = localStorage.getItem('uiMode');
var oldSort = localStorage.getItem('sort');
@ -2479,6 +2492,7 @@
if ((webstate.loctag != null) && (webstate.loctag != oldLoctag)) { if (webstate.loctag != null) { args.locale = webstate.loctag; } else { delete args.locale; } mainUpdate(0xFFFFFFFF); }
if ((webstate.nightMode != null) && (webstate.nightMode != oldNightMode)) { nightMode = (webstate.nightMode == '1'); if (nightMode) { QC('body').add('night'); QS('body')['background-color'] = '#000'; } else { QC('body').remove('night'); QS('body')['background-color'] = '#d3d9d6'; } }
if ((webstate.footerBar != null) && (webstate.footerBar != oldFooterBar)) { footerBar = (webstate.footerBar == '1'); QS('container')['grid-template-rows'] = null; QS('container')['-ms-grid-rows'] = null; adjustPanels(); }
if ((webstate.stars != null) && (webstate.stars != JSON.stringify(stars))) { stars = JSON.parse(webstate.stars); if (Q('SearchInput').value == '*') { mainUpdate(5); } else { mainUpdate(4); } }
}
} catch (ex) {}
break;
@ -3337,15 +3351,26 @@
if (showRealNames == true && node.rname != null) name = EscapeHtml(node.rname);
if (name.length == 0) { name = '<i>' + "None" + '</i>'; }
// Setup device notification
var devNotify = '';
// Add device notification icons
var devNotify = '', devNotifySub = '';
// This device is "starred"
if (stars[node._id] == 1) {
if (view == 2) {
devNotifySub += '<img class=deviceNotifySmallDotSub src=images/icon-star-notify-10.png width=10 height=10>';
} else {
devNotifySub += '<img class=deviceNotifyDotSub src=images/icon-star-notify-16.png width=16 height=16>';
}
}
// This device has session information
if (node.sessions != null) {
// Sessions are active
if ((node.sessions.kvm != null) || (node.sessions.terminal != null) || (node.sessions.files != null) || (node.sessions.tcp != null) || (node.sessions.udp != null)) {
if (view == 2) {
devNotify = '<img onclick=showDeviceSessions(\'' + node._id + '\',null,event) class=deviceNotifySmallDot src=images/icon-relay-notify10.png width=10 height=10>';
devNotifySub += '<img onclick=showDeviceSessions(\'' + node._id + '\',null,event) class=deviceNotifySmallDotSub src=images/icon-relay-notify10.png width=10 height=10>';
} else {
devNotify = '<img onclick=showDeviceSessions(\'' + node._id + '\',null,event) class=deviceNotifyDot src=images/icon-relay-notify.png width=16 height=16>';
devNotifySub += '<img onclick=showDeviceSessions(\'' + node._id + '\',null,event) class=deviceNotifyDotSub src=images/icon-relay-notify.png width=16 height=16>';
}
}
@ -3370,6 +3395,15 @@
}
}
// Add any device icons
if (devNotifySub != '') {
if (view == 2) {
devNotify += '<div class=deviceNotifySmallDot>' + devNotifySub + '</div>';
} else {
devNotify += '<div class=deviceNotifyDot>' + devNotifySub + '</div>';
}
}
// Node
var icon = node.icon;
if ((!node.conn) || (node.conn == 0)) { icon += ' gray'; }
@ -4205,12 +4239,10 @@
if (checkcount > 0) {
QE('GroupActionButton', true);
Q('SelectAllButton').value = "Select None";
QV('cxmgroupsplit', true);
QV('cxmdesktop', true);
} else {
QE('GroupActionButton', false);
Q('SelectAllButton').value = "Select All";
QV('cxmgroupsplit', false);
QV('cxmdesktop', false);
}
@ -4390,12 +4422,15 @@
for (var d in nodes) {
nodes[d].v = (((nodes[d].agent != null) && (nodes[d].agent.tag == null)) && (agentTagSearch == '')) || ((nodes[d].agent != null) && (nodes[d].agent.tag != null) && (nodes[d].agent.tag.toLowerCase().indexOf(agentTagSearch) >= 0));
}
} else if (userSearch != null) {
} else if (userSearch != null) {
// User search
for (var d in nodes) {
nodes[d].v = false;
if (nodes[d].users && nodes[d].users.length > 0) { for (var i in nodes[d].users) { if (nodes[d].users[i].toLowerCase().indexOf(userSearch) >= 0) { nodes[d].v = true; } } }
}
} else if (x == '*') {
// Star filter
for (var d in nodes) { nodes[d].v = (stars[nodes[d]._id] == 1); }
} else {
// Device name search
try {
@ -4473,6 +4508,8 @@
QV('cxfiles', ((mesh.mtype == 2) && ((node.agent == null) || (node.agent.caps == null) || ((node.agent.caps & 4) != 0))) && (rights & 8) && fileAccess);
QV('cxevents', (node.intelamt != null) && ((node.intelamt.state == 2) || (node.conn & 2)) && (rights & 8));
QV('cxconsole', (consoleRights && (mesh.mtype == 2) && ((node.agent == null) || (node.agent.caps == null) || ((node.agent.caps & 8) != 0))) && (rights & 8));
QV('cxmgroupsplit', true);
QV('cxstar', true);
break;
}
default: {
@ -4518,6 +4555,17 @@
}
}
}
if (action == 10) {
// Toggle star
var elements = document.getElementsByClassName('DeviceCheckbox'), selectedDevices = [];
for (var i = 0; i < elements.length; i++) { if (elements[i].checked === true) { selectedDevices.push(elements[i].defaultValue.substring(6)); } }
if (selectedDevices.length == 0) { selectedDevices.push(nodeid); }
for (var i in selectedDevices) { if (stars[selectedDevices[i]] != null) { delete stars[selectedDevices[i]]; delete selectedDevices[i]; } }
var starcount = Object.keys(stars).length;
for (var i in selectedDevices) { if ((starcount < 20) && (stars[selectedDevices[i]] == null)) { stars[selectedDevices[i]] = 1; starcount++; } }
putstore('stars', JSON.stringify(stars));
if (Q('SearchInput').value == '*') { mainUpdate(5); } else { mainUpdate(4); }
}
}
function cmmeshaction(action) {
@ -5269,6 +5317,7 @@
// Device Notification
QV('p10deviceNotify', (currentNode.sessions != null) && ((currentNode.sessions.kvm != null) || (currentNode.sessions.terminal != null) || (currentNode.sessions.files != null) || (currentNode.sessions.tcp != null) || (currentNode.sessions.udp != null)));
QV('p10deviceStar', stars[currentNode._id] == 1);
// Device Battery
QV('p10deviceBattery', false);
@ -13041,7 +13090,7 @@
var k = localStorage.key(i);
if (k[0] != '_') {
s[k] = localStorage.getItem(k);
if ((k != 'desktopsettings') && (typeof s[k] == 'string') && (s[k].length > 64)) { delete s[k]; }
if ((k != 'desktopsettings') && (k != 'stars') && (typeof s[k] == 'string') && (s[k].length > 64)) { delete s[k]; }
}
}
} catch (ex) {}

View File

@ -5704,8 +5704,9 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
var out = {};
for (var i in acceptableUserWebStateStrings) {
var n = acceptableUserWebStateStrings[i];
if ((state[n] != null) && ((typeof state[n] == 'number') || (typeof state[n] == 'boolean') || ((typeof state[n] == 'string') && (state[n].length < 32)))) { out[n] = state[n]; }
if ((state[n] != null) && ((typeof state[n] == 'number') || (typeof state[n] == 'boolean') || ((typeof state[n] == 'string') && (state[n].length < 64)))) { out[n] = state[n]; }
}
if ((typeof state.stars == 'string') && (state.stars.length < 2048)) { out.stars = state.stars; }
if (typeof state.desktopsettings == 'string') { try { state.desktopsettings = JSON.parse(state.desktopsettings); } catch (ex) { delete state.desktopsettings; } }
if (state.desktopsettings != null) {
out.desktopsettings = {};