mirror of
https://github.com/ajayyy/SponsorBlock.git
synced 2025-12-06 19:47:04 +03:00
Add local storage options to config
This commit is contained in:
@@ -685,7 +685,7 @@ class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeSta
|
|||||||
|
|
||||||
clearConfigListener(): void {
|
clearConfigListener(): void {
|
||||||
if (this.configListener) {
|
if (this.configListener) {
|
||||||
Config.configListeners.splice(Config.configListeners.indexOf(this.configListener), 1);
|
Config.configSyncListeners.splice(Config.configSyncListeners.indexOf(this.configListener), 1);
|
||||||
this.configListener = null;
|
this.configListener = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
|
|||||||
// Add as a config listener
|
// Add as a config listener
|
||||||
if (!this.configUpdateListener) {
|
if (!this.configUpdateListener) {
|
||||||
this.configUpdateListener = () => this.configUpdate();
|
this.configUpdateListener = () => this.configUpdate();
|
||||||
Config.configListeners.push(this.configUpdate.bind(this));
|
Config.configSyncListeners.push(this.configUpdate.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
this.checkToShowFullVideoWarning();
|
this.checkToShowFullVideoWarning();
|
||||||
@@ -80,7 +80,7 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
|
|||||||
|
|
||||||
componentWillUnmount(): void {
|
componentWillUnmount(): void {
|
||||||
if (this.configUpdateListener) {
|
if (this.configUpdateListener) {
|
||||||
Config.configListeners.splice(Config.configListeners.indexOf(this.configUpdate.bind(this)), 1);
|
Config.configSyncListeners.splice(Config.configSyncListeners.indexOf(this.configUpdate.bind(this)), 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -96,11 +96,16 @@ interface SBConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface SBStorage {
|
||||||
|
}
|
||||||
|
|
||||||
export interface SBObject {
|
export interface SBObject {
|
||||||
configListeners: Array<(changes: StorageChangesObject) => unknown>;
|
configSyncListeners: Array<(changes: StorageChangesObject) => unknown>;
|
||||||
defaults: SBConfig;
|
defaults: SBConfig;
|
||||||
localConfig: SBConfig;
|
cachedSyncConfig: SBConfig;
|
||||||
|
cachedLocalStorage: SBStorage;
|
||||||
config: SBConfig;
|
config: SBConfig;
|
||||||
|
local: SBStorage;
|
||||||
forceUpdate(prop: string): void;
|
forceUpdate(prop: string): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,7 +113,7 @@ const Config: SBObject = {
|
|||||||
/**
|
/**
|
||||||
* Callback function when an option is updated
|
* Callback function when an option is updated
|
||||||
*/
|
*/
|
||||||
configListeners: [],
|
configSyncListeners: [],
|
||||||
defaults: {
|
defaults: {
|
||||||
userID: null,
|
userID: null,
|
||||||
isVip: false,
|
isVip: false,
|
||||||
@@ -270,27 +275,35 @@ const Config: SBObject = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
localConfig: null,
|
cachedSyncConfig: null,
|
||||||
|
cachedLocalStorage: null,
|
||||||
config: null,
|
config: null,
|
||||||
|
local: null,
|
||||||
forceUpdate
|
forceUpdate
|
||||||
};
|
};
|
||||||
|
|
||||||
// Function setup
|
// Function setup
|
||||||
|
|
||||||
function configProxy(): SBConfig {
|
function configProxy(): { sync: SBConfig, local: SBStorage } {
|
||||||
chrome.storage.onChanged.addListener((changes: {[key: string]: chrome.storage.StorageChange}) => {
|
chrome.storage.onChanged.addListener((changes: {[key: string]: chrome.storage.StorageChange}, areaName) => {
|
||||||
for (const key in changes) {
|
if (areaName === "sync") {
|
||||||
Config.localConfig[key] = changes[key].newValue;
|
for (const key in changes) {
|
||||||
}
|
Config.cachedSyncConfig[key] = changes[key].newValue;
|
||||||
|
}
|
||||||
for (const callback of Config.configListeners) {
|
|
||||||
callback(changes);
|
for (const callback of Config.configSyncListeners) {
|
||||||
|
callback(changes);
|
||||||
|
}
|
||||||
|
} else if (areaName === "local") {
|
||||||
|
for (const key in changes) {
|
||||||
|
Config.cachedLocalStorage[key] = changes[key].newValue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const handler: ProxyHandler<SBConfig> = {
|
const syncHandler: ProxyHandler<SBConfig> = {
|
||||||
set<K extends keyof SBConfig>(obj: SBConfig, prop: K, value: SBConfig[K]) {
|
set<K extends keyof SBConfig>(obj: SBConfig, prop: K, value: SBConfig[K]) {
|
||||||
Config.localConfig[prop] = value;
|
Config.cachedSyncConfig[prop] = value;
|
||||||
|
|
||||||
chrome.storage.sync.set({
|
chrome.storage.sync.set({
|
||||||
[prop]: value
|
[prop]: value
|
||||||
@@ -300,7 +313,7 @@ function configProxy(): SBConfig {
|
|||||||
},
|
},
|
||||||
|
|
||||||
get<K extends keyof SBConfig>(obj: SBConfig, prop: K): SBConfig[K] {
|
get<K extends keyof SBConfig>(obj: SBConfig, prop: K): SBConfig[K] {
|
||||||
const data = Config.localConfig[prop];
|
const data = Config.cachedSyncConfig[prop];
|
||||||
|
|
||||||
return obj[prop] || data;
|
return obj[prop] || data;
|
||||||
},
|
},
|
||||||
@@ -313,25 +326,53 @@ function configProxy(): SBConfig {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return new Proxy<SBConfig>({handler} as unknown as SBConfig, handler);
|
const localHandler: ProxyHandler<SBStorage> = {
|
||||||
|
set<K extends keyof SBStorage>(obj: SBStorage, prop: K, value: SBStorage[K]) {
|
||||||
|
Config.cachedLocalStorage[prop] = value;
|
||||||
|
|
||||||
|
chrome.storage.local.set({
|
||||||
|
[prop]: value
|
||||||
|
});
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
get<K extends keyof SBStorage>(obj: SBStorage, prop: K): SBStorage[K] {
|
||||||
|
const data = Config.cachedLocalStorage[prop];
|
||||||
|
|
||||||
|
return obj[prop] || data;
|
||||||
|
},
|
||||||
|
|
||||||
|
deleteProperty(obj: SBConfig, prop: keyof SBStorage) {
|
||||||
|
chrome.storage.local.remove(<string> prop);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
sync: new Proxy<SBConfig>({handler: syncHandler} as unknown as SBConfig, syncHandler),
|
||||||
|
local: new Proxy<SBStorage>({handler: localHandler} as unknown as SBConfig, localHandler)
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function forceUpdate(prop: string): void {
|
function forceUpdate(prop: string): void {
|
||||||
chrome.storage.sync.set({
|
chrome.storage.sync.set({
|
||||||
[prop]: Config.localConfig[prop]
|
[prop]: Config.cachedSyncConfig[prop]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function fetchConfig(): Promise<void> {
|
function fetchConfig(): Promise<void> {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
chrome.storage.sync.get(null, function(items) {
|
chrome.storage.sync.get(null, function(items) {
|
||||||
Config.localConfig = <SBConfig> <unknown> items; // Data is ready
|
Config.cachedSyncConfig = <SBConfig> <unknown> items; // Data is ready
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function migrateOldFormats(config: SBConfig) {
|
function migrateOldSyncFormats(config: SBConfig) {
|
||||||
if (config["segmentTimes"]) {
|
if (config["segmentTimes"]) {
|
||||||
for (const item of config["segmentTimes"]) {
|
for (const item of config["segmentTimes"]) {
|
||||||
config.unsubmittedSegments[item[0]] = item[1];
|
config.unsubmittedSegments[item[0]] = item[1];
|
||||||
@@ -428,20 +469,21 @@ async function setupConfig() {
|
|||||||
await fetchConfig();
|
await fetchConfig();
|
||||||
addDefaults();
|
addDefaults();
|
||||||
const config = configProxy();
|
const config = configProxy();
|
||||||
migrateOldFormats(config);
|
migrateOldSyncFormats(config.sync);
|
||||||
|
|
||||||
Config.config = config;
|
Config.config = config.sync;
|
||||||
|
Config.local = config.local;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add defaults
|
// Add defaults
|
||||||
function addDefaults() {
|
function addDefaults() {
|
||||||
for (const key in Config.defaults) {
|
for (const key in Config.defaults) {
|
||||||
if(!Object.prototype.hasOwnProperty.call(Config.localConfig, key)) {
|
if(!Object.prototype.hasOwnProperty.call(Config.cachedSyncConfig, key)) {
|
||||||
Config.localConfig[key] = Config.defaults[key];
|
Config.cachedSyncConfig[key] = Config.defaults[key];
|
||||||
} else if (key === "barTypes") {
|
} else if (key === "barTypes") {
|
||||||
for (const key2 in Config.defaults[key]) {
|
for (const key2 in Config.defaults[key]) {
|
||||||
if(!Object.prototype.hasOwnProperty.call(Config.localConfig[key], key2)) {
|
if(!Object.prototype.hasOwnProperty.call(Config.cachedSyncConfig[key], key2)) {
|
||||||
Config.localConfig[key][key2] = Config.defaults[key][key2];
|
Config.cachedSyncConfig[key][key2] = Config.defaults[key][key2];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -227,8 +227,8 @@ function contentConfigUpdateListener(changes: StorageChangesObject) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Config.configListeners.includes(contentConfigUpdateListener)) {
|
if (!Config.configSyncListeners.includes(contentConfigUpdateListener)) {
|
||||||
Config.configListeners.push(contentConfigUpdateListener);
|
Config.configSyncListeners.push(contentConfigUpdateListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
function resetValues() {
|
function resetValues() {
|
||||||
|
|||||||
@@ -44,8 +44,8 @@ async function init() {
|
|||||||
createStickyHeader();
|
createStickyHeader();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Config.configListeners.includes(optionsConfigUpdateListener)) {
|
if (!Config.configSyncListeners.includes(optionsConfigUpdateListener)) {
|
||||||
Config.configListeners.push(optionsConfigUpdateListener);
|
Config.configSyncListeners.push(optionsConfigUpdateListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
await utils.wait(() => Config.config !== null);
|
await utils.wait(() => Config.config !== null);
|
||||||
@@ -499,7 +499,7 @@ function activatePrivateTextChange(element: HTMLElement) {
|
|||||||
// See if anything extra must be done
|
// See if anything extra must be done
|
||||||
switch (option) {
|
switch (option) {
|
||||||
case "*": {
|
case "*": {
|
||||||
result = JSON.stringify(Config.localConfig);
|
result = JSON.stringify(Config.cachedSyncConfig);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -579,7 +579,7 @@ async function setTextOption(option: string, element: HTMLElement, value: string
|
|||||||
|
|
||||||
function downloadConfig() {
|
function downloadConfig() {
|
||||||
const file = document.createElement("a");
|
const file = document.createElement("a");
|
||||||
const jsonData = JSON.parse(JSON.stringify(Config.localConfig));
|
const jsonData = JSON.parse(JSON.stringify(Config.cachedSyncConfig));
|
||||||
file.setAttribute("href", "data:text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(jsonData)));
|
file.setAttribute("href", "data:text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(jsonData)));
|
||||||
file.setAttribute("download", "SponsorBlockConfig.json");
|
file.setAttribute("download", "SponsorBlockConfig.json");
|
||||||
document.body.append(file);
|
document.body.append(file);
|
||||||
@@ -633,7 +633,7 @@ function copyDebugOutputToClipboard() {
|
|||||||
language: navigator.language,
|
language: navigator.language,
|
||||||
extensionVersion: chrome.runtime.getManifest().version
|
extensionVersion: chrome.runtime.getManifest().version
|
||||||
},
|
},
|
||||||
config: JSON.parse(JSON.stringify(Config.localConfig)) // Deep clone config object
|
config: JSON.parse(JSON.stringify(Config.cachedSyncConfig)) // Deep clone config object
|
||||||
};
|
};
|
||||||
|
|
||||||
// Sanitise sensitive user config values
|
// Sanitise sensitive user config values
|
||||||
|
|||||||
@@ -360,8 +360,8 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> {
|
|||||||
|
|
||||||
// Perform a second update after the config changes take effect as a workaround for a race condition
|
// Perform a second update after the config changes take effect as a workaround for a race condition
|
||||||
const removeListener = (listener: typeof lateUpdate) => {
|
const removeListener = (listener: typeof lateUpdate) => {
|
||||||
const index = Config.configListeners.indexOf(listener);
|
const index = Config.configSyncListeners.indexOf(listener);
|
||||||
if (index !== -1) Config.configListeners.splice(index, 1);
|
if (index !== -1) Config.configSyncListeners.splice(index, 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
const lateUpdate = () => {
|
const lateUpdate = () => {
|
||||||
@@ -369,7 +369,7 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> {
|
|||||||
removeListener(lateUpdate);
|
removeListener(lateUpdate);
|
||||||
};
|
};
|
||||||
|
|
||||||
Config.configListeners.push(lateUpdate);
|
Config.configSyncListeners.push(lateUpdate);
|
||||||
|
|
||||||
// Remove the listener after 200ms in case the changes were propagated by the time we got the response
|
// Remove the listener after 200ms in case the changes were propagated by the time we got the response
|
||||||
setTimeout(() => removeListener(lateUpdate), 200);
|
setTimeout(() => removeListener(lateUpdate), 200);
|
||||||
|
|||||||
Reference in New Issue
Block a user