2017-11-13 01:23:39 -05:00
|
|
|
'use strict';
|
|
|
|
|
|
|
|
// ============================================================================
|
|
|
|
// Settings Profiles
|
|
|
|
// ============================================================================
|
|
|
|
|
|
|
|
import {EventEmitter} from 'utilities/events';
|
2019-06-13 22:56:50 -04:00
|
|
|
import {has} from 'utilities/object';
|
|
|
|
import {createTester} from 'utilities/filtering';
|
2017-11-13 01:23:39 -05:00
|
|
|
|
2019-06-20 15:15:54 -04:00
|
|
|
const fetchJSON = (url, options) => fetch(url, options).then(r => r.ok ? r.json() : null).catch(() => null);
|
2017-11-13 01:23:39 -05:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Instances of SettingsProfile are used for getting and setting raw settings
|
|
|
|
* values, enumeration, and emit events when the raw settings are changed.
|
|
|
|
* @extends EventEmitter
|
|
|
|
*/
|
|
|
|
export default class SettingsProfile extends EventEmitter {
|
|
|
|
constructor(manager, data) {
|
|
|
|
super();
|
|
|
|
|
|
|
|
this.manager = manager;
|
|
|
|
this.provider = manager.provider;
|
|
|
|
|
|
|
|
this.data = data;
|
|
|
|
this.prefix = `p:${this.id}:`;
|
2019-10-09 16:02:25 -04:00
|
|
|
this.enabled_key = `${this.prefix}:enabled`;
|
2017-11-13 01:23:39 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
get data() {
|
|
|
|
return {
|
|
|
|
id: this.id,
|
|
|
|
parent: this.parent,
|
|
|
|
|
|
|
|
name: this.name,
|
|
|
|
i18n_key: this.i18n_key,
|
|
|
|
|
|
|
|
description: this.description,
|
|
|
|
desc_i18n_key: this.desc_i18n_key,
|
|
|
|
|
2019-06-13 22:56:50 -04:00
|
|
|
url: this.url,
|
2019-10-09 16:02:25 -04:00
|
|
|
show_toggle: this.show_toggle,
|
2019-06-13 22:56:50 -04:00
|
|
|
|
2017-11-13 01:23:39 -05:00
|
|
|
context: this.context
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
set data(val) {
|
|
|
|
if ( typeof val !== 'object' )
|
|
|
|
throw new TypeError('data must be an object');
|
|
|
|
|
2019-06-13 22:56:50 -04:00
|
|
|
this.matcher = null;
|
|
|
|
|
2017-11-13 01:23:39 -05:00
|
|
|
for(const key in val)
|
|
|
|
if ( has(val, key) )
|
|
|
|
this[key] = val[key];
|
|
|
|
}
|
|
|
|
|
|
|
|
matches(context) {
|
2019-06-13 22:56:50 -04:00
|
|
|
if ( ! this.matcher )
|
2020-07-18 16:27:45 -04:00
|
|
|
this.matcher = createTester(this.context, this.manager.filters, false, false, () => this.manager.updateSoon());
|
2017-11-13 01:23:39 -05:00
|
|
|
|
2019-06-13 22:56:50 -04:00
|
|
|
return this.matcher(context);
|
2017-11-13 01:23:39 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
save() {
|
|
|
|
this.manager.saveProfile(this.id);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-06-13 22:56:50 -04:00
|
|
|
getBackup() {
|
|
|
|
const out = {
|
|
|
|
version: 2,
|
|
|
|
type: 'profile',
|
|
|
|
profile: this.data,
|
2019-10-09 16:02:25 -04:00
|
|
|
toggled: this.toggled,
|
2019-06-13 22:56:50 -04:00
|
|
|
values: {}
|
|
|
|
};
|
|
|
|
|
|
|
|
for(const [k,v] of this.entries())
|
|
|
|
out.values[k] = v;
|
|
|
|
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async checkUpdate() {
|
|
|
|
if ( ! this.url )
|
|
|
|
return false;
|
|
|
|
|
2019-06-20 15:15:54 -04:00
|
|
|
const data = await fetchJSON(this.url);
|
2019-06-13 22:56:50 -04:00
|
|
|
if ( ! data || ! data.type === 'profile' || ! data.profile || ! data.values )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
delete data.profile.id;
|
|
|
|
this.data = data.profile;
|
|
|
|
|
|
|
|
const old_keys = new Set(this.keys());
|
|
|
|
|
|
|
|
for(const [key, value] of Object.entries(data.values)) {
|
|
|
|
old_keys.delete(key);
|
|
|
|
this.set(key, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
for(const key of old_keys)
|
|
|
|
this.delete(key);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-10-09 16:02:25 -04:00
|
|
|
// ========================================================================
|
|
|
|
// Toggled
|
|
|
|
// ========================================================================
|
|
|
|
|
|
|
|
get toggled() {
|
|
|
|
return this.provider.get(this.enabled_key, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
set toggled(val) {
|
|
|
|
if ( val === this.toggleState )
|
|
|
|
return;
|
|
|
|
|
|
|
|
this.provider.set(this.enabled_key, val);
|
|
|
|
this.emit('toggled', this, val);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-11-13 01:23:39 -05:00
|
|
|
// ========================================================================
|
|
|
|
// Context
|
|
|
|
// ========================================================================
|
|
|
|
|
|
|
|
updateContext(context) {
|
|
|
|
if ( this.id === 0 )
|
|
|
|
throw new Error('cannot set context of default profile');
|
|
|
|
|
|
|
|
this.context = Object.assign(this.context || {}, context);
|
2019-06-13 22:56:50 -04:00
|
|
|
this.matcher = null;
|
2017-11-13 01:23:39 -05:00
|
|
|
this.manager._saveProfiles();
|
|
|
|
}
|
|
|
|
|
|
|
|
setContext(context) {
|
|
|
|
if ( this.id === 0 )
|
|
|
|
throw new Error('cannot set context of default profile');
|
|
|
|
|
|
|
|
this.context = context;
|
2019-06-13 22:56:50 -04:00
|
|
|
this.matcher = null;
|
2017-11-13 01:23:39 -05:00
|
|
|
this.manager._saveProfiles();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ========================================================================
|
|
|
|
// Setting Access
|
|
|
|
// ========================================================================
|
|
|
|
|
|
|
|
get(key, default_value) {
|
|
|
|
return this.provider.get(this.prefix + key, default_value);
|
|
|
|
}
|
|
|
|
|
|
|
|
set(key, value) {
|
|
|
|
this.provider.set(this.prefix + key, value);
|
|
|
|
this.emit('changed', key, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
delete(key) {
|
|
|
|
this.provider.delete(this.prefix + key);
|
|
|
|
this.emit('changed', key, undefined, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
has(key) {
|
|
|
|
return this.provider.has(this.prefix + key);
|
|
|
|
}
|
|
|
|
|
|
|
|
keys() {
|
|
|
|
const out = [],
|
|
|
|
p = this.prefix,
|
|
|
|
len = p.length;
|
|
|
|
|
|
|
|
for(const key of this.provider.keys())
|
2019-10-09 16:02:25 -04:00
|
|
|
if ( key.startsWith(p) && key !== this.enabled_key )
|
2017-11-13 01:23:39 -05:00
|
|
|
out.push(key.slice(len));
|
|
|
|
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
|
|
|
|
clear() {
|
|
|
|
const p = this.prefix,
|
|
|
|
len = p.length;
|
|
|
|
for(const key of this.provider.keys())
|
2019-10-09 16:02:25 -04:00
|
|
|
if ( key.startsWith(p) && key !== this.enabled_key ) {
|
2017-11-13 01:23:39 -05:00
|
|
|
this.provider.delete(key);
|
|
|
|
this.emit('changed', key.slice(len), undefined, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
*entries() {
|
|
|
|
const p = this.prefix,
|
|
|
|
len = p.length;
|
|
|
|
|
|
|
|
for(const key of this.provider.keys())
|
2019-10-09 16:02:25 -04:00
|
|
|
if ( key.startsWith(p) && key !== this.enabled_key )
|
2017-11-13 01:23:39 -05:00
|
|
|
yield [key.slice(len), this.provider.get(key)];
|
|
|
|
}
|
|
|
|
|
|
|
|
get size() {
|
|
|
|
const p = this.prefix;
|
|
|
|
let count = 0;
|
|
|
|
|
|
|
|
for(const key of this.provider.keys())
|
2019-10-09 16:02:25 -04:00
|
|
|
if ( key.startsWith(p) && key !== this.enabled_key )
|
2017-11-13 01:23:39 -05:00
|
|
|
count++;
|
|
|
|
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SettingsProfile.Default = {
|
|
|
|
id: 0,
|
|
|
|
name: 'Default Profile',
|
|
|
|
i18n_key: 'setting.profiles.default',
|
|
|
|
|
|
|
|
description: 'Settings that apply everywhere on Twitch.'
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SettingsProfile.Moderation = {
|
|
|
|
id: 1,
|
|
|
|
name: 'Moderation',
|
|
|
|
i18n_key: 'setting.profiles.moderation',
|
|
|
|
|
|
|
|
description: 'Settings that apply when you are a moderator of the current channel.',
|
|
|
|
|
2019-06-13 22:56:50 -04:00
|
|
|
context: [
|
|
|
|
{
|
|
|
|
type: 'Moderator',
|
|
|
|
data: true
|
|
|
|
}
|
|
|
|
]
|
2017-11-13 01:23:39 -05:00
|
|
|
}
|