mirror of
https://github.com/ajayyy/SponsorBlock.git
synced 2025-12-12 14:37:23 +03:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7a1fa601da | ||
|
|
945ac5aad3 | ||
|
|
617f0e25e8 | ||
|
|
ac52a1cb1d | ||
|
|
2cefb9822b | ||
|
|
b81de96277 | ||
|
|
236c95d2f6 |
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "__MSG_fullName__",
|
||||
"short_name": "SponsorBlock",
|
||||
"version": "5.11.1",
|
||||
"version": "5.11.3",
|
||||
"default_locale": "en",
|
||||
"description": "__MSG_Description__",
|
||||
"homepage_url": "https://sponsor.ajay.app",
|
||||
|
||||
Submodule maze-utils updated: dc162b4e7d...a1e6ea7c60
Submodule public/_locales updated: 1853c78fc2...a45cc387ca
@@ -43,7 +43,7 @@ chrome.runtime.onMessage.addListener(function (request, sender, callback) {
|
||||
chrome.tabs.create({url: chrome.runtime.getURL(request.url)});
|
||||
return false;
|
||||
case "submitVote":
|
||||
submitVote(request.type, request.UUID, request.category).then(callback);
|
||||
submitVote(request.type, request.UUID, request.category, request.videoID).then(callback);
|
||||
|
||||
//this allows the callback to be called later
|
||||
return true;
|
||||
@@ -214,7 +214,7 @@ async function unregisterFirefoxContentScript(id: string) {
|
||||
}
|
||||
}
|
||||
|
||||
async function submitVote(type: number, UUID: string, category: string) {
|
||||
async function submitVote(type: number, UUID: string, category: string, videoID: string) {
|
||||
let userID = Config.config.userID;
|
||||
|
||||
if (userID == undefined || userID === "undefined") {
|
||||
@@ -226,7 +226,7 @@ async function submitVote(type: number, UUID: string, category: string) {
|
||||
const typeSection = (type !== undefined) ? "&type=" + type : "&category=" + category;
|
||||
|
||||
try {
|
||||
const response = await asyncRequestToServer("POST", "/api/voteOnSponsorTime?UUID=" + UUID + "&userID=" + userID + typeSection);
|
||||
const response = await asyncRequestToServer("POST", "/api/voteOnSponsorTime?UUID=" + UUID + "&videoID=" + videoID + "&userID=" + userID + typeSection);
|
||||
|
||||
if (response.ok) {
|
||||
return {
|
||||
|
||||
@@ -1400,7 +1400,7 @@ function updatePreviewBar(): void {
|
||||
showLarger: segment.actionType === ActionType.Poi,
|
||||
description: segment.description,
|
||||
source: segment.source,
|
||||
requiredSegment: requiredSegment && (segment.UUID === requiredSegment || segment.UUID?.startsWith(requiredSegment)),
|
||||
requiredSegment: requiredSegment && (segment.UUID === requiredSegment || segment.UUID?.startsWith(requiredSegment) || requiredSegment.startsWith(segment.UUID)),
|
||||
selectedSegment: selectedSegment && segment.UUID === selectedSegment
|
||||
});
|
||||
});
|
||||
@@ -1678,7 +1678,7 @@ function sendTelemetryAndCount(skippingSegments: SponsorTime[], secondsSkipped:
|
||||
counted = true;
|
||||
}
|
||||
|
||||
if (fullSkip) asyncRequestToServer("POST", "/api/viewedVideoSponsorTime?UUID=" + segment.UUID);
|
||||
if (fullSkip) asyncRequestToServer("POST", "/api/viewedVideoSponsorTime?UUID=" + segment.UUID + "&videoID=" + getVideoID());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2268,7 +2268,8 @@ async function voteAsync(type: number, UUID: SegmentUUID, category?: Category):
|
||||
message: "submitVote",
|
||||
type: type,
|
||||
UUID: UUID,
|
||||
category: category
|
||||
category: category,
|
||||
videoID: getVideoID()
|
||||
}, (response) => {
|
||||
if (response.successType === 1) {
|
||||
// Change the sponsor locally
|
||||
|
||||
17
src/popup.ts
17
src/popup.ts
@@ -681,9 +681,22 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> {
|
||||
uuidButton.className = "voteButton";
|
||||
uuidButton.src = chrome.runtime.getURL("icons/clipboard.svg");
|
||||
uuidButton.title = chrome.i18n.getMessage("copySegmentID");
|
||||
uuidButton.addEventListener("click", () => {
|
||||
copyToClipboard(UUID);
|
||||
uuidButton.addEventListener("click", async () => {
|
||||
const stopAnimation = AnimationUtils.applyLoadingAnimation(uuidButton, 0.3);
|
||||
|
||||
if (UUID.length > 60) {
|
||||
copyToClipboard(UUID);
|
||||
} else {
|
||||
const segmentIDData = await asyncRequestToServer("GET", "/api/segmentID", {
|
||||
UUID: UUID,
|
||||
videoID: currentVideoID
|
||||
});
|
||||
|
||||
if (segmentIDData.ok && segmentIDData.responseText) {
|
||||
copyToClipboard(segmentIDData.responseText);
|
||||
}
|
||||
}
|
||||
|
||||
stopAnimation();
|
||||
});
|
||||
|
||||
|
||||
14
src/utils.ts
14
src/utils.ts
@@ -5,6 +5,7 @@ import { getHash, HashedValue } from "../maze-utils/src/hash";
|
||||
import { waitFor } from "../maze-utils/src";
|
||||
import { findValidElementFromSelector } from "../maze-utils/src/dom";
|
||||
import { isSafari } from "../maze-utils/src/config";
|
||||
import { asyncRequestToServer } from "./utils/requests";
|
||||
|
||||
export default class Utils {
|
||||
|
||||
@@ -198,7 +199,7 @@ export default class Utils {
|
||||
|
||||
getSponsorIndexFromUUID(sponsorTimes: SponsorTime[], UUID: string): number {
|
||||
for (let i = 0; i < sponsorTimes.length; i++) {
|
||||
if (sponsorTimes[i].UUID === UUID) {
|
||||
if (sponsorTimes[i].UUID.startsWith(UUID) || UUID.startsWith(sponsorTimes[i].UUID)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
@@ -282,6 +283,17 @@ export default class Utils {
|
||||
if ((chrome.extension.inIncognitoContext && !Config.config.trackDownvotesInPrivate)
|
||||
|| !Config.config.trackDownvotes) return;
|
||||
|
||||
if (segmentUUID.length < 60) {
|
||||
const segmentIDData = await asyncRequestToServer("GET", "/api/segmentID", {
|
||||
UUID: segmentUUID,
|
||||
videoID
|
||||
});
|
||||
|
||||
if (segmentIDData.ok && segmentIDData.responseText) {
|
||||
segmentUUID = segmentIDData.responseText;
|
||||
}
|
||||
}
|
||||
|
||||
const hashedVideoID = (await getHash(videoID, 1)).slice(0, 4) as VideoID & HashedValue;
|
||||
const UUIDHash = await getHash(segmentUUID, 1);
|
||||
|
||||
|
||||
@@ -48,11 +48,13 @@ async function fetchSegmentsForVideo(videoID: VideoID): Promise<SegmentResponse>
|
||||
const extraRequestData: Record<string, unknown> = {};
|
||||
const hashParams = getHashParams();
|
||||
if (hashParams.requiredSegment) extraRequestData.requiredSegment = hashParams.requiredSegment;
|
||||
|
||||
|
||||
const hashPrefix = (await getHash(videoID, 1)).slice(0, 4) as VideoID & HashedValue;
|
||||
const hasDownvotedSegments = !!Config.local.downvotedSegments[hashPrefix];
|
||||
const response = await asyncRequestToServer('GET', "/api/skipSegments/" + hashPrefix, {
|
||||
categories: CompileConfig.categoryList,
|
||||
actionTypes: ActionTypes,
|
||||
trimUUIDs: hasDownvotedSegments ? null : 5,
|
||||
...extraRequestData
|
||||
}, {
|
||||
"X-CLIENT-NAME": `${chrome.runtime.id}/v${chrome.runtime.getManifest().version}`
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { isOnInvidious, parseYouTubeVideoIDFromURL } from "../../maze-utils/src/video";
|
||||
import Config from "../config";
|
||||
import { getVideoLabel } from "./videoLabels";
|
||||
import { getHasStartSegment, getVideoLabel } from "./videoLabels";
|
||||
import { getThumbnailSelector, setThumbnailListener } from "../../maze-utils/src/thumbnailManagement";
|
||||
import { VideoID } from "../types";
|
||||
import { getSegmentsForVideo } from "./segmentData";
|
||||
@@ -59,14 +59,14 @@ function thumbnailHoverListener(e: MouseEvent) {
|
||||
|
||||
// Pre-fetch data for this video
|
||||
let fetched = false;
|
||||
const preFetch = () => {
|
||||
const preFetch = async () => {
|
||||
fetched = true;
|
||||
const videoID = extractVideoID(thumbnail);
|
||||
if (videoID) {
|
||||
if (videoID && await getHasStartSegment(videoID)) {
|
||||
void getSegmentsForVideo(videoID, false);
|
||||
}
|
||||
};
|
||||
const timeout = setTimeout(preFetch, 200);
|
||||
const timeout = setTimeout(preFetch, 100);
|
||||
const onMouseDown = () => {
|
||||
clearTimeout(timeout);
|
||||
if (!fetched) {
|
||||
|
||||
@@ -6,9 +6,14 @@ import { asyncRequestToServer } from "./requests";
|
||||
|
||||
const utils = new Utils();
|
||||
|
||||
interface VideoLabelsCacheData {
|
||||
category: Category;
|
||||
hasStartSegment: boolean;
|
||||
}
|
||||
|
||||
export interface LabelCacheEntry {
|
||||
timestamp: number;
|
||||
videos: Record<VideoID, Category>;
|
||||
videos: Record<VideoID, VideoLabelsCacheData>;
|
||||
}
|
||||
|
||||
const labelCache: Record<string, LabelCacheEntry> = {};
|
||||
@@ -21,7 +26,7 @@ async function getLabelHashBlock(hashPrefix: string): Promise<LabelCacheEntry |
|
||||
return cachedEntry;
|
||||
}
|
||||
|
||||
const response = await asyncRequestToServer("GET", `/api/videoLabels/${hashPrefix}`);
|
||||
const response = await asyncRequestToServer("GET", `/api/videoLabels/${hashPrefix}?hasStartSegment=true`);
|
||||
if (response.status !== 200) {
|
||||
// No video labels or server down
|
||||
labelCache[hashPrefix] = {
|
||||
@@ -36,7 +41,10 @@ async function getLabelHashBlock(hashPrefix: string): Promise<LabelCacheEntry |
|
||||
|
||||
const newEntry: LabelCacheEntry = {
|
||||
timestamp: Date.now(),
|
||||
videos: Object.fromEntries(data.map(video => [video.videoID, video.segments[0].category])),
|
||||
videos: Object.fromEntries(data.map(video => [video.videoID, {
|
||||
category: video.segments[0]?.category,
|
||||
hasStartSegment: video.hasStartSegment
|
||||
}])),
|
||||
};
|
||||
labelCache[hashPrefix] = newEntry;
|
||||
|
||||
@@ -55,11 +63,11 @@ async function getLabelHashBlock(hashPrefix: string): Promise<LabelCacheEntry |
|
||||
}
|
||||
|
||||
export async function getVideoLabel(videoID: VideoID): Promise<Category | null> {
|
||||
const prefix = (await getHash(videoID, 1)).slice(0, 3);
|
||||
const prefix = (await getHash(videoID, 1)).slice(0, 4);
|
||||
const result = await getLabelHashBlock(prefix);
|
||||
|
||||
if (result) {
|
||||
const category = result.videos[videoID];
|
||||
const category = result.videos[videoID]?.category;
|
||||
if (category && utils.getCategorySelection(category).option !== CategorySkipOption.Disabled) {
|
||||
return category;
|
||||
} else {
|
||||
@@ -67,5 +75,16 @@ export async function getVideoLabel(videoID: VideoID): Promise<Category | null>
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export async function getHasStartSegment(videoID: VideoID): Promise<boolean | null> {
|
||||
const prefix = (await getHash(videoID, 1)).slice(0, 4);
|
||||
const result = await getLabelHashBlock(prefix);
|
||||
|
||||
if (result) {
|
||||
return result?.videos[videoID]?.hasStartSegment ?? false;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
Reference in New Issue
Block a user