From 930575290178151f19dad0d3e417bda614a60a8e Mon Sep 17 00:00:00 2001 From: Ajay Date: Sun, 14 Jun 2026 18:09:08 -0400 Subject: [PATCH 1/2] Fix YouTube chapters sometimes not being shown in the timeline --- src/content.ts | 4 +++- src/utils/pageUtils.ts | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/content.ts b/src/content.ts index d02beae29..f5bca1901 100644 --- a/src/content.ts +++ b/src/content.ts @@ -1427,7 +1427,9 @@ function updatePreviewBar(): void { const previewBarSegments: PreviewBarSegment[] = []; if (sponsorTimes) { sponsorTimes.forEach((segment) => { - if (segment.hidden !== SponsorHideType.Visible || getCategorySelection(segment).option === CategorySkipOption.Disabled) return; + if (segment.hidden !== SponsorHideType.Visible + || (getCategorySelection(segment).option === CategorySkipOption.Disabled + && ![SponsorSourceType.YouTube, SponsorSourceType.Autogenerated].includes(segment.source))) return; previewBarSegments.push({ segment: segment.segment as [number, number], diff --git a/src/utils/pageUtils.ts b/src/utils/pageUtils.ts index 034ff0f01..6293e5241 100644 --- a/src/utils/pageUtils.ts +++ b/src/utils/pageUtils.ts @@ -75,7 +75,7 @@ export function getExistingChapters(currentVideoID: VideoID, duration: number): const links = chaptersBox.querySelectorAll("ytd-macro-markers-list-item-renderer > a"); for (const link of links) { const timeElement = link.querySelector("#time") as HTMLElement; - const description = link.querySelector("#details h4") as HTMLElement; + const description = link.querySelector("#details h3") as HTMLElement; if (timeElement && description?.innerText?.length > 0 && link.getAttribute("href")?.includes(currentVideoID)) { const time = getFormattedTimeToSeconds(timeElement.innerText.replace(/\./g, ":")); if (time === null) return []; From 30144815a6d69263c6d0c788c2d01b423144beff Mon Sep 17 00:00:00 2001 From: Ajay Date: Sun, 14 Jun 2026 23:50:46 -0400 Subject: [PATCH 2/2] Add option to hide creator chapters --- public/_locales | 2 +- .../options/CategoryChooserComponent.tsx | 1 + .../options/CategorySkipOptionsComponent.tsx | 5 +++++ src/config.ts | 4 ++++ src/content.ts | 2 ++ src/js-components/previewBar.ts | 15 ++++++++++----- src/utils/pageUtils.ts | 3 ++- src/utils/skipProfiles.ts | 3 ++- 8 files changed, 27 insertions(+), 8 deletions(-) diff --git a/public/_locales b/public/_locales index 146846aaa..0ceeb00a0 160000 --- a/public/_locales +++ b/public/_locales @@ -1 +1 @@ -Subproject commit 146846aaa220ec3491ca4f2f3931227b090a1634 +Subproject commit 0ceeb00a056cbe4bd396fd08d8f8a32c6206f46a diff --git a/src/components/options/CategoryChooserComponent.tsx b/src/components/options/CategoryChooserComponent.tsx index 82f559e8d..996a85fca 100644 --- a/src/components/options/CategoryChooserComponent.tsx +++ b/src/components/options/CategoryChooserComponent.tsx @@ -41,6 +41,7 @@ export function CategoryChooserComponent() { name: `${chrome.i18n.getMessage("NewConfiguration")} ${Object.keys(Config.local.skipProfiles).length}`, categorySelections: [], showAutogeneratedChapters: null, + showCreatorChapters: null, autoSkipOnMusicVideos: null, skipNonMusicOnlyOnYoutubeMusic: null, muteSegments: null, diff --git a/src/components/options/CategorySkipOptionsComponent.tsx b/src/components/options/CategorySkipOptionsComponent.tsx index 808b78d64..b0801e56c 100644 --- a/src/components/options/CategorySkipOptionsComponent.tsx +++ b/src/components/options/CategorySkipOptionsComponent.tsx @@ -278,6 +278,11 @@ function getExtraOptions(category: string): ToggleOption[] { label: chrome.i18n.getMessage("showAutogeneratedChapters"), type: "toggle", dontDisable: true + }, { + configKey: "showCreatorChapters", + label: chrome.i18n.getMessage("showCreatorChapters"), + type: "toggle", + dontDisable: true }]; case "music_offtopic": return [{ diff --git a/src/config.ts b/src/config.ts index 1ec044754..38b579c5d 100644 --- a/src/config.ts +++ b/src/config.ts @@ -69,6 +69,7 @@ interface SBConfig { showCategoryWithoutPermission: boolean; showSegmentNameInChapterBar: boolean; showAutogeneratedChapters: boolean; + showCreatorChapters: boolean; useVirtualTime: boolean; showSegmentFailedToFetchWarning: boolean; allowScrollingToEdit: boolean; @@ -145,6 +146,7 @@ export interface CustomConfiguration { name: string; categorySelections: CategorySelection[]; showAutogeneratedChapters: boolean | null; + showCreatorChapters: boolean | null; autoSkipOnMusicVideos: boolean | null; skipNonMusicOnlyOnYoutubeMusic: boolean | null; muteSegments: boolean | null; @@ -239,6 +241,7 @@ function migrateOldSyncFormats(config: SBConfig, local: SBStorage) { option: CategorySkipOption.ShowOverlay })), showAutogeneratedChapters: null, + showCreatorChapters: null, autoSkipOnMusicVideos: null, skipNonMusicOnlyOnYoutubeMusic: null, muteSegments: null, @@ -430,6 +433,7 @@ const syncDefaults = { showCategoryWithoutPermission: false, showSegmentNameInChapterBar: true, showAutogeneratedChapters: true, + showCreatorChapters: true, useVirtualTime: true, showSegmentFailedToFetchWarning: true, allowScrollingToEdit: true, diff --git a/src/content.ts b/src/content.ts index 1a1301bac..75a1fd189 100644 --- a/src/content.ts +++ b/src/content.ts @@ -1327,6 +1327,8 @@ function importExistingChapters(wait: boolean) { function handleExistingChaptersChannelChange() { if (existingChaptersImported && hasAutogeneratedChapters() && !getSkipProfileBool("showAutogeneratedChapters")) { sponsorTimes = sponsorTimes.filter((segment) => segment.source !== SponsorSourceType.Autogenerated); + } else if (existingChaptersImported && !getSkipProfileBool("showCreatorChapters")) { + sponsorTimes = sponsorTimes.filter((segment) => segment.source !== SponsorSourceType.YouTube); } } diff --git a/src/js-components/previewBar.ts b/src/js-components/previewBar.ts index a90cc73dc..84e630c80 100644 --- a/src/js-components/previewBar.ts +++ b/src/js-components/previewBar.ts @@ -187,7 +187,8 @@ class PreviewBar { } const hasAYouTubeChapterRemoved = this.hasYouTubeChapters - || (!getSkipProfileBool("showAutogeneratedChapters") && hasAutogeneratedChapters()); + || (!getSkipProfileBool("showAutogeneratedChapters") && hasAutogeneratedChapters()) + || !getSkipProfileBool("showCreatorChapters"); if (hasAYouTubeChapterRemoved) { // Hide original tooltip if some chapter has been filtered out originalTooltip.style.display = "none"; @@ -463,7 +464,8 @@ class PreviewBar { || (!Config.config.renderSegmentsAsChapters && segments.every((segment) => segment.actionType !== ActionType.Chapter || [SponsorSourceType.YouTube, SponsorSourceType.Autogenerated].includes(segment.source)))) - && !(hasAutogeneratedChapters() && !getSkipProfileBool("showAutogeneratedChapters"))) { + && !(hasAutogeneratedChapters() && !getSkipProfileBool("showAutogeneratedChapters")) + && getSkipProfileBool("showCreatorChapters")) { if (this.customChaptersBar) this.customChaptersBar.style.display = "none"; this.originalChapterBar.style.removeProperty("display"); @@ -490,7 +492,8 @@ class PreviewBar { this.chapterGroups = this.unfilteredChapterGroups; } - if (this.chapterGroups.length === 0 && !getSkipProfileBool("showAutogeneratedChapters") && hasAutogeneratedChapters()) { + if (this.chapterGroups.length === 0 + && ((!getSkipProfileBool("showAutogeneratedChapters") && hasAutogeneratedChapters()) || !getSkipProfileBool("showCreatorChapters"))) { // Add placeholder chapter group for whole video this.chapterGroups = [{ segment: [0, this.videoDuration], @@ -892,7 +895,8 @@ class PreviewBar { if (!Config.config.showSegmentNameInChapterBar || Config.config.disableSkipping || ((!segments || segments.length <= 0) && submittingSegments?.length <= 0 - && (getSkipProfileBool("showAutogeneratedChapters") || !hasAutogeneratedChapters()))) { + && (getSkipProfileBool("showAutogeneratedChapters") || !hasAutogeneratedChapters()) + && getSkipProfileBool("showCreatorChapters"))) { const chaptersContainer = this.getChaptersContainer(); if (chaptersContainer) { chaptersContainer.querySelector(".sponsorChapterText")?.remove(); @@ -995,7 +999,8 @@ class PreviewBar { } else { this.chapterVote.setVisibility(false); } - } else if (!getSkipProfileBool("showAutogeneratedChapters") && hasAutogeneratedChapters()) { + } else if ((!getSkipProfileBool("showAutogeneratedChapters") && hasAutogeneratedChapters()) + || !getSkipProfileBool("showCreatorChapters")) { // Keep original hidden chaptersContainer.querySelector(".sponsorChapterText")?.remove(); const chapterTitle = chaptersContainer.querySelector(".ytp-chapter-title-content") as HTMLDivElement; diff --git a/src/utils/pageUtils.ts b/src/utils/pageUtils.ts index 6293e5241..4933c2145 100644 --- a/src/utils/pageUtils.ts +++ b/src/utils/pageUtils.ts @@ -66,7 +66,8 @@ export function getExistingChapters(currentVideoID: VideoID, duration: number): if (title?.textContent?.includes("Key moment")) return []; const autogenerated = hasAutogeneratedChapters(); - if (!getSkipProfileBool("showAutogeneratedChapters") && autogenerated) return []; + if ((!getSkipProfileBool("showAutogeneratedChapters") && autogenerated) + || !getSkipProfileBool("showCreatorChapters")) return []; const chapters: SponsorTime[] = []; // .ytp-timed-markers-container indicates that key-moments are present, which should not be divided diff --git a/src/utils/skipProfiles.ts b/src/utils/skipProfiles.ts index 7e0a6af03..fdd49c75a 100644 --- a/src/utils/skipProfiles.ts +++ b/src/utils/skipProfiles.ts @@ -58,6 +58,7 @@ export function getSkipProfile(): CustomConfiguration | null { type SkipProfileBoolKey = "showAutogeneratedChapters" + | "showCreatorChapters" | "autoSkipOnMusicVideos" | "skipNonMusicOnlyOnYoutubeMusic" | "muteSegments" @@ -74,7 +75,7 @@ export function getSkipProfileNum(key: "minDuration"): number { function getSkipProfileValue(key: keyof CustomConfiguration): T { const profile = getSkipProfile(); - if (profile && profile[key] !== null) { + if (profile && profile[key] !== null && profile[key] !== undefined) { return profile[key] as T; }