aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAjay <[email protected]>2022-06-22 13:21:44 -0400
committerAjay <[email protected]>2022-06-22 13:21:44 -0400
commit82b027159e9b02061ee93374ad3b56a3d6bf3ca7 (patch)
tree73b9447002a7908ecfa798d7e58652885c6500e8
parentc6405fc0c11718b26f897e0d837417659df9f3bc (diff)
downloadSponsorBlock-82b027159e9b02061ee93374ad3b56a3d6bf3ca7.tar.gz
SponsorBlock-82b027159e9b02061ee93374ad3b56a3d6bf3ca7.zip
Add UI for importing segments
-rw-r--r--public/_locales/en/messages.json6
-rw-r--r--public/popup.css8
-rw-r--r--public/popup.html22
-rw-r--r--src/content.ts23
-rw-r--r--src/messageTypes.ts14
-rw-r--r--src/popup.ts22
-rw-r--r--src/utils/exporter.ts4
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[] {