From 43f152f6e3ee4c03a906cfea328df3bcbc736ca2 Mon Sep 17 00:00:00 2001 From: flashwave Date: Wed, 28 Feb 2024 00:10:07 +0000 Subject: [PATCH] Keep chat settings in sync between tabs. --- build.js | 10 ++++----- src/mami.js/settings/settings.js | 33 ++++++++++++++++++++++-------- src/mami.js/settings/virtual.js | 1 + src/mami.js/settings/webstorage.js | 1 + 4 files changed, 31 insertions(+), 14 deletions(-) diff --git a/build.js b/build.js index 24f35cf..13c5eb6 100644 --- a/build.js +++ b/build.js @@ -21,15 +21,15 @@ const isDebugBuild = fs.existsSync(path.join(rootDir, '.debug')); const buildTasks = { js: [ - { source: 'websock.js', target: '/assets', name: 'mami-ws.{hash}.js', buildVar: 'MAMI_WS', buildVarsTarget: 'self', }, - { source: 'mami.js', target: '/assets', name: 'mami.{hash}.js', buildVar: 'MAMI_JS', }, - { source: 'mami-init.js', target: '/assets', name: 'mami-init.{hash}.js', es: 'es5', }, + { source: 'websock.js', target: '/assets', name: 'mami-ws.{hash}.js', buildVar: 'MAMI_WS', buildVarsTarget: 'self' }, + { source: 'mami.js', target: '/assets', name: 'mami.{hash}.js', buildVar: 'MAMI_JS' }, + { source: 'mami-init.js', target: '/assets', name: 'mami-init.{hash}.js', es: 'es5' }, ], css: [ - { source: 'mami.css', target: '/assets', name: 'mami.{hash}.css', }, + { source: 'mami.css', target: '/assets', name: 'mami.{hash}.css' }, ], html: [ - { source: 'mami.html', target: '/', name: 'index.html', }, + { source: 'mami.html', target: '/', name: 'index.html' }, ], webmanifest: [ { source: 'mami.webmanifest', target: '/', name: 'mami.webmanifest', icons: '/icons' } diff --git a/src/mami.js/settings/settings.js b/src/mami.js/settings/settings.js index 735d8be..31cc966 100644 --- a/src/mami.js/settings/settings.js +++ b/src/mami.js/settings/settings.js @@ -1,3 +1,4 @@ +#include uniqstr.js #include watcher.js #include settings/scoped.js #include settings/virtual.js @@ -14,9 +15,14 @@ const MamiSettings = function(storageOrPrefix) { || typeof storageOrPrefix.delete !== 'function') throw 'required methods do not exist in storageOrPrefix object'; - const storage = new MamiSettingsVirtualStorage(storageOrPrefix), - watchers = new MamiWatchers, - settings = new Map; + const storage = new MamiSettingsVirtualStorage(storageOrPrefix); + const watchers = new MamiWatchers; + const settings = new Map; + + const broadcast = new BroadcastChannel(`${MAMI_JS}:settings:${storage.name()}`); + const broadcastUpdate = (name, value) => { + setTimeout(() => broadcast.postMessage({ act: 'update', name: name, value: value }), 0); + }; const getSetting = name => { const setting = settings.get(name); @@ -38,6 +44,8 @@ const MamiSettings = function(storageOrPrefix) { return; storage.delete(setting.name); + watchers.call(setting.name, setting.fallback, setting.name); + broadcastUpdate(setting.name, setting.fallback); }; const setValue = (setting, value) => { @@ -83,6 +91,17 @@ const MamiSettings = function(storageOrPrefix) { storage.set(setting.name, value); watchers.call(setting.name, value, setting.name); + broadcastUpdate(setting.name, value); + }; + + broadcast.onmessage = ev => { + if(typeof ev.data !== 'object' || typeof ev.data.act !== 'string') + return; + + if(ev.data.act === 'update' && typeof ev.data.name === 'string') { + watchers.call(ev.data.name, ev.data.value, ev.data.name); + return; + } }; const pub = { @@ -117,11 +136,7 @@ const MamiSettings = function(storageOrPrefix) { }, get: name => getValue(getSetting(name)), set: (name, value) => setValue(getSetting(name), value), - delete: name => { - const setting = getSetting(name); - if(!setting.immutable) - storage.delete(setting.name) - }, + delete: name => deleteValue(getSetting(name)), toggle: name => { const setting = getSetting(name); if(!setting.immutable) @@ -134,7 +149,7 @@ const MamiSettings = function(storageOrPrefix) { clear: (criticalOnly, prefix) => { for(const setting of settings.values()) if((prefix === undefined || setting.name.startsWith(prefix)) && (!criticalOnly || setting.critical)) - storage.delete(setting.name); + deleteValue(setting); }, watch: (name, handler) => { const setting = getSetting(name); diff --git a/src/mami.js/settings/virtual.js b/src/mami.js/settings/virtual.js index f4b4466..8987772 100644 --- a/src/mami.js/settings/virtual.js +++ b/src/mami.js/settings/virtual.js @@ -2,6 +2,7 @@ const MamiSettingsVirtualStorage = function(storage) { const virtuals = new Map; return { + name: () => `virtual:${storage.name()}`, virtualise: name => virtuals.set(name, storage.get(name)), get: name => { if(virtuals.has(name)) diff --git a/src/mami.js/settings/webstorage.js b/src/mami.js/settings/webstorage.js index be44cb7..3b56294 100644 --- a/src/mami.js/settings/webstorage.js +++ b/src/mami.js/settings/webstorage.js @@ -5,6 +5,7 @@ const MamiSettingsWebStorage = function(storage, prefix) { prefix = ''; return { + name: () => `webstorage:${prefix}`, delete: name => storage.removeItem(prefix + name), set: (name, value) => storage.setItem(prefix + name, value === undefined ? null : JSON.stringify(value)), get: name => {