mirror of
https://github.com/ajayyy/SponsorBlock.git
synced 2025-12-29 10:58:22 +03:00
Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
de830cda48 | ||
|
|
d8057fb547 | ||
|
|
2dd69d443b | ||
|
|
6732850b41 | ||
|
|
287233785e | ||
|
|
de094cb11f | ||
|
|
2307691044 | ||
|
|
2dca0d7526 | ||
|
|
a1505bcf20 | ||
|
|
25b53754ba | ||
|
|
6c71036356 | ||
|
|
f55f2606a7 | ||
|
|
e9b7abd219 | ||
|
|
63d3309605 | ||
|
|
b4615d7d79 | ||
|
|
ec7eee650b | ||
|
|
154bb1749d | ||
|
|
742eb7ef57 | ||
|
|
88526aa46e | ||
|
|
1909e66c87 | ||
|
|
5f8447ec6b | ||
|
|
e6db5b43ff | ||
|
|
6566c129c7 | ||
|
|
e7f4be2d57 | ||
|
|
ba92e6e386 | ||
|
|
bdbe8b60cc |
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "__MSG_fullName__",
|
"name": "__MSG_fullName__",
|
||||||
"short_name": "SponsorBlock",
|
"short_name": "SponsorBlock",
|
||||||
"version": "5.5.5",
|
"version": "5.5.9",
|
||||||
"default_locale": "en",
|
"default_locale": "en",
|
||||||
"description": "__MSG_Description__",
|
"description": "__MSG_Description__",
|
||||||
"homepage_url": "https://sponsor.ajay.app",
|
"homepage_url": "https://sponsor.ajay.app",
|
||||||
|
|||||||
Submodule maze-utils updated: 08d3f65d35...036086403f
1238
package-lock.json
generated
1238
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -38,7 +38,7 @@
|
|||||||
"ts-loader": "^9.4.2",
|
"ts-loader": "^9.4.2",
|
||||||
"ts-node": "^10.9.1",
|
"ts-node": "^10.9.1",
|
||||||
"typescript": "4.9",
|
"typescript": "4.9",
|
||||||
"web-ext": "^7.6.2",
|
"web-ext": "^7.10.0",
|
||||||
"webpack": "^5.75.0",
|
"webpack": "^5.75.0",
|
||||||
"webpack-cli": "^4.10.0",
|
"webpack-cli": "^4.10.0",
|
||||||
"webpack-merge": "^5.8.0"
|
"webpack-merge": "^5.8.0"
|
||||||
|
|||||||
Submodule public/_locales updated: 96f860dc1d...9cfc718fd2
@@ -780,6 +780,18 @@ input::-webkit-inner-spin-button {
|
|||||||
line-height: 1.5em;
|
line-height: 1.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Description on right layout */
|
||||||
|
#title > #categoryPillParent {
|
||||||
|
font-size: 2rem;
|
||||||
|
font-weight: bold;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
line-height: 2.8rem;
|
||||||
|
}
|
||||||
|
#title > #categoryPillParent > #categoryPill.cbPillOpen {
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
#categoryPillParent {
|
#categoryPillParent {
|
||||||
height: fit-content;
|
height: fit-content;
|
||||||
margin-top: auto;
|
margin-top: auto;
|
||||||
|
|||||||
@@ -634,7 +634,19 @@
|
|||||||
|
|
||||||
<div class="small-description">__MSG_whatTrackDownvotes__</div>
|
<div class="small-description">__MSG_whatTrackDownvotes__</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div data-type="toggle" data-sync="trackDownvotesInPrivate" data-confirm-on="false">
|
||||||
|
<div class="switch-container">
|
||||||
|
<label class="switch">
|
||||||
|
<input id="trackDownvotesInPrivate" type="checkbox" checked>
|
||||||
|
<span class="slider round"></span>
|
||||||
|
</label>
|
||||||
|
<label class="switch-label" for="trackDownvotesInPrivate">
|
||||||
|
__MSG_enableTrackDownvotesInPrivate__
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div data-type="button-press" data-sync="copyDebugInformation" data-confirm-message="copyDebugInformation">
|
<div data-type="button-press" data-sync="copyDebugInformation" data-confirm-message="copyDebugInformation">
|
||||||
<div class="option-button trigger-button">
|
<div class="option-button trigger-button">
|
||||||
__MSG_copyDebugInformation__
|
__MSG_copyDebugInformation__
|
||||||
|
|||||||
@@ -23,12 +23,14 @@ export interface CategoryPillState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class CategoryPillComponent extends React.Component<CategoryPillProps, CategoryPillState> {
|
class CategoryPillComponent extends React.Component<CategoryPillProps, CategoryPillState> {
|
||||||
|
mainRef: React.MutableRefObject<HTMLSpanElement>;
|
||||||
tooltip?: Tooltip;
|
tooltip?: Tooltip;
|
||||||
|
|
||||||
constructor(props: CategoryPillProps) {
|
constructor(props: CategoryPillProps) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
|
this.mainRef = React.createRef();
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
segment: null,
|
segment: null,
|
||||||
show: false,
|
show: false,
|
||||||
@@ -43,13 +45,17 @@ class CategoryPillComponent extends React.Component<CategoryPillProps, CategoryP
|
|||||||
color: this.getTextColor(),
|
color: this.getTextColor(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// To be able to remove the margin from the parent
|
||||||
|
this.mainRef?.current?.parentElement?.classList?.toggle("cbPillOpen", this.state.show);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<span style={style}
|
<span style={style}
|
||||||
className={"sponsorBlockCategoryPill" + (!this.props.showTextByDefault ? " sbPillNoText" : "")}
|
className={"sponsorBlockCategoryPill" + (!this.props.showTextByDefault ? " sbPillNoText" : "")}
|
||||||
aria-label={this.getTitleText()}
|
aria-label={this.getTitleText()}
|
||||||
onClick={(e) => this.toggleOpen(e)}
|
onClick={(e) => this.toggleOpen(e)}
|
||||||
onMouseEnter={() => this.openTooltip()}
|
onMouseEnter={() => this.openTooltip()}
|
||||||
onMouseLeave={() => this.closeTooltip()}>
|
onMouseLeave={() => this.closeTooltip()}
|
||||||
|
ref={this.mainRef}>
|
||||||
|
|
||||||
<span className="sponsorBlockCategoryPillTitleSection">
|
<span className="sponsorBlockCategoryPillTitleSection">
|
||||||
<img className="sponsorSkipLogo sponsorSkipObject"
|
<img className="sponsorSkipLogo sponsorSkipObject"
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ interface SBConfig {
|
|||||||
trackViewCount: boolean;
|
trackViewCount: boolean;
|
||||||
trackViewCountInPrivate: boolean;
|
trackViewCountInPrivate: boolean;
|
||||||
trackDownvotes: boolean;
|
trackDownvotes: boolean;
|
||||||
|
trackDownvotesInPrivate: boolean;
|
||||||
dontShowNotice: boolean;
|
dontShowNotice: boolean;
|
||||||
noticeVisibilityMode: NoticeVisbilityMode;
|
noticeVisibilityMode: NoticeVisbilityMode;
|
||||||
hideVideoPlayerControls: boolean;
|
hideVideoPlayerControls: boolean;
|
||||||
@@ -290,6 +291,7 @@ const syncDefaults = {
|
|||||||
trackViewCount: true,
|
trackViewCount: true,
|
||||||
trackViewCountInPrivate: true,
|
trackViewCountInPrivate: true,
|
||||||
trackDownvotes: true,
|
trackDownvotes: true,
|
||||||
|
trackDownvotesInPrivate: false,
|
||||||
dontShowNotice: false,
|
dontShowNotice: false,
|
||||||
noticeVisibilityMode: NoticeVisbilityMode.FadedForAutoSkip,
|
noticeVisibilityMode: NoticeVisbilityMode.FadedForAutoSkip,
|
||||||
hideVideoPlayerControls: false,
|
hideVideoPlayerControls: false,
|
||||||
|
|||||||
@@ -258,7 +258,12 @@ function messageListener(request: Message, sender: unknown, sendResponse: (respo
|
|||||||
break;
|
break;
|
||||||
case "refreshSegments":
|
case "refreshSegments":
|
||||||
// update video on refresh if videoID invalid
|
// update video on refresh if videoID invalid
|
||||||
if (!getVideoID()) checkVideoIDChange();
|
if (!getVideoID()) {
|
||||||
|
checkVideoIDChange();
|
||||||
|
}
|
||||||
|
// if popup rescieves no response, or the videoID is invalid,
|
||||||
|
// it will assume the page is not a video page and stop the refresh animation
|
||||||
|
sendResponse({ hasVideo: getVideoID() != null });
|
||||||
// fetch segments
|
// fetch segments
|
||||||
sponsorsLookup(false);
|
sponsorsLookup(false);
|
||||||
|
|
||||||
@@ -2278,7 +2283,8 @@ async function sendSubmitMessage(): Promise<boolean> {
|
|||||||
if (!previewedSegment
|
if (!previewedSegment
|
||||||
&& !sponsorTimesSubmitting.every((segment) =>
|
&& !sponsorTimesSubmitting.every((segment) =>
|
||||||
[ActionType.Full, ActionType.Chapter, ActionType.Poi].includes(segment.actionType)
|
[ActionType.Full, ActionType.Chapter, ActionType.Poi].includes(segment.actionType)
|
||||||
|| segment.segment[1] >= getVideo()?.duration)) {
|
|| segment.segment[1] >= getVideo()?.duration
|
||||||
|
|| segment.segment[0] === 0)) {
|
||||||
alert(`${chrome.i18n.getMessage("previewSegmentRequired")} ${keybindToString(Config.config.previewKeybind)}`);
|
alert(`${chrome.i18n.getMessage("previewSegmentRequired")} ${keybindToString(Config.config.previewKeybind)}`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -748,6 +748,7 @@ class PreviewBar {
|
|||||||
|
|
||||||
updateChapterText(segments: SponsorTime[], submittingSegments: SponsorTime[], currentTime: number): SponsorTime[] {
|
updateChapterText(segments: SponsorTime[], submittingSegments: SponsorTime[], currentTime: number): SponsorTime[] {
|
||||||
if (!Config.config.showSegmentNameInChapterBar
|
if (!Config.config.showSegmentNameInChapterBar
|
||||||
|
|| Config.config.disableSkipping
|
||||||
|| ((!segments || segments.length <= 0) && submittingSegments?.length <= 0)) {
|
|| ((!segments || segments.length <= 0) && submittingSegments?.length <= 0)) {
|
||||||
const chaptersContainer = this.getChaptersContainer();
|
const chaptersContainer = this.getChaptersContainer();
|
||||||
if (chaptersContainer) {
|
if (chaptersContainer) {
|
||||||
|
|||||||
@@ -103,7 +103,8 @@ export type MessageResponse =
|
|||||||
| IsChannelWhitelistedResponse
|
| IsChannelWhitelistedResponse
|
||||||
| Record<string, never> // empty object response {}
|
| Record<string, never> // empty object response {}
|
||||||
| VoteResponse
|
| VoteResponse
|
||||||
| ImportSegmentsResponse;
|
| ImportSegmentsResponse
|
||||||
|
| RefreshSegmentsResponse;
|
||||||
|
|
||||||
export interface VoteResponse {
|
export interface VoteResponse {
|
||||||
successType: number;
|
successType: number;
|
||||||
@@ -115,6 +116,10 @@ interface ImportSegmentsResponse {
|
|||||||
importedSegments: SponsorTime[];
|
importedSegments: SponsorTime[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface RefreshSegmentsResponse {
|
||||||
|
hasVideo: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
export interface TimeUpdateMessage {
|
export interface TimeUpdateMessage {
|
||||||
message: "time";
|
message: "time";
|
||||||
time: number;
|
time: number;
|
||||||
|
|||||||
@@ -286,7 +286,7 @@ async function init() {
|
|||||||
break;
|
break;
|
||||||
case "resetToDefault":
|
case "resetToDefault":
|
||||||
Config.resetToDefault();
|
Config.resetToDefault();
|
||||||
window.location.reload();
|
setTimeout(() => window.location.reload(), 200);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -632,8 +632,7 @@ async function setTextOption(option: string, element: HTMLElement, value: string
|
|||||||
await invidiousOnClick(checkbox, "supportInvidious");
|
await invidiousOnClick(checkbox, "supportInvidious");
|
||||||
}
|
}
|
||||||
|
|
||||||
window.location.reload();
|
setTimeout(() => window.location.reload(), 200);
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
alert(chrome.i18n.getMessage("incorrectlyFormattedOptions"));
|
alert(chrome.i18n.getMessage("incorrectlyFormattedOptions"));
|
||||||
}
|
}
|
||||||
|
|||||||
57
src/popup.ts
57
src/popup.ts
@@ -15,6 +15,7 @@ import {
|
|||||||
Message,
|
Message,
|
||||||
MessageResponse,
|
MessageResponse,
|
||||||
PopupMessage,
|
PopupMessage,
|
||||||
|
RefreshSegmentsResponse,
|
||||||
SponsorStartResponse,
|
SponsorStartResponse,
|
||||||
VoteResponse,
|
VoteResponse,
|
||||||
} from "./messageTypes";
|
} from "./messageTypes";
|
||||||
@@ -459,37 +460,35 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> {
|
|||||||
stopLoadingAnimation = null;
|
stopLoadingAnimation = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chrome.runtime.lastError) {
|
if (chrome.runtime.lastError || request == undefined || request.found == undefined) {
|
||||||
//This page doesn't have the injected content script, or at least not yet
|
//This page doesn't have the injected content script, or at least not yet
|
||||||
|
// Or if the request is empty, meaning the current page is not YouTube or a video page
|
||||||
displayNoVideo();
|
displayNoVideo();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//if request is undefined, then the page currently being browsed is not YouTube
|
//remove loading text
|
||||||
if (request != undefined) {
|
PageElements.mainControls.style.display = "block";
|
||||||
//remove loading text
|
if (request.onMobileYouTube) PageElements.mainControls.classList.add("hidden");
|
||||||
PageElements.mainControls.style.display = "block";
|
PageElements.whitelistButton.classList.remove("hidden");
|
||||||
if (request.onMobileYouTube) PageElements.mainControls.classList.add("hidden");
|
PageElements.loadingIndicator.style.display = "none";
|
||||||
PageElements.whitelistButton.classList.remove("hidden");
|
|
||||||
PageElements.loadingIndicator.style.display = "none";
|
|
||||||
|
|
||||||
downloadedTimes = request.sponsorTimes ?? [];
|
downloadedTimes = request.sponsorTimes ?? [];
|
||||||
displayDownloadedSponsorTimes(downloadedTimes, request.time);
|
displayDownloadedSponsorTimes(downloadedTimes, request.time);
|
||||||
if (request.found) {
|
if (request.found) {
|
||||||
PageElements.videoFound.innerHTML = chrome.i18n.getMessage("sponsorFound");
|
PageElements.videoFound.innerHTML = chrome.i18n.getMessage("sponsorFound");
|
||||||
PageElements.issueReporterImportExport.classList.remove("hidden");
|
PageElements.issueReporterImportExport.classList.remove("hidden");
|
||||||
} else if (request.status == 404 || request.status == 200) {
|
} else if (request.status == 404 || request.status == 200) {
|
||||||
PageElements.videoFound.innerHTML = chrome.i18n.getMessage("sponsor404");
|
PageElements.videoFound.innerHTML = chrome.i18n.getMessage("sponsor404");
|
||||||
PageElements.issueReporterImportExport.classList.remove("hidden");
|
PageElements.issueReporterImportExport.classList.remove("hidden");
|
||||||
|
} else {
|
||||||
|
if (request.status) {
|
||||||
|
PageElements.videoFound.innerHTML = chrome.i18n.getMessage("connectionError") + request.status;
|
||||||
} else {
|
} else {
|
||||||
if (request.status) {
|
PageElements.videoFound.innerHTML = chrome.i18n.getMessage("segmentsStillLoading");
|
||||||
PageElements.videoFound.innerHTML = chrome.i18n.getMessage("connectionError") + request.status;
|
|
||||||
} else {
|
|
||||||
PageElements.videoFound.innerHTML = chrome.i18n.getMessage("segmentsStillLoading");
|
|
||||||
}
|
|
||||||
|
|
||||||
PageElements.issueReporterImportExport.classList.remove("hidden");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PageElements.issueReporterImportExport.classList.remove("hidden");
|
||||||
}
|
}
|
||||||
|
|
||||||
//see if whitelist button should be swapped
|
//see if whitelist button should be swapped
|
||||||
@@ -980,9 +979,17 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> {
|
|||||||
stopLoadingAnimation = AnimationUtils.applyLoadingAnimation(PageElements.refreshSegmentsButton, 0.3);
|
stopLoadingAnimation = AnimationUtils.applyLoadingAnimation(PageElements.refreshSegmentsButton, 0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
function refreshSegments() {
|
async function refreshSegments() {
|
||||||
startLoadingAnimation();
|
startLoadingAnimation();
|
||||||
sendTabMessage({ message: 'refreshSegments' });
|
const response = await sendTabMessageAsync({ message: 'refreshSegments' }) as RefreshSegmentsResponse;
|
||||||
|
|
||||||
|
if (response == null || !response.hasVideo) {
|
||||||
|
if (stopLoadingAnimation != null) {
|
||||||
|
stopLoadingAnimation();
|
||||||
|
stopLoadingAnimation = null;
|
||||||
|
}
|
||||||
|
displayNoVideo();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function skipSegment(actionType: ActionType, UUID: SegmentUUID, element?: HTMLElement): void {
|
function skipSegment(actionType: ActionType, UUID: SegmentUUID, element?: HTMLElement): void {
|
||||||
|
|||||||
@@ -43,9 +43,15 @@ export class CategoryPill {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async attachToPageInternal(): Promise<void> {
|
private async attachToPageInternal(): Promise<void> {
|
||||||
const referenceNode =
|
let referenceNode =
|
||||||
await waitFor(() => getYouTubeTitleNode());
|
await waitFor(() => getYouTubeTitleNode());
|
||||||
|
|
||||||
|
// Experimental YouTube layout with description on right
|
||||||
|
const isOnDescriptionOnRightLayout = document.querySelector("#title #description");
|
||||||
|
if (isOnDescriptionOnRightLayout) {
|
||||||
|
referenceNode = referenceNode.parentElement;
|
||||||
|
}
|
||||||
|
|
||||||
if (referenceNode && !referenceNode.contains(this.container)) {
|
if (referenceNode && !referenceNode.contains(this.container)) {
|
||||||
if (!this.container) {
|
if (!this.container) {
|
||||||
this.container = document.createElement('span');
|
this.container = document.createElement('span');
|
||||||
@@ -91,7 +97,9 @@ export class CategoryPill {
|
|||||||
parent.appendChild(this.container);
|
parent.appendChild(this.container);
|
||||||
|
|
||||||
referenceNode.prepend(parent);
|
referenceNode.prepend(parent);
|
||||||
referenceNode.style.display = "flex";
|
if (!isOnDescriptionOnRightLayout) {
|
||||||
|
referenceNode.style.display = "flex";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -281,7 +281,8 @@ export default class Utils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async addHiddenSegment(videoID: VideoID, segmentUUID: string, hidden: SponsorHideType) {
|
async addHiddenSegment(videoID: VideoID, segmentUUID: string, hidden: SponsorHideType) {
|
||||||
if (chrome.extension.inIncognitoContext || !Config.config.trackDownvotes) return;
|
if ((chrome.extension.inIncognitoContext && !Config.config.trackDownvotesInPrivate)
|
||||||
|
|| !Config.config.trackDownvotes) return;
|
||||||
|
|
||||||
const hashedVideoID = (await getHash(videoID, 1)).slice(0, 4) as VideoID & HashedValue;
|
const hashedVideoID = (await getHash(videoID, 1)).slice(0, 4) as VideoID & HashedValue;
|
||||||
const UUIDHash = await getHash(segmentUUID, 1);
|
const UUIDHash = await getHash(segmentUUID, 1);
|
||||||
|
|||||||
Reference in New Issue
Block a user