) => acc + vid.length, 0);
return <>
@@ -48,7 +48,7 @@ class UnsubmittedVideosComponent extends React.Component;
- /* Contains unsubmitted segments that the user has created. */
- unsubmittedSegments: Record;
defaultCategory: Category;
renderSegmentsAsChapters: boolean;
whitelistedChannels: string[];
@@ -142,6 +140,9 @@ interface SBStorage {
// Used when sync storage disbaled
alreadyInstalled: boolean;
+
+ /* Contains unsubmitted segments that the user has created. */
+ unsubmittedSegments: Record;
}
class ConfigClass extends ProtoConfig {
@@ -153,6 +154,10 @@ class ConfigClass extends ProtoConfig {
skipCount: this.config.skipCount,
sponsorTimesContributed: this.config.sponsorTimesContributed
});
+
+ chrome.storage.local.set({
+ ...this.localDefaults,
+ });
}
}
@@ -161,6 +166,14 @@ function migrateOldSyncFormats(config: SBConfig) {
chrome.storage.sync.remove("showZoomToFillError");
}
+ if (config["unsubmittedSegments"] && Object.keys(config["unsubmittedSegments"]).length > 0) {
+ chrome.storage.local.set({
+ unsubmittedSegments: config["unsubmittedSegments"]
+ }, () => {
+ chrome.storage.sync.remove("unsubmittedSegments");
+ });
+ }
+
if (!config["chapterCategoryAdded"]) {
config["chapterCategoryAdded"] = true;
@@ -174,15 +187,6 @@ function migrateOldSyncFormats(config: SBConfig) {
}
}
- if (config["segmentTimes"]) {
- const unsubmittedSegments = {};
- for (const item of config["segmentTimes"]) {
- unsubmittedSegments[item[0]] = item[1];
- }
-
- chrome.storage.sync.remove("segmentTimes", () => config.unsubmittedSegments = unsubmittedSegments);
- }
-
if (config["exclusive_accessCategoryAdded"] !== undefined) {
chrome.storage.sync.remove("exclusive_accessCategoryAdded");
}
@@ -268,7 +272,6 @@ const syncDefaults = {
userID: null,
isVip: false,
permissions: {},
- unsubmittedSegments: {},
defaultCategory: "chooseACategory" as Category,
renderSegmentsAsChapters: false,
whitelistedChannels: [],
@@ -464,7 +467,9 @@ const syncDefaults = {
const localDefaults = {
downvotedSegments: {},
navigationApiAvailable: null,
- alreadyInstalled: false
+ alreadyInstalled: false,
+
+ unsubmittedSegments: {}
};
const Config = new ConfigClass(syncDefaults, localDefaults, migrateOldSyncFormats);
diff --git a/src/content.ts b/src/content.ts
index bda3b4b7..76201831 100644
--- a/src/content.ts
+++ b/src/content.ts
@@ -307,7 +307,7 @@ function messageListener(request: Message, sender: unknown, sendResponse: (respo
}
if (addedSegments) {
- Config.config.unsubmittedSegments[getVideoID()] = sponsorTimesSubmitting;
+ Config.local.unsubmittedSegments[getVideoID()] = sponsorTimesSubmitting;
Config.forceSyncUpdate("unsubmittedSegments");
updateEditButtonsOnPlayer();
@@ -1925,7 +1925,7 @@ function startOrEndTimingNewSegment() {
}
// Save the newly created segment
- Config.config.unsubmittedSegments[getVideoID()] = sponsorTimesSubmitting;
+ Config.local.unsubmittedSegments[getVideoID()] = sponsorTimesSubmitting;
Config.forceSyncUpdate("unsubmittedSegments");
// Make sure they know if someone has already submitted something it while they were watching
@@ -1958,11 +1958,11 @@ function cancelCreatingSegment() {
if (isSegmentCreationInProgress()) {
if (sponsorTimesSubmitting.length > 1) { // If there's more than one segment: remove last
sponsorTimesSubmitting.pop();
- Config.config.unsubmittedSegments[getVideoID()] = sponsorTimesSubmitting;
+ Config.local.unsubmittedSegments[getVideoID()] = sponsorTimesSubmitting;
} else { // Otherwise delete the video entry & close submission menu
resetSponsorSubmissionNotice();
sponsorTimesSubmitting = [];
- delete Config.config.unsubmittedSegments[getVideoID()];
+ delete Config.local.unsubmittedSegments[getVideoID()];
}
Config.forceSyncUpdate("unsubmittedSegments");
}
@@ -1972,7 +1972,7 @@ function cancelCreatingSegment() {
}
function updateSponsorTimesSubmitting(getFromConfig = true) {
- const segmentTimes = Config.config.unsubmittedSegments[getVideoID()];
+ const segmentTimes = Config.local.unsubmittedSegments[getVideoID()];
//see if this data should be saved in the sponsorTimesSubmitting variable
if (getFromConfig && segmentTimes != undefined) {
@@ -2102,7 +2102,7 @@ function closeInfoMenu() {
function clearSponsorTimes() {
const currentVideoID = getVideoID();
- const sponsorTimes = Config.config.unsubmittedSegments[currentVideoID];
+ const sponsorTimes = Config.local.unsubmittedSegments[currentVideoID];
if (sponsorTimes != undefined && sponsorTimes.length > 0) {
const confirmMessage = chrome.i18n.getMessage("clearThis") + getSegmentsMessage(sponsorTimes)
@@ -2112,7 +2112,7 @@ function clearSponsorTimes() {
resetSponsorSubmissionNotice();
//clear the sponsor times
- delete Config.config.unsubmittedSegments[currentVideoID];
+ delete Config.local.unsubmittedSegments[currentVideoID];
Config.forceSyncUpdate("unsubmittedSegments");
//clear sponsor times submitting
@@ -2276,7 +2276,7 @@ async function sendSubmitMessage() {
}
//update sponsorTimes
- Config.config.unsubmittedSegments[getVideoID()] = sponsorTimesSubmitting;
+ Config.local.unsubmittedSegments[getVideoID()] = sponsorTimesSubmitting;
Config.forceSyncUpdate("unsubmittedSegments");
// Check to see if any of the submissions are below the minimum duration set
@@ -2304,7 +2304,7 @@ async function sendSubmitMessage() {
stopAnimation();
// Remove segments from storage since they've already been submitted
- delete Config.config.unsubmittedSegments[getVideoID()];
+ delete Config.local.unsubmittedSegments[getVideoID()];
Config.forceSyncUpdate("unsubmittedSegments");
const newSegments = sponsorTimesSubmitting;
@@ -2610,7 +2610,7 @@ function checkForPreloadedSegment() {
}
if (pushed) {
- Config.config.unsubmittedSegments[getVideoID()] = sponsorTimesSubmitting;
+ Config.local.unsubmittedSegments[getVideoID()] = sponsorTimesSubmitting;
Config.forceSyncUpdate("unsubmittedSegments");
}
}
diff --git a/src/options.ts b/src/options.ts
index 6b088538..6e963288 100644
--- a/src/options.ts
+++ b/src/options.ts
@@ -62,6 +62,10 @@ async function init() {
Config.configSyncListeners.push(optionsConfigUpdateListener);
}
+ if (!Config.configLocalListeners.includes(optionsLocalConfigUpdateListener)) {
+ Config.configLocalListeners.push(optionsLocalConfigUpdateListener);
+ }
+
await utils.wait(() => Config.config !== null);
if (!Config.config.darkMode) {
@@ -253,10 +257,10 @@ async function init() {
if (option == "*") {
const downloadButton = optionsElements[i].querySelector(".download-button");
- downloadButton.addEventListener("click", downloadConfig);
+ downloadButton.addEventListener("click", () => downloadConfig(optionsElements[i]));
const uploadButton = optionsElements[i].querySelector(".upload-button");
- uploadButton.addEventListener("change", (e) => uploadConfig(e));
+ uploadButton.addEventListener("change", (e) => uploadConfig(e, optionsElements[i] as HTMLElement));
}
const privateTextChangeOption = optionsElements[i].getAttribute("data-sync");
@@ -406,7 +410,11 @@ function optionsConfigUpdateListener(changes: StorageChangesObject) {
for (const chooser of categoryChoosers) {
chooser.update();
}
- } else if (changes.unsubmittedSegments) {
+ }
+}
+
+function optionsLocalConfigUpdateListener(changes: StorageChangesObject) {
+ if (changes.unsubmittedSegments) {
for (const chooser of unsubmittedVideos) {
chooser.update();
}
@@ -540,6 +548,7 @@ function activatePrivateTextChange(element: HTMLElement) {
const textBox = element.querySelector(".option-text-box");
const option = element.getAttribute("data-sync");
+ const optionType = element.getAttribute("data-sync-type");
// See if anything extra must be done
switch (option) {
@@ -552,7 +561,11 @@ function activatePrivateTextChange(element: HTMLElement) {
// See if anything extra must be done
switch (option) {
case "*": {
- result = JSON.stringify(Config.cachedSyncConfig);
+ if (optionType === "local") {
+ result = JSON.stringify(Config.cachedLocalStorage);
+ } else {
+ result = JSON.stringify(Config.cachedSyncConfig);
+ }
break;
}
}
@@ -595,6 +608,7 @@ function activatePrivateTextChange(element: HTMLElement) {
*/
async function setTextOption(option: string, element: HTMLElement, value: string, callbackOnError?: () => void) {
const confirmMessage = element.getAttribute("data-confirm-message");
+ const optionType = element.getAttribute("data-sync-type");
if (confirmMessage === null || confirm(chrome.i18n.getMessage(confirmMessage))) {
@@ -604,10 +618,14 @@ async function setTextOption(option: string, element: HTMLElement, value: string
try {
const newConfig = JSON.parse(value);
for (const key in newConfig) {
- Config.config[key] = newConfig[key];
+ if (optionType === "local") {
+ Config.local[key] = newConfig[key];
+ } else {
+ Config.config[key] = newConfig[key];
+ }
}
- if (newConfig.supportInvidious) {
+ if (optionType !== "local" && newConfig.supportInvidious) {
const checkbox = document.querySelector("#support-invidious > div > label > input");
checkbox.checked = true;
@@ -630,25 +648,27 @@ async function setTextOption(option: string, element: HTMLElement, value: string
}
}
-function downloadConfig() {
+function downloadConfig(element: Element) {
+ const optionType = element.getAttribute("data-sync-type");
+
const file = document.createElement("a");
- const jsonData = JSON.parse(JSON.stringify(Config.cachedSyncConfig));
+ const jsonData = JSON.parse(JSON.stringify(optionType === "local" ? Config.cachedLocalStorage : Config.cachedSyncConfig));
const dateTimeString = new Date().toJSON().replace("T", "_").replace(/:/g, ".").replace(/.\d+Z/g, "")
file.setAttribute("href", `data:text/json;charset=utf-8,${encodeURIComponent(JSON.stringify(jsonData))}`);
- file.setAttribute("download", `SponsorBlockConfig_${dateTimeString}.json`);
+ file.setAttribute("download", `SponsorBlock${optionType === "local" ? "OtherData" : "Config"}_${dateTimeString}.json`);
document.body.append(file);
file.click();
file.remove();
}
-function uploadConfig(e) {
- if (e.target.files.length == 1) {
- const file = e.target.files[0];
+function uploadConfig(e: Event, element: HTMLElement) {
+ const target = e.target as HTMLInputElement;
+ if (target.files.length == 1) {
+ const file = target.files[0];
const reader = new FileReader();
- const element = document.querySelector("[data-sync='*']") as HTMLElement;
reader.onload = function(ev) {
setTextOption("*", element, ev.target.result as string, () => {
- e.target.value = null;
+ target.value = null;
});
};
reader.readAsText(file);
diff --git a/src/popup.ts b/src/popup.ts
index 562fbfcb..e1e5757f 100644
--- a/src/popup.ts
+++ b/src/popup.ts
@@ -435,7 +435,7 @@ async function runThePopup(messageListener?: MessageListener): Promise {
}
await utils.wait(() => Config.config !== null, 5000, 10);
- sponsorTimes = Config.config.unsubmittedSegments[currentVideoID] ?? [];
+ sponsorTimes = Config.local.unsubmittedSegments[currentVideoID] ?? [];
updateSegmentEditingUI();
messageHandler.sendMessage(
@@ -527,7 +527,7 @@ async function runThePopup(messageListener?: MessageListener): Promise {
function startSponsorCallback(response: SponsorStartResponse) {
// Only update the segments after a segment was created
if (!response.creatingSegment) {
- sponsorTimes = Config.config.unsubmittedSegments[currentVideoID] || [];
+ sponsorTimes = Config.local.unsubmittedSegments[currentVideoID] || [];
}
// Update the UI
@@ -769,7 +769,7 @@ async function runThePopup(messageListener?: MessageListener): Promise {
}
function isCreatingSegment(): boolean {
- const segments = Config.config.unsubmittedSegments[currentVideoID];
+ const segments = Config.local.unsubmittedSegments[currentVideoID];
if (!segments) return false;
const lastSegment = segments[segments.length - 1];
return lastSegment && lastSegment?.segment?.length !== 2;
@@ -1094,7 +1094,7 @@ async function runThePopup(messageListener?: MessageListener): Promise {
for (const key in changes) {
switch(key) {
case "unsubmittedSegments":
- sponsorTimes = Config.config.unsubmittedSegments[currentVideoID] ?? [];
+ sponsorTimes = Config.local.unsubmittedSegments[currentVideoID] ?? [];
updateSegmentEditingUI();
break;
}
@@ -1144,7 +1144,7 @@ async function runThePopup(messageListener?: MessageListener): Promise {
break;
case "videoChanged":
currentVideoID = msg.videoID
- sponsorTimes = Config.config.unsubmittedSegments[currentVideoID] ?? [];
+ sponsorTimes = Config.local.unsubmittedSegments[currentVideoID] ?? [];
updateSegmentEditingUI();
if (msg.whitelisted) {