diff --git a/materialious/electron/package-lock.json b/materialious/electron/package-lock.json index 0066cb29..6e96ae80 100644 --- a/materialious/electron/package-lock.json +++ b/materialious/electron/package-lock.json @@ -1,12 +1,12 @@ { "name": "Materialious", - "version": "1.13.0", + "version": "1.13.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "Materialious", - "version": "1.13.0", + "version": "1.13.1", "license": "MIT", "dependencies": { "@capacitor-community/electron": "^5.0.0", diff --git a/materialious/src/lib/components/Player.svelte b/materialious/src/lib/components/Player.svelte index bf52e4cb..e8c5d90c 100644 --- a/materialious/src/lib/components/Player.svelte +++ b/materialious/src/lib/components/Player.svelte @@ -38,6 +38,7 @@ sponsorBlockCategoriesStore, sponsorBlockDisplayToastStore, sponsorBlockStore, + sponsorBlockTimelineStore, sponsorBlockUrlStore, synciousInstanceStore, synciousStore @@ -71,7 +72,8 @@ showControls = false }: Props = $props(); - let segments: Segment[] = []; + let segments: Segment[] = $state([]); + let segmentManualSkip: Segment | undefined = $state(); let snackBarAlert = $state(''); let originalOrigination: ScreenOrientationResult | undefined; @@ -264,20 +266,31 @@ document.addEventListener('fullscreenchange', onAndroidFullscreenChange); } + function skipSegment(segment: Segment) { + if (!playerElement) return; + + segmentManualSkip = undefined; + + if (Math.round(playerElement.currentTime) >= Math.round(playerElement.duration)) { + return; + } + playerElement.currentTime = segment.endTime + 1; + if (!get(sponsorBlockDisplayToastStore)) { + snackBarAlert = `${get(_)('skipping')} ${segment.category}`; + ui('#snackbar-alert'); + } + } + async function setupSponsorSkip() { if (!$sponsorBlockUrlStore || !$sponsorBlockCategoriesStore || !$sponsorBlockStore) return; - if ( - $sponsorBlockCategoriesStore.length > 0 && - $sponsorBlockUrlStore && - $sponsorBlockUrlStore !== '' - ) { + if ($sponsorBlockCategoriesStore && $sponsorBlockUrlStore && $sponsorBlockUrlStore !== '') { const sponsorBlock = new SponsorBlock('', { baseURL: $sponsorBlockUrlStore }); try { segments = await sponsorBlock.getSegments( data.video.videoId, - $sponsorBlockCategoriesStore as Category[] + Object.keys($sponsorBlockCategoriesStore) as Category[] ); playerElement?.addEventListener('timeupdate', () => { @@ -288,12 +301,13 @@ playerElement.currentTime >= segment.startTime && playerElement.currentTime <= segment.endTime ) { - if (Math.round(playerElement.currentTime) >= Math.round(playerElement.duration)) { - return; - } - playerElement.currentTime = segment.endTime + 1; - if (!get(sponsorBlockDisplayToastStore)) { - snackBarAlert = `${get(_)('skipping')} ${segment.category}`; + const segmentTrigger = $sponsorBlockCategoriesStore[segment.category]; + + if (segmentTrigger === 'automatic') { + skipSegment(segment); + } else if (segmentTrigger === 'manual') { + snackBarAlert = `${get(_)('upcomingSegment')} ${segment.category}`; + segmentManualSkip = segment; ui('#snackbar-alert'); } } @@ -747,6 +761,12 @@ playerElement.currentTime = playerElement.currentTime - playerDoubleTapSeek; return false; }); + + Mousetrap.bind('enter', () => { + if (segmentManualSkip) { + skipSegment(segmentManualSkip); + } + }); } Mousetrap.bind('c', () => { @@ -1057,7 +1077,7 @@ window.removeEventListener('resize', updateVideoPlayerHeight); - Mousetrap.unbind(['left', 'right', 'space', 'c', 'f', 'shift+left', 'shift+right']); + Mousetrap.unbind(['left', 'right', 'space', 'c', 'f', 'shift+left', 'shift+right', 'enter']); if (watchProgressInterval) clearTimeout(watchProgressInterval); @@ -1170,6 +1190,15 @@ )} > {/each} + {#if !$sponsorBlockTimelineStore} + {#each segments as segment (segment)} +
+ {/each} + {/if} {#if playerTimelineTooltipVisible} @@ -1443,6 +1472,9 @@ {#if !isEmbed}
{snackBarAlert} + {#if segmentManualSkip} + + {/if}
{/if} @@ -1547,6 +1579,10 @@ pointer-events: none; } + .segment-marker { + background-color: var(--tertiary); + } + menu.mobile { transform: scale(1) translateY(-40%) translateX(0); width: 300px; diff --git a/materialious/src/lib/components/settings/SponsorBlock.svelte b/materialious/src/lib/components/settings/SponsorBlock.svelte index c8328331..cc0a565d 100644 --- a/materialious/src/lib/components/settings/SponsorBlock.svelte +++ b/materialious/src/lib/components/settings/SponsorBlock.svelte @@ -8,14 +8,10 @@ sponsorBlockCategoriesStore, sponsorBlockDisplayToastStore, sponsorBlockStore, + sponsorBlockTimelineStore, sponsorBlockUrlStore } from '../../store'; - let sponsorCategoriesList: string[] = $state([]); - sponsorBlockCategoriesStore.subscribe((value) => { - sponsorCategoriesList = value; - }); - let sponsorBlockInstance = $state(get(sponsorBlockUrlStore)); const sponsorCategories = [ @@ -28,13 +24,21 @@ { name: $_('layout.sponsors.tangentJokes'), category: 'filler' } ]; - function toggleSponsor(category: string) { - if (sponsorCategoriesList.includes(category)) { - sponsorBlockCategoriesStore.set(sponsorCategoriesList.filter((value) => value !== category)); + function onSponsorSet( + category: string, + event: Event & { currentTarget: EventTarget & HTMLSelectElement } + ) { + const value = event.currentTarget.value as 'automatic' | 'manual' | 'timeline' | 'disabled'; + + const categories = get(sponsorBlockCategoriesStore); + + if (value !== 'disabled') { + categories[category] = value; } else { - sponsorCategoriesList.push(category); - sponsorBlockCategoriesStore.set(sponsorCategoriesList); + delete categories[category]; } + + sponsorBlockCategoriesStore.set(categories); } @@ -89,7 +93,7 @@ - +

{$_('layout.sponsors.Catagories')}

{#each sponsorCategories as sponsor (sponsor)} + {@const currentCatergoryTrigger = $sponsorBlockCategoriesStore[sponsor.category]}
{/each} diff --git a/materialious/src/lib/externalSettings.ts b/materialious/src/lib/externalSettings.ts index cc81f8bf..fba1ed33 100644 --- a/materialious/src/lib/externalSettings.ts +++ b/materialious/src/lib/externalSettings.ts @@ -25,7 +25,6 @@ import { returnYTDislikesInstanceStore, returnYtDislikesStore, showWarningStore, - sponsorBlockCategoriesStore, sponsorBlockDisplayToastStore, sponsorBlockStore, sponsorBlockUrlStore, @@ -109,11 +108,6 @@ const persistedStores: { store: sponsorBlockUrlStore, type: 'string' }, - { - name: 'sponsorBlockCategories', - store: sponsorBlockCategoriesStore, - type: 'array' - }, { name: 'deArrowInstance', store: deArrowInstanceStore, diff --git a/materialious/src/lib/i18n/locales/en.json b/materialious/src/lib/i18n/locales/en.json index 7e688c01..eba4e76a 100644 --- a/materialious/src/lib/i18n/locales/en.json +++ b/materialious/src/lib/i18n/locales/en.json @@ -29,6 +29,8 @@ "donate": "Donate", "deleteAllHistory": "Delete all history", "skipping": "Skipping", + "skip": "Skip", + "upcomingSegment": "Upcoming ", "comments": "comments", "reply": "reply", "replies": "replies", @@ -203,7 +205,10 @@ "intermissionIntroAnimation": "Intermission/Intro Animation", "credits": "Endcards/Credits", "preViewRecapHook": "Preview/Recap/Hook", - "tangentJokes": "Filler Tangent/Jokes" + "tangentJokes": "Filler Tangent/Jokes", + "automatic": "Auto skip", + "manual": "Manual skip", + "timeline": "Timeline only" }, "deArrow": { "title": "DeArrow", diff --git a/materialious/src/lib/store.ts b/materialious/src/lib/store.ts index 83ce5854..e62293f3 100644 --- a/materialious/src/lib/store.ts +++ b/materialious/src/lib/store.ts @@ -279,11 +279,10 @@ export const sponsorBlockUrlStore: Writable = persist createStorage(), 'sponsorBlockUrl' ); -export const sponsorBlockCategoriesStore: Writable = persist( - writable([]), - createStorage(), - 'sponsorBlockCategories' -); + +export const sponsorBlockCategoriesStore: Writable< + Record +> = persist(writable({}), createStorage(), 'sponsorBlockCategoriesv2'); export const sponsorBlockDisplayToastStore: Writable = persist( writable(false),