mirror of
https://github.com/ajayyy/SponsorBlock.git
synced 2024-11-10 01:01:55 +01:00
Move unsubmitted segments to local storage to remove limits
Also add a way to export local storage Fixes #1933
This commit is contained in:
parent
58d5036363
commit
8e366b1450
13 changed files with 109 additions and 59 deletions
|
@ -1 +1 @@
|
||||||
Subproject commit 04699c3634f2dc0661db8c87afe5c6882ddd28fc
|
Subproject commit 69d771d0f3b96951c970a9eacb046b808907bb1c
|
|
@ -1 +1 @@
|
||||||
Subproject commit 0c9f99989481a29522dcd338e821295f15eeb136
|
Subproject commit 7f2d4e63dc53facfeed96aae1086c2bc3329b519
|
|
@ -512,6 +512,31 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div data-type="private-text-change" data-sync-type="local" data-sync="*" data-confirm-message="exportOptionsWarning">
|
||||||
|
<h2>__MSG_exportOtherData__</h2>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<div class="option-button trigger-button inline">
|
||||||
|
__MSG_exportOptionsCopy__
|
||||||
|
</div>
|
||||||
|
<div class="option-button download-button inline">
|
||||||
|
__MSG_exportOptionsDownload__
|
||||||
|
</div>
|
||||||
|
<label for="importLocalOptions" class="option-button inline">
|
||||||
|
__MSG_exportOptionsUpload__
|
||||||
|
</label>
|
||||||
|
<input id="importLocalOptions" type="file" class="upload-button hidden" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="option-hidden-section hidden spacing indent">
|
||||||
|
<textarea class="option-text-box" rows="10" style="width:80%"></textarea>
|
||||||
|
|
||||||
|
<div class="option-button text-change-set">
|
||||||
|
__MSG_setOptions__
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div data-type="button-press" data-sync="resetToDefault" data-confirm-message="confirmResetToDefault">
|
<div data-type="button-press" data-sync="resetToDefault" data-confirm-message="confirmResetToDefault">
|
||||||
<div class="option-button trigger-button">
|
<div class="option-button trigger-button">
|
||||||
__MSG_resetToDefault__
|
__MSG_resetToDefault__
|
||||||
|
|
|
@ -563,9 +563,9 @@ class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeSta
|
||||||
source: SponsorSourceType.Local
|
source: SponsorSourceType.Local
|
||||||
};
|
};
|
||||||
|
|
||||||
const segmentTimes = Config.config.unsubmittedSegments[sponsorVideoID] || [];
|
const segmentTimes = Config.local.unsubmittedSegments[sponsorVideoID] || [];
|
||||||
segmentTimes.push(sponsorTimesSubmitting);
|
segmentTimes.push(sponsorTimesSubmitting);
|
||||||
Config.config.unsubmittedSegments[sponsorVideoID] = segmentTimes;
|
Config.local.unsubmittedSegments[sponsorVideoID] = segmentTimes;
|
||||||
Config.forceSyncUpdate("unsubmittedSegments");
|
Config.forceSyncUpdate("unsubmittedSegments");
|
||||||
|
|
||||||
this.props.contentContainer().sponsorTimesSubmitting.push(sponsorTimesSubmitting);
|
this.props.contentContainer().sponsorTimesSubmitting.push(sponsorTimesSubmitting);
|
||||||
|
|
|
@ -636,7 +636,7 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
|
||||||
const description = actionType === ActionType.Chapter ? this.descriptionOptionRef?.current?.value : "";
|
const description = actionType === ActionType.Chapter ? this.descriptionOptionRef?.current?.value : "";
|
||||||
sponsorTimesSubmitting[this.props.index].description = description;
|
sponsorTimesSubmitting[this.props.index].description = description;
|
||||||
|
|
||||||
Config.config.unsubmittedSegments[this.props.contentContainer().sponsorVideoID] = sponsorTimesSubmitting;
|
Config.local.unsubmittedSegments[this.props.contentContainer().sponsorVideoID] = sponsorTimesSubmitting;
|
||||||
Config.forceSyncUpdate("unsubmittedSegments");
|
Config.forceSyncUpdate("unsubmittedSegments");
|
||||||
|
|
||||||
this.props.contentContainer().updatePreviewBar();
|
this.props.contentContainer().updatePreviewBar();
|
||||||
|
@ -687,9 +687,9 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
|
||||||
|
|
||||||
//save this
|
//save this
|
||||||
if (sponsorTimes.length > 0) {
|
if (sponsorTimes.length > 0) {
|
||||||
Config.config.unsubmittedSegments[this.props.contentContainer().sponsorVideoID] = sponsorTimes;
|
Config.local.unsubmittedSegments[this.props.contentContainer().sponsorVideoID] = sponsorTimes;
|
||||||
} else {
|
} else {
|
||||||
delete Config.config.unsubmittedSegments[this.props.contentContainer().sponsorVideoID];
|
delete Config.local.unsubmittedSegments[this.props.contentContainer().sponsorVideoID];
|
||||||
}
|
}
|
||||||
Config.forceSyncUpdate("unsubmittedSegments");
|
Config.forceSyncUpdate("unsubmittedSegments");
|
||||||
|
|
||||||
|
|
|
@ -237,7 +237,7 @@ class SubmissionNoticeComponent extends React.Component<SubmissionNoticeProps, S
|
||||||
let sponsorTimesSubmitting = this.props.contentContainer().sponsorTimesSubmitting;
|
let sponsorTimesSubmitting = this.props.contentContainer().sponsorTimesSubmitting;
|
||||||
sponsorTimesSubmitting = sponsorTimesSubmitting.sort((a, b) => a.segment[0] - b.segment[0]);
|
sponsorTimesSubmitting = sponsorTimesSubmitting.sort((a, b) => a.segment[0] - b.segment[0]);
|
||||||
|
|
||||||
Config.config.unsubmittedSegments[this.props.contentContainer().sponsorVideoID] = sponsorTimesSubmitting;
|
Config.local.unsubmittedSegments[this.props.contentContainer().sponsorVideoID] = sponsorTimesSubmitting;
|
||||||
Config.forceSyncUpdate("unsubmittedSegments");
|
Config.forceSyncUpdate("unsubmittedSegments");
|
||||||
|
|
||||||
this.forceUpdate();
|
this.forceUpdate();
|
||||||
|
|
|
@ -24,7 +24,7 @@ class UnsubmittedVideoListComponent extends React.Component<UnsubmittedVideoList
|
||||||
|
|
||||||
render(): React.ReactElement {
|
render(): React.ReactElement {
|
||||||
// Render nothing if there are no unsubmitted segments
|
// Render nothing if there are no unsubmitted segments
|
||||||
if (Object.keys(Config.config.unsubmittedSegments).length == 0)
|
if (Object.keys(Config.local.unsubmittedSegments).length == 0)
|
||||||
return <></>;
|
return <></>;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -58,7 +58,7 @@ class UnsubmittedVideoListComponent extends React.Component<UnsubmittedVideoList
|
||||||
getUnsubmittedVideos(): JSX.Element[] {
|
getUnsubmittedVideos(): JSX.Element[] {
|
||||||
const elements: JSX.Element[] = [];
|
const elements: JSX.Element[] = [];
|
||||||
|
|
||||||
for (const videoID of Object.keys(Config.config.unsubmittedSegments)) {
|
for (const videoID of Object.keys(Config.local.unsubmittedSegments)) {
|
||||||
elements.push(
|
elements.push(
|
||||||
<UnsubmittedVideoListItem videoID={videoID} key={videoID}>
|
<UnsubmittedVideoListItem videoID={videoID} key={videoID}>
|
||||||
</UnsubmittedVideoListItem>
|
</UnsubmittedVideoListItem>
|
||||||
|
|
|
@ -23,7 +23,7 @@ class UnsubmittedVideoListItem extends React.Component<UnsubmittedVideosListItem
|
||||||
}
|
}
|
||||||
|
|
||||||
render(): React.ReactElement {
|
render(): React.ReactElement {
|
||||||
const segmentCount = Config.config.unsubmittedSegments[this.props.videoID]?.length ?? 0;
|
const segmentCount = Config.local.unsubmittedSegments[this.props.videoID]?.length ?? 0;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -69,17 +69,17 @@ class UnsubmittedVideoListItem extends React.Component<UnsubmittedVideosListItem
|
||||||
|
|
||||||
clearSegments(): void {
|
clearSegments(): void {
|
||||||
if (confirm(chrome.i18n.getMessage("clearThis"))) {
|
if (confirm(chrome.i18n.getMessage("clearThis"))) {
|
||||||
delete Config.config.unsubmittedSegments[this.props.videoID];
|
delete Config.local.unsubmittedSegments[this.props.videoID];
|
||||||
Config.forceSyncUpdate("unsubmittedSegments");
|
Config.forceSyncUpdate("unsubmittedSegments");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exportSegments(): void {
|
exportSegments(): void {
|
||||||
this.copyToClipboard(exportTimes(Config.config.unsubmittedSegments[this.props.videoID]));
|
this.copyToClipboard(exportTimes(Config.local.unsubmittedSegments[this.props.videoID]));
|
||||||
}
|
}
|
||||||
|
|
||||||
exportSegmentsAsURL(): void {
|
exportSegmentsAsURL(): void {
|
||||||
this.copyToClipboard(`https://youtube.com/watch?v=${this.props.videoID}${exportTimesAsHashParam(Config.config.unsubmittedSegments[this.props.videoID])}`)
|
this.copyToClipboard(`https://youtube.com/watch?v=${this.props.videoID}${exportTimesAsHashParam(Config.local.unsubmittedSegments[this.props.videoID])}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
copyToClipboard(text: string): void {
|
copyToClipboard(text: string): void {
|
||||||
|
|
|
@ -21,8 +21,8 @@ class UnsubmittedVideosComponent extends React.Component<UnsubmittedVideosProps,
|
||||||
}
|
}
|
||||||
|
|
||||||
render(): React.ReactElement {
|
render(): React.ReactElement {
|
||||||
const videoCount = Object.keys(Config.config.unsubmittedSegments).length;
|
const videoCount = Object.keys(Config.local.unsubmittedSegments).length;
|
||||||
const segmentCount = Object.values(Config.config.unsubmittedSegments).reduce((acc: number, vid: Array<unknown>) => acc + vid.length, 0);
|
const segmentCount = Object.values(Config.local.unsubmittedSegments).reduce((acc: number, vid: Array<unknown>) => acc + vid.length, 0);
|
||||||
|
|
||||||
return <>
|
return <>
|
||||||
<div style={{marginBottom: "10px"}}>
|
<div style={{marginBottom: "10px"}}>
|
||||||
|
@ -48,7 +48,7 @@ class UnsubmittedVideosComponent extends React.Component<UnsubmittedVideosProps,
|
||||||
|
|
||||||
clearAllSegments(): void {
|
clearAllSegments(): void {
|
||||||
if (confirm(chrome.i18n.getMessage("clearUnsubmittedSegmentsConfirm")))
|
if (confirm(chrome.i18n.getMessage("clearUnsubmittedSegmentsConfirm")))
|
||||||
Config.config.unsubmittedSegments = {};
|
Config.local.unsubmittedSegments = {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,8 +12,6 @@ interface SBConfig {
|
||||||
userID: string;
|
userID: string;
|
||||||
isVip: boolean;
|
isVip: boolean;
|
||||||
permissions: Record<Category, Permission>;
|
permissions: Record<Category, Permission>;
|
||||||
/* Contains unsubmitted segments that the user has created. */
|
|
||||||
unsubmittedSegments: Record<string, SponsorTime[]>;
|
|
||||||
defaultCategory: Category;
|
defaultCategory: Category;
|
||||||
renderSegmentsAsChapters: boolean;
|
renderSegmentsAsChapters: boolean;
|
||||||
whitelistedChannels: string[];
|
whitelistedChannels: string[];
|
||||||
|
@ -142,6 +140,9 @@ interface SBStorage {
|
||||||
|
|
||||||
// Used when sync storage disbaled
|
// Used when sync storage disbaled
|
||||||
alreadyInstalled: boolean;
|
alreadyInstalled: boolean;
|
||||||
|
|
||||||
|
/* Contains unsubmitted segments that the user has created. */
|
||||||
|
unsubmittedSegments: Record<string, SponsorTime[]>;
|
||||||
}
|
}
|
||||||
|
|
||||||
class ConfigClass extends ProtoConfig<SBConfig, SBStorage> {
|
class ConfigClass extends ProtoConfig<SBConfig, SBStorage> {
|
||||||
|
@ -153,6 +154,10 @@ class ConfigClass extends ProtoConfig<SBConfig, SBStorage> {
|
||||||
skipCount: this.config.skipCount,
|
skipCount: this.config.skipCount,
|
||||||
sponsorTimesContributed: this.config.sponsorTimesContributed
|
sponsorTimesContributed: this.config.sponsorTimesContributed
|
||||||
});
|
});
|
||||||
|
|
||||||
|
chrome.storage.local.set({
|
||||||
|
...this.localDefaults,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,6 +166,14 @@ function migrateOldSyncFormats(config: SBConfig) {
|
||||||
chrome.storage.sync.remove("showZoomToFillError");
|
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"]) {
|
if (!config["chapterCategoryAdded"]) {
|
||||||
config["chapterCategoryAdded"] = true;
|
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) {
|
if (config["exclusive_accessCategoryAdded"] !== undefined) {
|
||||||
chrome.storage.sync.remove("exclusive_accessCategoryAdded");
|
chrome.storage.sync.remove("exclusive_accessCategoryAdded");
|
||||||
}
|
}
|
||||||
|
@ -268,7 +272,6 @@ const syncDefaults = {
|
||||||
userID: null,
|
userID: null,
|
||||||
isVip: false,
|
isVip: false,
|
||||||
permissions: {},
|
permissions: {},
|
||||||
unsubmittedSegments: {},
|
|
||||||
defaultCategory: "chooseACategory" as Category,
|
defaultCategory: "chooseACategory" as Category,
|
||||||
renderSegmentsAsChapters: false,
|
renderSegmentsAsChapters: false,
|
||||||
whitelistedChannels: [],
|
whitelistedChannels: [],
|
||||||
|
@ -464,7 +467,9 @@ const syncDefaults = {
|
||||||
const localDefaults = {
|
const localDefaults = {
|
||||||
downvotedSegments: {},
|
downvotedSegments: {},
|
||||||
navigationApiAvailable: null,
|
navigationApiAvailable: null,
|
||||||
alreadyInstalled: false
|
alreadyInstalled: false,
|
||||||
|
|
||||||
|
unsubmittedSegments: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
const Config = new ConfigClass(syncDefaults, localDefaults, migrateOldSyncFormats);
|
const Config = new ConfigClass(syncDefaults, localDefaults, migrateOldSyncFormats);
|
||||||
|
|
|
@ -307,7 +307,7 @@ function messageListener(request: Message, sender: unknown, sendResponse: (respo
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addedSegments) {
|
if (addedSegments) {
|
||||||
Config.config.unsubmittedSegments[getVideoID()] = sponsorTimesSubmitting;
|
Config.local.unsubmittedSegments[getVideoID()] = sponsorTimesSubmitting;
|
||||||
Config.forceSyncUpdate("unsubmittedSegments");
|
Config.forceSyncUpdate("unsubmittedSegments");
|
||||||
|
|
||||||
updateEditButtonsOnPlayer();
|
updateEditButtonsOnPlayer();
|
||||||
|
@ -1925,7 +1925,7 @@ function startOrEndTimingNewSegment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save the newly created segment
|
// Save the newly created segment
|
||||||
Config.config.unsubmittedSegments[getVideoID()] = sponsorTimesSubmitting;
|
Config.local.unsubmittedSegments[getVideoID()] = sponsorTimesSubmitting;
|
||||||
Config.forceSyncUpdate("unsubmittedSegments");
|
Config.forceSyncUpdate("unsubmittedSegments");
|
||||||
|
|
||||||
// Make sure they know if someone has already submitted something it while they were watching
|
// Make sure they know if someone has already submitted something it while they were watching
|
||||||
|
@ -1958,11 +1958,11 @@ function cancelCreatingSegment() {
|
||||||
if (isSegmentCreationInProgress()) {
|
if (isSegmentCreationInProgress()) {
|
||||||
if (sponsorTimesSubmitting.length > 1) { // If there's more than one segment: remove last
|
if (sponsorTimesSubmitting.length > 1) { // If there's more than one segment: remove last
|
||||||
sponsorTimesSubmitting.pop();
|
sponsorTimesSubmitting.pop();
|
||||||
Config.config.unsubmittedSegments[getVideoID()] = sponsorTimesSubmitting;
|
Config.local.unsubmittedSegments[getVideoID()] = sponsorTimesSubmitting;
|
||||||
} else { // Otherwise delete the video entry & close submission menu
|
} else { // Otherwise delete the video entry & close submission menu
|
||||||
resetSponsorSubmissionNotice();
|
resetSponsorSubmissionNotice();
|
||||||
sponsorTimesSubmitting = [];
|
sponsorTimesSubmitting = [];
|
||||||
delete Config.config.unsubmittedSegments[getVideoID()];
|
delete Config.local.unsubmittedSegments[getVideoID()];
|
||||||
}
|
}
|
||||||
Config.forceSyncUpdate("unsubmittedSegments");
|
Config.forceSyncUpdate("unsubmittedSegments");
|
||||||
}
|
}
|
||||||
|
@ -1972,7 +1972,7 @@ function cancelCreatingSegment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateSponsorTimesSubmitting(getFromConfig = true) {
|
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
|
//see if this data should be saved in the sponsorTimesSubmitting variable
|
||||||
if (getFromConfig && segmentTimes != undefined) {
|
if (getFromConfig && segmentTimes != undefined) {
|
||||||
|
@ -2102,7 +2102,7 @@ function closeInfoMenu() {
|
||||||
function clearSponsorTimes() {
|
function clearSponsorTimes() {
|
||||||
const currentVideoID = getVideoID();
|
const currentVideoID = getVideoID();
|
||||||
|
|
||||||
const sponsorTimes = Config.config.unsubmittedSegments[currentVideoID];
|
const sponsorTimes = Config.local.unsubmittedSegments[currentVideoID];
|
||||||
|
|
||||||
if (sponsorTimes != undefined && sponsorTimes.length > 0) {
|
if (sponsorTimes != undefined && sponsorTimes.length > 0) {
|
||||||
const confirmMessage = chrome.i18n.getMessage("clearThis") + getSegmentsMessage(sponsorTimes)
|
const confirmMessage = chrome.i18n.getMessage("clearThis") + getSegmentsMessage(sponsorTimes)
|
||||||
|
@ -2112,7 +2112,7 @@ function clearSponsorTimes() {
|
||||||
resetSponsorSubmissionNotice();
|
resetSponsorSubmissionNotice();
|
||||||
|
|
||||||
//clear the sponsor times
|
//clear the sponsor times
|
||||||
delete Config.config.unsubmittedSegments[currentVideoID];
|
delete Config.local.unsubmittedSegments[currentVideoID];
|
||||||
Config.forceSyncUpdate("unsubmittedSegments");
|
Config.forceSyncUpdate("unsubmittedSegments");
|
||||||
|
|
||||||
//clear sponsor times submitting
|
//clear sponsor times submitting
|
||||||
|
@ -2276,7 +2276,7 @@ async function sendSubmitMessage() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//update sponsorTimes
|
//update sponsorTimes
|
||||||
Config.config.unsubmittedSegments[getVideoID()] = sponsorTimesSubmitting;
|
Config.local.unsubmittedSegments[getVideoID()] = sponsorTimesSubmitting;
|
||||||
Config.forceSyncUpdate("unsubmittedSegments");
|
Config.forceSyncUpdate("unsubmittedSegments");
|
||||||
|
|
||||||
// Check to see if any of the submissions are below the minimum duration set
|
// Check to see if any of the submissions are below the minimum duration set
|
||||||
|
@ -2304,7 +2304,7 @@ async function sendSubmitMessage() {
|
||||||
stopAnimation();
|
stopAnimation();
|
||||||
|
|
||||||
// Remove segments from storage since they've already been submitted
|
// Remove segments from storage since they've already been submitted
|
||||||
delete Config.config.unsubmittedSegments[getVideoID()];
|
delete Config.local.unsubmittedSegments[getVideoID()];
|
||||||
Config.forceSyncUpdate("unsubmittedSegments");
|
Config.forceSyncUpdate("unsubmittedSegments");
|
||||||
|
|
||||||
const newSegments = sponsorTimesSubmitting;
|
const newSegments = sponsorTimesSubmitting;
|
||||||
|
@ -2610,7 +2610,7 @@ function checkForPreloadedSegment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pushed) {
|
if (pushed) {
|
||||||
Config.config.unsubmittedSegments[getVideoID()] = sponsorTimesSubmitting;
|
Config.local.unsubmittedSegments[getVideoID()] = sponsorTimesSubmitting;
|
||||||
Config.forceSyncUpdate("unsubmittedSegments");
|
Config.forceSyncUpdate("unsubmittedSegments");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,6 +62,10 @@ async function init() {
|
||||||
Config.configSyncListeners.push(optionsConfigUpdateListener);
|
Config.configSyncListeners.push(optionsConfigUpdateListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!Config.configLocalListeners.includes(optionsLocalConfigUpdateListener)) {
|
||||||
|
Config.configLocalListeners.push(optionsLocalConfigUpdateListener);
|
||||||
|
}
|
||||||
|
|
||||||
await utils.wait(() => Config.config !== null);
|
await utils.wait(() => Config.config !== null);
|
||||||
|
|
||||||
if (!Config.config.darkMode) {
|
if (!Config.config.darkMode) {
|
||||||
|
@ -253,10 +257,10 @@ async function init() {
|
||||||
|
|
||||||
if (option == "*") {
|
if (option == "*") {
|
||||||
const downloadButton = optionsElements[i].querySelector(".download-button");
|
const downloadButton = optionsElements[i].querySelector(".download-button");
|
||||||
downloadButton.addEventListener("click", downloadConfig);
|
downloadButton.addEventListener("click", () => downloadConfig(optionsElements[i]));
|
||||||
|
|
||||||
const uploadButton = optionsElements[i].querySelector(".upload-button");
|
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");
|
const privateTextChangeOption = optionsElements[i].getAttribute("data-sync");
|
||||||
|
@ -406,7 +410,11 @@ function optionsConfigUpdateListener(changes: StorageChangesObject) {
|
||||||
for (const chooser of categoryChoosers) {
|
for (const chooser of categoryChoosers) {
|
||||||
chooser.update();
|
chooser.update();
|
||||||
}
|
}
|
||||||
} else if (changes.unsubmittedSegments) {
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function optionsLocalConfigUpdateListener(changes: StorageChangesObject) {
|
||||||
|
if (changes.unsubmittedSegments) {
|
||||||
for (const chooser of unsubmittedVideos) {
|
for (const chooser of unsubmittedVideos) {
|
||||||
chooser.update();
|
chooser.update();
|
||||||
}
|
}
|
||||||
|
@ -540,6 +548,7 @@ function activatePrivateTextChange(element: HTMLElement) {
|
||||||
|
|
||||||
const textBox = <HTMLInputElement> element.querySelector(".option-text-box");
|
const textBox = <HTMLInputElement> element.querySelector(".option-text-box");
|
||||||
const option = element.getAttribute("data-sync");
|
const option = element.getAttribute("data-sync");
|
||||||
|
const optionType = element.getAttribute("data-sync-type");
|
||||||
|
|
||||||
// See if anything extra must be done
|
// See if anything extra must be done
|
||||||
switch (option) {
|
switch (option) {
|
||||||
|
@ -552,7 +561,11 @@ function activatePrivateTextChange(element: HTMLElement) {
|
||||||
// See if anything extra must be done
|
// See if anything extra must be done
|
||||||
switch (option) {
|
switch (option) {
|
||||||
case "*": {
|
case "*": {
|
||||||
|
if (optionType === "local") {
|
||||||
|
result = JSON.stringify(Config.cachedLocalStorage);
|
||||||
|
} else {
|
||||||
result = JSON.stringify(Config.cachedSyncConfig);
|
result = JSON.stringify(Config.cachedSyncConfig);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -595,6 +608,7 @@ function activatePrivateTextChange(element: HTMLElement) {
|
||||||
*/
|
*/
|
||||||
async function setTextOption(option: string, element: HTMLElement, value: string, callbackOnError?: () => void) {
|
async function setTextOption(option: string, element: HTMLElement, value: string, callbackOnError?: () => void) {
|
||||||
const confirmMessage = element.getAttribute("data-confirm-message");
|
const confirmMessage = element.getAttribute("data-confirm-message");
|
||||||
|
const optionType = element.getAttribute("data-sync-type");
|
||||||
|
|
||||||
if (confirmMessage === null || confirm(chrome.i18n.getMessage(confirmMessage))) {
|
if (confirmMessage === null || confirm(chrome.i18n.getMessage(confirmMessage))) {
|
||||||
|
|
||||||
|
@ -604,10 +618,14 @@ async function setTextOption(option: string, element: HTMLElement, value: string
|
||||||
try {
|
try {
|
||||||
const newConfig = JSON.parse(value);
|
const newConfig = JSON.parse(value);
|
||||||
for (const key in newConfig) {
|
for (const key in newConfig) {
|
||||||
|
if (optionType === "local") {
|
||||||
|
Config.local[key] = newConfig[key];
|
||||||
|
} else {
|
||||||
Config.config[key] = newConfig[key];
|
Config.config[key] = newConfig[key];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (newConfig.supportInvidious) {
|
if (optionType !== "local" && newConfig.supportInvidious) {
|
||||||
const checkbox = <HTMLInputElement> document.querySelector("#support-invidious > div > label > input");
|
const checkbox = <HTMLInputElement> document.querySelector("#support-invidious > div > label > input");
|
||||||
|
|
||||||
checkbox.checked = true;
|
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 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, "")
|
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("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);
|
document.body.append(file);
|
||||||
file.click();
|
file.click();
|
||||||
file.remove();
|
file.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
function uploadConfig(e) {
|
function uploadConfig(e: Event, element: HTMLElement) {
|
||||||
if (e.target.files.length == 1) {
|
const target = e.target as HTMLInputElement;
|
||||||
const file = e.target.files[0];
|
if (target.files.length == 1) {
|
||||||
|
const file = target.files[0];
|
||||||
const reader = new FileReader();
|
const reader = new FileReader();
|
||||||
const element = document.querySelector("[data-sync='*']") as HTMLElement;
|
|
||||||
reader.onload = function(ev) {
|
reader.onload = function(ev) {
|
||||||
setTextOption("*", element, ev.target.result as string, () => {
|
setTextOption("*", element, ev.target.result as string, () => {
|
||||||
e.target.value = null;
|
target.value = null;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
reader.readAsText(file);
|
reader.readAsText(file);
|
||||||
|
|
10
src/popup.ts
10
src/popup.ts
|
@ -435,7 +435,7 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> {
|
||||||
}
|
}
|
||||||
|
|
||||||
await utils.wait(() => Config.config !== null, 5000, 10);
|
await utils.wait(() => Config.config !== null, 5000, 10);
|
||||||
sponsorTimes = Config.config.unsubmittedSegments[currentVideoID] ?? [];
|
sponsorTimes = Config.local.unsubmittedSegments[currentVideoID] ?? [];
|
||||||
updateSegmentEditingUI();
|
updateSegmentEditingUI();
|
||||||
|
|
||||||
messageHandler.sendMessage(
|
messageHandler.sendMessage(
|
||||||
|
@ -527,7 +527,7 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> {
|
||||||
function startSponsorCallback(response: SponsorStartResponse) {
|
function startSponsorCallback(response: SponsorStartResponse) {
|
||||||
// Only update the segments after a segment was created
|
// Only update the segments after a segment was created
|
||||||
if (!response.creatingSegment) {
|
if (!response.creatingSegment) {
|
||||||
sponsorTimes = Config.config.unsubmittedSegments[currentVideoID] || [];
|
sponsorTimes = Config.local.unsubmittedSegments[currentVideoID] || [];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the UI
|
// Update the UI
|
||||||
|
@ -769,7 +769,7 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> {
|
||||||
}
|
}
|
||||||
|
|
||||||
function isCreatingSegment(): boolean {
|
function isCreatingSegment(): boolean {
|
||||||
const segments = Config.config.unsubmittedSegments[currentVideoID];
|
const segments = Config.local.unsubmittedSegments[currentVideoID];
|
||||||
if (!segments) return false;
|
if (!segments) return false;
|
||||||
const lastSegment = segments[segments.length - 1];
|
const lastSegment = segments[segments.length - 1];
|
||||||
return lastSegment && lastSegment?.segment?.length !== 2;
|
return lastSegment && lastSegment?.segment?.length !== 2;
|
||||||
|
@ -1094,7 +1094,7 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> {
|
||||||
for (const key in changes) {
|
for (const key in changes) {
|
||||||
switch(key) {
|
switch(key) {
|
||||||
case "unsubmittedSegments":
|
case "unsubmittedSegments":
|
||||||
sponsorTimes = Config.config.unsubmittedSegments[currentVideoID] ?? [];
|
sponsorTimes = Config.local.unsubmittedSegments[currentVideoID] ?? [];
|
||||||
updateSegmentEditingUI();
|
updateSegmentEditingUI();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1144,7 +1144,7 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> {
|
||||||
break;
|
break;
|
||||||
case "videoChanged":
|
case "videoChanged":
|
||||||
currentVideoID = msg.videoID
|
currentVideoID = msg.videoID
|
||||||
sponsorTimes = Config.config.unsubmittedSegments[currentVideoID] ?? [];
|
sponsorTimes = Config.local.unsubmittedSegments[currentVideoID] ?? [];
|
||||||
updateSegmentEditingUI();
|
updateSegmentEditingUI();
|
||||||
|
|
||||||
if (msg.whitelisted) {
|
if (msg.whitelisted) {
|
||||||
|
|
Loading…
Reference in a new issue