mirror of
https://github.com/ajayyy/SponsorBlock.git
synced 2026-01-01 14:19:23 +03:00
Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dc2c7cc425 | ||
|
|
7bf3237b72 | ||
|
|
b48c854926 | ||
|
|
0bb7bef52c | ||
|
|
4ffa019c68 | ||
|
|
9c2007e0cf | ||
|
|
9176854d56 | ||
|
|
65c72d38ea | ||
|
|
6f54c8a731 | ||
|
|
ca7eb50a82 | ||
|
|
a7030fab9f | ||
|
|
0bb3528cde | ||
|
|
c8c141f5c9 | ||
|
|
88cfa023c9 | ||
|
|
41a2fc2cb3 | ||
|
|
0f0e404920 | ||
|
|
f34fe5a032 | ||
|
|
e4c9afecbd | ||
|
|
79e855a038 | ||
|
|
09a3a4e6d4 | ||
|
|
e271f2cbcc | ||
|
|
1cc4c18665 | ||
|
|
e650b7183a | ||
|
|
4eb097b422 | ||
|
|
04a9f82bdc |
@@ -1 +1 @@
|
|||||||
["www.youtubekids.com","anontube.lvkaszus.pl","inv.bp.projectsegfau.lt","inv.makerlab.tech","inv.pistasjis.net","inv.tux.pizza","inv.zzls.xyz","invidious.asir.dev","invidious.flokinet.to","invidious.io.lol","invidious.lunar.icu","invidious.no-logs.com","invidious.privacydev.net","invidious.private.coffee","invidious.protokolla.fi","invidious.slipfox.xyz","invidious.tiekoetter.com","iv.ggtyler.dev","iv.melmac.space","iv.nboeck.de","onion.tube","vid.priv.au","vid.puffyan.us","yewtu.be","yt.artemislena.eu","yt.drgnz.club","yt.oelrichsgarcia.de"]
|
["www.youtubekids.com","anontube.lvkaszus.pl","inv.citw.lgbt","inv.in.projectsegfau.lt","inv.tux.pizza","inv.zzls.xyz","invidious.asir.dev","invidious.drgns.space","invidious.fdn.fr","invidious.flokinet.to","invidious.io.lol","invidious.lunar.icu","invidious.nerdvpn.de","invidious.no-logs.com","invidious.perennialte.ch","invidious.privacydev.net","invidious.private.coffee","invidious.projectsegfau.lt","invidious.protokolla.fi","invidious.slipfox.xyz","iv.datura.network","iv.ggtyler.dev","iv.melmac.space","iv.nboeck.de","onion.tube","vid.priv.au","vid.puffyan.us","yewtu.be","yt.artemislena.eu","yt.cdaut.de","yt.drgnz.club","yt.oelrichsgarcia.de"]
|
||||||
@@ -1,7 +1,11 @@
|
|||||||
{
|
{
|
||||||
"browser_specific_settings": {
|
"browser_specific_settings": {
|
||||||
"gecko": {
|
"gecko": {
|
||||||
"id": "sponsorBlocker@ajay.app"
|
"id": "sponsorBlocker@ajay.app",
|
||||||
|
"strict_min_version": "48.0"
|
||||||
|
},
|
||||||
|
"gecko_android": {
|
||||||
|
"strict_min_version": "79.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"background": {
|
"background": {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "__MSG_fullName__",
|
"name": "__MSG_fullName__",
|
||||||
"short_name": "SponsorBlock",
|
"short_name": "SponsorBlock",
|
||||||
"version": "5.4.22",
|
"version": "5.4.26",
|
||||||
"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: a984d11483...92d368b051
Submodule public/_locales updated: 8024493171...8434a93598
@@ -7,7 +7,7 @@
|
|||||||
--sb-dark-red-outline: rgb(130,0,0,0.9);
|
--sb-dark-red-outline: rgb(130,0,0,0.9);
|
||||||
}
|
}
|
||||||
|
|
||||||
.hidden {
|
.sbhidden {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,7 +151,7 @@ div:hover > .sponsorBlockChapterBar {
|
|||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
}
|
}
|
||||||
|
|
||||||
.playerButton.hidden:not(.autoHiding) {
|
.playerButton.sbhidden:not(.autoHiding) {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,13 +169,13 @@ div:hover > .sponsorBlockChapterBar {
|
|||||||
overflow: visible !important;
|
overflow: visible !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.autoHiding:not(.hidden) {
|
.autoHiding:not(.sbhidden) {
|
||||||
transform: translateX(0%) scale(1);
|
transform: translateX(0%) scale(1);
|
||||||
/* opacity is from YouTube page */
|
/* opacity is from YouTube page */
|
||||||
transition: transform 0.2s, width 0.2s, opacity .1s cubic-bezier(0.4,0.0,1,1) !important;
|
transition: transform 0.2s, width 0.2s, opacity .1s cubic-bezier(0.4,0.0,1,1) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.autoHiding.hidden {
|
.autoHiding.sbhidden {
|
||||||
transform: translateX(100%) scale(0);
|
transform: translateX(100%) scale(0);
|
||||||
/* opacity is from YouTube page */
|
/* opacity is from YouTube page */
|
||||||
transition: transform 0.2s, width 0.2s, opacity .1s cubic-bezier(0.4,0.0,1,1) !important;
|
transition: transform 0.2s, width 0.2s, opacity .1s cubic-bezier(0.4,0.0,1,1) !important;
|
||||||
@@ -183,7 +183,7 @@ div:hover > .sponsorBlockChapterBar {
|
|||||||
width: 0px !important;
|
width: 0px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.autoHiding.hidden.autoHideLeft {
|
.autoHiding.sbhidden.autoHideLeft {
|
||||||
transform: translateX(-100%) scale(0);
|
transform: translateX(-100%) scale(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -272,7 +272,7 @@ div:hover > .sponsorBlockChapterBar {
|
|||||||
max-width: calc(100% - 50px);
|
max-width: calc(100% - 50px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.sponsorSkipNotice .hidden {
|
.sponsorSkipNotice .sbhidden {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -691,7 +691,7 @@ input::-webkit-inner-spin-button {
|
|||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.skipButtonControlBarContainer.hidden {
|
.skipButtonControlBarContainer.sbhidden {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -257,7 +257,7 @@ input[type='number'] {
|
|||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hidden {
|
.hidden, .sbhidden {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ body {
|
|||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hidden {
|
.hidden, .sbhidden {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
#sponsorBlockPopupBody .hidden {
|
#sponsorBlockPopupBody .hidden, #sponsorBlockPopupBody .sbhidden {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -260,19 +260,6 @@
|
|||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Buttons that appear under a segment on click
|
|
||||||
*/
|
|
||||||
.voteButton {
|
|
||||||
height: 20px;
|
|
||||||
padding: 0 5px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.voteButton:hover {
|
|
||||||
opacity: 0.8;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "Voted!" text that appears after voting on a segment
|
* "Voted!" text that appears after voting on a segment
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
max-width: calc(100% - 50px);
|
max-width: calc(100% - 50px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.sponsorSkipNotice .hidden {
|
.sponsorSkipNotice .sbhidden {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,4 +216,17 @@
|
|||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Buttons that appear under a segment on click
|
||||||
|
*/
|
||||||
|
.voteButton {
|
||||||
|
height: 20px;
|
||||||
|
padding: 0 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.voteButton:hover {
|
||||||
|
opacity: 0.8;
|
||||||
}
|
}
|
||||||
@@ -44,7 +44,7 @@ class ChapterVoteComponent extends React.Component<ChapterVoteProps, ChapterVote
|
|||||||
<>
|
<>
|
||||||
{/* Upvote Button */}
|
{/* Upvote Button */}
|
||||||
<button id={"sponsorTimesDownvoteButtonsContainerUpvoteChapter"}
|
<button id={"sponsorTimesDownvoteButtonsContainerUpvoteChapter"}
|
||||||
className={"playerButton sbPlayerUpvote ytp-button " + (!this.state.show ? "hidden" : "")}
|
className={"playerButton sbPlayerUpvote ytp-button " + (!this.state.show ? "sbhidden" : "")}
|
||||||
draggable="false"
|
draggable="false"
|
||||||
title={chrome.i18n.getMessage("upvoteButtonInfo")}
|
title={chrome.i18n.getMessage("upvoteButtonInfo")}
|
||||||
onClick={(e) => this.vote(e, 1)}>
|
onClick={(e) => this.vote(e, 1)}>
|
||||||
@@ -55,7 +55,7 @@ class ChapterVoteComponent extends React.Component<ChapterVoteProps, ChapterVote
|
|||||||
|
|
||||||
{/* Downvote Button */}
|
{/* Downvote Button */}
|
||||||
<button id={"sponsorTimesDownvoteButtonsContainerDownvoteChapter"}
|
<button id={"sponsorTimesDownvoteButtonsContainerDownvoteChapter"}
|
||||||
className={"playerButton sbPlayerDownvote ytp-button " + (!this.state.show ? "hidden" : "")}
|
className={"playerButton sbPlayerDownvote ytp-button " + (!this.state.show ? "sbhidden" : "")}
|
||||||
draggable="false"
|
draggable="false"
|
||||||
title={chrome.i18n.getMessage("reportButtonInfo")}
|
title={chrome.i18n.getMessage("reportButtonInfo")}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
|
|||||||
@@ -196,21 +196,21 @@ class NoticeComponent extends React.Component<NoticeProps, NoticeState> {
|
|||||||
<span
|
<span
|
||||||
id={"skipNoticeTimerText" + this.idSuffix}
|
id={"skipNoticeTimerText" + this.idSuffix}
|
||||||
key="skipNoticeTimerText"
|
key="skipNoticeTimerText"
|
||||||
className={this.state.countdownMode !== CountdownMode.Timer ? "hidden" : ""} >
|
className={this.state.countdownMode !== CountdownMode.Timer ? "sbhidden" : ""} >
|
||||||
{chrome.i18n.getMessage("NoticeTimeAfterSkip").replace("{seconds}", this.state.countdownTime.toString())}
|
{chrome.i18n.getMessage("NoticeTimeAfterSkip").replace("{seconds}", this.state.countdownTime.toString())}
|
||||||
</span>
|
</span>
|
||||||
),(
|
),(
|
||||||
<img
|
<img
|
||||||
id={"skipNoticeTimerPaused" + this.idSuffix}
|
id={"skipNoticeTimerPaused" + this.idSuffix}
|
||||||
key="skipNoticeTimerPaused"
|
key="skipNoticeTimerPaused"
|
||||||
className={this.state.countdownMode !== CountdownMode.Paused ? "hidden" : ""}
|
className={this.state.countdownMode !== CountdownMode.Paused ? "sbhidden" : ""}
|
||||||
src={chrome.runtime.getURL("icons/pause.svg")}
|
src={chrome.runtime.getURL("icons/pause.svg")}
|
||||||
alt={chrome.i18n.getMessage("paused")} />
|
alt={chrome.i18n.getMessage("paused")} />
|
||||||
),(
|
),(
|
||||||
<img
|
<img
|
||||||
id={"skipNoticeTimerStopped" + this.idSuffix}
|
id={"skipNoticeTimerStopped" + this.idSuffix}
|
||||||
key="skipNoticeTimerStopped"
|
key="skipNoticeTimerStopped"
|
||||||
className={this.state.countdownMode !== CountdownMode.Stopped ? "hidden" : ""}
|
className={this.state.countdownMode !== CountdownMode.Stopped ? "sbhidden" : ""}
|
||||||
src={chrome.runtime.getURL("icons/stop.svg")}
|
src={chrome.runtime.getURL("icons/stop.svg")}
|
||||||
alt={chrome.i18n.getMessage("manualPaused")} />
|
alt={chrome.i18n.getMessage("manualPaused")} />
|
||||||
)];
|
)];
|
||||||
|
|||||||
@@ -297,7 +297,7 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
|
|||||||
): ""}
|
): ""}
|
||||||
|
|
||||||
{(!isNaN(segment[1]) && ![ActionType.Poi, ActionType.Full].includes(sponsorTime.actionType)) ? (
|
{(!isNaN(segment[1]) && ![ActionType.Poi, ActionType.Full].includes(sponsorTime.actionType)) ? (
|
||||||
<span id={"sponsorTimePreviewButton" + this.idSuffix}
|
<span id={"sponsorTimePreviewEndButton" + this.idSuffix}
|
||||||
className="sponsorTimeEditButton"
|
className="sponsorTimeEditButton"
|
||||||
onClick={(e) => this.previewTime(e.ctrlKey, e.shiftKey, true)}>
|
onClick={(e) => this.previewTime(e.ctrlKey, e.shiftKey, true)}>
|
||||||
{chrome.i18n.getMessage("End")}
|
{chrome.i18n.getMessage("End")}
|
||||||
@@ -590,7 +590,24 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
|
|||||||
getFormattedTime(sponsorTime.segment[1], true)];
|
getFormattedTime(sponsorTime.segment[1], true)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lastEditTime = 0;
|
||||||
|
editTimeTimeout: NodeJS.Timeout | null = null;
|
||||||
saveEditTimes(): void {
|
saveEditTimes(): void {
|
||||||
|
// Rate limit edits
|
||||||
|
const timeSinceLastEdit = Date.now() - this.lastEditTime;
|
||||||
|
if (timeSinceLastEdit < 200) {
|
||||||
|
if (!this.editTimeTimeout) {
|
||||||
|
this.editTimeTimeout = setTimeout(() => {
|
||||||
|
this.saveEditTimes();
|
||||||
|
}, timeSinceLastEdit)
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.lastEditTime = Date.now();
|
||||||
|
this.editTimeTimeout = null;
|
||||||
|
|
||||||
const sponsorTimesSubmitting = this.props.contentContainer().sponsorTimesSubmitting;
|
const sponsorTimesSubmitting = this.props.contentContainer().sponsorTimesSubmitting;
|
||||||
const category = this.categoryOptionRef.current.value as Category
|
const category = this.categoryOptionRef.current.value as Category
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ class SubmissionNoticeComponent extends React.Component<SubmissionNoticeProps, S
|
|||||||
|
|
||||||
guidelinesReminder: GenericNotice;
|
guidelinesReminder: GenericNotice;
|
||||||
|
|
||||||
|
lastSegmentCount: number;
|
||||||
|
|
||||||
constructor(props: SubmissionNoticeProps) {
|
constructor(props: SubmissionNoticeProps) {
|
||||||
super(props);
|
super(props);
|
||||||
this.noticeRef = React.createRef();
|
this.noticeRef = React.createRef();
|
||||||
@@ -47,12 +49,14 @@ class SubmissionNoticeComponent extends React.Component<SubmissionNoticeProps, S
|
|||||||
|
|
||||||
const noticeTitle = chrome.i18n.getMessage("confirmNoticeTitle");
|
const noticeTitle = chrome.i18n.getMessage("confirmNoticeTitle");
|
||||||
|
|
||||||
|
this.lastSegmentCount = this.props.contentContainer().sponsorTimesSubmitting.length;
|
||||||
|
|
||||||
// Setup state
|
// Setup state
|
||||||
this.state = {
|
this.state = {
|
||||||
noticeTitle,
|
noticeTitle,
|
||||||
messages: [],
|
messages: [],
|
||||||
idSuffix: "SubmissionNotice"
|
idSuffix: "SubmissionNotice"
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount(): void {
|
componentDidMount(): void {
|
||||||
@@ -73,6 +77,18 @@ class SubmissionNoticeComponent extends React.Component<SubmissionNoticeProps, S
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidUpdate() {
|
||||||
|
const currentSegmentCount = this.props.contentContainer().sponsorTimesSubmitting.length;
|
||||||
|
if (currentSegmentCount > this.lastSegmentCount) {
|
||||||
|
this.lastSegmentCount = currentSegmentCount;
|
||||||
|
|
||||||
|
const scrollElement = this.noticeRef.current.getElement().current.querySelector("#sponsorSkipNoticeMiddleRowSubmissionNotice");
|
||||||
|
scrollElement.scrollTo({
|
||||||
|
top: scrollElement.scrollHeight + 1000
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
render(): React.ReactElement {
|
render(): React.ReactElement {
|
||||||
const sortButton =
|
const sortButton =
|
||||||
<img id={"sponsorSkipSortButton" + this.state.idSuffix}
|
<img id={"sponsorSkipSortButton" + this.state.idSuffix}
|
||||||
|
|||||||
@@ -98,6 +98,8 @@ utils.wait(() => Config.isReady(), 5000, 10).then(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const skipBuffer = 0.003;
|
const skipBuffer = 0.003;
|
||||||
|
// If this close to the end, skip to the end
|
||||||
|
const endTimeSkipBuffer = 0.5;
|
||||||
|
|
||||||
//was sponsor data found when doing SponsorsLookup
|
//was sponsor data found when doing SponsorsLookup
|
||||||
let sponsorDataFound = false;
|
let sponsorDataFound = false;
|
||||||
@@ -302,8 +304,7 @@ function messageListener(request: Message, sender: unknown, sendResponse: (respo
|
|||||||
reskipSponsorTime(sponsorTimes.find((segment) => segment.UUID === request.UUID), true);
|
reskipSponsorTime(sponsorTimes.find((segment) => segment.UUID === request.UUID), true);
|
||||||
break;
|
break;
|
||||||
case "selectSegment":
|
case "selectSegment":
|
||||||
selectedSegment = request.UUID;
|
selectSegment(request.UUID);
|
||||||
updatePreviewBar();
|
|
||||||
break;
|
break;
|
||||||
case "submitVote":
|
case "submitVote":
|
||||||
vote(request.type, request.UUID).then((response) => sendResponse(response));
|
vote(request.type, request.UUID).then((response) => sendResponse(response));
|
||||||
@@ -623,7 +624,8 @@ async function startSponsorSchedule(includeIntersectingSegments = false, current
|
|||||||
|
|
||||||
updateActiveSegment(currentTime);
|
updateActiveSegment(currentTime);
|
||||||
|
|
||||||
if (getVideo().paused) return;
|
if (getVideo().paused
|
||||||
|
|| (getVideo().currentTime >= getVideo().duration - 0.01 && getVideo().duration > 1)) return;
|
||||||
const skipInfo = getNextSkipIndex(currentTime, includeIntersectingSegments, includeNonIntersectingSegments);
|
const skipInfo = getNextSkipIndex(currentTime, includeIntersectingSegments, includeNonIntersectingSegments);
|
||||||
|
|
||||||
const currentSkip = skipInfo.array[skipInfo.index];
|
const currentSkip = skipInfo.array[skipInfo.index];
|
||||||
@@ -702,8 +704,12 @@ async function startSponsorSchedule(includeIntersectingSegments = false, current
|
|||||||
forcedSkipTime = skipTime[0] + 0.001;
|
forcedSkipTime = skipTime[0] + 0.001;
|
||||||
} else {
|
} else {
|
||||||
forcedSkipTime = skipTime[1];
|
forcedSkipTime = skipTime[1];
|
||||||
forcedIncludeIntersectingSegments = true;
|
|
||||||
forcedIncludeNonIntersectingSegments = false;
|
forcedIncludeNonIntersectingSegments = false;
|
||||||
|
|
||||||
|
// Only if not at the end of the video
|
||||||
|
if (Math.abs(skipTime[1] - getVideo().duration) > endTimeSkipBuffer) {
|
||||||
|
forcedIncludeIntersectingSegments = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
forcedSkipTime = forceVideoTime + 0.001;
|
forcedSkipTime = forceVideoTime + 0.001;
|
||||||
@@ -1071,6 +1077,7 @@ function setupSkipButtonControlBar() {
|
|||||||
openNotice: true,
|
openNotice: true,
|
||||||
forceAutoSkip: true
|
forceAutoSkip: true
|
||||||
}),
|
}),
|
||||||
|
selectSegment,
|
||||||
onMobileYouTube: isOnMobileYouTube()
|
onMobileYouTube: isOnMobileYouTube()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -1349,6 +1356,11 @@ function updatePreviewBarPositionMobile(parent: HTMLElement) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function selectSegment(UUID: SegmentUUID): void {
|
||||||
|
selectedSegment = UUID;
|
||||||
|
updatePreviewBar();
|
||||||
|
}
|
||||||
|
|
||||||
function updatePreviewBar(): void {
|
function updatePreviewBar(): void {
|
||||||
if (previewBar === null) return;
|
if (previewBar === null) return;
|
||||||
|
|
||||||
@@ -1660,6 +1672,9 @@ function skipToTime({v, skipTime, skippingSegments, openNotice, forceAutoSkip, u
|
|||||||
// MacOS will loop otherwise #1027
|
// MacOS will loop otherwise #1027
|
||||||
// Sometimes playlists loop too #1804
|
// Sometimes playlists loop too #1804
|
||||||
v.currentTime = v.duration - 0.001;
|
v.currentTime = v.duration - 0.001;
|
||||||
|
} else if (v.duration > 1 && Math.abs(skipTime[1] - v.duration) < endTimeSkipBuffer
|
||||||
|
&& isFirefoxOrSafari() && !isSafari()) {
|
||||||
|
v.currentTime = v.duration;
|
||||||
} else {
|
} else {
|
||||||
if (inMuteSegment(skipTime[1], true)) {
|
if (inMuteSegment(skipTime[1], true)) {
|
||||||
// Make sure not to mute if skipping into a mute segment
|
// Make sure not to mute if skipping into a mute segment
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
import Config from "../config";
|
import Config from "../config";
|
||||||
import { SponsorTime } from "../types";
|
import { SegmentUUID, SponsorTime } from "../types";
|
||||||
import { getSkippingText } from "../utils/categoryUtils";
|
import { getSkippingText } from "../utils/categoryUtils";
|
||||||
import { AnimationUtils } from "../utils/animationUtils";
|
import { AnimationUtils } from "../utils/animationUtils";
|
||||||
import { keybindToString } from "../../maze-utils/src/config";
|
import { keybindToString } from "../../maze-utils/src/config";
|
||||||
|
|
||||||
export interface SkipButtonControlBarProps {
|
export interface SkipButtonControlBarProps {
|
||||||
skip: (segment: SponsorTime) => void;
|
skip: (segment: SponsorTime) => void;
|
||||||
|
selectSegment: (UUID: SegmentUUID) => void;
|
||||||
onMobileYouTube: boolean;
|
onMobileYouTube: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,7 +42,7 @@ export class SkipButtonControlBar {
|
|||||||
|
|
||||||
this.container = document.createElement("div");
|
this.container = document.createElement("div");
|
||||||
this.container.classList.add("skipButtonControlBarContainer");
|
this.container.classList.add("skipButtonControlBarContainer");
|
||||||
this.container.classList.add("hidden");
|
this.container.classList.add("sbhidden");
|
||||||
if (this.onMobileYouTube) this.container.classList.add("mobile");
|
if (this.onMobileYouTube) this.container.classList.add("mobile");
|
||||||
|
|
||||||
this.skipIcon = document.createElement("img");
|
this.skipIcon = document.createElement("img");
|
||||||
@@ -54,8 +55,18 @@ export class SkipButtonControlBar {
|
|||||||
this.container.appendChild(this.skipIcon);
|
this.container.appendChild(this.skipIcon);
|
||||||
this.container.appendChild(this.textContainer);
|
this.container.appendChild(this.textContainer);
|
||||||
this.container.addEventListener("click", () => this.toggleSkip());
|
this.container.addEventListener("click", () => this.toggleSkip());
|
||||||
this.container.addEventListener("mouseenter", () => this.stopTimer());
|
this.container.addEventListener("mouseenter", () => {
|
||||||
this.container.addEventListener("mouseleave", () => this.startTimer());
|
this.stopTimer();
|
||||||
|
|
||||||
|
if (this.segment) {
|
||||||
|
props.selectSegment(this.segment.UUID);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.container.addEventListener("mouseleave", () => {
|
||||||
|
this.startTimer();
|
||||||
|
|
||||||
|
props.selectSegment(null);
|
||||||
|
});
|
||||||
if (this.onMobileYouTube) {
|
if (this.onMobileYouTube) {
|
||||||
this.container.addEventListener("touchstart", (e) => this.handleTouchStart(e));
|
this.container.addEventListener("touchstart", (e) => this.handleTouchStart(e));
|
||||||
this.container.addEventListener("touchmove", (e) => this.handleTouchMove(e));
|
this.container.addEventListener("touchmove", (e) => this.handleTouchMove(e));
|
||||||
@@ -103,7 +114,7 @@ export class SkipButtonControlBar {
|
|||||||
|
|
||||||
this.refreshText();
|
this.refreshText();
|
||||||
this.container?.classList?.remove("textDisabled");
|
this.container?.classList?.remove("textDisabled");
|
||||||
this.textContainer?.classList?.remove("hidden");
|
this.textContainer?.classList?.remove("sbhidden");
|
||||||
AnimationUtils.disableAutoHideAnimation(this.skipIcon);
|
AnimationUtils.disableAutoHideAnimation(this.skipIcon);
|
||||||
|
|
||||||
this.startTimer();
|
this.startTimer();
|
||||||
@@ -111,8 +122,8 @@ export class SkipButtonControlBar {
|
|||||||
|
|
||||||
refreshText(): void {
|
refreshText(): void {
|
||||||
if (this.segment) {
|
if (this.segment) {
|
||||||
this.chapterText?.classList?.add("hidden");
|
this.chapterText?.classList?.add("sbhidden");
|
||||||
this.container.classList.remove("hidden");
|
this.container.classList.remove("sbhidden");
|
||||||
this.textContainer.innerText = this.getTitle();
|
this.textContainer.innerText = this.getTitle();
|
||||||
this.skipIcon.setAttribute("title", this.getTitle());
|
this.skipIcon.setAttribute("title", this.getTitle());
|
||||||
}
|
}
|
||||||
@@ -134,10 +145,10 @@ export class SkipButtonControlBar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
disable(): void {
|
disable(): void {
|
||||||
this.container.classList.add("hidden");
|
this.container.classList.add("sbhidden");
|
||||||
|
|
||||||
this.chapterText?.classList?.remove("hidden");
|
this.chapterText?.classList?.remove("sbhidden");
|
||||||
this.getChapterPrefix()?.classList?.remove("hidden");
|
this.getChapterPrefix()?.classList?.remove("sbhidden");
|
||||||
|
|
||||||
this.enabled = false;
|
this.enabled = false;
|
||||||
}
|
}
|
||||||
@@ -160,10 +171,10 @@ export class SkipButtonControlBar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.container.classList.add("textDisabled");
|
this.container.classList.add("textDisabled");
|
||||||
this.textContainer?.classList?.add("hidden");
|
this.textContainer?.classList?.add("sbhidden");
|
||||||
this.chapterText?.classList?.remove("hidden");
|
this.chapterText?.classList?.remove("sbhidden");
|
||||||
|
|
||||||
this.getChapterPrefix()?.classList?.add("hidden");
|
this.getChapterPrefix()?.classList?.add("sbhidden");
|
||||||
|
|
||||||
AnimationUtils.enableAutoHideAnimation(this.skipIcon);
|
AnimationUtils.enableAutoHideAnimation(this.skipIcon);
|
||||||
if (this.onMobileYouTube) {
|
if (this.onMobileYouTube) {
|
||||||
|
|||||||
@@ -1052,9 +1052,10 @@ async function runThePopup(messageListener?: MessageListener): Promise<void> {
|
|||||||
*/
|
*/
|
||||||
function getFormattedHours(minutes) {
|
function getFormattedHours(minutes) {
|
||||||
minutes = Math.round(minutes * 10) / 10;
|
minutes = Math.round(minutes * 10) / 10;
|
||||||
const days = Math.floor(minutes / 1440);
|
const years = Math.floor(minutes / 525600); // Assumes 365.0 days in a year
|
||||||
|
const days = Math.floor(minutes / 1440) % 365;
|
||||||
const hours = Math.floor(minutes / 60) % 24;
|
const hours = Math.floor(minutes / 60) % 24;
|
||||||
return (days > 0 ? days + chrome.i18n.getMessage("dayAbbreviation") + " " : "") + (hours > 0 ? hours + chrome.i18n.getMessage("hourAbbreviation") + " " : "") + (minutes % 60).toFixed(1);
|
return (years > 0 ? years + chrome.i18n.getMessage("yearAbbreviation") + " " : "") + (days > 0 ? days + chrome.i18n.getMessage("dayAbbreviation") + " " : "") + (hours > 0 ? hours + chrome.i18n.getMessage("hourAbbreviation") + " " : "") + (minutes % 60).toFixed(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
function contentConfigUpdateListener(changes: StorageChangesObject) {
|
function contentConfigUpdateListener(changes: StorageChangesObject) {
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ function applyLoadingAnimation(element: HTMLElement, time: number, callback?: ()
|
|||||||
|
|
||||||
function setupCustomHideAnimation(element: Element, container: Element, enabled = true, rightSlide = true): { hide: () => void; show: () => void } {
|
function setupCustomHideAnimation(element: Element, container: Element, enabled = true, rightSlide = true): { hide: () => void; show: () => void } {
|
||||||
if (enabled) element.classList.add("autoHiding");
|
if (enabled) element.classList.add("autoHiding");
|
||||||
element.classList.add("hidden");
|
element.classList.add("sbhidden");
|
||||||
element.classList.add("animationDone");
|
element.classList.add("animationDone");
|
||||||
if (!rightSlide) element.classList.add("autoHideLeft");
|
if (!rightSlide) element.classList.add("autoHideLeft");
|
||||||
|
|
||||||
@@ -37,7 +37,7 @@ function setupCustomHideAnimation(element: Element, container: Element, enabled
|
|||||||
hide: () => {
|
hide: () => {
|
||||||
mouseEntered = false;
|
mouseEntered = false;
|
||||||
if (element.classList.contains("autoHiding")) {
|
if (element.classList.contains("autoHiding")) {
|
||||||
element.classList.add("hidden");
|
element.classList.add("sbhidden");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
show: () => {
|
show: () => {
|
||||||
@@ -46,7 +46,7 @@ function setupCustomHideAnimation(element: Element, container: Element, enabled
|
|||||||
|
|
||||||
// Wait for next event loop
|
// Wait for next event loop
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (mouseEntered) element.classList.remove("hidden")
|
if (mouseEntered) element.classList.remove("sbhidden")
|
||||||
}, 10);
|
}, 10);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -61,12 +61,12 @@ function setupAutoHideAnimation(element: Element, container: Element, enabled =
|
|||||||
|
|
||||||
function enableAutoHideAnimation(element: Element): void {
|
function enableAutoHideAnimation(element: Element): void {
|
||||||
element.classList.add("autoHiding");
|
element.classList.add("autoHiding");
|
||||||
element.classList.add("hidden");
|
element.classList.add("sbhidden");
|
||||||
}
|
}
|
||||||
|
|
||||||
function disableAutoHideAnimation(element: Element): void {
|
function disableAutoHideAnimation(element: Element): void {
|
||||||
element.classList.remove("autoHiding");
|
element.classList.remove("autoHiding");
|
||||||
element.classList.remove("hidden");
|
element.classList.remove("sbhidden");
|
||||||
}
|
}
|
||||||
|
|
||||||
export const AnimationUtils = {
|
export const AnimationUtils = {
|
||||||
|
|||||||
Reference in New Issue
Block a user