mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-09-15 17:46:55 +00:00
Fix setting sync using BroadcastChannel, since localStorage events are unreliable. Thanks Chrome. :D
This commit is contained in:
parent
8ce07a5603
commit
2e5c99c727
3 changed files with 57 additions and 2 deletions
|
@ -115,10 +115,13 @@ export default class SettingsManager extends Module {
|
|||
if ( key === 'profiles' )
|
||||
return this.loadProfiles();
|
||||
|
||||
if ( ! key.startsWith('p:') )
|
||||
return;
|
||||
|
||||
// If we're still here, it means an individual setting was changed.
|
||||
// Look up the profile it belongs to and emit a changed event from
|
||||
// that profile, thus notifying any contexts or UI instances.
|
||||
key = key.substr(2);
|
||||
const idx = key.indexOf(':');
|
||||
if ( idx === -1 )
|
||||
return;
|
||||
|
|
|
@ -75,8 +75,15 @@ export class LocalStorageProvider extends SettingsProvider {
|
|||
|
||||
this.ready = true;
|
||||
|
||||
this._boundHandleStorage = this.handleStorage.bind(this);
|
||||
window.addEventListener('storage', this._boundHandleStorage);
|
||||
if ( window.BroadcastChannel ) {
|
||||
const bc = this._broadcaster = new BroadcastChannel('ffz-settings');
|
||||
bc.addEventListener('message',
|
||||
this._boundHandleMessage = this.handleMessage.bind(this));
|
||||
|
||||
} else {
|
||||
window.addEventListener('storage',
|
||||
this._boundHandleStorage = this.handleStorage.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
destroy() {
|
||||
|
@ -87,6 +94,12 @@ export class LocalStorageProvider extends SettingsProvider {
|
|||
disable() {
|
||||
this.disabled = true;
|
||||
|
||||
if ( this._broadcaster ) {
|
||||
this._broadcaster.removeEventListener('message', this._boundHandleMessage);
|
||||
this._broadcaster.close();
|
||||
this._boundHandleMessage = this._broadcaster = null;
|
||||
}
|
||||
|
||||
if ( this._boundHandleStorage ) {
|
||||
window.removeEventListener('storage', this._boundHandleStorage);
|
||||
this._boundHandleStorage = null;
|
||||
|
@ -94,6 +107,37 @@ export class LocalStorageProvider extends SettingsProvider {
|
|||
}
|
||||
|
||||
|
||||
broadcast(msg) {
|
||||
if ( this._broadcaster )
|
||||
this._broadcaster.postMessage(msg);
|
||||
}
|
||||
|
||||
|
||||
handleMessage(event) {
|
||||
if ( this.disabled || ! event.isTrusted || ! event.data )
|
||||
return;
|
||||
|
||||
this.manager.log.debug('storage broadcast event', event.data);
|
||||
const {type, key} = event.data;
|
||||
|
||||
if ( type === 'set' ) {
|
||||
const val = JSON.parse(localStorage.getItem(this.prefix + key));
|
||||
this._cached.set(key, val);
|
||||
this.emit('changed', key, val, false);
|
||||
|
||||
} else if ( type === 'delete' ) {
|
||||
this._cached.delete(key);
|
||||
this.emit('changed', key, undefined, true);
|
||||
|
||||
} else if ( type === 'clear' ) {
|
||||
const old_keys = Array.from(this._cached.keys());
|
||||
this._cached.clear();
|
||||
for(const key of old_keys)
|
||||
this.emit('changed', key, undefined, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
handleStorage(event) {
|
||||
if ( this.disabled )
|
||||
return;
|
||||
|
@ -129,11 +173,13 @@ export class LocalStorageProvider extends SettingsProvider {
|
|||
set(key, value) {
|
||||
this._cached.set(key, value);
|
||||
localStorage.setItem(this.prefix + key, JSON.stringify(value));
|
||||
this.broadcast({type: 'set', key});
|
||||
}
|
||||
|
||||
delete(key) {
|
||||
this._cached.delete(key);
|
||||
localStorage.removeItem(this.prefix + key);
|
||||
this.broadcast({type: 'delete', key});
|
||||
}
|
||||
|
||||
has(key) {
|
||||
|
@ -149,6 +195,7 @@ export class LocalStorageProvider extends SettingsProvider {
|
|||
localStorage.removeItem(this.prefix + key);
|
||||
|
||||
this._cached.clear();
|
||||
this.broadcast({type: 'clear'});
|
||||
}
|
||||
|
||||
entries() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue