Skip to content

Commit dfb28b1

Browse files
Feat: SponsorBlock improvements (#1849)
* Add setting for each SB category * Update SB Settings Component * Show other SB categories in seek bar * Use camelCase for SponsorBlock values Co-authored-by: PikachuEXE <[email protected]> * change "Don't Skip" to "Do Nothing" in locale * improve styling of sponsorblock settings * add filler category, don't repeat colors * Fix JS format issue caused during code conflict resolving * make sponsor block markers transparent * change opacity to 0.6 Co-authored-by: PikachuEXE <[email protected]>
1 parent 052a1fb commit dfb28b1

File tree

10 files changed

+350
-110
lines changed

10 files changed

+350
-110
lines changed
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
import Vue from 'vue'
2+
import { mapActions } from 'vuex'
3+
import FtSelect from '../ft-select/ft-select.vue'
4+
5+
export default Vue.extend({
6+
name: 'FtSponsorBlockCategory',
7+
components: {
8+
'ft-select': FtSelect
9+
},
10+
props: {
11+
categoryName: {
12+
type: String,
13+
required: true
14+
}
15+
},
16+
data: function () {
17+
return {
18+
categoryColor: '',
19+
skipOption: '',
20+
skipValues: [
21+
'autoSkip',
22+
// 'promptToSkip',
23+
'showInSeekBar',
24+
'doNothing'
25+
]
26+
}
27+
},
28+
computed: {
29+
colorValues: function () {
30+
return this.$store.getters.getColorNames
31+
},
32+
33+
colorNames: function () {
34+
return this.colorValues.map(colorVal => {
35+
// add spaces before capital letters
36+
const colorName = colorVal.replace(/([A-Z])/g, ' $1').trim()
37+
return this.$t(`Settings.Theme Settings.Main Color Theme.${colorName}`)
38+
})
39+
},
40+
41+
sponsorBlockValues: function() {
42+
let sponsorVal = ''
43+
switch (this.categoryName.toLowerCase()) {
44+
case 'sponsor':
45+
sponsorVal = this.$store.getters.getSponsorBlockSponsor
46+
break
47+
case 'self-promotion':
48+
sponsorVal = this.$store.getters.getSponsorBlockSelfPromo
49+
break
50+
case 'interaction':
51+
sponsorVal = this.$store.getters.getSponsorBlockInteraction
52+
break
53+
case 'intro':
54+
sponsorVal = this.$store.getters.getSponsorBlockIntro
55+
break
56+
case 'outro':
57+
sponsorVal = this.$store.getters.getSponsorBlockOutro
58+
break
59+
case 'recap':
60+
sponsorVal = this.$store.getters.getSponsorBlockRecap
61+
break
62+
case 'music offtopic':
63+
sponsorVal = this.$store.getters.getSponsorBlockMusicOffTopic
64+
break
65+
case 'filler':
66+
sponsorVal = this.$store.getters.getSponsorBlockFiller
67+
break
68+
}
69+
return sponsorVal
70+
},
71+
72+
skipNames: function() {
73+
return [
74+
this.$t('Settings.SponsorBlock Settings.Skip Options.Auto Skip'),
75+
// this.$t('Settings.SponsorBlock Settings.Skip Options.Prompt To Skip'),
76+
this.$t('Settings.SponsorBlock Settings.Skip Options.Show In Seek Bar'),
77+
this.$t('Settings.SponsorBlock Settings.Skip Options.Do Nothing')
78+
]
79+
}
80+
},
81+
82+
methods: {
83+
updateColor: function (color) {
84+
const payload = {
85+
color: color,
86+
skip: this.sponsorBlockValues.skip
87+
}
88+
this.updateSponsorCategory(payload)
89+
},
90+
91+
updateSkipOption: function (skipOption) {
92+
const payload = {
93+
color: this.sponsorBlockValues.color,
94+
skip: skipOption
95+
}
96+
97+
this.updateSponsorCategory(payload)
98+
},
99+
100+
updateSponsorCategory: function (payload) {
101+
switch (this.categoryName.toLowerCase()) {
102+
case 'sponsor':
103+
this.updateSponsorBlockSponsor(payload)
104+
break
105+
case 'self-promotion':
106+
this.updateSponsorBlockSelfPromo(payload)
107+
break
108+
case 'interaction':
109+
this.updateSponsorBlockInteraction(payload)
110+
break
111+
case 'intro':
112+
this.updateSponsorBlockIntro(payload)
113+
break
114+
case 'outro':
115+
this.updateSponsorBlockOutro(payload)
116+
break
117+
case 'recap':
118+
this.updateSponsorBlockRecap(payload)
119+
break
120+
case 'music offtopic':
121+
this.updateSponsorBlockMusicOffTopic(payload)
122+
break
123+
case 'filler':
124+
this.updateSponsorBlockFiller(payload)
125+
break
126+
}
127+
},
128+
129+
...mapActions([
130+
'showToast',
131+
'openExternalLink',
132+
'updateSponsorBlockSponsor',
133+
'updateSponsorBlockSelfPromo',
134+
'updateSponsorBlockInteraction',
135+
'updateSponsorBlockIntro',
136+
'updateSponsorBlockOutro',
137+
'updateSponsorBlockRecap',
138+
'updateSponsorBlockMusicOffTopic',
139+
'updateSponsorBlockFiller'
140+
])
141+
}
142+
})
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
@use "../../sass-partials/settings"
2+
.sponsorBlockCategory
3+
margin-top: 30px
4+
padding: 0 10px
5+
.sponsorTitle
6+
font-size: x-large
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<template>
2+
<div class="sponsorBlockCategory">
3+
<div class="sponsorTitle">
4+
{{ $t("Video.Sponsor Block category."+categoryName) }}
5+
</div>
6+
<ft-select
7+
:placeholder="$t('Settings.SponsorBlock Settings.Category Color')"
8+
:value="sponsorBlockValues.color"
9+
:select-names="colorNames"
10+
:select-values="colorValues"
11+
@change="updateColor"
12+
/>
13+
<ft-select
14+
:placeholder="$t('Settings.SponsorBlock Settings.Skip Options.Skip Option')"
15+
:value="sponsorBlockValues.skip"
16+
:select-names="skipNames"
17+
:select-values="skipValues"
18+
@change="updateSkipOption"
19+
/>
20+
</div>
21+
</template>
22+
<script src="./ft-sponsor-block-category.js" />
23+
<style scoped lang="sass" src="./ft-sponsor-block-category.sass" />

src/renderer/components/ft-video-player/ft-video-player.js

Lines changed: 69 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,62 @@ export default Vue.extend({
188188
return this.$store.getters.getDisplayVideoPlayButton
189189
},
190190

191+
sponsorSkips: function () {
192+
const sponsorCats = ['sponsor',
193+
'selfpromo',
194+
'interaction',
195+
'intro',
196+
'outro',
197+
'preview',
198+
'music_offtopic',
199+
'filler'
200+
]
201+
const autoSkip = {}
202+
const seekBar = []
203+
const promptSkip = {}
204+
const categoryData = {}
205+
sponsorCats.forEach(x => {
206+
let sponsorVal = {}
207+
switch (x) {
208+
case 'sponsor':
209+
sponsorVal = this.$store.getters.getSponsorBlockSponsor
210+
break
211+
case 'selfpromo':
212+
sponsorVal = this.$store.getters.getSponsorBlockSelfPromo
213+
break
214+
case 'interaction':
215+
sponsorVal = this.$store.getters.getSponsorBlockInteraction
216+
break
217+
case 'intro':
218+
sponsorVal = this.$store.getters.getSponsorBlockIntro
219+
break
220+
case 'outro':
221+
sponsorVal = this.$store.getters.getSponsorBlockOutro
222+
break
223+
case 'preview':
224+
sponsorVal = this.$store.getters.getSponsorBlockRecap
225+
break
226+
case 'music_offtopic':
227+
sponsorVal = this.$store.getters.getSponsorBlockMusicOffTopic
228+
break
229+
case 'filler':
230+
sponsorVal = this.$store.getters.getSponsorBlockFiller
231+
break
232+
}
233+
if (sponsorVal.skip !== 'doNothing') {
234+
seekBar.push(x)
235+
}
236+
if (sponsorVal.skip === 'autoSkip') {
237+
autoSkip[x] = true
238+
}
239+
if (sponsorVal.skip === 'promptToSkip') {
240+
promptSkip[x] = true
241+
}
242+
categoryData[x] = sponsorVal
243+
})
244+
return { autoSkip, seekBar, promptSkip, categoryData }
245+
},
246+
191247
maxVideoPlaybackRate: function () {
192248
return parseInt(this.$store.getters.getMaxVideoPlaybackRate)
193249
},
@@ -459,7 +515,7 @@ export default Vue.extend({
459515
initializeSponsorBlock() {
460516
this.sponsorBlockSkipSegments({
461517
videoId: this.videoId,
462-
categories: ['sponsor']
518+
categories: this.sponsorSkips.seekBar
463519
}).then((skipSegments) => {
464520
if (skipSegments.length === 0) {
465521
return
@@ -477,7 +533,8 @@ export default Vue.extend({
477533
this.addSponsorBlockMarker({
478534
time: startTime,
479535
duration: endTime - startTime,
480-
color: this.sponsorBlockCategoryColor(category)
536+
color: 'var(--primary-color)',
537+
category: category
481538
})
482539
})
483540
})
@@ -496,10 +553,12 @@ export default Vue.extend({
496553
}
497554
})
498555
if (newTime !== null && Math.abs(duration - currentTime) > 0.500) {
499-
if (this.sponsorBlockShowSkippedToast) {
500-
this.showSkippedSponsorSegmentInformation(skippedCategory)
556+
if (this.sponsorSkips.autoSkip[skippedCategory]) {
557+
if (this.sponsorBlockShowSkippedToast) {
558+
this.showSkippedSponsorSegmentInformation(skippedCategory)
559+
}
560+
this.player.currentTime(newTime)
501561
}
502-
this.player.currentTime(newTime)
503562
}
504563
},
505564

@@ -524,42 +583,25 @@ export default Vue.extend({
524583
return this.$t('Video.Sponsor Block category.interaction')
525584
case 'music_offtopic':
526585
return this.$t('Video.Sponsor Block category.music offtopic')
586+
case 'filler':
587+
return this.$t('Video.Sponsor Block category.filler')
527588
default:
528589
console.error(`Unknown translation for SponsorBlock category ${category}`)
529590
return category
530591
}
531592
},
532593

533-
sponsorBlockCategoryColor(category) {
534-
// TODO: allow to set these colors in settings
535-
switch (category) {
536-
case 'sponsor':
537-
return 'var(--accent-color)'
538-
case 'intro':
539-
return 'var(--accent-color)'
540-
case 'outro':
541-
return 'var(--accent-color)'
542-
case 'selfpromo':
543-
return 'var(--accent-color)'
544-
case 'interaction':
545-
return 'var(--accent-color)'
546-
case 'music_offtopic':
547-
return 'var(--accent-color)'
548-
default:
549-
console.error(`Unknown SponsorBlock category ${category}`)
550-
return 'var(--accent-color)'
551-
}
552-
},
553-
554594
addSponsorBlockMarker(marker) {
555595
const markerDiv = videojs.dom.createEl('div', {}, {})
556596

557-
markerDiv.className = 'sponsorBlockMarker'
597+
markerDiv.className = `sponsorBlockMarker main${this.sponsorSkips.categoryData[marker.category].color}`
558598
markerDiv.style.height = '100%'
559599
markerDiv.style.position = 'absolute'
600+
markerDiv.style.opacity = '0.6'
560601
markerDiv.style['background-color'] = marker.color
561602
markerDiv.style.width = (marker.duration / this.player.duration()) * 100 + '%'
562603
markerDiv.style.marginLeft = (marker.time / this.player.duration()) * 100 + '%'
604+
markerDiv.title = this.sponsorBlockTranslatedCategory(marker.category)
563605

564606
this.player.el().querySelector('.vjs-progress-holder').appendChild(markerDiv)
565607
},

src/renderer/components/sponsor-block-settings/sponsor-block-settings.js

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,30 @@ import FtCard from '../ft-card/ft-card.vue'
44
import FtToggleSwitch from '../ft-toggle-switch/ft-toggle-switch.vue'
55
import FtInput from '../ft-input/ft-input.vue'
66
import FtFlexBox from '../ft-flex-box/ft-flex-box.vue'
7+
import FtSponsorBlockCategory from '../ft-sponsor-block-category/ft-sponsor-block-category.vue'
78

89
export default Vue.extend({
910
name: 'SponsorBlockSettings',
1011
components: {
1112
'ft-card': FtCard,
1213
'ft-toggle-switch': FtToggleSwitch,
1314
'ft-input': FtInput,
14-
'ft-flex-box': FtFlexBox
15+
'ft-flex-box': FtFlexBox,
16+
'ft-sponsor-block-category': FtSponsorBlockCategory
17+
},
18+
data: function () {
19+
return {
20+
categories: [
21+
'sponsor',
22+
'self-promotion',
23+
'interaction',
24+
'intro',
25+
'outro',
26+
'recap',
27+
'music offtopic',
28+
'filler'
29+
]
30+
}
1531
},
1632
computed: {
1733
useSponsorBlock: function () {

src/renderer/components/sponsor-block-settings/sponsor-block-settings.vue

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,13 @@
3232
@input="handleUpdateSponsorBlockUrl"
3333
/>
3434
</ft-flex-box>
35+
<ft-flex-box>
36+
<ft-sponsor-block-category
37+
v-for="category in categories"
38+
:key="category"
39+
:category-name="category"
40+
/>
41+
</ft-flex-box>
3542
</div>
3643
</details>
3744
</template>

0 commit comments

Comments
 (0)