diff --git a/src/mami.js/eventtarget.js b/src/mami.js/eventtarget.js new file mode 100644 index 0000000..b90bac3 --- /dev/null +++ b/src/mami.js/eventtarget.js @@ -0,0 +1,22 @@ +const MamiEventTarget = function(prefix) { + prefix = typeof prefix === 'string' ? `${prefix}:` : ''; + + const eventTarget = new EventTarget; + const createEvent = (name, detail) => new CustomEvent(prefix + name, (typeof detail === 'object' && detail !== null && 'detail' in detail ? detail : { detail: detail })); + + return { + create: createEvent, + + addEventListener: eventTarget.addEventListener.bind(eventTarget), + removeEventListener: eventTarget.removeEventListener.bind(eventTarget), + dispatchEvent: eventTarget.dispatchEvent.bind(eventTarget), + + watch: (name, ...args) => { + eventTarget.addEventListener(prefix + name, ...args); + }, + unwatch: (name, ...args) => { + eventTarget.removeEventListener(prefix + name, ...args); + }, + dispatch: (...args) => eventTarget.dispatchEvent(createEvent(...args)), + }; +}; diff --git a/src/mami.js/main.js b/src/mami.js/main.js index bc0e5b5..5457ca2 100644 --- a/src/mami.js/main.js +++ b/src/mami.js/main.js @@ -150,8 +150,9 @@ window.Umi = { UI: {}, Protocol: { SockChat: { Protocol: {} } } }; settings.virtualise('soundEnable'); } - settings.watch('soundEnable', (v, n, i) => { - if(v) { + settings.watch('soundEnable', ev => { + console.log(ev); + if(ev.detail.value) { if(!soundCtx.ready) soundCtx.reset(); @@ -161,22 +162,22 @@ window.Umi = { UI: {}, Protocol: { SockChat: { Protocol: {} } } }; soundCtx.library.play(soundCtx.pack.getEventSound('server')); } - soundCtx.muted = !v; + soundCtx.muted = !ev.detail.value; }); - settings.watch('soundPack', (v, n, i) => { + settings.watch('soundPack', ev => { const packs = soundCtx.packs; - if(!packs.has(v)) { - settings.delete(n); + if(!packs.has(ev.detail.value)) { + settings.delete(ev.detail.name); return; } - soundCtx.pack = packs.get(v); - if(!i) soundCtx.library.play(soundCtx.pack.getEventSound('server')); + soundCtx.pack = packs.get(ev.detail.value); + if(!ev.detail.initial) soundCtx.library.play(soundCtx.pack.getEventSound('server')); }); - settings.watch('soundVolume', v => { - soundCtx.volume = v / 100; + settings.watch('soundVolume', ev => { + soundCtx.volume = ev.detail.value / 100; }) @@ -238,28 +239,28 @@ window.Umi = { UI: {}, Protocol: { SockChat: { Protocol: {} } } }; Umi.UI.View.AccentReload(); Umi.UI.Hooks.AddHooks(); - settings.watch('style', (v, n, i) => { if(!i) Umi.UI.View.AccentReload(); }); - settings.watch('compactView', (v, n, i) => { if(!i) Umi.UI.View.AccentReload(); }); - settings.watch('preventOverflow', v => document.body.classList.toggle('prevent-overflow', v)); - settings.watch('tmpDisableOldThemeSys', (v, n, i) => { if(!i) Umi.UI.View.AccentReload(); }); + settings.watch('style', ev => { if(!ev.detail.initial) Umi.UI.View.AccentReload(); }); + settings.watch('compactView', ev => { if(!ev.detail.initial) Umi.UI.View.AccentReload(); }); + settings.watch('preventOverflow', ev => document.body.classList.toggle('prevent-overflow', ev.detail.value)); + settings.watch('tmpDisableOldThemeSys', ev => { if(!ev.detail.initial) Umi.UI.View.AccentReload(); }); - settings.watch('minecraft', (v, n, i) => { - if(i && v === 'no') + settings.watch('minecraft', ev => { + if(ev.detail.initial && ev.detail.value === 'no') return; soundCtx.library.play((() => { if(i) return 'minecraft:nether:enter'; - if(v === 'yes') + if(ev.detail.value === 'yes') return 'minecraft:door:open'; - if(v === 'old') + if(ev.detail.value === 'old') return 'minecraft:door:open-old'; return soundCtx.pack.getEventSound('join'); })()); }); - settings.watch('enableNotifications', v => { - if(!v || !('Notification' in window) + settings.watch('enableNotifications', ev => { + if(!ev.detail.value || !('Notification' in window) || (Notification.permission === 'granted' && Notification.permission !== 'denied')) return; @@ -270,20 +271,20 @@ window.Umi = { UI: {}, Protocol: { SockChat: { Protocol: {} } } }; }); }); - settings.watch('playJokeSounds', v => { - if(!v) return; + settings.watch('playJokeSounds', ev => { + if(!ev.detail.value) return; if(!textTriggers.hasTriggers()) futami.getJson('texttriggers').then(trigInfos => textTriggers.addTriggers(trigInfos)); }); - settings.watch('weeaboo', v => { - if(v) Weeaboo.init(); + settings.watch('weeaboo', ev => { + if(ev.detail.value) Weeaboo.init(); }); - settings.watch('osuKeysV2', (v, n, i) => { + settings.watch('osuKeysV2', ev => { // migrate old value - if(i) { + if(ev.detail.initial) { if(settings.has('osuKeys')) { settings.set('osuKeysV2', settings.get('osuKeys') ? 'yes' : 'no'); settings.delete('osuKeys'); @@ -291,8 +292,8 @@ window.Umi = { UI: {}, Protocol: { SockChat: { Protocol: {} } } }; } } - OsuKeys.setEnable(v !== 'no'); - OsuKeys.setRandomRate(v === 'rng'); + OsuKeys.setEnable(ev.detail.value !== 'no'); + OsuKeys.setRandomRate(ev.detail.value === 'rng'); }); @@ -356,8 +357,8 @@ window.Umi = { UI: {}, Protocol: { SockChat: { Protocol: {} } } }; settings.toggle('autoScroll'); } }, 'Autoscroll'); - settings.watch('autoScroll', function(value) { - Umi.UI.Toggles.Get('scroll').classList[value ? 'remove' : 'add']('sidebar__selector-mode--scroll-off'); + settings.watch('autoScroll', ev => { + Umi.UI.Toggles.Get('scroll').classList.toggle('sidebar__selector-mode--scroll-off', !ev.detail.value); }); if(window.innerWidth < 768) @@ -368,8 +369,8 @@ window.Umi = { UI: {}, Protocol: { SockChat: { Protocol: {} } } }; settings.toggle('soundEnable'); } }, 'Sounds'); - settings.watch('soundEnable', function(value) { - Umi.UI.Toggles.Get('audio').classList[value ? 'remove' : 'add']('sidebar__selector-mode--audio-off'); + settings.watch('soundEnable', ev => { + Umi.UI.Toggles.Get('audio').classList.toggle('sidebar__selector-mode--audio-off', !ev.detail.value); }); Umi.UI.Toggles.Add('unembed', { @@ -587,8 +588,8 @@ window.Umi = { UI: {}, Protocol: { SockChat: { Protocol: {} } } }; MamiCompat('Umi.Server', { get: () => sockChat, configurable: true }); let dumpEvents = false; - settings.watch('dumpEvents', value => dumpEvents = value); - settings.watch('dumpPackets', value => sockChat.setDumpPackets(value)); + settings.watch('dumpEvents', ev => dumpEvents = ev.detail.value); + settings.watch('dumpPackets', ev => sockChat.setDumpPackets(ev.detail.value)); Umi.UI.Hooks.SetCallbacks(sockChat.sendMessage, sockChat.switchChannel); @@ -596,60 +597,60 @@ window.Umi = { UI: {}, Protocol: { SockChat: { Protocol: {} } } }; MamiCompat('Umi.Protocol.SockChat.Protocol.Instance.SendMessage', { value: text => sockChat.sendMessage(text), configurable: true }); MamiCompat('Umi.Protocol.SockLegacy.Protocol.Instance.SendMessage', { value: text => sockChat.sendMessage(text), configurable: true }); - sockChat.watch('conn:init', init => { - if(dumpEvents) console.log('conn:init', init); + sockChat.watch('conn:init', ev => { + if(dumpEvents) console.log('conn:init', ev); let message = 'Connecting to server...'; - if(init.attempt > 2) + if(ev.detail.attempt > 2) message += ` (Attempt ${connectAttempts})`; getLoadingOverlay('spinner', 'Loading...', message); }); - sockChat.watch('conn:ready', ready => { - if(dumpEvents) console.log('conn:ready', ready); + sockChat.watch('conn:ready', ev => { + if(dumpEvents) console.log('conn:ready', ev); getLoadingOverlay('spinner', 'Loading...', 'Authenticating...'); const authInfo = MamiMisuzuAuth.getInfo(); sockChat.sendAuth(authInfo.method, authInfo.token); }); - sockChat.watch('conn:lost', lost => { - if(dumpEvents) console.log('conn:lost', lost); + sockChat.watch('conn:lost', ev => { + if(dumpEvents) console.log('conn:lost', ev); getLoadingOverlay( 'unlink', 'Disconnected!', - wsCloseReasons[`_${lost.code}`] ?? `Something caused an unexpected connection loss. (${lost.code})` + wsCloseReasons[`_${ev.detail.code}`] ?? `Something caused an unexpected connection loss. (${ev.detail.code})` ); }); - sockChat.watch('conn:error', error => { - console.error('conn:error', error); + sockChat.watch('conn:error', ev => { + console.error('conn:error', ev); }); - sockChat.watch('ping:send', send => { - if(dumpEvents) console.log('ping:send', send); + sockChat.watch('ping:send', ev => { + if(dumpEvents) console.log('ping:send', ev); }); - sockChat.watch('ping:long', long => { - if(dumpEvents) console.log('ping:long', long); + sockChat.watch('ping:long', ev => { + if(dumpEvents) console.log('ping:long', ev); pingToggle.title = '+2000ms'; pingIndicator.setStrength(0); }); - sockChat.watch('ping:recv', recv => { - if(dumpEvents) console.log('ping:recv', recv); + sockChat.watch('ping:recv', ev => { + if(dumpEvents) console.log('ping:recv', ev); let strength = 3; - if(recv.diff >= 1000) --strength; - if(recv.diff >= 250) --strength; + if(ev.detail.diff >= 1000) --strength; + if(ev.detail.diff >= 250) --strength; - pingToggle.title = `${recv.diff.toLocaleString()}ms`; + pingToggle.title = `${ev.detail.diff.toLocaleString()}ms`; pingIndicator.setStrength(strength); }); - sockChat.watch('session:start', start => { - if(dumpEvents) console.log('session:start', start); + sockChat.watch('session:start', ev => { + if(dumpEvents) console.log('session:start', ev); - const userInfo = new Umi.User(start.user.id, start.user.name, start.user.colour, start.user.permsRaw); + const userInfo = new Umi.User(ev.detail.user.id, ev.detail.user.name, ev.detail.user.colour, ev.detail.user.permsRaw); Umi.User.setCurrentUser(userInfo); Umi.Users.Add(userInfo); @@ -675,84 +676,84 @@ window.Umi = { UI: {}, Protocol: { SockChat: { Protocol: {} } } }; }, })); }); - sockChat.watch('session:fail', fail => { - if(dumpEvents) console.log('session:fail', fail); + sockChat.watch('session:fail', ev => { + if(dumpEvents) console.log('session:fail', ev); - if(fail.baka !== undefined) { - new MamiForceDisconnectNotice(fail.baka).pushOn(views); + if(ev.detail.baka !== undefined) { + new MamiForceDisconnectNotice(ev.detail.baka).pushOn(views); return; } getLoadingOverlay( 'cross', 'Failed!', - sessFailReasons[fail.session.reason] ?? `Unknown reason: ${fail.session.reason}` + sessFailReasons[ev.detail.session.reason] ?? `Unknown reason: ${ev.detail.session.reason}` ); - if(fail.session.needsAuth) + if(ev.detail.session.needsAuth) setTimeout(() => location.assign(futami.get('login')), 1000); }); - sockChat.watch('session:term', term => { - if(dumpEvents) console.log('session:term', term); + sockChat.watch('session:term', ev => { + if(dumpEvents) console.log('session:term', ev); - new MamiForceDisconnectNotice(term.baka).pushOn(views); + new MamiForceDisconnectNotice(ev.detail.baka).pushOn(views); }); - sockChat.watch('user:add', add => { - if(dumpEvents) console.log('user:add', add); + sockChat.watch('user:add', ev => { + if(dumpEvents) console.log('user:add', ev); - if(add.user.self) + if(ev.detail.user.self) return; - const userInfo = new Umi.User(add.user.id, add.user.name, add.user.colour, add.user.permsRaw); + const userInfo = new Umi.User(ev.detail.user.id, ev.detail.user.name, ev.detail.user.colour, ev.detail.user.permsRaw); Umi.Users.Add(userInfo); - if(add.msg !== undefined) + if(ev.detail.msg !== undefined) Umi.Messages.Add(new Umi.Message( - add.msg.id, add.msg.time, undefined, '', add.msg.channel, false, + ev.detail.msg.id, ev.detail.msg.time, undefined, '', ev.detail.msg.channel, false, { isError: false, - type: add.msg.botInfo.type, - args: add.msg.botInfo.args, + type: ev.detail.msg.botInfo.type, + args: ev.detail.msg.botInfo.args, target: userInfo, } )); }); - sockChat.watch('user:remove', remove => { - if(dumpEvents) console.log('user:remove', remove); + sockChat.watch('user:remove', ev => { + if(dumpEvents) console.log('user:remove', ev); - const userInfo = Umi.Users.Get(remove.user.id); + const userInfo = Umi.Users.Get(ev.detail.user.id); if(userInfo === null) return; - if(remove.msg !== undefined) + if(ev.detail.msg !== undefined) Umi.Messages.Add(new Umi.Message( - remove.msg.id, - remove.msg.time, + ev.detail.msg.id, + ev.detail.msg.time, undefined, '', - remove.msg.channel, + ev.detail.msg.channel, false, { isError: false, - type: remove.msg.botInfo.type, - args: remove.msg.botInfo.args, + type: ev.detail.msg.botInfo.type, + args: ev.detail.msg.botInfo.args, target: userInfo, }, )); Umi.Users.Remove(userInfo); }); - sockChat.watch('user:update', update => { - if(dumpEvents) console.log('user:update', update); + sockChat.watch('user:update', ev => { + if(dumpEvents) console.log('user:update', ev); - const userInfo = Umi.Users.Get(update.user.id); - userInfo.setName(update.user.name); - userInfo.setColour(update.user.colour); - userInfo.setPermissions(update.user.permsRaw); + const userInfo = Umi.Users.Get(ev.detail.user.id); + userInfo.setName(ev.detail.user.name); + userInfo.setColour(ev.detail.user.colour); + userInfo.setPermissions(ev.detail.user.permsRaw); Umi.Users.Update(userInfo.getId(), userInfo); }); - sockChat.watch('user:clear', () => { - if(dumpEvents) console.log('user:clear'); + sockChat.watch('user:clear', ev => { + if(dumpEvents) console.log('user:clear', ev); const self = Umi.User.currentUser; Umi.Users.Clear(); @@ -760,48 +761,48 @@ window.Umi = { UI: {}, Protocol: { SockChat: { Protocol: {} } } }; Umi.Users.Add(self); }); - sockChat.watch('chan:add', add => { - if(dumpEvents) console.log('chan:add', add); + sockChat.watch('chan:add', ev => { + if(dumpEvents) console.log('chan:add', ev); Umi.Channels.Add(new Umi.Channel( - add.channel.name, - add.channel.hasPassword, - add.channel.isTemporary, + ev.detail.channel.name, + ev.detail.channel.hasPassword, + ev.detail.channel.isTemporary, )); }); - sockChat.watch('chan:remove', remove => { - if(dumpEvents) console.log('chan:remove', remove); + sockChat.watch('chan:remove', ev => { + if(dumpEvents) console.log('chan:remove', ev); - Umi.Channels.Remove(Umi.Channels.Get(remove.channel.name)); + Umi.Channels.Remove(Umi.Channels.Get(ev.detail.channel.name)); }); - sockChat.watch('chan:update', update => { - if(dumpEvents) console.log('chan:update', update); + sockChat.watch('chan:update', ev => { + if(dumpEvents) console.log('chan:update', ev); - const chanInfo = Umi.Channels.Get(update.channel.previousName); - chanInfo.setName(update.channel.name); - chanInfo.setHasPassword(update.channel.hasPassword); - chanInfo.setTemporary(update.channel.isTemporary); - Umi.Channels.Update(update.channel.previousName, chanInfo); + const chanInfo = Umi.Channels.Get(ev.detail.channel.previousName); + chanInfo.setName(ev.detail.channel.name); + chanInfo.setHasPassword(ev.detail.channel.hasPassword); + chanInfo.setTemporary(ev.detail.channel.isTemporary); + Umi.Channels.Update(ev.detail.channel.previousName, chanInfo); }); - sockChat.watch('chan:clear', () => { - if(dumpEvents) console.log('chan:clear'); + sockChat.watch('chan:clear', ev => { + if(dumpEvents) console.log('chan:clear', ev); Umi.Channels.Clear(); }); - sockChat.watch('chan:focus', focus => { - if(dumpEvents) console.log('chan:focus', focus); + sockChat.watch('chan:focus', ev => { + if(dumpEvents) console.log('chan:focus', ev); - Umi.Channels.Switch(Umi.Channels.Get(focus.channel.name)); + Umi.Channels.Switch(Umi.Channels.Get(ev.detail.channel.name)); }); - sockChat.watch('chan:join', join => { - if(dumpEvents) console.log('chan:join', join); + sockChat.watch('chan:join', ev => { + if(dumpEvents) console.log('chan:join', ev); - const userInfo = new Umi.User(join.user.id, join.user.name, join.user.colour, join.user.permsRaw); + const userInfo = new Umi.User(ev.detail.user.id, ev.detail.user.name, ev.detail.user.colour, ev.detail.user.permsRaw); Umi.Users.Add(userInfo); - if(join.msg !== undefined) + if(ev.detail.msg !== undefined) Umi.Messages.Add(new Umi.Message( - join.msg.id, null, undefined, '', join.msg.channel, false, + ev.detail.msg.id, null, undefined, '', ev.detail.msg.channel, false, { isError: false, type: leave.msg.botInfo.type, @@ -810,22 +811,22 @@ window.Umi = { UI: {}, Protocol: { SockChat: { Protocol: {} } } }; }, )); }); - sockChat.watch('chan:leave', leave => { - if(dumpEvents) console.log('chan:leave', leave); + sockChat.watch('chan:leave', ev => { + if(dumpEvents) console.log('chan:leave', ev); - if(leave.user.self) + if(ev.detail.user.self) return; - const userInfo = Umi.Users.Get(leave.user.id); + const userInfo = Umi.Users.Get(ev.detail.user.id); if(userInfo === null) return; - if(leave.msg !== undefined) + if(ev.detail.msg !== undefined) Umi.Messages.Add(new Umi.Message( - leave.msg.id, null, undefined, '', leave.msg.channel, false, + ev.detail.msg.id, null, undefined, '', ev.detail.msg.channel, false, { isError: false, - type: leave.msg.botInfo.type, + type: ev.detail.msg.botInfo.type, args: [ userInfo.getName() ], target: userInfo, }, @@ -834,16 +835,16 @@ window.Umi = { UI: {}, Protocol: { SockChat: { Protocol: {} } } }; Umi.Users.Remove(userInfo); }); - sockChat.watch('msg:add', add => { - if(dumpEvents) console.log('msg:add', add); + sockChat.watch('msg:add', ev => { + if(dumpEvents) console.log('msg:add', ev); - const senderInfo = add.msg.sender; + const senderInfo = ev.detail.msg.sender; const userInfo = senderInfo.name === undefined ? Umi.Users.Get(senderInfo.id) : new Umi.User(senderInfo.id, senderInfo.name, senderInfo.colour, senderInfo.permsRaw); // hack - let channelName = add.msg.channel; + let channelName = ev.detail.msg.channel; if(channelName !== undefined && channelName.startsWith('@~')) { const chanUserInfo = Umi.Users.Get(channelName.substring(2)); if(chanUserInfo !== null) @@ -851,7 +852,7 @@ window.Umi = { UI: {}, Protocol: { SockChat: { Protocol: {} } } }; } // also hack - if(add.msg.flags.isPM) { + if(ev.detail.msg.flags.isPM) { if(Umi.Channels.Get(channelName) === null) Umi.Channels.Add(new Umi.Channel(channelName, false, true, true)); @@ -860,24 +861,24 @@ window.Umi = { UI: {}, Protocol: { SockChat: { Protocol: {} } } }; } Umi.Messages.Add(new Umi.Message( - add.msg.id, - add.msg.time, + ev.detail.msg.id, + ev.detail.msg.time, userInfo, - add.msg.text, + ev.detail.msg.text, channelName, false, - add.msg.botInfo, - add.msg.flags.isAction, - add.msg.silent, + ev.detail.msg.botInfo, + ev.detail.msg.flags.isAction, + ev.detail.msg.silent, )); }); - sockChat.watch('msg:remove', remove => { - if(dumpEvents) console.log('msg:remove', remove); + sockChat.watch('msg:remove', ev => { + if(dumpEvents) console.log('msg:remove', ev); - Umi.Messages.Remove(Umi.Messages.Get(remove.msg.id)); + Umi.Messages.Remove(Umi.Messages.Get(ev.detail.msg.id)); }); - sockChat.watch('msg:clear', () => { - if(dumpEvents) console.log('msg:clear'); + sockChat.watch('msg:clear', ev => { + if(dumpEvents) console.log('msg:clear', ev); Umi.UI.Messages.RemoveAll(); }); diff --git a/src/mami.js/settings/settings.js b/src/mami.js/settings/settings.js index d368317..f75c687 100644 --- a/src/mami.js/settings/settings.js +++ b/src/mami.js/settings/settings.js @@ -1,4 +1,4 @@ -#include watcher.js +#include eventtarget.js #include settings/scoped.js #include settings/virtual.js #include settings/webstorage.js @@ -15,9 +15,16 @@ const MamiSettings = function(storageOrPrefix) { throw 'required methods do not exist in storageOrPrefix object'; const storage = new MamiSettingsVirtualStorage(storageOrPrefix); - const watchers = new MamiWatchers; const settings = new Map; + const eventTarget = new MamiEventTarget('mami:setting'); + const createUpdateEvent = (name, value, initial) => eventTarget.create(name, { + name: name, + value: value, + initial: !!initial, + }); + const dispatchUpdate = (name, value) => eventTarget.dispatchEvent(createUpdateEvent(name, value)); + const broadcast = new BroadcastChannel(`${MAMI_JS}:settings:${storage.name()}`); const broadcastUpdate = (name, value) => { setTimeout(() => broadcast.postMessage({ act: 'update', name: name, value: value }), 0); @@ -43,7 +50,7 @@ const MamiSettings = function(storageOrPrefix) { return; storage.delete(setting.name); - watchers.call(setting.name, setting.fallback, setting.name); + dispatchUpdate(setting.name, setting.fallback); broadcastUpdate(setting.name, setting.fallback); }; @@ -89,7 +96,7 @@ const MamiSettings = function(storageOrPrefix) { } else storage.set(setting.name, value); - watchers.call(setting.name, value, setting.name); + dispatchUpdate(setting.name, value); broadcastUpdate(setting.name, value); }; @@ -98,7 +105,7 @@ const MamiSettings = function(storageOrPrefix) { return; if(ev.data.act === 'update' && typeof ev.data.name === 'string') { - watchers.call(ev.data.name, ev.data.value, ev.data.name); + dispatchUpdate(ev.data.name, ev.data.value); return; } }; @@ -122,8 +129,6 @@ const MamiSettings = function(storageOrPrefix) { if(virtual === true) storage.virtualise(name); - - watchers.define(name); }, info: name => getSetting(name), names: () => Array.from(settings.keys()), @@ -143,7 +148,7 @@ const MamiSettings = function(storageOrPrefix) { }, touch: name => { const setting = getSetting(name); - watchers.call(setting.name, getValue(setting), setting.name); + dispatchUpdate(setting.name, getValue(setting)); }, clear: (criticalOnly, prefix) => { for(const setting of settings.values()) @@ -152,10 +157,11 @@ const MamiSettings = function(storageOrPrefix) { }, watch: (name, handler) => { const setting = getSetting(name); - watchers.watch(setting.name, handler, getValue(setting), setting.name); + eventTarget.watch(setting.name, handler); + handler(createUpdateEvent(setting.name, getValue(setting), true)); }, unwatch: (name, handler) => { - watchers.unwatch(getSetting(name).name, handler); + eventTarget.unwatch(name, handler); }, virtualise: name => storage.virtualise(getSetting(name).name), scope: name => new MamiSettingsScoped(pub, name), diff --git a/src/mami.js/sockchat_old.js b/src/mami.js/sockchat_old.js index b4692c6..8e3e197 100644 --- a/src/mami.js/sockchat_old.js +++ b/src/mami.js/sockchat_old.js @@ -1,18 +1,10 @@ #include common.js +#include eventtarget.js #include servers.js -#include watcher.js #include websock.js Umi.Protocol.SockChat.Protocol = function() { - const watchers = new MamiWatchers(false); - watchers.define([ - 'conn:init', 'conn:ready', 'conn:lost', 'conn:error', - 'ping:send', 'ping:long', 'ping:recv', - 'session:start', 'session:fail', 'session:term', - 'user:add', 'user:remove', 'user:update', 'user:clear', - 'chan:add', 'chan:remove', 'chan:update', 'chan:clear', 'chan:focus', 'chan:join', 'chan:leave', - 'msg:add', 'msg:remove', 'msg:clear', - ]); + const eventTarget = new MamiEventTarget('mami:proto'); const parseUserColour = str => { // todo @@ -61,7 +53,7 @@ Umi.Protocol.SockChat.Protocol = function() { stopPingWatcher(); if(lastPong === undefined) - watchers.call('ping:long'); + eventTarget.dispatch('ping:long'); }, 2000); }; @@ -81,7 +73,7 @@ Umi.Protocol.SockChat.Protocol = function() { if(selfUserId === undefined) return; - watchers.call('ping:send'); + eventTarget.dispatch('ping:send'); startPingWatcher(); lastPong = undefined; @@ -111,10 +103,10 @@ Umi.Protocol.SockChat.Protocol = function() { isRestarting = false; // see if these are neccesary - watchers.call('user:clear'); - watchers.call('chan:clear'); + eventTarget.dispatch('user:clear'); + eventTarget.dispatch('chan:clear'); - watchers.call('conn:ready', { wasConnected: wasConnected }); + eventTarget.dispatch('conn:ready', { wasConnected: wasConnected }); }; const onClose = ev => { @@ -136,7 +128,7 @@ Umi.Protocol.SockChat.Protocol = function() { } else if(code === 1012) isRestarting = true; - watchers.call('conn:lost', { + eventTarget.dispatch('conn:lost', { wasConnected: wasConnected, isRestarting: isRestarting, code: code, @@ -148,7 +140,7 @@ Umi.Protocol.SockChat.Protocol = function() { }; const onError = ex => { - watchers.call('conn:error', ex); + eventTarget.dispatch('conn:error', ex); }; const unfuckText = text => { @@ -181,7 +173,7 @@ Umi.Protocol.SockChat.Protocol = function() { // pong handler handlers['0'] = () => { lastPong = Date.now(); - watchers.call('ping:recv', { + eventTarget.dispatch('ping:recv', { ping: lastPing, pong: lastPong, diff: lastPong - lastPing, @@ -194,7 +186,7 @@ Umi.Protocol.SockChat.Protocol = function() { selfUserId = userIdOrReason; selfChannelName = chanNameOrMsgId; - watchers.call('session:start', { + eventTarget.dispatch('session:start', { wasConnected: wasConnected, session: { success: true }, ctx: { @@ -235,11 +227,11 @@ Umi.Protocol.SockChat.Protocol = function() { until: userNameOrExpiry === '-1' ? undefined : new Date(parseInt(userNameOrExpiry) * 1000), }; - watchers.call('session:fail', failInfo); + eventTarget.dispatch('session:fail', failInfo); return; } - watchers.call('user:add', { + eventTarget.dispatch('user:add', { msg: { id: chanNameOrMsgId, time: new Date(parseInt(successOrTimeStamp) * 1000), @@ -300,12 +292,12 @@ Umi.Protocol.SockChat.Protocol = function() { }; } - watchers.call('msg:add', msgInfo); + eventTarget.dispatch('msg:add', msgInfo); }; // user leave handlers['3'] = (userId, userName, reason, timeStamp, msgId) => { - watchers.call('user:remove', { + eventTarget.dispatch('user:remove', { leave: { type: reason }, msg: { id: msgId, @@ -329,7 +321,7 @@ Umi.Protocol.SockChat.Protocol = function() { // channel add handlers['4']['0'] = (name, hasPass, isTemp) => { - watchers.call('chan:add', { + eventTarget.dispatch('chan:add', { channel: { name: name, hasPassword: hasPass !== '0', @@ -340,7 +332,7 @@ Umi.Protocol.SockChat.Protocol = function() { // channel update handlers['4']['1'] = (prevName, name, hasPass, isTemp) => { - watchers.call('chan:update', { + eventTarget.dispatch('chan:update', { channel: { previousName: prevName, name: name, @@ -352,7 +344,7 @@ Umi.Protocol.SockChat.Protocol = function() { // channel remove handlers['4']['2'] = name => { - watchers.call('chan:remove', { + eventTarget.dispatch('chan:remove', { channel: { name: name }, }); }; @@ -362,7 +354,7 @@ Umi.Protocol.SockChat.Protocol = function() { // user join channel handlers['5']['0'] = (userId, userName, userColour, userPerms, msgId) => { - watchers.call('chan:join', { + eventTarget.dispatch('chan:join', { user: { id: userId, self: userId === selfUserId, @@ -384,7 +376,7 @@ Umi.Protocol.SockChat.Protocol = function() { // user leave channel handlers['5']['1'] = (userId, msgId) => { - watchers.call('chan:leave', { + eventTarget.dispatch('chan:leave', { user: { id: userId, self: userId === selfUserId, @@ -404,14 +396,14 @@ Umi.Protocol.SockChat.Protocol = function() { handlers['5']['2'] = name => { selfChannelName = name; - watchers.call('chan:focus', { + eventTarget.dispatch('chan:focus', { channel: { name: selfChannelName }, }); }; // message delete handlers['6'] = msgId => { - watchers.call('msg:remove', { + eventTarget.dispatch('msg:remove', { msg: { id: msgId, channel: selfChannelName, @@ -429,7 +421,7 @@ Umi.Protocol.SockChat.Protocol = function() { for(let i = 0; i < count; ++i) { const offset = 5 * i; - watchers.call('user:add', { + eventTarget.dispatch('user:add', { user: { id: args[offset], self: args[offset] === selfUserId, @@ -479,7 +471,7 @@ Umi.Protocol.SockChat.Protocol = function() { }; } - watchers.call('msg:add', info); + eventTarget.dispatch('msg:add', info); }; // existing channels @@ -489,7 +481,7 @@ Umi.Protocol.SockChat.Protocol = function() { for(let i = 0; i < count; ++i) { const offset = 3 * i; - watchers.call('chan:add', { + eventTarget.dispatch('chan:add', { channel: { name: args[offset], hasPassword: args[offset + 1] !== '0', @@ -499,7 +491,7 @@ Umi.Protocol.SockChat.Protocol = function() { }); } - watchers.call('chan:focus', { + eventTarget.dispatch('chan:focus', { channel: { name: selfChannelName }, }); }; @@ -507,13 +499,13 @@ Umi.Protocol.SockChat.Protocol = function() { // context clear handlers['8'] = mode => { if(mode === '0' || mode === '3' || mode === '4') - watchers.call('msg:clear'); + eventTarget.dispatch('msg:clear'); if(mode === '1' || mode === '3' || mode === '4') - watchers.call('user:clear'); + eventTarget.dispatch('user:clear'); if(mode === '2' || mode === '4') - watchers.call('chan:clear'); + eventTarget.dispatch('chan:clear'); }; // baka (ban/kick) @@ -533,12 +525,12 @@ Umi.Protocol.SockChat.Protocol = function() { bakaInfo.baka.until = expiry === '-1' ? undefined : new Date(parseInt(expiry) * 1000); } - watchers.call('session:term', bakaInfo); + eventTarget.dispatch('session:term', bakaInfo); }; // user update handlers['10'] = (userId, userName, userColour, userPerms) => { - watchers.call('user:update', { + eventTarget.dispatch('user:update', { user: { id: userId, self: userId === selfUserId, @@ -558,7 +550,7 @@ Umi.Protocol.SockChat.Protocol = function() { return; UmiServers.getServer(server => { - watchers.call('conn:init', { + eventTarget.dispatch('conn:init', { server: server, wasConnected: wasConnected, attempt: ++connectAttempts, @@ -604,8 +596,8 @@ Umi.Protocol.SockChat.Protocol = function() { noReconnect = true; sock?.close(); }, - watch: (name, handler) => watchers.watch(name, handler), - unwatch: (name, handler) => watchers.unwatch(name, handler), + watch: (name, handler) => eventTarget.watch(name, handler), + unwatch: (name, handler) => eventTarget.unwatch(name, handler), setDumpPackets: state => dumpPackets = !!state, switchChannel: channelInfo => { if(selfUserId === undefined) diff --git a/src/mami.js/ui/settings.jsx b/src/mami.js/ui/settings.jsx index a66f245..76cfda7 100644 --- a/src/mami.js/ui/settings.jsx +++ b/src/mami.js/ui/settings.jsx @@ -454,7 +454,7 @@ Umi.UI.Settings = (function() { input.disabled = true; if(display.type === 'checkbox') { - mami.settings.watch(setting.name, v => input.checked = v); + mami.settings.watch(setting.name, ev => input.checked = ev.detail.value); input.addEventListener('change', () => { if(display.confirm !== undefined && input.checked !== setting.fallback && !confirm(display.confirm)) { input.checked = setting.fallback; @@ -464,7 +464,7 @@ Umi.UI.Settings = (function() { mami.settings.toggle(setting.name); }); } else { - mami.settings.watch(setting.name, v => input.value = v); + mami.settings.watch(setting.name, ev => input.value = ev.detail.value); input.addEventListener('change', () => mami.settings.set(setting.name, input.value)); } } diff --git a/src/mami.js/watcher.js b/src/mami.js/watcher.js deleted file mode 100644 index b859a0f..0000000 --- a/src/mami.js/watcher.js +++ /dev/null @@ -1,77 +0,0 @@ -#include utility.js - -const MamiWatcher = function(initCall) { - if(typeof initCall !== 'boolean') - initCall = true; - - const handlers = []; - - const watch = (handler, ...args) => { - if(typeof handler !== 'function') - throw 'handler must be a function'; - if(handlers.includes(handler)) - throw 'handler already registered'; - - handlers.push(handler); - - if(initCall) { - args.push(true); - handler(...args); - } - }; - - const unwatch = handler => { - $ari(handlers, handler); - }; - - return { - watch: watch, - unwatch: unwatch, - call: (...args) => { - if(initCall) - args.push(false); - - for(const handler of handlers) - handler(...args); - }, - }; -}; - -const MamiWatchers = function(initCall) { - if(typeof initCall !== 'boolean') - initCall = true; - - const watchers = new Map; - - const getWatcher = name => { - const watcher = watchers.get(name); - if(watcher === undefined) - throw 'undefined watcher name'; - return watcher; - }; - - const watch = (name, handler, ...args) => { - getWatcher(name).watch(handler, ...args); - }; - - const unwatch = (name, handler) => { - getWatcher(name).unwatch(handler); - }; - - return { - watch: watch, - unwatch: unwatch, - define: names => { - if(typeof names === 'string') - watchers.set(names, new MamiWatcher(initCall)); - else if(Array.isArray(names)) - for(const name of names) - watchers.set(name, new MamiWatcher(initCall)); - else - throw 'names must be an array of names or a single name'; - }, - call: (name, ...args) => { - getWatcher(name).call(...args); - }, - }; -};