Compare commits

...

9 Commits

Author SHA1 Message Date
Ajay
97aea1c268 Fix icon sizes 2022-05-31 13:12:01 -04:00
Ajay
b70f50e1a0 Fix skip notice width limiting 2022-05-31 03:06:48 -04:00
Ajay
4880227320 Fix blank skip notice title when unskipping 2022-05-31 02:58:36 -04:00
Ajay
dfa21068f4 Fix buttons being offset on guidelines notice 2022-05-31 02:55:44 -04:00
Ajay
fd75a33e50 Use full details instead of learn more 2022-05-31 02:55:32 -04:00
Ajay
1409c563e2 Add guidelines for all categories 2022-05-31 02:37:29 -04:00
Ajay
588c42d579 Add initial sponsor help page 2022-05-31 00:50:32 -04:00
Ajay
d7ff6aa6a2 Add user to channel id regex 2022-05-26 22:25:16 -04:00
Ajay
44266e508b Another fix for firefox addon icon 2022-05-26 15:56:21 -04:00
25 changed files with 780 additions and 42 deletions

View File

@@ -34,6 +34,7 @@
"icons/settings.svg",
"icons/pencil.svg",
"icons/check.svg",
"icons/check-smaller.svg",
"icons/upvote.png",
"icons/downvote.png",
"icons/thumbs_down.svg",
@@ -50,6 +51,16 @@
"icons/heart.svg",
"icons/visible.svg",
"icons/not_visible.svg",
"icons/money.svg",
"icons/segway.png",
"icons/close-smaller.svg",
"icons/right-arrow.svg",
"icons/campaign.svg",
"icons/star.svg",
"icons/lightbulb.svg",
"icons/bolt.svg",
"icons/stopwatch.svg",
"icons/music-note.svg",
"icons/PlayerInfoIconSponsorBlocker.svg",
"icons/PlayerDeleteIconSponsorBlocker.svg",
"popup.html",
@@ -68,8 +79,31 @@
"default_icon": {
"16": "icons/IconSponsorBlocker16px.png",
"32": "icons/IconSponsorBlocker32px.png",
"64": "icons/LogoSponsorBlocker64px.png"
}
"64": "icons/LogoSponsorBlocker64px.png",
"128": "icons/LogoSponsorBlocker128px.png"
},
"theme_icons": [
{
"light": "icons/IconSponsorBlocker16px.png",
"dark": "icons/IconSponsorBlocker16px.png",
"size": 16
},
{
"light": "icons/IconSponsorBlocker32px.png",
"dark": "icons/IconSponsorBlocker32px.png",
"size": 32
},
{
"light": "icons/LogoSponsorBlocker64px.png",
"dark": "icons/LogoSponsorBlocker64px.png",
"size": 64
},
{
"light": "icons/LogoSponsorBlocker128px.png",
"dark": "icons/LogoSponsorBlocker128px.png",
"size": 128
}
]
},
"background": {
"scripts":[

View File

@@ -239,6 +239,9 @@
"showSkipNotice": {
"message": "Show Notice After A Segment Is Skipped"
},
"showCategoryGuidelines": {
"message": "Show Category Help"
},
"noticeVisibilityMode0": {
"message": "Full Size Skip Notices"
},
@@ -542,18 +545,39 @@
"message": "to",
"description": "Used between segments. Example: 1:20 to 1:30"
},
"generic_guideline1": {
"message": "Include segue transitions"
},
"generic_guideline2": {
"message": "Plays as if nothing was skipped"
},
"category_sponsor": {
"message": "Sponsor"
},
"category_sponsor_description": {
"message": "Paid promotion, paid referrals and direct advertisements. Not for self-promotion or free shoutouts to causes/creators/websites/products they like."
},
"category_sponsor_guideline1": {
"message": "Paid promotions"
},
"category_sponsor_guideline2": {
"message": "Not for donations or custom merch"
},
"category_selfpromo": {
"message": "Unpaid/Self Promotion"
},
"category_selfpromo_description": {
"message": "Similar to \"sponsor\" except for unpaid or self promotion. This includes sections about merchandise, donations, or information about who they collaborated with."
},
"category_selfpromo_guideline1": {
"message": "Donations, memberships and custom merch"
},
"category_selfpromo_guideline2": {
"message": "Free shoutouts that don't add to the video"
},
"category_selfpromo_guideline3": {
"message": "Not for corporate designed products and merch"
},
"category_exclusive_access": {
"message": "Exclusive Access"
},
@@ -564,12 +588,24 @@
"message": "This video showcases a product, service or location that they've received free or subsidized access to",
"description": "Short description for this category"
},
"category_exclusive_access_guideline1": {
"message": "Entire video showcases something where recieved free or subsidized access"
},
"category_interaction": {
"message": "Interaction Reminder (Subscribe)"
},
"category_interaction_description": {
"message": "When there is a short reminder to like, subscribe or follow them in the middle of content. If it is long or about something specific, it should be under self promotion instead."
},
"category_interaction_guideline1": {
"message": "Short reminders to like, subscribe or follow"
},
"category_interaction_guideline2": {
"message": "Includes indirect reminders to comment"
},
"category_interaction_guideline3": {
"message": "Not for general promotion, only calls to action"
},
"category_interaction_short": {
"message": "Interaction Reminder"
},
@@ -582,18 +618,36 @@
"category_intro_short": {
"message": "Intermission"
},
"category_intro_guideline1": {
"message": "Interval without actual content"
},
"category_intro_guideline2": {
"message": "Not for transitions with information"
},
"category_outro": {
"message": "Endcards/Credits"
},
"category_outro_description": {
"message": "Credits or when the YouTube endcards appear. Not for conclusions with information."
},
"category_outro_guideline1": {
"message": "Don't include content, even if endcards are on screen"
},
"category_preview": {
"message": "Preview/Recap"
},
"category_preview_description": {
"message": "Quick recap of previous episodes, or a preview of what's coming up later in the current video. Meant for edited together clips, not for spoken summaries."
},
"category_preview_guideline1": {
"message": "Clips that appear later, or in a future video"
},
"category_preview_guideline2": {
"message": "Recap of a previous video"
},
"category_preview_guideline3": {
"message": "Not for sections that add additional content"
},
"category_filler": {
"message": "Filler Tangent/Jokes"
},
@@ -603,6 +657,15 @@
"category_filler_short": {
"message": "Filler"
},
"category_filler_guideline1": {
"message": "Tangential scenes only for filler or humor"
},
"category_filler_guideline2": {
"message": "Distractions, bloopers, replays"
},
"category_filler_guideline3": {
"message": "Not for scenes required to understand the topic"
},
"category_music_offtopic": {
"message": "Music: Non-Music Section"
},
@@ -612,12 +675,27 @@
"category_music_offtopic_short": {
"message": "Non-Music"
},
"category_music_offtopic_guideline1": {
"message": "Sections not in official releases"
},
"category_music_offtopic_guideline2": {
"message": "Non-music in a live performance"
},
"category_poi_highlight": {
"message": "Highlight"
},
"category_poi_highlight_description": {
"message": "The part of the video that most people are looking for. Similar to \"Video starts at x\" comments."
},
"category_poi_highlight_guideline1": {
"message": "Section most people are looking for"
},
"category_poi_highlight_guideline2": {
"message": "Can help skip past context"
},
"category_poi_highlight_guideline3": {
"message": "Can skip to the title or thumbnail"
},
"category_livestream_messages": {
"message": "Livestream: Donation/Message Readings"
},
@@ -867,7 +945,10 @@
"LearnMore": {
"message": "Learn More"
},
"CopyDownvoteButtonInfo": {
"FullDetails": {
"message": "Full Details"
},
"CopyDownvoteButtonInfo": {
"message": "Downvotes and creates a local copy for you to resubmit"
},
"OpenCategoryWikiPage": {

View File

@@ -156,9 +156,6 @@
}
.sponsorSkipNoticeParent, .sponsorSkipNotice {
min-width: 350px;
max-width: 50%;
border-spacing: 5px 10px;
padding-left: 5px;
padding-right: 5px;
@@ -166,6 +163,15 @@
border-collapse: unset;
}
.sponsorSkipNoticeParent {
min-width: 350px;
max-width: 50%;
}
.sponsorSkipNotice {
width: 100%;
}
.sponsorSkipNoticeTableContainer {
background-color: rgba(28, 28, 28, 0.9);
border-radius: 5px;
@@ -177,7 +183,7 @@
}
.sponsorSkipNoticeLimitWidth {
min-width: calc(100% - 50px);
max-width: calc(100% - 50px);
}
.sponsorSkipNotice .hidden {
@@ -347,6 +353,22 @@
color: rgb(235, 235, 235);
}
.sb-guidelines-notice .sponsorTimesInfoMessage td {
padding-left: 5px;
padding-top: 2px;
padding-bottom: 2px;
font-size: 15px;
display: flex;
align-items: center;
}
.sponsorTimesInfoIcon {
width: 30px;
padding-right: 10px;
padding-left: 10px;
}
.segmentSummary {
outline: none !important;
}

37
public/icons/bolt.svg Normal file
View File

@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
height="48"
width="48"
version="1.1"
id="svg4"
sodipodi:docname="bolt.svg"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs8" />
<sodipodi:namedview
id="namedview6"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="13.125"
inkscape:cx="24"
inkscape:cy="24"
inkscape:window-width="1920"
inkscape:window-height="983"
inkscape:window-x="482"
inkscape:window-y="768"
inkscape:window-maximized="1"
inkscape:current-layer="svg4" />
<path
d="M19.95 42 22 27.9H14.7Q14.15 27.9 13.9 27.4Q13.65 26.9 13.9 26.45L26.15 6H28.2L26.15 20.05H33.35Q33.9 20.05 34.175 20.55Q34.45 21.05 34.2 21.5L22 42Z"
id="path2"
style="fill:#ffffff" />
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

37
public/icons/campaign.svg Normal file
View File

@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
height="48"
width="48"
version="1.1"
id="svg4"
sodipodi:docname="campaign.svg"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs8" />
<sodipodi:namedview
id="namedview6"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="13.125"
inkscape:cx="24"
inkscape:cy="24"
inkscape:window-width="1920"
inkscape:window-height="983"
inkscape:window-x="482"
inkscape:window-y="768"
inkscape:window-maximized="1"
inkscape:current-layer="svg4" />
<path
d="M36.5 25.5V22.5H44V25.5ZM39 40 32.95 35.5 34.75 33.1 40.8 37.6ZM34.9 14.85 33.1 12.45 39 8 40.8 10.4ZM10.5 38V30H7Q5.75 30 4.875 29.125Q4 28.25 4 27V21Q4 19.75 4.875 18.875Q5.75 18 7 18H16L26 12V36L16 30H13.5V38ZM28 30.7V17.3Q29.35 18.5 30.175 20.225Q31 21.95 31 24Q31 26.05 30.175 27.775Q29.35 29.5 28 30.7Z"
id="path2"
style="fill:#ffffff" />
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="24"
height="24"
version="1.1"
id="svg4"
sodipodi:docname="check-smaller.svg"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs8" />
<sodipodi:namedview
id="namedview6"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="26.25"
inkscape:cx="12.038095"
inkscape:cy="12"
inkscape:window-width="1920"
inkscape:window-height="983"
inkscape:window-x="482"
inkscape:window-y="768"
inkscape:window-maximized="1"
inkscape:current-layer="svg4" />
<path
fill="#ffffff"
d="M 17.69347,4.9833775 9.9421192,12.940517 6.3065298,9.5107153 3.7684768,12.048769 9.9421192,18.016623 20.231523,7.5214304 Z"
id="path2"
style="stroke-width:0.68596" />
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
height="48"
width="48"
version="1.1"
id="svg4"
sodipodi:docname="close-smaller.svg"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs8" />
<sodipodi:namedview
id="namedview6"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="13.125"
inkscape:cx="24"
inkscape:cy="24"
inkscape:window-width="1366"
inkscape:window-height="731"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg4" />
<path
d="M12.45 37.65 10.35 35.55 21.9 24 10.35 12.45 12.45 10.35 24 21.9 35.55 10.35 37.65 12.45 26.1 24 37.65 35.55 35.55 37.65 24 26.1Z"
id="path2"
style="fill:#ffffff" />
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
height="48"
width="48"
version="1.1"
id="svg4"
sodipodi:docname="lightbulb.svg"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs8" />
<sodipodi:namedview
id="namedview6"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="13.125"
inkscape:cx="24"
inkscape:cy="24"
inkscape:window-width="1920"
inkscape:window-height="983"
inkscape:window-x="482"
inkscape:window-y="768"
inkscape:window-maximized="1"
inkscape:current-layer="svg4" />
<path
d="M24 44Q22.3 44 21.125 42.825Q19.95 41.65 19.95 39.95H28.05Q28.05 41.65 26.875 42.825Q25.7 44 24 44ZM15.9 36.85V33.85H32.1V36.85ZM16.15 30.8Q12.85 28.65 10.925 25.425Q9 22.2 9 18.15Q9 12.05 13.45 7.6Q17.9 3.15 24 3.15Q30.1 3.15 34.55 7.6Q39 12.05 39 18.15Q39 22.2 37.1 25.425Q35.2 28.65 31.85 30.8Z"
id="path2"
style="fill:#ffffff" />
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

37
public/icons/money.svg Normal file
View File

@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
height="48"
width="48"
version="1.1"
id="svg4"
sodipodi:docname="money.svg"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs8" />
<sodipodi:namedview
id="namedview6"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="6.5625"
inkscape:cx="37.942857"
inkscape:cy="29.714286"
inkscape:window-width="1366"
inkscape:window-height="731"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg4" />
<path
d="M 22.070204,47.757552 V 42.214123 Q 18.308592,41.554191 15.89984,39.343419 13.491088,37.132647 12.435197,33.766994 l 3.695619,-1.517844 q 1.121884,3.167674 3.233667,4.718514 2.111782,1.55084 5.081476,1.55084 3.167674,0 5.213463,-1.583837 2.045789,-1.583837 2.045789,-4.355551 0,-2.903701 -1.814813,-4.487538 -1.814813,-1.583836 -6.830296,-3.233666 -4.75151,-1.517844 -7.094269,-4.025586 -2.342759,-2.507741 -2.342759,-6.269354 0,-3.629626 2.342759,-6.0713741 2.342759,-2.4417484 6.104371,-2.7717144 V 0.24244792 h 3.959592 V 5.7198835 q 2.969694,0.329966 5.114473,1.9467994 2.144779,1.6168335 3.266663,4.1245751 l -3.695619,1.583837 q -0.923905,-2.111783 -2.474745,-3.068684 -1.55084,-0.9569014 -4.058582,-0.9569014 -3.035687,0 -4.817503,1.3858574 -1.781817,1.385857 -1.781817,3.761612 0,2.507742 1.979796,4.058582 1.979796,1.55084 7.325246,3.20067 4.487537,1.385857 6.632316,3.992589 2.144779,2.606731 2.144779,6.566323 0,4.157572 -2.441748,6.69831 -2.441749,2.540738 -7.193259,3.266663 v 5.477436 z"
id="path2"
style="fill:#ffffff;stroke-width:1.31986" />
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
height="48"
width="48"
version="1.1"
id="svg4"
sodipodi:docname="music-note.svg"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs8" />
<sodipodi:namedview
id="namedview6"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="13.125"
inkscape:cx="24"
inkscape:cy="24"
inkscape:window-width="1920"
inkscape:window-height="983"
inkscape:window-x="482"
inkscape:window-y="768"
inkscape:window-maximized="1"
inkscape:current-layer="svg4" />
<path
d="M19.65 42Q16.5 42 14.325 39.825Q12.15 37.65 12.15 34.5Q12.15 31.35 14.325 29.175Q16.5 27 19.65 27Q21.05 27 22.175 27.4Q23.3 27.8 24.15 28.5V6H35.85V12.75H27.15V34.5Q27.15 37.65 24.975 39.825Q22.8 42 19.65 42Z"
id="path2"
style="fill:#ffffff" />
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
height="48"
width="48"
version="1.1"
id="svg4"
sodipodi:docname="right-arrow.svg"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs8" />
<sodipodi:namedview
id="namedview6"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="13.125"
inkscape:cx="24.07619"
inkscape:cy="24"
inkscape:window-width="1920"
inkscape:window-height="983"
inkscape:window-x="482"
inkscape:window-y="768"
inkscape:window-maximized="1"
inkscape:current-layer="svg4" />
<path
d="M 17.039265,39.62264 14.838095,37.382164 28.320259,23.9 14.838095,10.417836 17.039265,8.1773601 32.761905,23.9 Z"
id="path2"
style="fill:#ffffff;stroke-width:0.786132" />
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
public/icons/segway.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

37
public/icons/star.svg Normal file
View File

@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
height="48"
width="48"
version="1.1"
id="svg4"
sodipodi:docname="star.svg"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs8" />
<sodipodi:namedview
id="namedview6"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="13.125"
inkscape:cx="24"
inkscape:cy="24"
inkscape:window-width="1920"
inkscape:window-height="983"
inkscape:window-x="482"
inkscape:window-y="768"
inkscape:window-maximized="1"
inkscape:current-layer="svg4" />
<path
d="M11.65 44 16.3 28.8 4 20H19.2L24 4L28.8 20H44L31.7 28.8L36.35 44L24 34.6Z"
id="path2"
style="fill:#ffffff" />
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
height="48"
width="48"
version="1.1"
id="svg4"
sodipodi:docname="stopwatch.svg"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs8" />
<sodipodi:namedview
id="namedview6"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="13.125"
inkscape:cx="24"
inkscape:cy="24"
inkscape:window-width="1920"
inkscape:window-height="983"
inkscape:window-x="482"
inkscape:window-y="768"
inkscape:window-maximized="1"
inkscape:current-layer="svg4" />
<path
d="M14.45 34Q16.3 35.95 18.8 36.975Q21.3 38 24 38Q29.85 38 33.925 33.925Q38 29.85 38 24Q38 18.15 33.925 14.075Q29.85 10 24 10V24ZM24 44Q19.75 44 16.1 42.475Q12.45 40.95 9.75 38.25Q7.05 35.55 5.525 31.9Q4 28.25 4 24Q4 19.8 5.525 16.15Q7.05 12.5 9.75 9.8Q12.45 7.1 16.1 5.55Q19.75 4 24 4Q28.2 4 31.85 5.55Q35.5 7.1 38.2 9.8Q40.9 12.5 42.45 16.15Q44 19.8 44 24Q44 28.25 42.45 31.9Q40.9 35.55 38.2 38.25Q35.5 40.95 31.85 42.475Q28.2 44 24 44Z"
id="path2"
style="fill:#ffffff" />
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -175,6 +175,18 @@
<option value="4">__MSG_noticeVisibilityMode4__</option>
</select>
</div>
<div data-type="toggle" data-sync="showCategoryGuidelines">
<div class="switch-container">
<label class="switch">
<input id="showCategoryGuidelines" type="checkbox" checked>
<span class="slider round"></span>
</label>
<label class="switch-label" for="showCategoryGuidelines">
__MSG_showCategoryGuidelines__
</label>
</div>
</div>
<div data-type="toggle" data-toggle-type="reverse" data-sync="hideVideoPlayerControls">
<div class="switch-container">

View File

@@ -24,6 +24,7 @@ export interface NoticeProps {
smaller?: boolean,
limitWidth?: boolean,
extraClass?: string,
// Callback for when this is closed
closeListener: () => void,
@@ -35,8 +36,6 @@ export interface NoticeProps {
}
export interface NoticeState {
noticeTitle: string,
maxCountdownTime: () => number,
countdownTime: number,
@@ -54,9 +53,13 @@ class NoticeComponent extends React.Component<NoticeProps, NoticeState> {
amountOfPreviousNotices: number;
parentRef: React.RefObject<HTMLDivElement>;
constructor(props: NoticeProps) {
super(props);
this.parentRef = React.createRef();
const maxCountdownTime = () => {
if (this.props.maxCountdownTime) return this.props.maxCountdownTime();
else return Config.config.skipNoticeDuration;
@@ -71,8 +74,6 @@ class NoticeComponent extends React.Component<NoticeProps, NoticeState> {
// Setup state
this.state = {
noticeTitle: props.noticeTitle,
maxCountdownTime,
//the countdown until this notice closes
@@ -97,9 +98,11 @@ class NoticeComponent extends React.Component<NoticeProps, NoticeState> {
return (
<div id={"sponsorSkipNotice" + this.idSuffix}
className={"sponsorSkipObject sponsorSkipNoticeParent"
+ (this.props.showInSecondSlot ? " secondSkipNotice" : "")}
+ (this.props.showInSecondSlot ? " secondSkipNotice" : "")
+ (this.props.extraClass ? ` ${this.props.extraClass}` : "")}
onMouseEnter={(e) => this.onMouseEnter(e) }
onMouseLeave={() => this.timerMouseLeave()}
ref={this.parentRef}
style={noticeStyle} >
<div className={"sponsorSkipNoticeTableContainer"
+ (this.props.fadeIn ? " sponsorSkipNoticeFadeIn" : "")
@@ -123,7 +126,7 @@ class NoticeComponent extends React.Component<NoticeProps, NoticeState> {
style={{float: "left"}}
className="sponsorSkipMessage sponsorSkipObject">
{this.state.noticeTitle}
{this.props.noticeTitle}
</span>
{this.props.firstColumn}
@@ -344,12 +347,6 @@ class NoticeComponent extends React.Component<NoticeProps, NoticeState> {
if (!silent) this.props.closeListener();
}
changeNoticeTitle(title: string): void {
this.setState({
noticeTitle: title
});
}
addNoticeInfoMessage(message: string, message2 = ""): void {
//TODO: Replace
@@ -384,6 +381,10 @@ class NoticeComponent extends React.Component<NoticeProps, NoticeState> {
document.querySelector("#sponsorSkipNotice" + this.idSuffix + " > tbody").insertBefore(thanksForVotingText2, document.getElementById("sponsorSkipNoticeSpacer" + this.idSuffix));
}
}
getElement(): React.RefObject<HTMLDivElement> {
return this.parentRef;
}
}
export default NoticeComponent;

View File

@@ -1,6 +1,7 @@
import * as React from "react";
export interface NoticeTextSelectionProps {
icon?: string,
text: string,
idSuffix: string,
onClick?: (event: React.MouseEvent) => unknown
@@ -24,12 +25,21 @@ class NoticeTextSelectionComponent extends React.Component<NoticeTextSelectionPr
}
return (
<p id={"sponsorTimesInfoMessage" + this.props.idSuffix}
<tr id={"sponsorTimesInfoMessage" + this.props.idSuffix}
onClick={this.props.onClick}
style={style}
className="sponsorTimesInfoMessage">
{this.props.text}
</p>
<td>
{this.props.icon ?
<img src={chrome.runtime.getURL(this.props.icon)} className="sponsorTimesInfoIcon" />
: null}
<span>
{this.props.text}
</span>
</td>
</tr>
);
}
}

View File

@@ -617,11 +617,6 @@ class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeSta
countdownTime: Config.config.skipNoticeDuration
};
// See if the title should be changed
if (!this.autoSkip) {
newState.noticeTitle = chrome.i18n.getMessage("noticeTitle");
}
//reset countdown
this.setState(newState, () => {
this.noticeRef.current.resetCountdown();

View File

@@ -18,6 +18,7 @@ export interface SponsorTimeEditProps {
submissionNotice: SubmissionNoticeComponent;
categoryList?: Category[];
categoryChangeListener?: (index: number, category: Category) => void;
}
export interface SponsorTimeEditState {
@@ -365,9 +366,10 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
}
categorySelectionChange(event: React.ChangeEvent<HTMLSelectElement>): void {
const chosenCategory = event.target.value as Category;
// See if show more categories was pressed
if (event.target.value !== DEFAULT_CATEGORY && !Config.config.categorySelections.some((category) => category.name === event.target.value)) {
const chosenCategory = event.target.value;
event.target.value = DEFAULT_CATEGORY;
// Alert that they have to enable this category first
@@ -381,8 +383,12 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
}
const sponsorTime = this.props.contentContainer().sponsorTimesSubmitting[this.props.index];
this.handleReplacingLostTimes(event.target.value as Category, sponsorTime.actionType, sponsorTime);
this.handleReplacingLostTimes(chosenCategory, sponsorTime.actionType, sponsorTime);
this.saveEditTimes();
if (this.props.categoryChangeListener) {
this.props.categoryChangeListener(this.props.index, chosenCategory);
}
}
actionTypeSelectionChange(event: React.ChangeEvent<HTMLSelectElement>): void {

View File

@@ -1,10 +1,13 @@
import * as React from "react";
import Config from "../config"
import { ContentContainer } from "../types";
import GenericNotice from "../render/GenericNotice";
import { Category, ContentContainer } from "../types";
import * as CompileConfig from "../../config.json";
import NoticeComponent from "./NoticeComponent";
import NoticeTextSelectionComponent from "./NoticeTextSectionComponent";
import SponsorTimeEditComponent from "./SponsorTimeEditComponent";
import { getGuidelineInfo } from "../utils/constants";
export interface SubmissionNoticeProps {
// Contains functions and variables from the content script needed by the skip notice
@@ -32,6 +35,8 @@ class SubmissionNoticeComponent extends React.Component<SubmissionNoticeProps, S
videoObserver: MutationObserver;
guidelinesReminder: GenericNotice;
constructor(props: SubmissionNoticeProps) {
super(props);
this.noticeRef = React.createRef();
@@ -128,6 +133,7 @@ class SubmissionNoticeComponent extends React.Component<SubmissionNoticeProps, S
index={i}
contentContainer={this.props.contentContainer}
submissionNotice={this}
categoryChangeListener={this.categoryChangeListener.bind(this)}
ref={timeRef}>
</SponsorTimeEditComponent>
);
@@ -154,6 +160,7 @@ class SubmissionNoticeComponent extends React.Component<SubmissionNoticeProps, S
}
cancel(): void {
this.guidelinesReminder?.close();
this.noticeRef.current.close(true);
this.contentContainer().resetSponsorSubmissionNotice();
@@ -190,6 +197,45 @@ class SubmissionNoticeComponent extends React.Component<SubmissionNoticeProps, S
this.cancel();
}
categoryChangeListener(index: number, category: Category): void {
const dialogWidth = this.noticeRef?.current?.getElement()?.current?.offsetWidth;
if (category !== "chooseACategory" && Config.config.showCategoryGuidelines
&& this.contentContainer().v.offsetWidth > dialogWidth * 2) {
const options = {
title: chrome.i18n.getMessage(`category_${category}`),
textBoxes: getGuidelineInfo(category),
buttons: [{
name: chrome.i18n.getMessage("FullDetails"),
listener: () => window.open(CompileConfig.wikiLinks[category])
},
{
name: chrome.i18n.getMessage("Hide"),
listener: () => {
Config.config.showCategoryGuidelines = false;
this.guidelinesReminder?.close();
this.guidelinesReminder = null;
}
}],
timed: false,
style: {
right: `${dialogWidth + 10}px`,
},
extraClass: "sb-guidelines-notice"
};
if (options.textBoxes) {
if (this.guidelinesReminder) {
this.guidelinesReminder.update(options);
} else {
this.guidelinesReminder = new GenericNotice(null, "GuidelinesReminder", options);
}
} else {
this.guidelinesReminder?.close();
this.guidelinesReminder = null;
}
}
}
}
export default SubmissionNoticeComponent;

View File

@@ -55,6 +55,7 @@ interface SBConfig {
scrollToEditTimeUpdate: boolean,
categoryPillUpdate: boolean,
darkMode: boolean,
showCategoryGuidelines: boolean,
// Used to cache calculated text color info
categoryPillColors: {
@@ -167,6 +168,7 @@ const Config: SBObject = {
scrollToEditTimeUpdate: false, // false means the tooltip will be shown
categoryPillUpdate: false,
darkMode: true,
showCategoryGuidelines: true,
categoryPillColors: {},

View File

@@ -1128,7 +1128,7 @@ async function whitelistCheck() {
?? document.querySelector("a.ytp-title-channel-logo") // YouTube Embed
?? document.querySelector(".channel-profile #channel-name")?.parentElement.parentElement // Invidious
?? document.querySelector("a.slim-owner-icon-and-title")) // Mobile YouTube
?.getAttribute("href")?.match(/(?:\/c\/|\/channel\/)(UC[a-zA-Z0-9_-]{22}|[a-zA-Z0-9_-]+)/)?.[1];
?.getAttribute("href")?.match(/\/(?:channel|c|user)\/(UC[a-zA-Z0-9_-]{22}|[a-zA-Z0-9_-]+)/)?.[1];
try {
await utils.wait(() => !!getChannelID(), 6000, 20);

View File

@@ -13,12 +13,19 @@ export interface ButtonListener {
listener: (e?: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void
}
export interface TextBox {
icon: string,
text: string
}
export interface NoticeOptions {
title: string,
textBoxes?: string[],
textBoxes?: TextBox[],
buttons?: ButtonListener[],
fadeIn?: boolean,
timed?: boolean
style?: React.CSSProperties;
extraClass?: string;
}
export default class GenericNotice {
@@ -27,9 +34,11 @@ export default class GenericNotice {
noticeElement: HTMLDivElement;
noticeRef: React.MutableRefObject<NoticeComponent>;
idSuffix: string;
constructor(contentContainer: ContentContainer, idSuffix: string, options: NoticeOptions) {
this.noticeRef = React.createRef();
this.idSuffix = idSuffix;
this.contentContainer = contentContainer;
@@ -40,39 +49,47 @@ export default class GenericNotice {
referenceNode.prepend(this.noticeElement);
this.update(options);
}
update(options: NoticeOptions): void {
ReactDOM.render(
<NoticeComponent
noticeTitle={options.title}
idSuffix={idSuffix}
idSuffix={this.idSuffix}
fadeIn={options.fadeIn ?? true}
timed={options.timed ?? true}
ref={this.noticeRef}
style={options.style}
extraClass={options.extraClass}
closeListener={() => this.close()} >
{this.getMessageBox(idSuffix, options.textBoxes)}
{this.getMessageBox(this.idSuffix, options.textBoxes)}
<tr id={"sponsorSkipNoticeSpacer" + idSuffix}
<tr id={"sponsorSkipNoticeSpacer" + this.idSuffix}
className="sponsorBlockSpacer">
</tr>
<div className="sponsorSkipNoticeRightSection"
<tr className="sponsorSkipNoticeRightSection"
style={{position: "relative"}}>
{this.getButtons(options.buttons)}
</div>
<td>
{this.getButtons(options.buttons)}
</td>
</tr>
</NoticeComponent>,
this.noticeElement
);
}
getMessageBox(idSuffix: string, textBoxes: string[]): JSX.Element[] {
getMessageBox(idSuffix: string, textBoxes: TextBox[]): JSX.Element[] {
if (textBoxes) {
const result = [];
for (let i = 0; i < textBoxes.length; i++) {
result.push(
<NoticeTextSelectionComponent idSuffix={idSuffix}
key={i}
text={textBoxes[i]} />
icon={textBoxes[i].icon}
text={textBoxes[i].text} />
)
}

141
src/utils/constants.ts Normal file
View File

@@ -0,0 +1,141 @@
import { TextBox } from "../render/GenericNotice";
import { Category } from "../types";
export function getGuidelineInfo(category: Category): TextBox[] {
switch (category) {
case "sponsor":
return [{
icon: "icons/money.svg",
text: chrome.i18n.getMessage(`category_${category}_guideline1`)
}, {
icon: "icons/close-smaller.svg",
text: chrome.i18n.getMessage(`category_${category}_guideline2`)
}, {
icon: "icons/segway.png",
text: chrome.i18n.getMessage(`generic_guideline1`)
}, {
icon: "icons/right-arrow.svg",
text: chrome.i18n.getMessage(`generic_guideline2`)
}];
case "selfpromo":
return [{
icon: "icons/money.svg",
text: chrome.i18n.getMessage(`category_${category}_guideline1`)
}, {
icon: "icons/campaign.svg",
text: chrome.i18n.getMessage(`category_${category}_guideline2`)
}, {
icon: "icons/close-smaller.svg",
text: chrome.i18n.getMessage(`category_${category}_guideline3`)
}, {
icon: "icons/segway.png",
text: chrome.i18n.getMessage(`generic_guideline1`)
}, {
icon: "icons/right-arrow.svg",
text: chrome.i18n.getMessage(`generic_guideline2`)
}];
case "exclusive_access":
return [{
icon: "icons/money.svg",
text: chrome.i18n.getMessage(`category_${category}_guideline1`)
}];
case "interaction":
return [{
icon: "icons/lightbulb.svg",
text: chrome.i18n.getMessage(`category_${category}_guideline1`)
}, {
icon: "icons/lightbulb.svg",
text: chrome.i18n.getMessage(`category_${category}_guideline2`)
}, {
icon: "icons/close-smaller.svg",
text: chrome.i18n.getMessage(`category_${category}_guideline3`)
}, {
icon: "icons/segway.png",
text: chrome.i18n.getMessage(`generic_guideline1`)
}, {
icon: "icons/right-arrow.svg",
text: chrome.i18n.getMessage(`generic_guideline2`)
}];
case "intro":
return [{
icon: "icons/check-smaller.svg",
text: chrome.i18n.getMessage(`category_${category}_guideline1`)
}, {
icon: "icons/close-smaller.svg",
text: chrome.i18n.getMessage(`category_${category}_guideline2`)
}, {
icon: "icons/segway.png",
text: chrome.i18n.getMessage(`generic_guideline1`)
}, {
icon: "icons/right-arrow.svg",
text: chrome.i18n.getMessage(`generic_guideline2`)
}];
case "outro":
return [{
icon: "icons/close-smaller.svg",
text: chrome.i18n.getMessage(`category_${category}_guideline1`)
}, {
icon: "icons/segway.png",
text: chrome.i18n.getMessage(`generic_guideline1`)
}, {
icon: "icons/right-arrow.svg",
text: chrome.i18n.getMessage(`generic_guideline2`)
}];
case "preview":
return [{
icon: "icons/check-smaller.svg",
text: chrome.i18n.getMessage(`category_${category}_guideline1`)
}, {
icon: "icons/check-smaller.svg",
text: chrome.i18n.getMessage(`category_${category}_guideline2`)
}, {
icon: "icons/close-smaller.svg",
text: chrome.i18n.getMessage(`category_${category}_guideline3`)
}, {
icon: "icons/segway.png",
text: chrome.i18n.getMessage(`generic_guideline1`)
}, {
icon: "icons/right-arrow.svg",
text: chrome.i18n.getMessage(`generic_guideline2`)
}];
case "filler":
return [{
icon: "icons/stopwatch.svg",
text: chrome.i18n.getMessage(`category_${category}_guideline1`)
}, {
icon: "icons/stopwatch.svg",
text: chrome.i18n.getMessage(`category_${category}_guideline2`)
}, {
icon: "icons/close-smaller.svg",
text: chrome.i18n.getMessage(`category_${category}_guideline3`)
}, {
icon: "icons/segway.png",
text: chrome.i18n.getMessage(`generic_guideline1`)
}, {
icon: "icons/right-arrow.svg",
text: chrome.i18n.getMessage(`generic_guideline2`)
}];
case "music_offtopic":
return [{
icon: "icons/music-note.svg",
text: chrome.i18n.getMessage(`category_${category}_guideline1`)
}, {
icon: "icons/music-note.svg",
text: chrome.i18n.getMessage(`category_${category}_guideline2`)
}, {
icon: "icons/right-arrow.svg",
text: chrome.i18n.getMessage(`generic_guideline2`)
}];
case "poi_highlight":
return [{
icon: "icons/star.svg",
text: chrome.i18n.getMessage(`category_${category}_guideline1`)
}, {
icon: "icons/bolt.svg",
text: chrome.i18n.getMessage(`category_${category}_guideline2`)
}, {
icon: "icons/bolt.svg",
text: chrome.i18n.getMessage(`category_${category}_guideline3`)
}];
}
}

View File

@@ -62,7 +62,7 @@ function hexToRgb(hex: string): {r: number, g: number, b: number} {
g: parseInt(result[2], 16),
b: parseInt(result[3], 16)
} : null;
}
}
export const GenericUtils = {
wait,