Preliminary message handling overhauls (also fixes DMs being catastrophically broken).

This commit is contained in:
flash 2024-05-07 21:08:53 +00:00
parent 4741190913
commit c379c4bd0e
10 changed files with 288 additions and 273 deletions

114
package-lock.json generated
View file

@ -5,7 +5,7 @@
"packages": { "packages": {
"": { "": {
"dependencies": { "dependencies": {
"@swc/core": "^1.4.14", "@swc/core": "^1.5.3",
"autoprefixer": "^10.4.19", "autoprefixer": "^10.4.19",
"cssnano": "^6.1.2", "cssnano": "^6.1.2",
"html-minifier-terser": "^7.2.0", "html-minifier-terser": "^7.2.0",
@ -65,9 +65,9 @@
} }
}, },
"node_modules/@swc/core": { "node_modules/@swc/core": {
"version": "1.4.14", "version": "1.5.3",
"resolved": "https://registry.npmjs.org/@swc/core/-/core-1.4.14.tgz", "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.5.3.tgz",
"integrity": "sha512-tHXg6OxboUsqa/L7DpsCcFnxhLkqN/ht5pCwav1HnvfthbiNIJypr86rNx4cUnQDJepETviSqBTIjxa7pSpGDQ==", "integrity": "sha512-pSEglypnBGLHBoBcv3aYS7IM2t2LRinubYMyP88UoFIcD2pear2CeB15CbjJ2IzuvERD0ZL/bthM7cDSR9g+aQ==",
"hasInstallScript": true, "hasInstallScript": true,
"dependencies": { "dependencies": {
"@swc/counter": "^0.1.2", "@swc/counter": "^0.1.2",
@ -81,16 +81,16 @@
"url": "https://opencollective.com/swc" "url": "https://opencollective.com/swc"
}, },
"optionalDependencies": { "optionalDependencies": {
"@swc/core-darwin-arm64": "1.4.14", "@swc/core-darwin-arm64": "1.5.3",
"@swc/core-darwin-x64": "1.4.14", "@swc/core-darwin-x64": "1.5.3",
"@swc/core-linux-arm-gnueabihf": "1.4.14", "@swc/core-linux-arm-gnueabihf": "1.5.3",
"@swc/core-linux-arm64-gnu": "1.4.14", "@swc/core-linux-arm64-gnu": "1.5.3",
"@swc/core-linux-arm64-musl": "1.4.14", "@swc/core-linux-arm64-musl": "1.5.3",
"@swc/core-linux-x64-gnu": "1.4.14", "@swc/core-linux-x64-gnu": "1.5.3",
"@swc/core-linux-x64-musl": "1.4.14", "@swc/core-linux-x64-musl": "1.5.3",
"@swc/core-win32-arm64-msvc": "1.4.14", "@swc/core-win32-arm64-msvc": "1.5.3",
"@swc/core-win32-ia32-msvc": "1.4.14", "@swc/core-win32-ia32-msvc": "1.5.3",
"@swc/core-win32-x64-msvc": "1.4.14" "@swc/core-win32-x64-msvc": "1.5.3"
}, },
"peerDependencies": { "peerDependencies": {
"@swc/helpers": "^0.5.0" "@swc/helpers": "^0.5.0"
@ -102,9 +102,9 @@
} }
}, },
"node_modules/@swc/core-darwin-arm64": { "node_modules/@swc/core-darwin-arm64": {
"version": "1.4.14", "version": "1.5.3",
"resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.4.14.tgz", "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.5.3.tgz",
"integrity": "sha512-8iPfLhYNspBl836YYsfv6ErXwDUqJ7IMieddV3Ey/t/97JAEAdNDUdtTKDtbyP0j/Ebyqyn+fKcqwSq7rAof0g==", "integrity": "sha512-kRmmV2XqWegzGXvJfVVOj10OXhLgaVOOBjaX3p3Aqg7Do5ksg+bY5wi1gAN/Eul7B08Oqf7GG7WJevjDQGWPOg==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -117,9 +117,9 @@
} }
}, },
"node_modules/@swc/core-darwin-x64": { "node_modules/@swc/core-darwin-x64": {
"version": "1.4.14", "version": "1.5.3",
"resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.4.14.tgz", "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.5.3.tgz",
"integrity": "sha512-9CqSj8uRZ92cnlgAlVaWMaJJBdxtNvCzJxaGj5KuIseeG6Q0l1g+qk8JcU7h9dAsH9saHTNwNFBVGKQo0W0ujg==", "integrity": "sha512-EYs0+ovaRw6ZN9GBr2nIeC7gUXWA0q4RYR+Og3Vo0Qgv2Mt/XudF44A2lPK9X7M3JIfu6JjnxnTuvsK1Lqojfw==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -132,9 +132,9 @@
} }
}, },
"node_modules/@swc/core-linux-arm-gnueabihf": { "node_modules/@swc/core-linux-arm-gnueabihf": {
"version": "1.4.14", "version": "1.5.3",
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.4.14.tgz", "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.5.3.tgz",
"integrity": "sha512-mfd5JArPITTzMjcezH4DwMw+BdjBV1y25Khp8itEIpdih9ei+fvxOOrDYTN08b466NuE2dF2XuhKtRLA7fXArQ==", "integrity": "sha512-RBVUTidSf4wgPdv98VrgJ4rMzMDN/3LBWdT7l+R7mNFH+mtID7ZAhTON0o/m1HkECgAgi1xcbTOVAw1xgd5KLA==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@ -147,9 +147,9 @@
} }
}, },
"node_modules/@swc/core-linux-arm64-gnu": { "node_modules/@swc/core-linux-arm64-gnu": {
"version": "1.4.14", "version": "1.5.3",
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.4.14.tgz", "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.5.3.tgz",
"integrity": "sha512-3Lqlhlmy8MVRS9xTShMaPAp0oyUt0KFhDs4ixJsjdxKecE0NJSV/MInuDmrkij1C8/RQ2wySRlV9np5jK86oWw==", "integrity": "sha512-DCC6El3MiTYfv98CShxz/g2s4Pxn6tV0mldCQ0UdRqaN2ApUn7E+zTrqaj5bk7yII3A43WhE9Mr6wNPbXUeVyg==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -162,9 +162,9 @@
} }
}, },
"node_modules/@swc/core-linux-arm64-musl": { "node_modules/@swc/core-linux-arm64-musl": {
"version": "1.4.14", "version": "1.5.3",
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.4.14.tgz", "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.5.3.tgz",
"integrity": "sha512-n0YoCa64TUcJrbcXIHIHDWQjdUPdaXeMHNEu7yyBtOpm01oMGTKP3frsUXIABLBmAVWtKvqit4/W1KVKn5gJzg==", "integrity": "sha512-p04ysjYXEyaCGpJvwHm0T0nkPawXtdKBTThWnlh8M5jYULVNVA1YmC9azG2Avs1GDaLgBPVUgodmFYpdSupOYA==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -177,9 +177,9 @@
} }
}, },
"node_modules/@swc/core-linux-x64-gnu": { "node_modules/@swc/core-linux-x64-gnu": {
"version": "1.4.14", "version": "1.5.3",
"resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.4.14.tgz", "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.5.3.tgz",
"integrity": "sha512-CGmlwLWbfG1dB4jZBJnp2IWlK5xBMNLjN7AR5kKA3sEpionoccEnChOEvfux1UdVJQjLRKuHNV9yGyqGBTpxfQ==", "integrity": "sha512-/l4KJu0xwYm6tcVSOvF8RbXrIeIHJAhWnKvuX4ZnYKFkON968kB8Ghx+1yqBQcZf36tMzSuZUC5xBUA9u66lGA==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -192,9 +192,9 @@
} }
}, },
"node_modules/@swc/core-linux-x64-musl": { "node_modules/@swc/core-linux-x64-musl": {
"version": "1.4.14", "version": "1.5.3",
"resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.4.14.tgz", "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.5.3.tgz",
"integrity": "sha512-xq4npk8YKYmNwmr8fbvF2KP3kUVdZYfXZMQnW425gP3/sn+yFQO8Nd0bGH40vOVQn41kEesSe0Z5O/JDor2TgQ==", "integrity": "sha512-54DmSnrTXq4fYEKNR0nFAImG3+FxsHlQ6Tol/v3l+rxmg2K0FeeDOpH7wTXeWhMGhFlGrLIyLSnA+SzabfoDIA==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -207,9 +207,9 @@
} }
}, },
"node_modules/@swc/core-win32-arm64-msvc": { "node_modules/@swc/core-win32-arm64-msvc": {
"version": "1.4.14", "version": "1.5.3",
"resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.4.14.tgz", "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.5.3.tgz",
"integrity": "sha512-imq0X+gU9uUe6FqzOQot5gpKoaC00aCUiN58NOzwp0QXEupn8CDuZpdBN93HiZswfLruu5jA1tsc15x6v9p0Yg==", "integrity": "sha512-piUMqoHNwDXChBfaaFIMzYgoxepfd8Ci1uXXNVEnuiRKz3FiIcNLmvXaBD7lKUwKcnGgVziH/CrndX6SldKQNQ==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -222,9 +222,9 @@
} }
}, },
"node_modules/@swc/core-win32-ia32-msvc": { "node_modules/@swc/core-win32-ia32-msvc": {
"version": "1.4.14", "version": "1.5.3",
"resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.4.14.tgz", "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.5.3.tgz",
"integrity": "sha512-cH6QpXMw5D3t+lpx6SkErHrxN0yFzmQ0lgNAJxoDRiaAdDbqA6Col8UqUJwUS++Ul6aCWgNhCdiEYehPaoyDPA==", "integrity": "sha512-zV5utPYBUzYhBOomCByAjKAvfVBcOCJtnszx7Zlfz7SAv/cGm8D1QzPDCvv6jDhIlUtLj6KyL8JXeFr+f95Fjw==",
"cpu": [ "cpu": [
"ia32" "ia32"
], ],
@ -237,9 +237,9 @@
} }
}, },
"node_modules/@swc/core-win32-x64-msvc": { "node_modules/@swc/core-win32-x64-msvc": {
"version": "1.4.14", "version": "1.5.3",
"resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.4.14.tgz", "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.5.3.tgz",
"integrity": "sha512-FmZ4Tby4wW65K/36BKzmuu7mlq7cW5XOxzvufaSNVvQ5PN4OodAlqPjToe029oma4Av+ykJiif64scMttyNAzg==", "integrity": "sha512-QmUiXiPIV5gBADfDh8e2jKynEhyRC+dcKP/zF9y5KqDUErYzlhocLd68uYS4uIegP6AylYlmigHgcaktGEE9VQ==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -381,9 +381,9 @@
} }
}, },
"node_modules/caniuse-lite": { "node_modules/caniuse-lite": {
"version": "1.0.30001610", "version": "1.0.30001616",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001610.tgz", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001616.tgz",
"integrity": "sha512-QFutAY4NgaelojVMjY63o6XlZyORPaLfyMnsl3HgnWdJUcX6K0oaJymHjH8PT5Gk7sTm8rvC/c5COUQKXqmOMA==", "integrity": "sha512-RHVYKov7IcdNjVHJFNY/78RdG4oGVjbayxv8u5IO74Wv7Hlq4PnJE6mo/OjFijjVFNy5ijnCt6H3IIo4t+wfEw==",
"funding": [ "funding": [
{ {
"type": "opencollective", "type": "opencollective",
@ -647,9 +647,9 @@
} }
}, },
"node_modules/electron-to-chromium": { "node_modules/electron-to-chromium": {
"version": "1.4.737", "version": "1.4.757",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.737.tgz", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.757.tgz",
"integrity": "sha512-QvLTxaLHKdy5YxvixAw/FfHq2eWLUL9KvsPjp0aHK1gI5d3EDuDgITkvj0nFO2c6zUY3ZqVAJQiBYyQP9tQpfw==" "integrity": "sha512-jftDaCknYSSt/+KKeXzH3LX5E2CvRLm75P3Hj+J/dv3CL0qUYcOt13d5FN1NiL5IJbbhzHrb3BomeG2tkSlZmw=="
}, },
"node_modules/entities": { "node_modules/entities": {
"version": "4.5.0", "version": "4.5.0",
@ -1314,9 +1314,9 @@
} }
}, },
"node_modules/terser": { "node_modules/terser": {
"version": "5.30.3", "version": "5.31.0",
"resolved": "https://registry.npmjs.org/terser/-/terser-5.30.3.tgz", "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.0.tgz",
"integrity": "sha512-STdUgOUx8rLbMGO9IOwHLpCqolkDITFFQSMYYwKE1N2lY6MVSaeoi10z/EhWxRc6ybqoVmKSkhKYH/XUpl7vSA==", "integrity": "sha512-Q1JFAoUKE5IMfI4Z/lkE/E6+SwgzO+x4tq4v1AyBLRj8VSYvRO6A/rQrPg1yud4g0En9EKI1TvFRF2tQFcoUkg==",
"dependencies": { "dependencies": {
"@jridgewell/source-map": "^0.3.3", "@jridgewell/source-map": "^0.3.3",
"acorn": "^8.8.2", "acorn": "^8.8.2",
@ -1341,9 +1341,9 @@
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
}, },
"node_modules/update-browserslist-db": { "node_modules/update-browserslist-db": {
"version": "1.0.13", "version": "1.0.15",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.15.tgz",
"integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", "integrity": "sha512-K9HWH62x3/EalU1U6sjSZiylm9C8tgq2mSvshZpqc7QE69RaA2qjhkW2HlNA0tFpEbtyFz7HTqbSdN4MSwUodA==",
"funding": [ "funding": [
{ {
"type": "opencollective", "type": "opencollective",
@ -1359,7 +1359,7 @@
} }
], ],
"dependencies": { "dependencies": {
"escalade": "^3.1.1", "escalade": "^3.1.2",
"picocolors": "^1.0.0" "picocolors": "^1.0.0"
}, },
"bin": { "bin": {

View file

@ -1,6 +1,6 @@
{ {
"dependencies": { "dependencies": {
"@swc/core": "^1.4.14", "@swc/core": "^1.5.3",
"autoprefixer": "^10.4.19", "autoprefixer": "^10.4.19",
"cssnano": "^6.1.2", "cssnano": "^6.1.2",
"html-minifier-terser": "^7.2.0", "html-minifier-terser": "^7.2.0",

View file

@ -7,7 +7,6 @@ window.Umi = { UI: {} };
#include context.js #include context.js
#include emotes.js #include emotes.js
#include events.js #include events.js
#include messages.js
#include mszauth.js #include mszauth.js
#include txtrigs.js #include txtrigs.js
#include utility.js #include utility.js
@ -29,6 +28,7 @@ window.Umi = { UI: {} };
#include ui/loading-overlay.jsx #include ui/loading-overlay.jsx
#include ui/markup.js #include ui/markup.js
#include ui/menus.js #include ui/menus.js
#include ui/messages.jsx
#include ui/ping.jsx #include ui/ping.jsx
#include ui/settings.jsx #include ui/settings.jsx
#include ui/toggles.js #include ui/toggles.js
@ -378,7 +378,6 @@ window.Umi = { UI: {} };
Umi.UI.Toggles.Add('clear', { Umi.UI.Toggles.Add('clear', {
'click': function() { 'click': function() {
ctx.msgbox.show({ body: 'ARE YOU SURE ABOUT THAT???', yes: true, no: true }).then(() => { ctx.msgbox.show({ body: 'ARE YOU SURE ABOUT THAT???', yes: true, no: true }).then(() => {
const limit = settings.get('explosionRadius');
const explode = $e({ const explode = $e({
tag: 'img', tag: 'img',
attrs: { attrs: {
@ -392,7 +391,7 @@ window.Umi = { UI: {} };
pointerEvents: 'none', pointerEvents: 'none',
}, },
onLoad: function() { onLoad: function() {
setTimeout(function(){ setTimeout(function() {
$r(explode); $r(explode);
}, 1700); }, 1700);
@ -402,14 +401,7 @@ window.Umi = { UI: {} };
}); });
document.body.appendChild(explode); document.body.appendChild(explode);
Umi.UI.Messages.Clear(settings.get('explosionRadius'));
let backLog = Umi.Messages.All();
backLog = backLog.slice(Math.max(backLog.length - limit, 0));
Umi.Messages.Clear();
for(const blMsg of backLog)
Umi.Messages.Add(blMsg);
}).catch(() => {}); }).catch(() => {});
} }
}, 'Clear Logs'); }, 'Clear Logs');

View file

@ -18,8 +18,6 @@ Umi.Message = (() => {
isLog = !!isLog; isLog = !!isLog;
hasSeen = isLog; hasSeen = isLog;
const msgIdInt = parseInt(msgId);
return { return {
getId: () => msgId, getId: () => msgId,
getIdInt: () => { getIdInt: () => {
@ -40,50 +38,3 @@ Umi.Message = (() => {
}; };
}; };
})(); })();
Umi.Messages = (function() {
const msgs = new Map;
return {
Add: function(msg) {
const msgId = msg.getId();
if(!msgs.has(msgId)) {
msgs.set(msgId, msg);
Umi.UI.Messages.Add(msg);
mami.globalEvents.dispatch('umi:message_add', msg);
}
},
Remove: function(msg) {
const msgId = msg.getId();
if(msgs.has(msgId)) {
msgs.delete(msgId);
Umi.UI.Messages.Remove(msg);
}
},
Clear: function() {
msgs.clear();
Umi.UI.Messages.RemoveAll();
},
All: function(channel, excludeNull) {
if(!channel)
return Array.from(msgs.values());
if(!Umi.Channels.Get(channel))
return null;
const filtered = [];
msgs.forEach(function(msg) {
if(msg.getChannel() === channel || (!excludeNull && msg.getChannel() === null))
filtered.push(msg);
});
return filtered.slice(Math.max(filtered.length - 30, 0));
},
Get: function(msgId) {
msgId = msgId.toString();
if(msgs.has(msgId))
return msgs.get(msgId);
return null;
},
};
})();

View file

@ -1,4 +1,3 @@
#include messages.js
#include utility.js #include utility.js
#include ui/markup.js #include ui/markup.js
@ -109,18 +108,17 @@ Umi.Parsing = (function() {
} }
const extractMotiv = function(elem) { const extractMotiv = function(elem) {
const msgId = parseInt(elem.parentNode.parentNode.parentNode.parentNode.id.substring(8)); let topText = 'Top Text';
let topText = 'Top Text', let bottomText = 'Bottom Text';
bottomText = 'Bottom Text';
const msg = Umi.Messages.Get(msgId); const root = elem.closest('.message');
if(msg) { if(root instanceof Element && 'body' in root.dataset) {
const msgText = msg.getText().replace(/\[(.*?)\](.*?)\[\/(.*?)\]/g, '').trim(); const msgText = root.dataset.body.replace(/\[(.*?)\](.*?)\[\/(.*?)\]/g, '').trim();
if(msgText.length > 0) { if(msgText.length > 0) {
const msgTextParts = msgText.split(' '), const msgTextParts = msgText.split(' ');
topTextLength = Math.ceil(msgTextParts.length / 10), const topTextLength = Math.ceil(msgTextParts.length / 10);
topTextParts = msgTextParts.slice(0, topTextLength); const topTextParts = msgTextParts.slice(0, topTextLength);
let bottomTextParts = null; let bottomTextParts = null;
if(msgTextParts.length === 1 || Math.random() > .7) { if(msgTextParts.length === 1 || Math.random() > .7) {

View file

@ -142,7 +142,7 @@ const MamiSockChatHandlers = function(ctx, client, setLoadingOverlay, sockChatRe
Umi.Users.Add(userInfo); Umi.Users.Add(userInfo);
if(ev.detail.msg !== undefined) if(ev.detail.msg !== undefined)
Umi.Messages.Add(new Umi.Message( Umi.UI.Messages.Add(new Umi.Message(
ev.detail.msg.id, ev.detail.msg.time, undefined, '', ev.detail.msg.channel, false, ev.detail.msg.id, ev.detail.msg.time, undefined, '', ev.detail.msg.channel, false,
{ {
isError: false, isError: false,
@ -160,7 +160,7 @@ const MamiSockChatHandlers = function(ctx, client, setLoadingOverlay, sockChatRe
return; return;
if(ev.detail.msg !== undefined) if(ev.detail.msg !== undefined)
Umi.Messages.Add(new Umi.Message( Umi.UI.Messages.Add(new Umi.Message(
ev.detail.msg.id, ev.detail.msg.id,
ev.detail.msg.time, ev.detail.msg.time,
undefined, undefined,
@ -250,11 +250,11 @@ const MamiSockChatHandlers = function(ctx, client, setLoadingOverlay, sockChatRe
Umi.Users.Add(userInfo); Umi.Users.Add(userInfo);
if(ev.detail.msg !== undefined) if(ev.detail.msg !== undefined)
Umi.Messages.Add(new Umi.Message( Umi.UI.Messages.Add(new Umi.Message(
ev.detail.msg.id, null, undefined, '', ev.detail.msg.channel, false, ev.detail.msg.id, null, undefined, '', ev.detail.msg.channel, false,
{ {
isError: false, isError: false,
type: leave.msg.botInfo.type, type: ev.detail.msg.botInfo.type,
args: [ userInfo.name ], args: [ userInfo.name ],
target: userInfo, target: userInfo,
}, },
@ -271,7 +271,7 @@ const MamiSockChatHandlers = function(ctx, client, setLoadingOverlay, sockChatRe
return; return;
if(ev.detail.msg !== undefined) if(ev.detail.msg !== undefined)
Umi.Messages.Add(new Umi.Message( Umi.UI.Messages.Add(new Umi.Message(
ev.detail.msg.id, null, undefined, '', ev.detail.msg.channel, false, ev.detail.msg.id, null, undefined, '', ev.detail.msg.channel, false,
{ {
isError: false, isError: false,
@ -319,7 +319,7 @@ const MamiSockChatHandlers = function(ctx, client, setLoadingOverlay, sockChatRe
Umi.UI.Menus.Attention('channels'); Umi.UI.Menus.Attention('channels');
} }
Umi.Messages.Add(new Umi.Message( Umi.UI.Messages.Add(new Umi.Message(
ev.detail.msg.id, ev.detail.msg.id,
ev.detail.msg.time, ev.detail.msg.time,
userInfo, userInfo,
@ -334,12 +334,7 @@ const MamiSockChatHandlers = function(ctx, client, setLoadingOverlay, sockChatRe
handlers['msg:remove'] = ev => { handlers['msg:remove'] = ev => {
if(dumpEvents) console.log('msg:remove', ev.detail); if(dumpEvents) console.log('msg:remove', ev.detail);
Umi.Messages.Remove(Umi.Messages.Get(ev.detail.msg.id)); Umi.UI.Messages.Remove(ev.detail.msg.id);
};
handlers['msg:clear'] = () => {
if(dumpEvents) console.log('msg:clear');
Umi.UI.Messages.RemoveAll();
}; };

View file

@ -1,5 +1,4 @@
#include channels.js #include channels.js
#include messages.js
#include utility.js #include utility.js
#include ui/menus.js #include ui/menus.js
@ -50,22 +49,16 @@ Umi.UI.Channels = (function() {
Umi.UI.Menus.Get('channels').innerHTML = ''; Umi.UI.Menus.Get('channels').innerHTML = '';
}, },
Reload: function(initial) { Reload: function(initial) {
const current = Umi.Channels.Current(), const current = Umi.Channels.Current();
channel = $i('channel-' + current.name.toLowerCase().replace(' ', '-')), const channel = $i('channel-' + current.name.toLowerCase().replace(' ', '-'));
prev = $c(sidebarChannelCurrent)[0]; const prev = $c(sidebarChannelCurrent)[0];
if((typeof prev).toLowerCase() !== 'undefined') if(prev instanceof Element)
prev.classList.remove(sidebarChannelCurrent); prev.classList.remove(sidebarChannelCurrent);
channel.classList.add(sidebarChannelCurrent); channel.classList.add(sidebarChannelCurrent);
if(initial) Umi.UI.Messages.SwitchChannel(current);
return;
Umi.UI.Messages.RemoveAll();
const channelMsgs = Umi.Messages.All(current.name);
for(const channelMsg of channelMsgs)
Umi.UI.Messages.Add(channelMsg);
}, },
Switch: function(channelName) { Switch: function(channelName) {
markUnread(channelName, true); markUnread(channelName, true);

View file

@ -11,10 +11,7 @@
#include ui/emotes.js #include ui/emotes.js
Umi.UI.Messages = (function() { Umi.UI.Messages = (function() {
let forceUserInfo = false; let focusChannelName = '';
let lastMsgUser = null;
let lastMsgChannel = null;
let lastWasTiny = null;
const title = new MamiWindowTitle({ const title = new MamiWindowTitle({
getName: () => futami.get('title'), getName: () => futami.get('title'),
@ -22,6 +19,16 @@ Umi.UI.Messages = (function() {
window.addEventListener('focus', () => title.clear()); window.addEventListener('focus', () => title.clear());
const shouldDisplayAuthorInfo = (target, ref) => {
if(!(target instanceof Element) || !(ref instanceof Element))
return true;
return target.dataset.tiny !== undefined
|| target.dataset.author !== ref.dataset.author
|| target.dataset.channel !== ref.dataset.channel
|| target.dataset.tiny !== ref.dataset.tiny;
};
const botMsgs = { const botMsgs = {
'say': { text: '%0' }, 'say': { text: '%0' },
'generr': { text: 'Something unexpected happened.' }, 'generr': { text: 'Something unexpected happened.' },
@ -115,27 +122,40 @@ Umi.UI.Messages = (function() {
return { return {
Add: function(msg) { Add: function(msg) {
const currentChannel = Umi.Channels.Current(); mami.globalEvents.dispatch('umi:message_add', msg);
const msgId = msg.getId();
const elementId = `message-${msgId}`;
if(msgId !== '' && $i(elementId))
return;
const channelName = msg.getChannel(); const channelName = msg.getChannel();
const sender = msg.getUserV2(); const sender = msg.getUserV2();
const isBot = sender.id === '-1'; const isBot = sender.id === '-1';
const isOutgoing = Umi.User.isCurrentUser(sender); const isOutgoing = Umi.User.isCurrentUser(sender);
const hasSeen = msg.hasSeen(); const hasSeen = msg.hasSeen();
const displayMessage = currentChannel === null || channelName === null || channelName === currentChannel.name; const displayMessage = focusChannelName === '' || channelName === '' || channelName === focusChannelName;
const notifyPM = !displayMessage && !isOutgoing && !hasSeen && channelName.startsWith('@'); const notifyPM = !displayMessage && !isOutgoing && !hasSeen && channelName.startsWith('@');
let isTiny = false, let isTiny = false;
skipTextParsing = false, let skipTextParsing = false;
msgText = msg.getText(), let msgText = msg.getText();
msgTextLong = msgText; let msgTextLong = msgText;
let eBase, eAvatar, eText, eMeta, eUser; let eBase;
let eAvatar;
let eText;
let eMeta;
let eUser;
let avatarUser = sender, let avatarUser = sender;
avatarSize = '80'; let avatarSize = '80';
let soundName = isOutgoing ? 'outgoing' : 'incoming', let soundIsLegacy = true;
soundVolume, soundRate, soundIsLegacy = true; let soundName = isOutgoing ? 'outgoing' : 'incoming';
let soundVolume;
let soundRate;
const userClass = `message--user-${sender.id}`; const userClass = `message--user-${sender.id}`;
@ -144,24 +164,21 @@ Umi.UI.Messages = (function() {
const avatarClasses = ['message__avatar']; const avatarClasses = ['message__avatar'];
const msgIsFirst = forceUserInfo || lastMsgUser !== sender.id || lastMsgChannel !== msg.getChannel();
if(msgIsFirst) {
forceUserInfo = false;
classes.push('message--first');
}
if(msg.isAction()) { if(msg.isAction()) {
isTiny = true; isTiny = true;
classes.push('message-action'); classes.push('message-action');
} }
if(!displayMessage)
classes.push('hidden');
if(sender.id === "136") if(sender.id === "136")
styles.transform = 'scaleY(' + (0.76 + (0.01 * Math.max(0, Math.ceil(Date.now() / (7 * 24 * 60 * 60000)) - 2813))).toString() + ')'; styles.transform = 'scaleY(' + (0.76 + (0.01 * Math.max(0, Math.ceil(Date.now() / (7 * 24 * 60 * 60000)) - 2813))).toString() + ')';
const msgDateTimeObj = msg.getTime(); const msgCreated = msg.getTime();
const msgDateTime = msgDateTimeObj.getHours().toString().padStart(2, '0') const msgDateTime = msgCreated.getHours().toString().padStart(2, '0')
+ ':' + msgDateTimeObj.getMinutes().toString().padStart(2, '0') + ':' + msgCreated.getMinutes().toString().padStart(2, '0')
+ ':' + msgDateTimeObj.getSeconds().toString().padStart(2, '0'); + ':' + msgCreated.getSeconds().toString().padStart(2, '0');
if(isBot) { if(isBot) {
const botInfo = msg.getBotInfo(); const botInfo = msg.getBotInfo();
@ -222,94 +239,121 @@ Umi.UI.Messages = (function() {
.replace('{resolution}', avatarSize) .replace('{resolution}', avatarSize)
.replace('{user:avatar_change}', avatarUser.avatarChangeTime); .replace('{user:avatar_change}', avatarUser.avatarChangeTime);
if(displayMessage) { eAvatar = <div class={avatarClasses}/>;
if(isTiny) { eUser = <div class="message__user" style={{ color: avatarUser.colour }}>{avatarUser.name}</div>;
if(!msgIsFirst) // small messages must always be "first"
classes.push('message--first');
classes.push('message-tiny');
avatarSize = '40'; if(isTiny) {
classes.push('message-tiny');
if(msgText.indexOf("'") !== 0 || (msgText.match(/\'/g).length % 2) === 0) avatarSize = '40';
msgText = "\xA0" + msgText;
eBase = <div id={`message-${msg.getId()}`} class={classes} style={styles}> if(msgText.indexOf("'") !== 0 || (msgText.match(/\'/g).length % 2) === 0)
{eAvatar = <div class={avatarClasses}/>} msgText = "\xA0" + msgText;
<div class="message__container">
{eMeta = <div class="message__meta">
{eUser = <div class="message__user" style={{ color: avatarUser.colour }}>{avatarUser.name}</div>}
{eText = <div class="message-tiny-text"/>}
<div class="message__time">{msgDateTime}</div>
</div>}
</div>
</div>;
} else {
eBase = <div id={`message-${msg.getId()}`} class={classes} style={styles}>
{eAvatar = <div class={avatarClasses}/>}
<div class="message__container">
{eMeta = <div class="message__meta">
{eUser = <div class="message__user" style={{ color: avatarUser.colour }}>{avatarUser.name}</div>}
<div class="message__time">{msgDateTime}</div>
</div>}
{eText = <div class="message__text"/>}
</div>
</div>;
}
eText.innerText = msgText; eBase = <div class={classes} style={styles}>
{eAvatar}
<div class="message__container">
{eMeta = <div class="message__meta">
{eUser}
{eText = <div class="message-tiny-text"/>}
<div class="message__time">{msgDateTime}</div>
</div>}
</div>
</div>;
} else {
eBase = <div class={classes} style={styles}>
{eAvatar}
<div class="message__container">
{eMeta = <div class="message__meta">
{eUser}
<div class="message__time">{msgDateTime}</div>
</div>}
{eText = <div class="message__text"/>}
</div>
</div>;
}
if(!skipTextParsing) { if(msgId !== '') {
eText = Umi.UI.Emoticons.Parse(eText, msg); eBase.id = elementId;
eText = Umi.Parsing.Parse(eText, msg); eBase.dataset.id = msgId;
}
if(!isBot)
eBase.dataset.author = sender.id;
if(channelName !== '')
eBase.dataset.channel = channelName;
if(isTiny)
eBase.dataset.tiny = '1';
eBase.dataset.created = msgCreated.toISOString();
const urls = []; eBase.dataset.body = msgText;
eText.innerText = msgText;
if(mami.settings.get('autoParseUrls')) { if(!skipTextParsing) {
const textSplit = eText.innerText.split(' '); eText = Umi.UI.Emoticons.Parse(eText, msg);
for(const textPart of textSplit) { eText = Umi.Parsing.Parse(eText, msg);
const uri = Umi.URI.Parse(textPart);
if(uri !== null && uri.Slashes !== null) { const urls = [];
urls.push(textPart);
const anchorElem = <a class="markup__link" href={textPart} target="_blank" rel="nofollow noreferrer noopener">{textPart}</a>; if(mami.settings.get('autoParseUrls')) {
eText.innerHTML = eText.innerHTML.replace(textPart.replace(/&/g, '&amp;'), anchorElem.outerHTML); const textSplit = eText.innerText.split(' ');
} for(const textPart of textSplit) {
const uri = Umi.URI.Parse(textPart);
if(uri !== null && uri.Slashes !== null) {
urls.push(textPart);
const anchorElem = <a class="markup__link" href={textPart} target="_blank" rel="nofollow noreferrer noopener">{textPart}</a>;
eText.innerHTML = eText.innerHTML.replace(textPart.replace(/&/g, '&amp;'), anchorElem.outerHTML);
} }
} }
if(mami.settings.get('weeaboo')) {
eText.appendChild($t(Weeaboo.getTextSuffix(sender)));
const kaomoji = Weeaboo.getRandomKaomoji(true, msg);
if(kaomoji) {
eText.appendChild($t(' '));
eText.appendChild($t(kaomoji));
}
}
if(mami.settings.get('weeaboo'))
eUser.appendChild($t(Weeaboo.getNameSuffix(sender)));
} }
if(isTiny !== lastWasTiny) { if(mami.settings.get('weeaboo')) {
if(!msgIsFirst) eText.appendChild($t(Weeaboo.getTextSuffix(sender)));
eBase.classList.add('message--first');
const kaomoji = Weeaboo.getRandomKaomoji(true, msg);
if(kaomoji) {
eText.appendChild($t(' '));
eText.appendChild($t(kaomoji));
}
}
if(mami.settings.get('weeaboo'))
eUser.appendChild($t(Weeaboo.getNameSuffix(sender)));
}
if(avatarUrl === undefined)
eAvatar.classList.add('message__avatar--disabled');
else
eAvatar.style.backgroundImage = `url(${avatarUrl})`;
const msgsList = $i('umi-messages');
let insertAfter = msgsList.lastElementChild;
if(insertAfter instanceof Element) {
while(insertAfter.dataset.created > eBase.dataset.created) {
if(!insertAfter.previousElementSibling || !insertAfter.previousElementSibling.dataset.channel)
break;
insertAfter = insertAfter.previousElementSibling;
}
eBase.classList.toggle('message--first', shouldDisplayAuthorInfo(eBase, insertAfter));
if(eBase.dataset.tiny !== insertAfter.dataset.tiny)
eBase.classList.add(isTiny ? 'message-tiny-fix' : 'message-big-fix'); eBase.classList.add(isTiny ? 'message-tiny-fix' : 'message-big-fix');
}
lastWasTiny = isTiny;
if(avatarUrl === undefined) insertAfter.after(eBase);
eAvatar.classList.add('message__avatar--disabled');
else
eAvatar.style.backgroundImage = `url(${avatarUrl})`;
const msgsList = $i('umi-messages'); if(eBase.nextElementSibling instanceof Element)
eBase.nextElementSibling.classList.toggle('message--first', shouldDisplayAuthorInfo(eBase.nextElementSibling, eBase));
msgsList.appendChild(eBase); } else {
lastMsgUser = sender.id; eBase.classList.add('message--first');
lastMsgChannel = msg.getChannel(); if(isTiny) eBase.classList.add('message-tiny-fix');
msgsList.append(eBase);
}
if(displayMessage) {
if(mami.settings.get('autoEmbedV1')) { if(mami.settings.get('autoEmbedV1')) {
const callEmbedOn = eBase.querySelectorAll('a[onclick^="Umi.Parser.SockChatBBcode.Embed"]'); const callEmbedOn = eBase.querySelectorAll('a[onclick^="Umi.Parser.SockChatBBcode.Embed"]');
for(const embedElem of callEmbedOn) for(const embedElem of callEmbedOn)
@ -322,7 +366,7 @@ Umi.UI.Messages = (function() {
} }
let isMentioned = false; let isMentioned = false;
const mentionTriggers = (mami.settings.get('notificationTriggers') || '').toLowerCase().split(' '); const mentionTriggers = mami.settings.get('notificationTriggers').toLowerCase().split(' ');
const currentUser = Umi.User.getCurrentUser(); const currentUser = Umi.User.getCurrentUser();
if(typeof currentUser === 'object' && typeof currentUser.name === 'string') if(typeof currentUser === 'object' && typeof currentUser.name === 'string')
mentionTriggers.push(currentUser.name.toLowerCase()); mentionTriggers.push(currentUser.name.toLowerCase());
@ -347,8 +391,7 @@ Umi.UI.Messages = (function() {
? ` ${msgTextLong}` ? ` ${msgTextLong}`
: ` ${sender.name}`; : ` ${sender.name}`;
// oops this won't work lol, we're filtering at the top if(focusChannelName !== '' && focusChannelName !== channelName)
if(currentChannel !== null && currentChannel.name !== channelName)
titleText += ` @ ${channelName}`; titleText += ` @ ${channelName}`;
title.strobe([ title.strobe([
@ -389,27 +432,72 @@ Umi.UI.Messages = (function() {
mami.sound.library.play(soundName, soundVolume, soundRate); mami.sound.library.play(soundName, soundVolume, soundRate);
} }
if(eBase instanceof HTMLElement) mami.globalEvents.dispatch('umi:ui:message_add', {
mami.globalEvents.dispatch('umi:ui:message_add', { element: eBase,
element: eBase, message: msg,
message: msg, });
});
msg.markSeen(); msg.markSeen();
}, },
Remove: function(msg) { SwitchChannel: channel => {
forceUserInfo = true; if(typeof channel === 'object' && channel !== null && 'name' in channel)
lastMsgUser = null; channel = channel.name;
lastMsgChannel = null; if(typeof channel !== 'string')
lastWasTiny = null; return;
$ri(`message-${msg.getId()}`);
focusChannelName = channel;
const root = $i('umi-messages');
for(const elem of root.children)
elem.classList.toggle('hidden', elem.dataset.channel !== undefined && elem.dataset.channel !== focusChannelName);
}, },
RemoveAll: function() { Clear: retain => {
forceUserInfo = true; if(typeof retain === 'string' && !isNaN(retain))
lastMsgUser = null; retain = parseInt(retain);
lastMsgChannel = null; if(typeof retain !== 'number')
lastWasTiny = null; return;
$i('umi-messages').innerHTML = '';
const root = $i('umi-messages');
// remove messages
if(root.childElementCount > retain)
for(let i = root.childElementCount - 1; i >= 0; --i) {
const elem = root.children[i];
if(!elem.dataset.channel || elem.classList.contains('hidden') || --retain > 0)
continue;
$r(elem);
}
// fix author display
for(const elem of root.children) {
elem.classList.toggle('message--first', shouldDisplayAuthorInfo(elem, elem.previousElementSibling));
lastAuthor = elem.dataset.author;
}
},
Remove: function(msgId) {
if(typeof msgId === 'object' && msgId !== null) {
if('getId' in msgId)
msgId = msgId.getId();
else if('id' in msgId)
msgId = msgId.id;
}
if(typeof msgId !== 'string')
msgId = msgId.toString();
if(msgId === '')
return;
const elem = $i(`message-${msgId}`);
if(!(elem instanceof Element))
return;
// todo: take channel into account
if(elem.nextElementSibling && elem.nextElementSibling.dataset.author === elem.dataset.author)
elem.nextElementSibling.classList.add('message--first');
$r(elem);
}, },
}; };
})(); })();

View file

@ -230,7 +230,6 @@ const SockChatS2CMessagePopulate = (ctx, timeStamp, userId, userName, userColour
const statusInfo = SockChatParseStatusInfo(userName); const statusInfo = SockChatParseStatusInfo(userName);
const info = { const info = {
msg: { msg: {
id: msgId,
time: new Date(parseInt(timeStamp) * 1000), time: new Date(parseInt(timeStamp) * 1000),
channel: ctx.channelName, channel: ctx.channelName,
sender: { sender: {
@ -249,9 +248,8 @@ const SockChatS2CMessagePopulate = (ctx, timeStamp, userId, userName, userColour
}, },
}; };
const msgIdFirst = info.msg.id.charCodeAt(0); if(!isNaN(msgId))
if(msgIdFirst < 48 || msgIdFirst > 57) info.msg.id = msgId;
info.msg.id = (Math.round(Number.MIN_SAFE_INTEGER * Math.random())).toString();
if(info.msg.isBot) { if(info.msg.isBot) {
const botParts = msgText.split("\f"); const botParts = msgText.split("\f");

View file

@ -234,7 +234,7 @@ const SockChatProtocol = function(dispatch, options) {
const name = info.name; const name = info.name;
if(info.isUserChannel) { if(info.isUserChannel) {
selfPseudoChannelName = name.substring(1); ctx.pseudoChannelName = name.substring(1);
} else { } else {
ctx.pseudoChannelName = undefined; ctx.pseudoChannelName = undefined;
if(ctx.channelName === name) if(ctx.channelName === name)