MeshMessenger text starts at bottom.
Ylian Saint-Hilaire committed
Mar 21, 2021 at 13:16 UTC
d5639f1121007bbf34df844f51b43987e4871b2c
3 files changed
+66
-7
views/default-mobile.handlebars
+54
-4
@@ -677,9 +677,6 @@
677
</div>
678
<div style="padding:0;font-size:25px;background-color:#036;width:50px;border-radius:0 0 10px 0;height:36px">◀</div>
679
</td>
680
- <td>
681
- <img src="/images/user-50.png" width=50 height=50 />
682
- </td>
680
<td>
681
<div style=margin-left:5px>
682
<strong style="font-size:large"><span id=p3userName></span></strong><br />
@@ -688,6 +685,7 @@
685
</tr>
686
</table>
687
<div id=p3info style="overflow-y:auto;position:absolute;top:55px;bottom:0px;width:100%">
688
+ <img id="p2AccountImage" alt="" loading="lazy" width="128" height="128" onclick="account_manageImage(0)" src="images/user-256.png" style="position:absolute;right:8px;top:7px;border-radius:8px;box-shadow:0px 0px 7px #000" />
689
<div style="margin-left:8px">
690
<div id="p3AccountActions">
691
<div id="p2AccountSecurity" style="display:none">
@@ -1118,6 +1116,7 @@
1116
<div id="idx_dlgButtonBar" style="padding:10px;margin-bottom:20px">
1117
<input id="idx_dlgCancelButton" type="button" value="Cancel" style="float:right;width:80px;margin-left:5px" onclick="dialogclose(0)">
1118
<input id="idx_dlgOkButton" type="button" value="OK" style="float:right;width:80px" onclick="dialogclose(1)">
1119
+ <div><input id="idx_dlgDeleteButton" type="button" value="Delete" style="display:none" onclick="dialogclose(2)" /></div>
1120
</div>
1121
</div>
1122
<div id=topMenu style="z-index:1000;background-color:#EEE;box-shadow:0px 0px 15px #666;font-family:Arial,Helvetica,sans-serif;border-radius:0px 0px 5px 5px;position:fixed;top:50px;right:5px;width:170px;display:none">
@@ -1311,6 +1310,14 @@
1310
QV('p3createMeshLink1', false);
1311
QV('p3createMeshLink2', false);
1312
1313
+ // Update user image
1314
+ if ((userinfo.flags != null) && (userinfo.flags & 1)) {
1315
+ if (userinfo.accountImageRnd == null) { userinfo.accountImageRnd = Math.floor(Math.random() * 9999999999); }
1316
+ Q('p2AccountImage').src = 'userimage.ashx?rnd=' + userinfo.accountImageRnd;
1317
+ } else {
1318
+ Q('p2AccountImage').src = 'images/user-256.png';
1319
+ }
1320
+
1321
if (typeof userinfo.passchange == 'number') {
1322
if (userinfo.passchange == -1) { QH('p2nextPasswordUpdateTime', " - Reset on next login."); }
1323
else if ((passRequirements != null) && (typeof passRequirements.reset == 'number')) {
@@ -1568,7 +1575,7 @@
1575
}
1576
case 'previousLogins': {
1577
if ((xxdialogMode == 2) && (xxdialogTag == 'previousLogins')) {
1571
- var x = '', c = 'BBB';
1578
+ var x = '', c = 'BBB', xx = '';
1579
if (message.events.length == 0) {
1580
x += 'No previous login.';
1581
} else {
@@ -2045,6 +2052,48 @@
2052
meshserver.send({ action: 'previousLogins' });
2053
}
2054
2055
+ function account_manageImage(mode) {
2056
+ if (xxdialogMode) return;
2057
+ var user = (mode == 0) ? userinfo : currentUser;
2058
+ var x = '<input id=p2file type=file style=width:100% accept="image/*" onchange=account_manageImageEx()><div style=width:100%><canvas id=p2canvas width=256 height=256 style="width:256px;height:256px;margin-left:12px;margin-top:8px;border-radius:16px;box-shadow: 0px 0px 15px #000" onclick=account_canvasClick() /></div>';
2059
+ setDialogMode(2, "Manage Account Image", 7, account_manageImageEx2, x, user._id);
2060
+ var ctx = Q('p2canvas').getContext('2d');
2061
+ if (user.accountImageRnd == null) { user.accountImageRnd = Math.floor(Math.random() * 9999999999); }
2062
+ var arg = '';
2063
+ if (mode == 1) { arg = '&id=' + user._id.split('/')[2]; }
2064
+ var myImg = new Image();
2065
+ myImg.onload = function () { ctx.clearRect(0, 0, 256, 256); ctx.drawImage(myImg, 0, 0); };
2066
+ myImg.src = ((user.flags != null) && (user.flags & 1)) ? ('userimage.ashx?rnd=' + user.accountImageRnd + arg) : 'images/user-256.png';
2067
+ QE('idx_dlgDeleteButton', (user.flags != null) && (user.flags & 1));
2068
+ QE('idx_dlgOkButton', false);
2069
+ }
2070
+
2071
+ function account_canvasClick() { Q('p2file').click(); }
2072
+
2073
+ function account_manageImageEx() {
2074
+ var file = Q('p2file').files[0];
2075
+ var img = new Image;
2076
+ img.onload = function () {
2077
+ var cx = 0, cy = 0, min = Math.min(img.width, img.height);
2078
+ if (img.width > min) { cx = (img.width - min) / 2; }
2079
+ if (img.height > min) { cy = (img.height - min) / 2; }
2080
+ var ctx = Q('p2canvas').getContext('2d');
2081
+ ctx.imageSmoothingEnabled = true;
2082
+ ctx.webkitImageSmoothingEnabled = true;
2083
+ ctx.mozImageSmoothingEnabled = true;
2084
+ ctx.clearRect(0, 0, 256, 256);
2085
+ ctx.drawImage(img, cx, cy, min, min, 0, 0, 256, 256);
2086
+ QE('idx_dlgOkButton', true);
2087
+ }
2088
+ img.src = URL.createObjectURL(file);
2089
+ }
2090
+
2091
+ function account_manageImageEx2(b, userid) {
2092
+ // Send updated image, or 0 if we pressed the delete button
2093
+ meshserver.send({ action: 'updateUserImage', userid: userid, image: (b == 2) ? 0 : Q('p2canvas').toDataURL('image/jpeg', 0.8) });
2094
+ //meshserver.send({ action: 'updateUserImage', image: (b == 2)?0:Q('p2canvas').toDataURL('image/png', 0.8) });
2095
+ }
2096
+
2097
function toggleNightMode() {
2098
if (xxdialogMode) return;
2099
var cNightMode = getstore('nightMode', '0');
@@ -5621,6 +5670,7 @@
5670
QV('idx_dlgOkButton', b & 1);
5671
QV('idx_dlgCancelButton', b & 2);
5672
QV('id_dialogclose', (b & 2) || (b & 8));
5673
+ QV('idx_dlgDeleteButton', b & 4);
5674
QV('idx_dlgButtonBar', b & 7);
5675
if (y) QH('id_dialogtitle', y);
5676
for (var i = 1; i < 24; i++) { QV('dialog' + i, i == x); } // Edit this line when more dialogs are added
views/default.handlebars
-2
@@ -2683,8 +2683,6 @@
2683
if (userinfo._id == message.event.account._id) {
2684
var newsiteadmin = message.event.account.siteadmin?message.event.account.siteadmin:0;
2685
var oldsiteadmin = userinfo.siteadmin?userinfo.siteadmin:0;
2686
- var newflags = message.event.account.flags?message.event.account.flags:0;
2687
- var oldflags = userinfo.flags?userinfo.flags:0;
2686
if ((message.event.account.quota != userinfo.quota) || (((userinfo.siteadmin & 8) == 0) && ((message.event.account.siteadmin & 8) != 0))) { meshserver.send({ action: 'files' }); }
2687
var oldgroups = userinfo.groups;
2688
userinfo = message.event.account;
views/messenger.handlebars
+12
-1
@@ -27,7 +27,7 @@
27
<div style="padding-top:9px;padding-left:6px;font-size:20px;display:inline-block"><b><span id="xtitle"></span></b></div>
28
</div>
29
<div id="xmiddle" style="position:absolute;left:0;right:0;top:38px;bottom:36px;font-size:18px">
30
- <div id="xmsgparent" style="position:absolute;left:0;right:0;top:0;bottom:0;overflow-y:scroll">
30
+ <div id="xmsgparent" style="position:absolute;left:0;right:0;bottom:0;max-height:100%;overflow-y:auto">
31
<div id="xmsg" style="padding:5px"></div>
32
<div id="typingIndicator" style="display:none;margin-left:5px;clear:both"><img src="images/3dots-24.gif" srcset="images/3dots-48.gif 2x" /></div>
33
</div>
@@ -379,6 +379,17 @@
379
if (typeof data == 'string') {
380
try { data = JSON.parse(data); } catch (ex) { console.log('Unable to parse', data); return; }
381
//console.log('RECV', data);
382
+
383
+ // Handle control command
384
+ if (data.ctrlChannel == '102938') {
385
+ switch (data.type) {
386
+ case 'ping': { send({ ctrlChannel: '102938', type: 'pong' }); break; }
387
+ case 'pong': { break; }
388
+ }
389
+ return;
390
+ }
391
+
392
+ // Handle command
393
switch (data.action) {
394
case 'chat': { displayRemote(data.msg); updateRemoteOutText(false); break; } // Incoming chat message.
395
case 'outtext': { updateRemoteOutText(data.value); break; }