diff --git a/src/mami.js/main.js b/src/mami.js/main.js index f98045f..b978a81 100644 --- a/src/mami.js/main.js +++ b/src/mami.js/main.js @@ -88,11 +88,7 @@ window.Umi = { UI: {} }; settings.define('autoScroll').default(true).create(); settings.define('closeTabConfirm').default(false).create(); settings.define('showChannelList').default(false).create(); - settings.define('fancyInfo').default(true).create(); settings.define('autoCloseUserContext').default(true).create(); - settings.define('enableParser').default(true).create(); - settings.define('enableEmoticons').default(true).create(); - settings.define('autoParseUrls').default(true).create(); settings.define('preventOverflow').default(false).create(); settings.define('expandTextBox').default(false).create(); settings.define('eepromAutoInsert').default(true).create(); @@ -113,7 +109,6 @@ window.Umi = { UI: {} }; settings.define('windowsLiveMessenger').default(false).create(); settings.define('seinfeld').default(false).create(); settings.define('flashTitle').default(true).create(); - settings.define('showServerMsgInTitle').default(true).create(); settings.define('onlyConnectWhenVisible').default(true).create(); settings.define('playJokeSounds').default(true).create(); settings.define('weeaboo').default(false).create(); diff --git a/src/mami.js/messages.js b/src/mami.js/messages.js index 392c924..d03cee8 100644 --- a/src/mami.js/messages.js +++ b/src/mami.js/messages.js @@ -1,40 +1,74 @@ -#include channels.js #include users.js -#include ui/messages.jsx -// messages should probably also be an "event" like how it is on the server +const MamiMessageAuthorInfo = function(self = false, user = null, id = null, name = null, colour = null, rank = null, avatar = null) { + if(typeof self !== 'boolean') + throw 'self must be a boolean'; -Umi.Message = (() => { - const chatBot = new MamiUserInfo('-1', 'Server'); + if(user === null) { + id ??= ''; + name ??= ''; + colour ??= 'inherit'; + rank ??= 0; + avatar ??= new MamiUserAvatarInfo(id); + } else { + if(typeof user !== 'object') + throw 'user must be an object or null'; - return function(msgId, time, user, text, channel, highlight, botInfo, isAction, isLog) { - msgId = (msgId || '').toString(); - time = time === null ? new Date() : (typeof time === 'object' ? time : new Date(parseInt(time || 0) * 1000)); - user = user !== null && typeof user === 'object' ? user : chatBot; - text = (text || '').toString(); - channel = (channel || '').toString(); - highlight = !!highlight; - isAction = !!isAction; - isLog = !!isLog; - hasSeen = isLog; + id ??= user.id; + name ??= user.name; + colour ??= user.colour; + rank ??= user.perms.rank; + avatar ??= user.avatar; + } - return { - getId: () => msgId, - getIdInt: () => { - const num = parseInt(msgId); - return isNaN(num) ? (Math.round(Number.MIN_SAFE_INTEGER * Math.random())) : num; - }, - getTime: () => time, - getUser: () => MamiConvertUserInfoToUmi(user), - getUserV2: () => user, - getText: () => text, - getChannel: () => channel, - shouldHighlight: () => highlight, - getBotInfo: () => botInfo, - isAction: () => isAction, - isLog: () => isLog, - hasSeen: () => hasSeen, - markSeen: () => hasSeen = true, - }; + if(typeof id !== 'string') + throw 'id must be a string'; + if(typeof name !== 'string') + throw 'name must be a string'; + if(typeof colour !== 'string') + throw 'colour must be a string'; + if(typeof rank !== 'number') + throw 'rank must be a number'; + if(typeof avatar !== 'object') + throw 'avatar must be an object'; + + return { + get self() { return self; }, + + get user() { return user; }, + get hasUser() { return user !== null; }, + + get id() { return id; }, + get name() { return name; }, + get colour() { return colour; }, + get rank() { return rank; }, + get avatar() { return avatar; }, }; -})(); +}; + +const MamiMessageInfo = function(type, created = null, detail = null, id = '', author = null, channel = '', silent = false) { + if(typeof type !== 'string') + throw 'type must be a string'; + if(created === null) + created = new Date; + else if(!(created instanceof Date)) + throw 'created must be an instance of window.Date or null'; + if(typeof id !== 'string') + throw 'id must be a string'; + if(typeof author !== 'object') + throw 'author must be an object'; + if(typeof channel !== 'string') + throw 'channel must be a string'; + if(typeof silent !== 'boolean') + throw 'silent must be a boolean'; + + return { + get type() { return type; }, + get created() { return created; }, + get detail() { return detail; }, + get id() { return id; }, + get author() { return author; }, + get channel() { return channel; }, + get silent() { return silent; }, + }; +}; diff --git a/src/mami.js/parsing.js b/src/mami.js/parsing.js index 2736c1d..18b694a 100644 --- a/src/mami.js/parsing.js +++ b/src/mami.js/parsing.js @@ -378,8 +378,6 @@ Umi.Parsing = (function() { } } } - - return element; }, }; })(); diff --git a/src/mami.js/rng.js b/src/mami.js/rng.js index c67c700..972d4c4 100644 --- a/src/mami.js/rng.js +++ b/src/mami.js/rng.js @@ -3,7 +3,7 @@ const MamiRNG = function(seed) { const MBIG = 0x7FFFFFFF; const MSEED = 161803398; - if((typeof seed).toLowerCase() !== 'number') + if(isNaN(seed)) seed = Math.round(Date.now() / 1000); const seedArray = new Int32Array(56); diff --git a/src/mami.js/sockchat/handlers.js b/src/mami.js/sockchat/handlers.js index 8e8ed3a..2c15b69 100644 --- a/src/mami.js/sockchat/handlers.js +++ b/src/mami.js/sockchat/handlers.js @@ -142,14 +142,13 @@ const MamiSockChatHandlers = function(ctx, client, setLoadingOverlay, sockChatRe Umi.Users.Add(userInfo); if(ev.detail.msg !== undefined) - Umi.UI.Messages.Add(new Umi.Message( - ev.detail.msg.id, ev.detail.msg.time, undefined, '', ev.detail.msg.channel, false, - { - isError: false, - type: ev.detail.msg.botInfo.type, - args: ev.detail.msg.botInfo.args, - target: userInfo, - } + Umi.UI.Messages.Add(new MamiMessageInfo( + 'user:join', + ev.detail.msg.time, + null, + ev.detail.msg.id, + new MamiMessageAuthorInfo(ev.detail.user.self, userInfo), + ev.detail.msg.channel )); }; handlers['user:remove'] = ev => { @@ -160,19 +159,13 @@ const MamiSockChatHandlers = function(ctx, client, setLoadingOverlay, sockChatRe return; if(ev.detail.msg !== undefined) - Umi.UI.Messages.Add(new Umi.Message( - ev.detail.msg.id, + Umi.UI.Messages.Add(new MamiMessageInfo( + 'user:leave', ev.detail.msg.time, - undefined, - '', - ev.detail.msg.channel, - false, - { - isError: false, - type: ev.detail.msg.botInfo.type, - args: ev.detail.msg.botInfo.args, - target: userInfo, - }, + { reason: ev.detail.leave.type }, + ev.detail.msg.id, + new MamiMessageAuthorInfo(ev.detail.user.self, userInfo), + ev.detail.msg.channel )); Umi.Users.Remove(userInfo); @@ -183,7 +176,7 @@ const MamiSockChatHandlers = function(ctx, client, setLoadingOverlay, sockChatRe const userInfo = Umi.Users.Get(ev.detail.user.id); userInfo.name = ev.detail.user.name; userInfo.colour = ev.detail.user.colour; - userInfo.avatarChangeTime = Date.now(); + userInfo.avatar = new MamiUserAvatarInfo(ev.detail.user.id); userInfo.status = new MamiUserStatusInfo(ev.detail.user.status.isAway, ev.detail.user.status.message); userInfo.perms = new MamiUserPermsInfo( ev.detail.user.perms.rank, ev.detail.user.perms.kick, @@ -250,14 +243,12 @@ const MamiSockChatHandlers = function(ctx, client, setLoadingOverlay, sockChatRe Umi.Users.Add(userInfo); if(ev.detail.msg !== undefined) - Umi.UI.Messages.Add(new Umi.Message( - ev.detail.msg.id, null, undefined, '', ev.detail.msg.channel, false, - { - isError: false, - type: ev.detail.msg.botInfo.type, - args: [ userInfo.name ], - target: userInfo, - }, + Umi.UI.Messages.Add(new MamiMessageInfo( + 'channel:join', + null, null, + ev.detail.msg.id, + new MamiMessageAuthorInfo(ev.detail.user.self, userInfo), + ev.detail.msg.channel )); }; handlers['chan:leave'] = ev => { @@ -271,14 +262,12 @@ const MamiSockChatHandlers = function(ctx, client, setLoadingOverlay, sockChatRe return; if(ev.detail.msg !== undefined) - Umi.UI.Messages.Add(new Umi.Message( - ev.detail.msg.id, null, undefined, '', ev.detail.msg.channel, false, - { - isError: false, - type: ev.detail.msg.botInfo.type, - args: [ userInfo.name ], - target: userInfo, - }, + Umi.UI.Messages.Add(new MamiMessageInfo( + 'channel:leave', + null, null, + ev.detail.msg.id, + new MamiMessageAuthorInfo(ev.detail.user.self, userInfo), + ev.detail.msg.channel )); Umi.Users.Remove(userInfo); @@ -289,8 +278,9 @@ const MamiSockChatHandlers = function(ctx, client, setLoadingOverlay, sockChatRe if(dumpEvents) console.log('msg:add', ev.detail); const senderInfo = ev.detail.msg.sender; + const rawUserInfo = Umi.Users.Get(senderInfo.id); const userInfo = senderInfo.name === undefined - ? Umi.Users.Get(senderInfo.id) + ? rawUserInfo : new MamiUserInfo( senderInfo.id, senderInfo.name, @@ -319,15 +309,71 @@ const MamiSockChatHandlers = function(ctx, client, setLoadingOverlay, sockChatRe Umi.UI.Menus.Attention('channels'); } - Umi.UI.Messages.Add(new Umi.Message( - ev.detail.msg.id, + let type, detail, author; + if(ev.detail.msg.isBot) { + const botInfo = ev.detail.msg.botInfo; + let authorMethod; + + if(botInfo.type === 'join') { + type = 'user:join'; + authorMethod = 'nameArg'; + } else if(['leave', 'kick', 'flood', 'timeout'].includes(botInfo.type)) { + type = 'user:leave'; + authorMethod = 'nameArg'; + detail = { reason: botInfo.type }; + } else if(botInfo.type === 'jchan') { + type = 'channel:join'; + authorMethod = 'nameArg'; + } else if(botInfo.type === 'lchan') { + type = 'channel:leave'; + authorMethod = 'nameArg'; + } + + if(authorMethod === 'nameArg') { + author = botInfo.args[0]; + authorMethod = 'name'; + } + + if(authorMethod === 'name') { + // the concat below should be done by the server, remove when fixed + const botUserInfo = Umi.Users.FindExact(author) ?? Umi.Users.FindExact(`~${author}`); + author = new MamiMessageAuthorInfo( + Umi.User.isCurrentUser(botUserInfo), + botUserInfo, + null, + author + ); + } + + if(typeof type !== 'string') { + type = `legacy:${botInfo.type}`; + detail = { + error: botInfo.isError, + args: botInfo.args, + }; + } + } else { + author = new MamiMessageAuthorInfo( + senderInfo.self, + rawUserInfo, + senderInfo.id ?? rawUserInfo.id, + senderInfo.name ?? rawUserInfo.name, + senderInfo.colour ?? rawUserInfo.colour, + senderInfo.perms?.rank ?? rawUserInfo.perms?.rank ?? 0, + new MamiUserAvatarInfo(senderInfo.id ?? rawUserInfo.id ?? '0'), + ); + + type = `message:${ev.detail.msg.flags.isAction ? 'action' : 'text'}`; + detail = { body: ev.detail.msg.text }; + } + + Umi.UI.Messages.Add(new MamiMessageInfo( + type, ev.detail.msg.time, - userInfo, - ev.detail.msg.text, - channelName, - false, - ev.detail.msg.botInfo, - ev.detail.msg.flags.isAction, + detail, + ev.detail.msg.id, + author, + ev.detail.msg.channel, ev.detail.msg.silent, )); }; diff --git a/src/mami.js/ui/emotes.js b/src/mami.js/ui/emotes.js index d095df1..1621fde 100644 --- a/src/mami.js/ui/emotes.js +++ b/src/mami.js/ui/emotes.js @@ -33,12 +33,9 @@ Umi.UI.Emoticons = (function() { }); }, Parse: function(element, message) { - if(!mami.settings.get('enableEmoticons')) - return element; - let inner = element.innerHTML; - MamiEmotes.forEach(message.getUserV2().perms.rank, function(emote) { + MamiEmotes.forEach(message?.author?.perms?.rank ?? 0, function(emote) { const image = $e({ tag: 'img', attrs: { @@ -56,8 +53,6 @@ Umi.UI.Emoticons = (function() { }); element.innerHTML = inner; - - return element; }, Insert: function(sender) { const emoticon = sender.getAttribute('data-umi-emoticon'); diff --git a/src/mami.js/ui/messages.jsx b/src/mami.js/ui/messages.jsx index fe3e35e..f292b81 100644 --- a/src/mami.js/ui/messages.jsx +++ b/src/mami.js/ui/messages.jsx @@ -122,103 +122,44 @@ Umi.UI.Messages = (function() { return { Add: function(msg) { - mami.globalEvents.dispatch('umi:message_add', msg); + const elementId = `message-${msg.id}`; - const msgId = msg.getId(); - const elementId = `message-${msgId}`; - - if(msgId !== '' && $i(elementId)) + if(msg.id !== '' && $i(elementId)) return; - const channelName = msg.getChannel(); - const sender = msg.getUserV2(); - const isBot = sender.id === '-1'; - const isOutgoing = Umi.User.isCurrentUser(sender); - const hasSeen = msg.hasSeen(); - const displayMessage = focusChannelName === '' || channelName === '' || channelName === focusChannelName; - const notifyPM = !displayMessage && !isOutgoing && !hasSeen && channelName.startsWith('@'); - let isTiny = false; let skipTextParsing = false; - let msgText = msg.getText(); - let msgTextLong = msgText; - - let eBase; - let eAvatar; - let eText; - let eMeta; - let eUser; - - let avatarUser = sender; - let avatarSize = '80'; + let msgText = ''; + let msgTextLong = ''; + let msgAuthor = msg.author; let soundIsLegacy = true; - let soundName = isOutgoing ? 'outgoing' : 'incoming'; + let soundName; let soundVolume; let soundRate; - const userClass = `message--user-${sender.id}`; + const eText =
; + const eAvatar =
; + const eUser =
; + const eMeta =
{eUser}
; + const eTime =
+ {msg.created.getHours().toString().padStart(2, '0')} + :{msg.created.getMinutes().toString().padStart(2, '0')} + :{msg.created.getSeconds().toString().padStart(2, '0')} +
; + const eContainer =
{eMeta}
; + const eBase =
+ {eAvatar} + {eContainer} +
; - const classes = ['message', userClass]; - const styles = {}; + if(msg.type.startsWith('message:')) { + msgText = msgTextLong = msg.detail.body; + soundName = msg.author?.self === true ? 'outgoing' : 'incoming'; - const avatarClasses = ['message__avatar']; + if(msg.type === 'message:action') + isTiny = true; - if(msg.isAction()) { - isTiny = true; - classes.push('message-action'); - } - - if(!displayMessage) - classes.push('hidden'); - - if(sender.id === "136") - styles.transform = 'scaleY(' + (0.76 + (0.01 * Math.max(0, Math.ceil(Date.now() / (7 * 24 * 60 * 60000)) - 2813))).toString() + ')'; - - const msgCreated = msg.getTime(); - const msgDateTime = msgCreated.getHours().toString().padStart(2, '0') - + ':' + msgCreated.getMinutes().toString().padStart(2, '0') - + ':' + msgCreated.getSeconds().toString().padStart(2, '0'); - - if(isBot) { - const botInfo = msg.getBotInfo(); - soundName = botInfo.isError ? 'error' : 'server'; - - if(botMsgs.hasOwnProperty(botInfo.type)) { - const bmInfo = botMsgs[botInfo.type]; - - let bArgs = botInfo.args; - if(typeof bmInfo.filter === 'function') - bArgs = bmInfo.filter(bArgs); - - if(typeof bmInfo.sound === 'string') - soundName = bmInfo.sound; - - let actionSuccess = false; - if(typeof bmInfo.action === 'string' && mami.settings.get('fancyInfo')) { - const target = botInfo.target ?? Umi.Users.FindExact(bArgs[0]) ?? Umi.Users.FindExact('~' + bArgs[0]); // shitty fix for server sending invalid data - - if(target) { - actionSuccess = true; - isTiny = true; - skipTextParsing = true; - avatarUser = target; - - $ari(classes, userClass); - - msgText = formatTemplate(bmInfo.action, bArgs); - if(typeof bmInfo.avatar === 'string') - avatarClasses.push(`avatar-filter-${bmInfo.avatar}`); - } - } - - msgTextLong = formatTemplate(bmInfo.text, bArgs); - - if(!actionSuccess) - msgText = msgTextLong; - } else - msgText = msgTextLong = `!!! Received unsupported message type: ${botInfo.type} !!!`; - } else { if(mami.settings.get('playJokeSounds')) try { const trigger = mami.textTriggers.getTrigger(msgText); @@ -229,103 +170,135 @@ Umi.UI.Messages = (function() { soundRate = trigger.getRate(); } } catch(ex) {} + } else { + let bIsError = false; + let bType; + let bArgs; + + if(msg.type === 'user:join') { + bType = 'join'; + bArgs = [msgAuthor.name]; + } else if(msg.type === 'user:leave') { + bType = msg.detail.reason; + bArgs = [msgAuthor.name]; + } else if(msg.type === 'channel:join') { + bType = 'jchan'; + bArgs = [msgAuthor.name]; + } else if(msg.type === 'channel:leave') { + bType = 'lchan'; + bArgs = [msgAuthor.name]; + } else if(msg.type.startsWith('legacy:')) { + bType = msg.type.substring(7); + bIsError = msg.detail.error; + bArgs = msg.detail.args; + msgAuthor = Umi.Users.FindExact(bArgs[0]) ?? Umi.Users.FindExact('~' + bArgs[0]); + } + + soundName = bIsError ? 'error' : 'server'; + + if(botMsgs.hasOwnProperty(bType)) { + const bmInfo = botMsgs[bType]; + + if(typeof bmInfo.filter === 'function') + bArgs = bmInfo.filter(bArgs); + + if(typeof bmInfo.sound === 'string') + soundName = bmInfo.sound; + + let actionSuccess = false; + if(typeof bmInfo.action === 'string') + if(msgAuthor) { + actionSuccess = true; + isTiny = true; + skipTextParsing = true; + + msgText = formatTemplate(bmInfo.action, bArgs); + if(typeof bmInfo.avatar === 'string') + eAvatar.classList.add(`avatar-filter-${bmInfo.avatar}`); + } + + msgTextLong = formatTemplate(bmInfo.text, bArgs); + + if(!actionSuccess) + msgText = msgTextLong; + } else + msgText = msgTextLong = `!!! Received unsupported message type: ${msg.type} !!!`; } - let avatarUrl = futami.get('avatar'); - if(typeof avatarUrl !== 'string' || avatarUrl.length < 1) - avatarUrl = undefined; - else - avatarUrl = avatarUrl.replace('{user:id}', avatarUser.id) - .replace('{resolution}', avatarSize) - .replace('{user:avatar_change}', avatarUser.avatarChangeTime); - - eAvatar =
; - eUser =
{avatarUser.name}
; + if(msgAuthor !== null) { + eUser.style.color = msgAuthor.colour; + eUser.textContent = msgAuthor.name; + } if(isTiny) { - classes.push('message-tiny'); - - avatarSize = '40'; + eText.classList.add('message-tiny-text'); + eBase.classList.add('message-tiny'); if(msgText.indexOf("'") !== 0 || (msgText.match(/\'/g).length % 2) === 0) msgText = "\xA0" + msgText; - eBase =
- {eAvatar} -
- {eMeta =
- {eUser} - {eText =
} -
{msgDateTime}
-
} -
-
; + eMeta.append(eText, eTime); } else { - eBase =
- {eAvatar} -
- {eMeta =
- {eUser} -
{msgDateTime}
-
} - {eText =
} -
-
; + eText.classList.add('message__text'); + eMeta.append(eTime); + eContainer.append(eText); + + if(msgAuthor?.id === '136') + eBase.style.transform = 'scaleY(' + (0.76 + (0.01 * Math.max(0, Math.ceil(Date.now() / (7 * 24 * 60 * 60000)) - 2813))).toString() + ')'; } - if(msgId !== '') { + eBase.classList.add(`message--user-${msgAuthor?.id ?? '-1'}`); + + if(focusChannelName !== '' && msg.channel !== '' && msg.channel !== focusChannelName) + eBase.classList.add('hidden'); + + if(msg.id !== '') { eBase.id = elementId; - eBase.dataset.id = msgId; + eBase.dataset.id = msg.id; } - if(!isBot) - eBase.dataset.author = sender.id; - if(channelName !== '') - eBase.dataset.channel = channelName; + if(msgAuthor) + eBase.dataset.author = msgAuthor.id; + if(msg.channel !== '') + eBase.dataset.channel = msg.channel; if(isTiny) eBase.dataset.tiny = '1'; - eBase.dataset.created = msgCreated.toISOString(); + eBase.dataset.created = msg.created.toISOString(); eBase.dataset.body = msgText; eText.innerText = msgText; if(!skipTextParsing) { - eText = Umi.UI.Emoticons.Parse(eText, msg); - eText = Umi.Parsing.Parse(eText, msg); + Umi.UI.Emoticons.Parse(eText, msg); + Umi.Parsing.Parse(eText, msg); const urls = []; + const textSplit = eText.innerText.split(' '); + for(const textPart of textSplit) { + const uri = Umi.URI.Parse(textPart); - if(mami.settings.get('autoParseUrls')) { - 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); - if(uri !== null && uri.Slashes !== null) { - urls.push(textPart); - - const anchorElem = {textPart}; - eText.innerHTML = eText.innerHTML.replace(textPart.replace(/&/g, '&'), anchorElem.outerHTML); - } + const anchorElem = {textPart}; + eText.innerHTML = eText.innerHTML.replace(textPart.replace(/&/g, '&'), anchorElem.outerHTML); } } if(mami.settings.get('weeaboo')) { - eText.appendChild($t(Weeaboo.getTextSuffix(sender))); + eUser.appendChild($t(Weeaboo.getNameSuffix(msgAuthor))); + eText.appendChild($t(Weeaboo.getTextSuffix(msgAuthor))); const kaomoji = Weeaboo.getRandomKaomoji(true, msg); - if(kaomoji) { - eText.appendChild($t(' ')); - eText.appendChild($t(kaomoji)); - } + if(kaomoji) + eText.append(` ${kaomoji}`); } - - if(mami.settings.get('weeaboo')) - eUser.appendChild($t(Weeaboo.getNameSuffix(sender))); } - if(avatarUrl === undefined) - eAvatar.classList.add('message__avatar--disabled'); + const avatarUrl = msgAuthor?.avatar?.[isTiny ? 'x40' : 'x80'] ?? ''; + if(avatarUrl.length > 0) + eAvatar.style.backgroundImage = `url('${avatarUrl}')`; else - eAvatar.style.backgroundImage = `url(${avatarUrl})`; + eAvatar.classList.add('message__avatar--disabled'); const msgsList = $i('umi-messages'); @@ -353,7 +326,7 @@ Umi.UI.Messages = (function() { msgsList.append(eBase); } - if(displayMessage) { + if(!eBase.classList.contains('hidden')) { if(mami.settings.get('autoEmbedV1')) { const callEmbedOn = eBase.querySelectorAll('a[onclick^="Umi.Parser.SockChatBBcode.Embed"]'); for(const embedElem of callEmbedOn) @@ -387,12 +360,9 @@ Umi.UI.Messages = (function() { if(document.hidden) { if(mami.settings.get('flashTitle')) { - let titleText = isBot && mami.settings.get('showServerMsgInTitle') - ? ` ${msgTextLong}` - : ` ${sender.name}`; - - if(focusChannelName !== '' && focusChannelName !== channelName) - titleText += ` @ ${channelName}`; + let titleText = msgAuthor?.name ?? msgTextLong; + if(focusChannelName !== '' && focusChannelName !== msg.channel) + titleText += ` @ ${msg.channel}`; title.strobe([ `[ @] ${titleText}`, @@ -400,8 +370,8 @@ Umi.UI.Messages = (function() { ]); } - if(!hasSeen) { - Umi.UI.Channels.Unread(channelName); + if(!msg.silent) { + Umi.UI.Channels.Unread(msg.channel); if(mami.settings.get('enableNotifications') && isMentioned) { const options = {}; @@ -410,10 +380,10 @@ Umi.UI.Messages = (function() { if(mami.settings.get('notificationShowMessage')) options.body += "\n" + msgTextLong; - if(avatarUrl !== undefined) + if(avatarUrl.length > 0) options.icon = avatarUrl; - const notif = new Notification(`${sender.name} mentioned you!`, options); + const notif = new Notification(`${msgAuthor.name} mentioned you!`, options); notif.addEventListener('click', () => { window.focus(); }); @@ -425,19 +395,14 @@ Umi.UI.Messages = (function() { } } - if(soundName !== undefined && !hasSeen) { + if(!msg.silent && soundName !== undefined) { if(soundIsLegacy) soundName = Umi.Sound.Convert(soundName); mami.sound.library.play(soundName, soundVolume, soundRate); } - mami.globalEvents.dispatch('umi:ui:message_add', { - element: eBase, - message: msg, - }); - - msg.markSeen(); + mami.globalEvents.dispatch('umi:ui:message_add', { element: eBase }); }, SwitchChannel: channel => { if(typeof channel === 'object' && channel !== null && 'name' in channel) diff --git a/src/mami.js/ui/settings.jsx b/src/mami.js/ui/settings.jsx index 0402291..4230d31 100644 --- a/src/mami.js/ui/settings.jsx +++ b/src/mami.js/ui/settings.jsx @@ -43,11 +43,6 @@ Umi.UI.Settings = (function() { title: 'Show channel list', type: 'checkbox', }, - { - name: 'fancyInfo', - title: 'Fancy server messages', - type: 'checkbox', - }, { name: 'autoCloseUserContext', title: 'Auto-close user menus', @@ -59,21 +54,6 @@ Umi.UI.Settings = (function() { name: 'text', title: 'Text', items: [ - { - name: 'enableParser', - title: 'Parse markup', - type: 'checkbox', - }, - { - name: 'enableEmoticons', - title: 'Parse emoticons', - type: 'checkbox', - }, - { - name: 'autoParseUrls', - title: 'Auto detect links', - type: 'checkbox', - }, { name: 'preventOverflow', title: 'Prevent overflow', @@ -105,11 +85,6 @@ Umi.UI.Settings = (function() { title: 'Strobe title on new message', type: 'checkbox', }, - { - name: 'showServerMsgInTitle', - title: 'Show server message in title', - type: 'checkbox', - }, { name: 'enableNotifications', title: 'Show notifications', diff --git a/src/mami.js/ui/users.js b/src/mami.js/ui/users.js index 22c56ef..75da577 100644 --- a/src/mami.js/ui/users.js +++ b/src/mami.js/ui/users.js @@ -165,9 +165,9 @@ Umi.UI.Users = (function() { uName.appendChild($t(user.name)); } - const avatarUrl = futami.get('avatar'); - if(avatarUrl !== null && avatarUrl.length > 1) { - uAvatar.style.backgroundImage = 'url({0})'.replace('{0}', avatarUrl.replace('{user:id}', user.id).replace('{resolution}', '80').replace('{user:avatar_change}', user.avatarChangeTime)); + const avatarUrl = user.avatar.x60; + if(avatarUrl !== '') { + uAvatar.style.backgroundImage = `url('${avatarUrl}')`; uDetails.appendChild(uAvatar); } @@ -184,9 +184,9 @@ Umi.UI.Users = (function() { uBase.style.backgroundColor = user.colour === 'inherit' ? '#fff' : user.colour; uName.textContent = ''; - const avatarUrl = futami.get('avatar'); - if(avatarUrl !== null && avatarUrl.length > 1) - uAvatar.style.backgroundImage = 'url({0})'.replace('{0}', avatarUrl.replace('{user:id}', user.id).replace('{resolution}', '80').replace('{user:avatar_change}', user.avatarChangeTime)); + const avatarUrl = user.avatar.x60; + if(uAvatar instanceof Element && avatarUrl !== '') + uAvatar.style.backgroundImage = `url('${avatarUrl}')`; if(user.status.isAway) uName.appendChild($e({ attrs: { 'class': 'user-sidebar-afk' }, child: user.status.message })); diff --git a/src/mami.js/users.js b/src/mami.js/users.js index b743f41..2f7b7fc 100644 --- a/src/mami.js/users.js +++ b/src/mami.js/users.js @@ -28,7 +28,27 @@ const MamiUserStatusInfo = function(isAway = false, message = '') { }; }; -const MamiUserInfo = function(id, name, colour = 'inherit', status = null, perms = null) { +const MamiUserAvatarInfo = function(userId) { + userId ??= ''; + + const template = futami.get('avatar') ?? ''; + const changeTime = Date.now(); + + const getAvatar = res => { + return template.replace('{user:id}', userId) + .replace('{resolution}', res) + .replace('{user:avatar_change}', changeTime); + }; + + return { + get original() { return getAvatar('0'); }, + get x80() { return getAvatar('80'); }, + get x60() { return getAvatar('60'); }, + get x40() { return getAvatar('40'); }, + }; +}; + +const MamiUserInfo = function(id, name, colour = 'inherit', status = null, perms = null, avatar = null) { if(typeof id !== 'string') throw 'id must be a string'; if(typeof name !== 'string') @@ -43,8 +63,10 @@ const MamiUserInfo = function(id, name, colour = 'inherit', status = null, perms perms = new MamiUserPermsInfo; else if(typeof perms !== 'object') throw 'perms must be an object'; - - let avatarChangeTime = Date.now(); + if(avatar === null) + avatar = new MamiUserAvatarInfo(id); + else if(typeof avatar !== 'object') + throw 'avatar must be an object'; return { get id() { return id; }, @@ -77,48 +99,15 @@ const MamiUserInfo = function(id, name, colour = 'inherit', status = null, perms perms = value; }, - get avatarChangeTime() { return avatarChangeTime; }, - set avatarChangeTime(value) { - if(typeof value !== 'number') - throw 'value must be a number'; - avatarChangeTime = value; + get avatar() { return avatar; }, + set avatar(value) { + if(typeof value !== 'object' || value === null) + throw 'value must be an object'; + avatar = value; }, }; }; -const MamiConvertUserInfoToUmi = info => { - return { - getId: () => info.id, - getIdInt: () => parseInt(info.id), - - getName: () => { - let name = info.name; - if(info.status.isAway) - name = `<${info.status.message.substring(0, 5).toUpperCase()}>_${name}`; - - return name; - }, - setName: () => {}, - - getColour: () => info.colour, - setColour: () => {}, - - setPermissions: () => {}, - - getRank: () => info.perms.rank, - canBan: () => info.perms.canKick, - canSilence: () => false, - canCreateChannel: () => info.perms.canCreateChannels, - canSetNickName: () => info.perms.canSetNick, - getAvatarTime: () => info.avatarChangeTime, - bumpAvatarTime: () => { - info.avatarChangeTime = Date.now(); - }, - - isBot: () => info.id === '-1', - }; -}; - Umi.User = (() => { let userInfo; diff --git a/src/mami.js/weeb.js b/src/mami.js/weeb.js index 98477f0..d27b6c9 100644 --- a/src/mami.js/weeb.js +++ b/src/mami.js/weeb.js @@ -27,7 +27,7 @@ const Weeaboo = (function() { if((typeof allowEmpty).toLowerCase() !== 'boolean') allowEmpty = true; - const rng = new MamiRNG(message.getIdInt() || undefined); + const rng = new MamiRNG(parseInt(message.id)); if(allowEmpty && rng.next(0, 10000) <= 9000) return ''; @@ -39,9 +39,9 @@ const Weeaboo = (function() { if(typeof user !== 'object' || user === null) return ''; - if(user.perms.rank >= 10) + if(user.rank >= 10) return '-sama'; - if(user.perms.rank >= 5) + if(user.rank >= 5) return '-sensei'; if(user.colour.toLowerCase() === '#f02d7d') return '-san'; diff --git a/src/proto.js/sockchat/authed.js b/src/proto.js/sockchat/authed.js index e784741..7b3af54 100644 --- a/src/proto.js/sockchat/authed.js +++ b/src/proto.js/sockchat/authed.js @@ -123,10 +123,6 @@ const SockChatS2CUserAdd = (ctx, timeStamp, userId, userName, userColour, userPe id: msgId, time: new Date(parseInt(timeStamp) * 1000), channel: ctx.channelName, - botInfo: { - type: 'join', - args: [statusInfo.name], - }, }, user: { id: userId, @@ -163,10 +159,6 @@ const SockChatS2CUserRemove = (ctx, userId, userName, reason, timeStamp, msgId) id: msgId, time: new Date(parseInt(timeStamp) * 1000), channel: ctx.channelName, - botInfo: { - type: reason, - args: [statusInfo.name], - }, }, user: { id: userId, @@ -192,10 +184,6 @@ const SockChatS2CUserChannelJoin = (ctx, userId, userName, userColour, userPerms msg: { id: msgId, channel: ctx.channelName, - botInfo: { - type: 'jchan', - args: [statusInfo.name], - }, }, }); }; @@ -209,10 +197,6 @@ const SockChatS2CUserChannelLeave = (ctx, userId, msgId) => { msg: { id: msgId, channel: ctx.channelName, - botInfo: { - type: 'lchan', - args: [userId], - }, }, }); }; @@ -238,7 +222,7 @@ const SockChatS2CMessagePopulate = (ctx, timeStamp, userId, userName, userColour name: statusInfo.name, status: statusInfo.status, colour: SockChatParseUserColour(userColour), - perms: SockChatParseUserColour(userPerms), + perms: SockChatParseUserPerms(userPerms), }, isBot: userId === '-1', silent: msgNotify === '0',