diff options
author | Ajay <[email protected]> | 2022-06-22 13:21:44 -0400 |
---|---|---|
committer | Ajay <[email protected]> | 2022-06-22 13:21:44 -0400 |
commit | 82b027159e9b02061ee93374ad3b56a3d6bf3ca7 (patch) | |
tree | 73b9447002a7908ecfa798d7e58652885c6500e8 | |
parent | c6405fc0c11718b26f897e0d837417659df9f3bc (diff) | |
download | SponsorBlock-82b027159e9b02061ee93374ad3b56a3d6bf3ca7.tar.gz SponsorBlock-82b027159e9b02061ee93374ad3b56a3d6bf3ca7.zip |
Add UI for importing segments
-rw-r--r-- | public/_locales/en/messages.json | 6 | ||||
-rw-r--r-- | public/popup.css | 8 | ||||
-rw-r--r-- | public/popup.html | 22 | ||||
-rw-r--r-- | src/content.ts | 23 | ||||
-rw-r--r-- | src/messageTypes.ts | 14 | ||||
-rw-r--r-- | src/popup.ts | 22 | ||||
-rw-r--r-- | src/utils/exporter.ts | 4 |
7 files changed, 86 insertions, 13 deletions
diff --git a/public/_locales/en/messages.json b/public/_locales/en/messages.json index 49c32662..2653f270 100644 --- a/public/_locales/en/messages.json +++ b/public/_locales/en/messages.json @@ -1063,6 +1063,10 @@ "message": "Export segments" }, "importSegments": { - "message": "Import segments" + "message": "Import chapters" + }, + "Import": { + "message": "Import", + "description": "Button to initiate importing segments. Appears under the textbox where they paste in the data" } } diff --git a/public/popup.css b/public/popup.css index 5dd0ec5b..c69ab668 100644 --- a/public/popup.css +++ b/public/popup.css @@ -180,6 +180,14 @@ display: block; } +#importSegmentsText { + margin-top: 7px; +} + +#importSegmentsMenu button { + padding: 10px; +} + /* * <details> wrapper around each segment */ diff --git a/public/popup.html b/public/popup.html index 91b0e0bb..1ded0c27 100644 --- a/public/popup.html +++ b/public/popup.html @@ -45,12 +45,22 @@ </div> <div id="issueReporterTimeButtons"></div> <div id="issueReporterImportExport" class="hidden"> - <button id="importSegmentsButton" title="__MSG_importSegments__"> - <img src="/icons/import.svg" alt="Refresh icon" id="importSegments" /> - </button> - <button id="exportSegmentsButton" title="__MSG_exportSegments__"> - <img src="/icons/export.svg" alt="Export icon" id="exportSegments" /> - </button> + <div id="importExportButtons"> + <button id="importSegmentsButton" title="__MSG_importSegments__"> + <img src="/icons/import.svg" alt="Refresh icon" id="importSegments" /> + </button> + <button id="exportSegmentsButton" title="__MSG_exportSegments__"> + <img src="/icons/export.svg" alt="Export icon" id="exportSegments" /> + </button> + </div> + + <span id="importSegmentsMenu" class="hidden"> + <textarea id="importSegmentsText" rows="5" style="width:80%"></textarea> + + <button id="importSegmentsSubmit" title="__MSG_importSegments__"> + __MSG_Import__ + </button> + </span> </div> </div> </div> diff --git a/src/content.ts b/src/content.ts index b96479b7..340e6ad5 100644 --- a/src/content.ts +++ b/src/content.ts @@ -19,6 +19,7 @@ import { CategoryPill } from "./render/CategoryPill"; import { AnimationUtils } from "./utils/animationUtils"; import { GenericUtils } from "./utils/genericUtils"; import { logDebug } from "./utils/logger"; +import { importTimes } from "./utils/exporter"; // Hack to get the CSS loaded on permission-based sites (Invidious) utils.wait(() => Config.config !== null, 5000, 10).then(addCSS); @@ -231,7 +232,29 @@ function messageListener(request: Message, sender: unknown, sendResponse: (respo case "copyToClipboard": navigator.clipboard.writeText(request.text); break; + case "importSegments": { + const importedSegments = importTimes(request.data, video.duration); + let addedSegments = false; + for (const segment of importedSegments) { + if (!sponsorTimesSubmitting.some((s) => s.segment[0] === segment.segment[0] && s.segment[1] === s.segment[1])) { + sponsorTimesSubmitting.push(segment); + addedSegments = true; + } + } + + if (addedSegments) { + Config.config.unsubmittedSegments[sponsorVideoID] = sponsorTimesSubmitting; + Config.forceSyncUpdate("unsubmittedSegments"); + + updateEditButtonsOnPlayer(); + updateSponsorTimesSubmitting(false); + } + sendResponse({ + importedSegments + }); + break; + } } } diff --git a/src/messageTypes.ts b/src/messageTypes.ts index 3d3575cb..99a10f5e 100644 --- a/src/messageTypes.ts +++ b/src/messageTypes.ts @@ -52,7 +52,12 @@ interface CopyToClipboardMessage { text: string; } -export type Message = BaseMessage & (DefaultMessage | BoolValueMessage | IsInfoFoundMessage | SkipMessage | SubmitVoteMessage | HideSegmentMessage | CopyToClipboardMessage); +interface ImportSegmentsMessage { + message: "importSegments"; + data: string; +} + +export type Message = BaseMessage & (DefaultMessage | BoolValueMessage | IsInfoFoundMessage | SkipMessage | SubmitVoteMessage | HideSegmentMessage | CopyToClipboardMessage | ImportSegmentsMessage); export interface IsInfoFoundMessageResponse { found: boolean; @@ -83,10 +88,15 @@ export type MessageResponse = | SponsorStartResponse | IsChannelWhitelistedResponse | Record<string, never> - | VoteResponse; + | VoteResponse + | ImportSegmentsResponse; export interface VoteResponse { successType: number; statusCode: number; responseText: string; +} + +export interface ImportSegmentsResponse { + importedSegments: SponsorTime[]; }
\ No newline at end of file diff --git a/src/popup.ts b/src/popup.ts index 9c5cafec..b312e110 100644 --- a/src/popup.ts +++ b/src/popup.ts @@ -2,7 +2,7 @@ import Config from "./config"; import Utils from "./utils"; import { SponsorTime, SponsorHideType, ActionType, SegmentUUID, SponsorSourceType } from "./types"; -import { Message, MessageResponse, IsInfoFoundMessageResponse } from "./messageTypes"; +import { Message, MessageResponse, IsInfoFoundMessageResponse, ImportSegmentsResponse } from "./messageTypes"; import { showDonationLink } from "./utils/configUtils"; import { AnimationUtils } from "./utils/animationUtils"; import { GenericUtils } from "./utils/genericUtils"; @@ -143,7 +143,11 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> { "sbCloseButton", "issueReporterImportExport", "importSegmentsButton", - "exportSegmentsButton" + "exportSegmentsButton", + "importSegmentsMenu", + "importSegmentsText", + "importSegmentsSubmit" + ].forEach(id => PageElements[id] = document.getElementById(id)); getSegmentsFromContentScript(false); @@ -174,6 +178,9 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> { } PageElements.exportSegmentsButton.addEventListener("click", exportSegments); + PageElements.importSegmentsButton.addEventListener("click", + () => PageElements.importSegmentsMenu.classList.toggle("hidden")); + PageElements.importSegmentsSubmit.addEventListener("click", importSegments); PageElements.sponsorStart.addEventListener("click", sendSponsorStartMessage); PageElements.whitelistToggle.addEventListener("change", function () { @@ -962,6 +969,17 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> { } } + async function importSegments() { + const text = (PageElements.importSegmentsText as HTMLInputElement).value; + + await sendTabMessage({ + message: "importSegments", + data: text + }) as ImportSegmentsResponse; + + PageElements.importSegmentsMenu.classList.add("hidden"); + } + function exportSegments() { copyToClipboard(exportTimes(downloadedTimes)); diff --git a/src/utils/exporter.ts b/src/utils/exporter.ts index 5de9353c..2620a40f 100644 --- a/src/utils/exporter.ts +++ b/src/utils/exporter.ts @@ -17,9 +17,9 @@ export function exportTimes(segments: SponsorTime[]): string { function exportTime(segment: SponsorTime): string { const name = segment.description || shortCategoryName(segment.category); - return `${GenericUtils.getFormattedTime(segment.segment[0])}${ + return `${GenericUtils.getFormattedTime(segment.segment[0], true)}${ segment.segment[1] && segment.segment[0] !== segment.segment[1] - ? ` - ${GenericUtils.getFormattedTime(segment.segment[1])}` : ""} ${name}`; + ? ` - ${GenericUtils.getFormattedTime(segment.segment[1], true)}` : ""} ${name}`; } export function importTimes(data: string, videoDuration: number): SponsorTime[] { |