Compare commits

...

1357 Commits

Author SHA1 Message Date
Ajay
3f81006526 hide stuff 2022-04-01 02:22:54 -04:00
Ajay
f50110636d square icons 2022-03-27 19:02:06 -04:00
Ajay
2a64499ba9 Fix error 2022-03-27 18:45:21 -04:00
Ajay
bb901be43f Firefox manifest 2022-03-27 18:44:49 -04:00
Ajay
e4f6bbfcd6 remove thanks 2022-03-27 18:43:35 -04:00
Ajay
ece0c3c8f0 uninstall warning 2022-03-27 18:42:58 -04:00
Ajay
88fc02dacd delete translations 2022-03-27 18:30:09 -04:00
Ajay
834ae33696 better slogan 2022-03-27 18:29:34 -04:00
Ajay
46c5b5897e more implementation 2022-03-27 18:23:19 -04:00
Ajay
d2c50d2562 Reverse segments to skip content 2022-03-27 14:25:53 -04:00
Ajay Ramachandran
5d72498aac Merge pull request #1247 from ajayyy/dependabot/npm_and_yarn/minimist-1.2.6
Bump minimist from 1.2.5 to 1.2.6
2022-03-25 20:00:05 -04:00
dependabot[bot]
e8536fd404 Bump minimist from 1.2.5 to 1.2.6
Bumps [minimist](https://github.com/substack/minimist) from 1.2.5 to 1.2.6.
- [Release notes](https://github.com/substack/minimist/releases)
- [Commits](https://github.com/substack/minimist/compare/1.2.5...1.2.6)

---
updated-dependencies:
- dependency-name: minimist
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-25 23:39:45 +00:00
Ajay Ramachandran
9489354357 Merge pull request #1242 from AlecRust/improve-readme
Improve "load in Firefox" docs
2022-03-22 22:10:11 -04:00
Ajay Ramachandran
940350504a different wording 2022-03-22 22:09:57 -04:00
Ajay
0e37ebd789 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock 2022-03-21 22:42:48 -04:00
Ajay
c66110a60f Increase tooltip zindex 2022-03-21 22:42:47 -04:00
Alec Rust
ac7f2eb5b1 Refine "load in Firefox" docs 2022-03-20 12:15:04 +00:00
Ajay Ramachandran
0cdbcfc97e Merge pull request #1228 from AlecRust/refine-popup
Fix popup width and improve close button
2022-03-18 19:29:56 -04:00
Ajay
821bbc969b bump version 2022-03-17 22:19:33 -04:00
Ajay
e20011ce08 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock 2022-03-17 22:19:22 -04:00
Ajay
e30bccd2b7 Don't use virtual time on firefox 2022-03-17 22:19:21 -04:00
Alec Rust
c0cfa3a683 Fix "You've saved" and "You've skipped" not being on separate lines
Screenshot: https://i.imgur.com/VqeXMmS.png
2022-03-17 17:53:33 +00:00
Alec Rust
f7510eea88 Improve close popup button 2022-03-17 17:50:06 +00:00
Alec Rust
24fc5e4370 Fix popup width when rendered in-page 2022-03-17 17:47:52 +00:00
Ajay Ramachandran
5b62e76a63 Merge pull request #1234 from molniya0207/patch-1
Fix guidelines link
2022-03-17 12:29:11 -04:00
Stopper
15c73d7940 Fix guidelines link 2022-03-17 22:24:00 +06:00
Ajay
36f0fccd9c Force css 2022-03-17 00:29:33 -04:00
Ajay
d4544a7c47 Fixes for safari 2022-03-17 00:27:36 -04:00
Ajay Ramachandran
d9f1ee9bb8 New Crowdin updates (#1225) 2022-03-16 22:14:42 -04:00
Ajay Ramachandran
5f4c4332be bump version 2022-03-16 22:14:14 -04:00
Ajay
1acda5fe0a Improve precision on chromium using predicted virtual time 2022-03-16 16:17:44 -04:00
Ajay
21d4f0487c Fix skip notice behind controls on mobile youtube
Fix #1229
2022-03-16 13:30:20 -04:00
Ajay
340127a7f3 Switch font back to arial 2022-03-16 12:30:35 -04:00
Ajay Ramachandran
38ab10a191 Merge pull request #1227 from AlecRust/details-element
Refactor segment expanding to use <details>
2022-03-12 15:54:17 -05:00
Alec Rust
ced30c711e Refactor segment expanding to use <details> 2022-03-12 12:03:33 +00:00
Ajay
6bb265939a bump version 2022-03-12 00:25:47 -05:00
Ajay Ramachandran
d495be18a3 Merge pull request #1189 from AlecRust/improve-popup
Add menu bar to popup
2022-03-12 00:24:46 -05:00
Ajay Ramachandran
476efff47b New Crowdin updates (#1207) 2022-03-12 00:24:26 -05:00
Ajay
dcbefb5457 More specific class name 2022-03-12 00:23:16 -05:00
Ajay Ramachandran
b167cecdce Merge pull request #1224 from mchangrh/5xx-no-cf
ignore body if cloudflare error found
2022-03-12 00:02:41 -05:00
Michael C
924c777736 ignore body if cloudflare error found 2022-03-11 23:52:30 -05:00
Ajay Ramachandran
405fb342f0 Merge pull request #1218 from MRuy/userinfo
Get user infos from userInfo api for popup
2022-03-10 10:24:11 -05:00
Ajay
c76f241b63 Formatting 2022-03-10 10:23:35 -05:00
Ajay
54013681ef Ask for specific values 2022-03-10 10:22:53 -05:00
Ajay Ramachandran
8e94a05fa9 Merge pull request #1222 from mchangrh/custom5xx
custom error handler for 5xx
2022-03-10 10:18:44 -05:00
Michael C
7c747e6566 custom error handler for 5xx 2022-03-10 02:31:19 -05:00
Nanobyte
effac2449a Get user infos from userInfo api for popup 2022-03-05 23:52:44 +01:00
github-actions[bot]
d02aab4ba3 Update Invidious List 2022-02-28 22:26:53 -05:00
Ajay
a1caf8fbdb Switch hotkeys to not use array 2022-02-27 20:17:19 -05:00
Alec Rust
a3734e050f Refactor away global styles 2022-02-24 19:37:00 +00:00
Alec Rust
5496b05c88 Add menu bar to popup 2022-02-24 19:37:00 +00:00
Ajay Ramachandran
f6d2497e7b bump version 2022-02-24 14:34:51 -05:00
Ajay Ramachandran
6ea18fd536 New Crowdin updates (#1204) 2022-02-24 14:34:36 -05:00
Ajay Ramachandran
3d51c4eb53 Merge pull request #1192 from asportnoy/master
fix: ignore switchingVideos in Safari
2022-02-24 14:34:16 -05:00
Ajay Ramachandran
e11a8531fe Merge pull request #1205 from AronHK/settings
Settings css fixes
2022-02-24 13:50:51 -05:00
Ajay Ramachandran
05ba554075 Merge pull request #1206 from AronHK/keybind
Fix alt-tab, round 2
2022-02-24 12:46:41 -05:00
Áron Hegymegi-Kiss
0e5606423e fix alt-tab in chrome 2022-02-24 18:34:04 +01:00
Áron Hegymegi-Kiss
87354009b5 settings css fixes 2022-02-24 14:24:12 +01:00
Ajay Ramachandran
50c87a6842 New Crowdin updates (#1190) 2022-02-22 12:08:42 -05:00
Ajay
84a234f9b6 Fix full video saving old times
Fix #1198
2022-02-22 01:21:18 -05:00
Ajay
fd5ab9f153 bump version 2022-02-22 01:06:09 -05:00
Ajay
30fe40a523 Fix minimum duration
Fix #1202
2022-02-22 01:05:57 -05:00
Ajay
6e23650a99 Add category pill right away
Fix #1199
2022-02-22 01:01:27 -05:00
Ajay
d6a0029b85 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock 2022-02-16 13:28:10 -05:00
Ajay
f25f986200 Fix category pill option
Fixes #1196
2022-02-16 13:27:50 -05:00
Ajay Ramachandran
8843fb767e Merge pull request #1195 from ajayyy/dependabot/npm_and_yarn/follow-redirects-1.14.8
Bump follow-redirects from 1.14.7 to 1.14.8
2022-02-15 10:44:01 -05:00
dependabot[bot]
3a17299610 Bump follow-redirects from 1.14.7 to 1.14.8
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.14.7 to 1.14.8.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.14.7...v1.14.8)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-15 12:21:10 +00:00
Albert Portnoy
64d2c0a299 fix: ignore switchingVideos in Safari (see #1142) 2022-02-13 22:09:22 -06:00
Ajay Ramachandran
a2a5d27900 bump version 2022-02-12 13:21:43 -05:00
Ajay Ramachandran
eb9e2d8726 New Crowdin updates (#1186) 2022-02-12 12:17:06 -05:00
Ajay Ramachandran
ddc34bacc7 Merge pull request #1188 from AronHK/keybindFix
Fix keybind sometimes not working
2022-02-12 12:16:41 -05:00
Áron Hegymegi-Kiss
60b0a59ba1 keybind fix 2022-02-12 16:19:28 +01:00
Ajay
c9903b5926 Don't use setinterval on safari 2022-02-09 15:28:02 -05:00
Ajay Ramachandran
db7251cbfb bump version 2022-02-09 14:12:14 -05:00
Ajay Ramachandran
fcf42560bf New Crowdin updates (#1180) 2022-02-09 14:07:37 -05:00
Ajay Ramachandran
036b3967a9 Merge pull request #1182 from ajayyy/precise-skipping
Improve precision of skips on both chromium and firefox
2022-02-09 14:06:30 -05:00
Ajay
e622ee725c remove logging 2022-02-08 19:59:33 -05:00
Ajay
5ace92dc8b Use current video time if performance.now is restricted (fingerprinting) 2022-02-08 19:47:42 -05:00
Ajay
bb490bf7ad perfomance instead of date 2022-02-08 16:04:23 -05:00
Ajay
4cc248eb17 Improve precision of skips on both chromium and firefox
< 5ms in my testing
2022-02-08 15:46:38 -05:00
Ajay Ramachandran
2e8ce93c1d bump version 2022-02-08 11:42:58 -05:00
Ajay Ramachandran
4fc9856e34 New Crowdin updates (#1178) 2022-02-08 11:42:22 -05:00
Ajay Ramachandran
f92e3dbc9a Merge pull request #1179 from mchangrh/noFullButton
hide inspect & edit on Full Video actionType
2022-02-07 18:30:27 -05:00
Michael C
7f75929d81 hide inspect & edit on Full Video actionType 2022-02-07 18:26:44 -05:00
Ajay
43699c1875 Add unsubmitted segments after deleting old variable 2022-02-07 17:38:39 -05:00
Ajay
6128d37ac2 remove unused translation and add context 2022-02-07 13:13:52 -05:00
Ajay
c64c5125fb Fix broken icons and centering 2022-02-07 11:13:27 -05:00
Ajay
cbb8d48820 Add option to disable tracking downvotes and clear when disabled 2022-02-07 10:58:47 -05:00
Ajay
008079c74c Add jokes to filler name 2022-02-07 10:42:19 -05:00
Ajay
e65642237f Don't save dislikes for VIP 2022-02-07 10:38:05 -05:00
Ajay
84d4c9da4c Fix version 2022-02-06 23:37:38 -05:00
Ajay
e623af859f Fix release ci 2022-02-06 23:34:32 -05:00
Ajay
8c60f25d4a Don't save downvotes in incognito 2022-02-06 23:20:01 -05:00
Ajay
7896b474db bump version 2022-02-06 23:17:49 -05:00
Ajay
4d60dec7f9 Save downvotes and segment hides in local storage 2022-02-06 23:17:34 -05:00
Ajay
53d0ac8677 Add animation to segment hiding 2022-02-06 21:08:15 -05:00
Ajay
e4ba67999c Add segment hiding in popup 2022-02-06 21:03:39 -05:00
Ajay
0b6ade4a1d Improve typing on getHash 2022-02-06 20:01:19 -05:00
Ajay
816e9a78be Add local storage options to config 2022-02-06 19:17:20 -05:00
Ajay
ccb0e8bed9 Fix parameters not optional 2022-02-06 18:55:27 -05:00
Ajay
459de6654a Merge branch 'master' of https://github.com/ajayyy/SponsorBlock 2022-02-06 18:48:05 -05:00
Ajay
8b6f0d8a2e Better title text for full video labels 2022-02-06 18:48:03 -05:00
Ajay
cf792e849f remove log 2022-02-06 18:19:42 -05:00
Ajay
fce82b48b0 Add popup donation prompt 2022-02-06 18:12:58 -05:00
Ajay Ramachandran
3d2fe8c409 Merge pull request #1176 from ajayyy/ci/update_invidious_list
Update Invidious List
2022-02-06 17:23:09 -05:00
github-actions[bot]
f513c3b8cb Update Invidious List 2022-02-06 22:21:30 +00:00
Ajay
c66e624c16 Delete unused unsubmitted objects 2022-02-06 17:01:14 -05:00
Ajay
ddca15ca01 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock 2022-02-06 15:10:48 -05:00
Ajay
199ccb1b12 Move segment times from encoded array to normal js object 2022-02-06 15:10:46 -05:00
Ajay Ramachandran
552b33104b Remove instructions for attribute generation, now handled by github action 2022-02-06 14:37:08 -05:00
Ajay Ramachandran
57b952f64c Merge pull request #1175 from ajayyy/ci/oss_attribution
Update OSS Attribution
2022-02-06 14:35:55 -05:00
github-actions[bot]
6867fa88d3 Update OSS Attribution 2022-02-06 19:17:39 +00:00
Ajay Ramachandran
93af8d966b Merge pull request #1174 from mchangrh/fix-oss-ci
Fix OSS CI
2022-02-06 14:16:09 -05:00
Ajay
32fa9c3398 Hide segments when voting from the popup 2022-02-06 14:04:54 -05:00
Ajay Ramachandran
4a8e769596 Merge pull request #1155 from mchangrh/misc-fix
Misc fixes
2022-02-06 13:45:28 -05:00
Ajay
9c836a89a3 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into misc-fix 2022-02-06 13:42:58 -05:00
Ajay Ramachandran
b21b6edb0c semicolon 2022-02-06 13:39:37 -05:00
Michael M. Chang
ca49b48814 workflow_dispatch 2022-02-06 13:35:48 -05:00
Michael M. Chang
2b9a93deb0 npm ci to check node_modules 2022-02-06 13:33:02 -05:00
Ajay Ramachandran
d9dede6578 Merge pull request #1167 from mchangrh/update-dependencies
update dependencies
2022-02-06 13:27:33 -05:00
Ajay Ramachandran
2a8a9ba667 New Crowdin updates (#1148) 2022-02-06 13:27:08 -05:00
Michael C
1bd7c6a33a update depndencies
- add engines targeting dev
- bump webpack
- update-oss-attribution CI
- appease eslint for webpack
- clean up packages
  - move @types to devDependencies
  - moved concurrently to devDependencies
  - remove unused babel
2022-02-06 13:24:47 -05:00
Ajay Ramachandran
f5301fc374 Merge pull request #1168 from mchangrh/youtubeClip
early return if url is youtube clips url
2022-02-06 13:22:52 -05:00
Ajay Ramachandran
159e7598d7 Merge pull request #1164 from ajayyy/dependabot/npm_and_yarn/tmpl-1.0.5
Bump tmpl from 1.0.4 to 1.0.5
2022-02-06 13:22:28 -05:00
Ajay Ramachandran
2bd1688d8d Merge pull request #1165 from ajayyy/dependabot/npm_and_yarn/nth-check-2.0.1
Bump nth-check from 2.0.0 to 2.0.1
2022-02-06 13:22:23 -05:00
Ajay Ramachandran
26143460b7 Merge pull request #1163 from ajayyy/dependabot/npm_and_yarn/nanoid-3.2.0
Bump nanoid from 3.1.23 to 3.2.0
2022-02-06 13:22:16 -05:00
Ajay
2575141d35 Don't load segments from url multiple times 2022-02-06 13:13:08 -05:00
Michael C
48124e56d6 early return if url is youtube clips url 2022-02-06 01:05:19 -05:00
Ajay
e8307a2af7 Add text color based off luminance for full video label 2022-02-05 22:23:11 -05:00
dependabot[bot]
d01ed86803 Bump nth-check from 2.0.0 to 2.0.1
Bumps [nth-check](https://github.com/fb55/nth-check) from 2.0.0 to 2.0.1.
- [Release notes](https://github.com/fb55/nth-check/releases)
- [Commits](https://github.com/fb55/nth-check/compare/v2.0.0...v2.0.1)

---
updated-dependencies:
- dependency-name: nth-check
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-04 15:38:35 +00:00
dependabot[bot]
628c978286 Bump tmpl from 1.0.4 to 1.0.5
Bumps [tmpl](https://github.com/daaku/nodejs-tmpl) from 1.0.4 to 1.0.5.
- [Release notes](https://github.com/daaku/nodejs-tmpl/releases)
- [Commits](https://github.com/daaku/nodejs-tmpl/commits/v1.0.5)

---
updated-dependencies:
- dependency-name: tmpl
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-04 15:38:34 +00:00
dependabot[bot]
a0ba496d83 Bump nanoid from 3.1.23 to 3.2.0
Bumps [nanoid](https://github.com/ai/nanoid) from 3.1.23 to 3.2.0.
- [Release notes](https://github.com/ai/nanoid/releases)
- [Changelog](https://github.com/ai/nanoid/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ai/nanoid/compare/3.1.23...3.2.0)

---
updated-dependencies:
- dependency-name: nanoid
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-04 15:38:34 +00:00
Ajay Ramachandran
0ac4ef7a4b Merge pull request #1162 from mchangrh/invidious-ci-fix
fix updateInvidious ci
2022-02-04 10:37:54 -05:00
Michael C
ba2efe59cb fix updateInvidious ci
- add ts-node
- fix path
- add npm ci
2022-02-04 02:38:14 -05:00
Ajay
88f61cf292 Fix width with left bar options and make it appear more often 2022-01-29 23:33:30 -05:00
Michael C
86e5ef7523 merge only one 2022-01-27 15:02:07 -05:00
Michael C
0451dcd975 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into misc-fix 2022-01-27 14:56:47 -05:00
Michael C
ba7d46dd73 add mediaSession, remove bindMediaKey 2022-01-27 14:52:13 -05:00
Ajay
1115ffd8cf Fix ugly long category pill titles
FIx #1152
2022-01-27 11:57:14 -05:00
Ajay
fa926ef686 Don't hide exclusive access for min duration
Fix #1156
2022-01-27 11:36:26 -05:00
Michael C
22fcea99f5 revert package-lock 2022-01-27 01:52:37 -05:00
Michael C
876b55dcc1 add bindMediaKey to options 2022-01-27 01:43:40 -05:00
Michael C
6d0d533fa7 force listen for mediaKeys 2022-01-27 00:53:30 -05:00
Michael C
9457aff44f linting + audio override 2022-01-26 17:54:58 -05:00
Michael C
193374db30 substr -> slice 2022-01-26 17:54:35 -05:00
Ajay Ramachandran
2a7f08f360 Merge pull request #1154 from AronHK/localization
Add missing localizations
2022-01-26 16:47:08 -05:00
Áron Hegymegi-Kiss
b02e4c1b4f missing localization 2022-01-26 22:32:15 +01:00
Ajay Ramachandran
8922c6cb67 Fix typo 2022-01-25 19:51:06 -05:00
Ajay Ramachandran
f555a8e7bb Merge pull request #1093 from AronHK/settings
Settings rework
2022-01-24 23:41:21 -05:00
Ajay
aac2572b4e Add live update for dark mode 2022-01-24 23:38:44 -05:00
Ajay
56e7dc842e Fix tab button contrast on light theme 2022-01-24 23:36:35 -05:00
Ajay
8452bfb32a lightmode -> dark mode 2022-01-24 23:33:27 -05:00
Ajay
c49ebbe371 Fix slow animation transitioning to light mode 2022-01-24 23:31:12 -05:00
Ajay
e87ec3842b fix merge issue 2022-01-24 23:28:51 -05:00
Ajay Ramachandran
595cb84941 Merge branch 'master' into settings 2022-01-24 23:27:52 -05:00
Ajay
8d5f244d2f Dark mode unless explicitely disabled (sorry) 2022-01-24 23:27:00 -05:00
Ajay
8455ac8b39 Make server address buttons bigger 2022-01-24 23:20:08 -05:00
Ajay
666aaab7f2 Use color for hover 2022-01-24 23:16:38 -05:00
Ajay
963ead0a30 Fix weird scrolling on help page 2022-01-24 22:59:43 -05:00
Ajay
28a711de75 use addeventlistener 2022-01-24 22:58:52 -05:00
Ajay
1fca10a1c1 Max width on options page 2022-01-24 22:58:03 -05:00
Ajay
96cefeaaf3 Remove stick header on help page 2022-01-24 20:53:36 -05:00
Ajay
23a6940894 Clarify that skip notice time is in seconds 2022-01-21 21:54:33 -05:00
Ajay
7f2b1c60c7 Only display single action type for full video 2022-01-21 20:20:17 -05:00
Ajay
c542cd9f73 Save times when accidentally switching to exclusive access 2022-01-21 19:37:14 -05:00
Ajay
7e091d1c67 Remove sponsor lookup retries 2022-01-21 18:39:07 -05:00
Ajay
6a07a9f693 Use new Poi action type fetch method 2022-01-21 18:38:04 -05:00
Ajay Ramachandran
c34d1e0bc1 Merge branch 'master' into settings 2022-01-21 12:28:47 -05:00
Ajay Ramachandran
b4c8e54d3e New Crowdin updates (#1137) 2022-01-21 12:27:41 -05:00
Ajay Ramachandran
b83426caba bump version 2022-01-21 12:26:04 -05:00
Ajay
9da99688d3 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock 2022-01-20 16:03:43 -05:00
Ajay
9bcee6afce Remove 502 retry logic 2022-01-20 16:03:41 -05:00
Ajay Ramachandran
1b5d7ccf3e Merge pull request #1141 from mchangrh/videoPreviewButtons
fix hover preview segments
2022-01-19 15:26:42 -05:00
Ajay
41a8b2718a Remove deleted import 2022-01-19 11:30:04 -05:00
Ajay
002f22c040 Wait for hover preview using mutation observer 2022-01-19 11:27:19 -05:00
Ajay
bf735f47b0 Fix reference node order to fix issue with player-container always being visible 2022-01-19 10:57:28 -05:00
Michael C
e4aa7efd3c add infinite wait for hover preview 2022-01-19 01:47:43 -05:00
Michael C
b210b22af3 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into videoPreviewButtons 2022-01-18 14:30:29 -05:00
Ajay Ramachandran
154e12f201 bump version 2022-01-18 13:20:46 -05:00
Ajay
b6c1ee1743 Don't allow submissions on active premieres or livestreams
Fix #523
Fix #367
2022-01-16 13:56:57 -05:00
Ajay
6b6ca6198f Don't schedule skips for full video segments 2022-01-16 01:17:49 -05:00
Ajay
6788394be1 Fix typo 2022-01-16 00:12:27 -05:00
Michael C
059a674ae1 fix hover preview segments 2022-01-15 22:49:22 -05:00
Ajay
a45bd4c5c7 Fix potential null issue 2022-01-15 18:28:53 -05:00
Ajay
bb47863080 Add safari extra manifest and use chrome's manifest for edge 2022-01-14 21:51:42 -05:00
Ajay
d50a69f1fd New hash format for previewing segments 2022-01-14 19:34:54 -05:00
Ajay
31014b78ac Add method to create segments from url parameters 2022-01-14 19:21:09 -05:00
Ajay
cf9e016581 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock 2022-01-14 17:35:54 -05:00
Ajay
dee836c783 Fix making dir automatically 2022-01-14 17:35:52 -05:00
Ajay Ramachandran
5c7f8cef45 bump version 2022-01-14 17:08:24 -05:00
Ajay
9f5ec09789 Add safari and edge build to release 2022-01-14 17:07:10 -05:00
Ajay
a82062da5b Add build mode for edge languages 2022-01-14 16:07:24 -05:00
Ajay
35da572f3f Add build option for safari that fixes locales
Fix #801 and #1061
2022-01-14 15:56:38 -05:00
Ajay
cf01679f16 null check for skip notice 2022-01-14 14:57:46 -05:00
Ajay
16f4ab53b6 Don't warn about minimum duration for full video
Fix #1133
2022-01-14 11:51:51 -05:00
Ajay Ramachandran
65f4a2ec28 bump version 2022-01-14 11:46:16 -05:00
Ajay Ramachandran
983b1f64da New Crowdin updates (#1126) 2022-01-14 11:45:14 -05:00
Ajay Ramachandran
70b2491975 bump version 2022-01-14 00:30:04 -05:00
Ajay
0fdb76ffe0 Hide time from exclusive access right away 2022-01-14 00:03:21 -05:00
Ajay
e2ba5c2063 Make wiki link go to specific page and fix crash when submitting 2022-01-13 23:56:15 -05:00
Ajay
6d4ec823a0 Update config 2022-01-13 23:53:13 -05:00
Ajay
917e644822 Add exclusive access category 2022-01-13 23:44:09 -05:00
Ajay
c986860a42 Add close button to category pill 2022-01-13 22:55:08 -05:00
Áron Hegymegi-Kiss
881cea4f6d refine settings usragent check 2022-01-13 19:13:08 +01:00
Áron Hegymegi-Kiss
5dd78e1cb3 show icon 2022-01-12 21:22:43 +01:00
Áron Hegymegi-Kiss
83db64d084 address isssues for pull request 2022-01-09 21:28:30 +01:00
Ajay
0da8a34e7a Add title element for category pill on updated youtube 2022-01-08 15:22:21 -05:00
Áron Hegymegi-Kiss
ed17d4859f Merge remote-tracking branch 'origin/master' into settings
# Conflicts:
#	public/options/options.html
#	src/config.ts
#	src/content.ts
#	src/options.ts
2022-01-08 19:30:49 +01:00
Áron Hegymegi-Kiss
dc560cd73e import/export settings to file 2022-01-08 19:03:46 +01:00
Áron Hegymegi-Kiss
90eaab4e50 multikey shortcuts 2022-01-08 17:07:37 +01:00
Áron Hegymegi-Kiss
3b54fde3f9 fixes 2022-01-08 16:34:49 +01:00
Ajay Ramachandran
02d8bf9a6f Merge pull request #1125 from mchangrh/fixPillError
fix "cannot read properties of null" when voting on full video tag
2022-01-07 02:03:12 -05:00
Michael C
2cf89b1850 fix "cannot read properties of null" when voting on full video tag 2022-01-07 02:00:04 -05:00
Ajay Ramachandran
fb74823c92 bump version 2022-01-06 20:59:54 -05:00
Ajay
024480513c Merge branch 'master' of https://github.com/ajayyy/SponsorBlock 2022-01-06 20:08:14 -05:00
Ajay
e9b217c685 Add tooltip about full video update 2022-01-06 20:08:12 -05:00
Ajay Ramachandran
7b917fb2b6 New Crowdin updates (#1112) 2022-01-06 16:57:12 -05:00
Ajay Ramachandran
2db35a624a Merge pull request #1116 from mchangrh/embeddedVideos
Support embedded videos
2022-01-06 16:50:58 -05:00
Ajay
c31866ff5f Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into pr/mchangrh/1116 2022-01-06 16:48:58 -05:00
Ajay Ramachandran
e347165073 Merge pull request #1122 from ajayyy/full-video
Full video labels
2022-01-06 16:40:23 -05:00
Ajay
57de51475f Add option to disable showing full video segments 2022-01-06 16:26:59 -05:00
Ajay
d16a409db2 Show black text on pill for unpaid promotion 2022-01-06 15:18:40 -05:00
Ajay
c63416fd7b Fix voting on category pill on mobile 2022-01-06 02:10:28 -05:00
Ajay
4d724deba3 Add title text and hide on downvote 2022-01-06 02:06:55 -05:00
Ajay
1aac863df0 Fix error 2022-01-06 01:54:47 -05:00
Ajay
c7d5011cc0 Add tooltip recommending full video report for large segments 2022-01-06 01:19:20 -05:00
Ajay
8e964b40b3 Add vote buttons to pill that open on click 2022-01-05 20:49:56 -05:00
Ajay
a6a9b7dd8c Decrease font size of pill 2022-01-05 17:26:05 -05:00
Ajay
d23e434209 Show full video on popup 2022-01-05 15:16:29 -05:00
Ajay
040bce2638 Make category pill work on invidious and mobile youtube 2022-01-05 15:13:42 -05:00
Ajay
388b9179ac Don't show full segments on preview bar 2022-01-05 02:39:13 -05:00
Ajay
2883a50f27 Add pill beside title for full video reports 2022-01-05 02:35:58 -05:00
Ajay
d36b4a54f3 Allow submitting as full video 2022-01-02 23:35:24 -05:00
Ajay Ramachandran
6ed946c998 bump version 2022-01-01 14:41:07 -05:00
Michael C
44bc8741ef fix UI issues with embeds
- add loadStart trigger to create & update preview and buttons
- show info button on /embed/ but not /channel/
2021-12-31 22:56:46 -05:00
Michael C
7a7b21cd87 add path for embedded videos and playlists 2021-12-31 18:17:15 -05:00
Michael C
229bd23a68 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into channelTrailer 2021-12-31 17:30:17 -05:00
Ajay Ramachandran
894410db98 Merge pull request #1115 from Choromanski/master
Fixed minute to day conversion
2021-12-31 16:36:52 -05:00
Brian Choromanski
0336157673 Fixed minute to day conversion 2021-12-31 16:34:29 -05:00
Ajay Ramachandran
b758cbb25f bump version 2021-12-30 17:20:11 -05:00
Ajay Ramachandran
f2be7a9c5b Merge pull request #1113 from CyberPhoenix90/fix_interval_leak
fix leak that was killing performance over long periods
2021-12-30 10:56:42 -05:00
CyberPhoenix90
8763d173bd fix missing semi colon 2021-12-30 15:22:02 +01:00
CyberPhoenix90
07e3117e22 fix leak that was killing performance over long periods 2021-12-30 15:05:09 +01:00
Ajay
12bc10ea1f Make youtube settings in front of skip notice 2021-12-29 00:35:33 -05:00
Ajay
2db1971190 Don't change countdown speed with playback speed
Fix #1067
2021-12-29 00:30:24 -05:00
Ajay
9b152a5525 Fix preview bar not being recreated 2021-12-28 20:46:31 -05:00
Ajay
7f374f0f86 Trigger changes even if videoid doesn't change if video element changes 2021-12-28 20:46:31 -05:00
Ajay
aca52abefc Make skip notice work on channel trailer 2021-12-28 20:46:31 -05:00
Michael C
6930980a4d set isInvidious to bypass UI bugs 2021-12-28 20:46:31 -05:00
Michael C
5af4833763 change parser to use document if applicable 2021-12-28 20:46:27 -05:00
Ajay Ramachandran
c3107ffcff bump version 2021-12-28 15:25:20 -05:00
Ajay Ramachandran
4bca8ad2f7 Merge pull request #1071 from mchangrh/invidiousCI
Auto-populate invidious list
2021-12-28 15:09:19 -05:00
Ajay Ramachandran
e729e036cf New Crowdin updates (#1054) 2021-12-28 14:51:14 -05:00
Ajay
7b74307013 formatting 2021-12-28 14:50:18 -05:00
Ajay
6aa1665d7c Create pull request for invidious list instead of commit 2021-12-28 14:50:12 -05:00
Ajay Ramachandran
a1bae95cdc Merge pull request #1091 from AronHK/audio-notification
Decouple audio notification from Skip Notice
2021-12-28 11:36:04 -05:00
Ajay
c5b72a01a2 Remove filler update notice 2021-12-26 20:16:26 -05:00
Ajay
8ade66d7b3 Fix skip notice deleting segments causing issues
Fixes #1105
2021-12-22 12:13:31 -05:00
Ajay Ramachandran
d42862541b Merge branch 'master' of https://github.com/ajayyy/SponsorBlock 2021-12-15 22:01:31 -05:00
Ajay Ramachandran
54001763a7 Don't hide userID option if not set
Fix #1025
2021-12-15 22:01:28 -05:00
Áron Hegymegi-Kiss
46e515b130 design fixes 2021-12-15 22:22:06 +01:00
Áron Hegymegi-Kiss
9a9e564dbf show version + clickable labels 2021-12-13 12:14:51 +01:00
Áron Hegymegi-Kiss
4971824067 missing labels, hide options when sth they depend on gets turned off 2021-12-13 02:37:15 +01:00
Áron Hegymegi-Kiss
dface28c84 group settings into tabs 2021-12-12 23:31:09 +01:00
Ajay Ramachandran
7186829bc3 Merge pull request #1079 from Choromanski/feature/format-time-to-days
Format minutes now Days, Hours and Minutes
2021-12-11 19:39:28 -05:00
Aron HK
3d3b261f8f skipNoticeContentContainer().v -> video
Co-authored-by: Ajay Ramachandran <dev@ajay.app>
2021-12-12 01:38:31 +01:00
Ajay Ramachandran
33094f2541 Add example for abbreviations 2021-12-11 19:33:11 -05:00
Hegymegi Kiss Áron
9f9df9479b move audio notification to content.ts
fixes  #756
2021-12-11 16:02:07 +01:00
Ajay Ramachandran
1c911581db Fix loop fix on Safari 2021-12-10 23:53:56 -05:00
Ajay Ramachandran
071f8b1729 Don't skip exactly to the end on Safari
Fix #1027
2021-12-10 23:52:50 -05:00
Ajay Ramachandran
8d1b35403d Fix auto hiding info not hiding
Fix #811
2021-12-10 19:09:25 -05:00
Brian Choromanski
a8fee918e4 Merge branch 'master' into feature/format-time-to-days 2021-12-06 06:09:21 -05:00
Brian Choromanski
7bca8e508e Localized d and h 2021-12-06 05:57:37 -05:00
Michael C
e16aae393f also check against length 2021-12-04 23:16:26 -05:00
Ajay Ramachandran
44de741e84 Merge pull request #1072 from Choromanski/feature/updated-comments
Changed comments from seconds and hours to minutes
2021-12-04 22:18:53 -05:00
Brian Choromanski
bc990cd683 Format minutes from hours, and minutes to days, hours, and minutes 2021-12-04 11:56:55 -05:00
Michael C
33098ac659 migrate and populat on reset 2021-12-01 17:48:07 -05:00
Ajay Ramachandran
2f8ec7a5e5 Merge pull request #1073 from mchangrh/patch-1
Update licence in package.json
2021-12-01 17:00:17 -05:00
Ajay Ramachandran
48f7c1e0a1 fix license in package.json 2021-12-01 17:00:04 -05:00
Michael M. Chang
29c3b80d0b Update licence in package.json
#721
2021-12-01 16:44:08 -05:00
Michael C
dc47b9ffd2 appease CI/ webpack
move to ci/
change triggers
2021-11-30 18:17:28 -05:00
Brian Choromanski
eaa47c8d40 Changed comments from seconds and hours to minutes 2021-11-30 17:36:21 -05:00
Michael C
e4e453a11c add code to parse and filter 2021-11-30 15:55:26 -05:00
Ajay Ramachandran
2209c230e7 Fix autohide info button affecting skip to highlight
Fix #1063
2021-11-27 00:06:52 -05:00
Ajay Ramachandran
9d70332c9a bump version 2021-11-24 18:33:53 -05:00
Ajay Ramachandran
8150d38df0 New Crowdin updates (#1036) 2021-11-24 18:33:40 -05:00
Ajay Ramachandran
75b5c31d07 Fix filler category notice 2021-11-23 21:05:27 -05:00
Ajay Ramachandran
c007ac3d86 Add tooltip about filler category 2021-11-21 19:40:25 -05:00
Ajay Ramachandran
7218be73c6 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock 2021-11-16 23:26:16 -05:00
Ajay Ramachandran
96693342a3 Fix start time messing up when end time too far in preview bar 2021-11-16 23:26:15 -05:00
Ajay Ramachandran
d2ff7b5c04 bump version 2021-11-09 22:47:24 -05:00
Ajay Ramachandran
9a0f1db31e New Crowdin updates (#1033) 2021-11-09 22:47:10 -05:00
Ajay Ramachandran
06da4d6556 Remove notice about highlight category update 2021-11-08 19:57:46 -05:00
Ajay Ramachandran
20d0c05049 Update manifest.json 2021-11-08 19:29:55 -05:00
Ajay Ramachandran
96e4957f71 Add filler category and allow mute intro, outro, preview 2021-11-08 19:19:00 -05:00
Ajay Ramachandran
9c5eeac239 Merge pull request #1029 from opl-/docs/readme-building
Add more detail to building section of readme
2021-11-03 19:38:12 -04:00
Ajay Ramachandran
e685697bbb Add back info about adjusting config 2021-11-03 19:36:45 -04:00
Ajay Ramachandran
752e515a1c Merge pull request #1018 from FlorianZahn/fontSizeFixTooltip
Makes rectangleTooltip fontSize bigger
2021-11-02 00:08:26 -04:00
Ajay Ramachandran
ca0f68bb7d Merge pull request #1019 from FlorianZahn/roundSubmitTimes
unsubmitted segments are initialized rounded to 3 digits
2021-11-02 00:08:10 -04:00
Ajay Ramachandran
34884026d9 New Crowdin updates (#1014) 2021-11-02 00:07:08 -04:00
Ajay Ramachandran
7a38bf0c08 bump version 2021-11-02 00:06:56 -04:00
Ajay Ramachandran
5adcec2ca5 Remove segment duration filter
Close #1031 #989
2021-11-02 00:06:40 -04:00
Ajay Ramachandran
36989907a2 Remove highlight skipping by clicking near it
Closes #973
2021-10-30 22:02:21 -04:00
opl-
db55778fd8 Add more detail to building section of readme 2021-10-29 20:59:21 +02:00
Ajay Ramachandran
41be51b384 formatting fixes 2021-10-26 18:37:37 -04:00
Ajay Ramachandran
e87efe2c67 bump version 2021-10-23 15:09:47 -04:00
Ajay Ramachandran
069299e968 Merge pull request #1021 from opl-/fix/wheel-edits
Fix mouse wheel can enter edit mode
2021-10-22 23:11:22 -04:00
opl-
4d09a603fe Fix mouse wheel can enter edit mode 2021-10-23 00:52:52 +02:00
Ajay Ramachandran
8b595af5e9 Fix skip to highlight not hiding when none 2021-10-22 01:50:17 -04:00
Ajay Ramachandran
41739a8799 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock 2021-10-22 01:29:47 -04:00
Ajay Ramachandran
23bebbca7c Fix help page on mobile 2021-10-22 01:29:46 -04:00
Ajay Ramachandran
5f2af12150 bump version 2021-10-21 22:39:15 -04:00
Ajay Ramachandran
628abd03f0 Added swiping away for skip to highlight on mobile 2021-10-21 22:33:49 -04:00
Ajay Ramachandran
8e254c5807 Make bigger buttons on mobile skip button 2021-10-21 22:11:26 -04:00
Ajay Ramachandran
0647576d6f Add animation for skip to highlight on mobile 2021-10-21 21:58:43 -04:00
Ajay Ramachandran
c803ae9499 Add skip to highlight to mobile 2021-10-21 01:30:52 -04:00
FlorianZahn
95f45312e1 support for multiple poi categories 2021-10-21 04:19:26 +02:00
FlorianZahn
9dda9a583d unsubmitted segments are initialized rounded to 3 digits 2021-10-21 03:14:45 +02:00
Ajay Ramachandran
d1e6421e5b Fix type errors 2021-10-20 19:33:48 -04:00
Ajay Ramachandran
bd0a6aaaad Hide submissions on mobile 2021-10-20 19:28:00 -04:00
Ajay Ramachandran
1e8b176c69 Allow finer tuned previewing 2021-10-19 22:57:46 -04:00
Ajay Ramachandran
14018798f7 Add wiki links to options 2021-10-19 19:10:27 -04:00
Ajay Ramachandran
a0d06ca6e8 Fix start time in preview bar in wrong place 2021-10-19 19:00:30 -04:00
FlorianZahn
95fe1eef6f Makes rectangleTooltip fontSize bigger 2021-10-19 21:38:44 +02:00
Ajay Ramachandran
38b1dda20b Add support for required segment parameter 2021-10-18 19:51:44 -04:00
Ajay Ramachandran
07cf1764dc bump version 2021-10-17 19:12:38 -04:00
Ajay Ramachandran
aeb9c5b203 New Crowdin updates (#1012) 2021-10-17 19:12:09 -04:00
Ajay Ramachandran
ad3f0c1a06 Don't filter segments when switching videos still
Fixes #989
2021-10-16 13:41:07 -04:00
Ajay Ramachandran
4bc180077e Fix segments sometimes displaying after the seek bar if at the end 2021-10-16 13:15:47 -04:00
Ajay Ramachandran
510db57666 bump version 2021-10-15 19:29:15 -04:00
Ajay Ramachandran
5ee6a2195d Merge pull request #1002 from maximmax42/patch-1
Added margin-bottom for #sponsorblockPopup
2021-10-15 19:28:54 -04:00
Ajay Ramachandran
63d4c1aedb New Crowdin updates (#990) 2021-10-15 19:01:03 -04:00
Ajay Ramachandran
e9204be96f Merge pull request #988 from FlorianZahn/copySegment
Copy segments into your unsubmitted and SkipNotice changes
2021-10-15 19:00:38 -04:00
Ajay Ramachandran
0863061665 Fix indentation in manifest 2021-10-15 18:57:36 -04:00
FlorianZahn
8aea74160c only change color if user isVip 2021-10-15 21:01:32 +02:00
FlorianZahn
d375a97e99 Vip Warning also in popup 2021-10-15 20:52:15 +02:00
Ajay Ramachandran
fe5499e80a Code style fixes and react errors 2021-10-15 00:56:48 -04:00
Ajay Ramachandran
598da2a7fe Merge branch 'copySegment' of https://github.com/florianzahn/sponsorblock into pr/FlorianZahn/988 2021-10-15 00:31:09 -04:00
Ajay Ramachandran
fcbeeb9fc1 Remove extra segment lookup and use lockbyhash lookup 2021-10-15 00:31:07 -04:00
FlorianZahn
d82ef63d89 fix loading text not displaying upon voting 2021-10-14 19:05:36 +02:00
FlorianZahn
a457a8009e SkipNotice countdown now updates again on config update 2021-10-14 08:05:55 +02:00
FlorianZahn
7698be8462 Remove merge mistake 2021-10-14 07:21:07 +02:00
FlorianZahn
738868da8d Merge branch 'master' into copySegment 2021-10-14 07:16:55 +02:00
Ajay Ramachandran
fc7fc693ed Fix getting locked category 2021-10-13 23:57:59 -04:00
Ajay Ramachandran
27f5997e5a Add return types to vip fetching functions 2021-10-13 23:34:25 -04:00
Ajay Ramachandran
45274f5c72 Wait for vip info to be fetched 2021-10-13 23:32:52 -04:00
Ajay Ramachandran
2bdfd3f39b Merge branch 'copySegment' of https://github.com/florianzahn/sponsorblock into pr/FlorianZahn/988 2021-10-13 23:25:48 -04:00
Ajay Ramachandran
9b9174ab9a Simplify vip info fetching 2021-10-13 23:25:46 -04:00
FlorianZahn
3e3e9796b1 syntax error
Co-authored-by: Ajay Ramachandran <dev@ajay.app>
2021-10-14 05:19:18 +02:00
Ajay Ramachandran
ff5fa4c724 Move config values and close notice 2021-10-13 23:14:51 -04:00
Ajay Ramachandran
b8ab05ccad Merge pull request #985 from FlorianZahn/editSegmentTimesByScrolling
Scrolling over the edit-segment-time component will change them.
2021-10-13 22:37:31 -04:00
FlorianZahn
93e440385f Removed console.log and redundancy 2021-10-14 02:16:04 +02:00
FlorianZahn
af66a77026 Fixed logic mistake if undovotes are ever implemented 2021-10-14 02:11:15 +02:00
Maxim
75607dea1c Added margin-bottom for #sponsorblockPopup
This margin is to separate popup window from playlist/related videos list
2021-10-13 22:48:07 +05:00
FlorianZahn
5b353b05ac replaced tab with 4 spaces 2021-10-13 06:22:50 +02:00
FlorianZahn
3162ab93a1 Formatting 2021-10-13 06:19:48 +02:00
FlorianZahn
b18f631d33 better if/else readability
Co-authored-by: Ajay Ramachandran <dev@ajay.app>
2021-10-13 06:14:03 +02:00
FlorianZahn
2e254cb917 prettier spaces
Co-authored-by: Ajay Ramachandran <dev@ajay.app>
2021-10-13 06:13:32 +02:00
FlorianZahn
77ce9433a7 removed response.ok for response === 200 2021-10-13 06:08:14 +02:00
FlorianZahn
509e54762f Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into editSegmentTimesByScrolling 2021-10-13 06:02:50 +02:00
FlorianZahn
caeb347137 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into copySegment 2021-10-13 05:55:21 +02:00
Ajay Ramachandran
a2b054844a Fix unsubmitted segments sometimes not skipping 2021-10-11 22:22:36 -04:00
Ajay Ramachandran
5b79d4ef48 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock 2021-10-11 19:02:22 -04:00
Ajay Ramachandran
3de66ebe23 Potentially fix info button reappearing 2021-10-11 19:02:20 -04:00
FlorianZahn
60ef51b7f5 I forgot to change the 24h countdown back to 24h instead of 1 seconds 2021-10-11 03:50:19 +02:00
FlorianZahn
aa8ee02277 Added colored text if a category is locked for submitting and changing category 2021-10-11 03:49:14 +02:00
FlorianZahn
b927ebbbf7 Lint fixes 2021-10-10 10:56:27 +02:00
FlorianZahn
d72d5dcbcb Lint fixes 2021-10-10 10:50:35 +02:00
FlorianZahn
d9f703d808 Vip warning added when downvoting. sry that it is in the same branch, but this is the most current UI 2021-10-10 10:47:47 +02:00
FlorianZahn
a9cc43c586 Changed heigt of 2nd notice. Minor changes. Upvoting lets downvoted segment reappear 2021-10-10 00:41:21 +02:00
FlorianZahn
844567dcdf Lit fixes 2021-10-09 08:13:02 +02:00
FlorianZahn
52ed4f73f4 SkipNotice now remembers what has already been voted. Also nicer highlighting of current selection. 2021-10-09 08:08:46 +02:00
FlorianZahn
907bd68e4e Buttons now change color depending on state. Added colorPalette config entry 2021-10-09 02:43:39 +02:00
Ajay Ramachandran
f35afaf6bc bump version 2021-10-06 21:10:31 -04:00
Ajay Ramachandran
85b1b51b76 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock 2021-10-06 21:02:02 -04:00
Ajay Ramachandran
9dc5449e37 Make capitalization consistent 2021-10-06 21:01:59 -04:00
FlorianZahn
6ea226c972 Added string to the language file 2021-10-06 23:38:06 +02:00
FlorianZahn
44f9ab9806 changed let to const 2021-10-06 23:16:53 +02:00
FlorianZahn
edd1011737 margin in ContinueVoting 2021-10-06 23:13:10 +02:00
FlorianZahn
08558bfaeb Merge branch 'copySegment' of https://github.com/FlorianZahn/SponsorBlock into copySegment 2021-10-06 23:08:22 +02:00
FlorianZahn
4afc2c153a Restart Voting button. Wiki links. SkipNotice Improvements 2021-10-06 23:02:26 +02:00
FlorianZahn
988905c155 Update config.ts 2021-10-06 16:33:11 +02:00
FlorianZahn
51aab00985 Update config.ts 2021-10-06 08:31:18 +02:00
FlorianZahn
84924b6364 Update SkipNoticeComponent.tsx 2021-10-06 08:29:45 +02:00
FlorianZahn
93f02877a7 copy segments basics done 2021-10-06 08:15:15 +02:00
Ajay Ramachandran
7baac9dcbf New Crowdin updates (#984) 2021-10-05 20:52:16 -04:00
Ajay Ramachandran
4045978b54 Support older browsers 2021-10-05 20:51:20 -04:00
Ajay Ramachandran
56bc3fca04 Hide skip to highlight right away when dismissing 2021-10-05 20:06:18 -04:00
FlorianZahn
c571a9ecb6 made the tool tip fully opaque for better readability 2021-10-04 21:37:15 +02:00
FlorianZahn
1ad60720df empty function fix 2021-10-04 21:04:02 +02:00
FlorianZahn
e5fe99c89b Changed empty arrow function to empty function 2021-10-04 20:24:52 +02:00
FlorianZahn
3fc32a68c3 Changing the time a little manually opens a popup 2021-10-04 20:20:04 +02:00
FlorianZahn
142cc2881f added step modifier ctrl 2021-10-04 14:26:24 +02:00
FlorianZahn
4de55ea5fe Scroll amount now 1/1000th while pressing "shift" 2021-10-04 04:24:14 +02:00
FlorianZahn
620e75517c Now handeling deltaY=0 and shrunk down code 2021-10-03 22:11:33 +02:00
FlorianZahn
cba26a42af combined similar code into function. More readable function names 2021-10-03 21:50:02 +02:00
FlorianZahn
f3f598d6c7 combined similar code into function. More readable function names 2021-10-03 21:48:12 +02:00
FlorianZahn
fe7d9986fa Boolean --> boolean; var --> let 2021-10-03 21:23:33 +02:00
FlorianZahn
143ca6f6e0 Highlight time stamps are synchronized when scorlling 2021-10-03 21:19:06 +02:00
FlorianZahn
69ce065588 Scrolling over the segment times will change them 2021-10-03 20:56:10 +02:00
Ajay Ramachandran
bfa31429f1 Support shorts with additional parts of url 2021-10-03 13:08:50 -04:00
Ajay Ramachandran
66f0cc8883 Support shorts 2021-10-03 13:07:47 -04:00
Ajay Ramachandran
1a0ac27e49 New Crowdin updates (#980) 2021-10-02 18:05:41 -04:00
Ajay Ramachandran
7b87ae7b08 bump version 2021-10-02 18:00:58 -04:00
Ajay Ramachandran
9ab8e63b1d Merge pull request #983 from ajayyy/test-action
Add testing action
2021-10-02 18:00:09 -04:00
Ajay Ramachandran
0e147134f3 Add testing action 2021-10-02 17:42:47 -04:00
Ajay Ramachandran
8605e23fbb Fix starting segments when there is a t=? in the url 2021-10-02 17:13:30 -04:00
Ajay Ramachandran
5f34a777f1 Fix starting segment sometimes not being skipped and duration filter 2021-10-02 16:15:53 -04:00
Ajay Ramachandran
1f43d07e16 Remove possible error in notice 2021-10-02 16:05:23 -04:00
Ajay Ramachandran
a88aaf4590 Prevent error when video not loaded yet 2021-10-02 15:46:33 -04:00
Ajay Ramachandran
25f78ed55b Merge branch 'master' of https://github.com/ajayyy/SponsorBlock 2021-10-02 15:24:01 -04:00
Ajay Ramachandran
26e73c515c Fix seeking issues with poi segment 2021-10-02 15:23:59 -04:00
Ajay Ramachandran
028374e62d Update manifest.json 2021-10-02 14:38:59 -04:00
Ajay Ramachandran
dc1e5ce762 Fix styling on voting wrong category 2021-10-01 18:28:11 -04:00
Ajay Ramachandran
8fcf8ac46c Speed up autohiding button transition 2021-10-01 18:08:02 -04:00
Ajay Ramachandran
ef70e71051 Fix segments not appearing when loaded early 2021-10-01 18:07:15 -04:00
Ajay Ramachandran
23a91c626d bump version 2021-09-30 19:39:54 -04:00
Ajay Ramachandran
c92f63af36 New Crowdin updates (#978) 2021-09-30 19:39:14 -04:00
Ajay Ramachandran
0a21ef7af0 Merge pull request #958 from FlorianZahn/PersistantHighlight
Highlight Button now persists; Implements issue #953
2021-09-30 19:33:39 -04:00
Ajay Ramachandran
5a74a28520 Fix skip to highlight text reappearing 2021-09-30 19:26:28 -04:00
Ajay Ramachandran
1bfb5cfb13 Compact button options and add option for skip to highlight button 2021-09-30 19:23:17 -04:00
Ajay Ramachandran
59f8f82655 Add alt text to skip to highlight 2021-09-30 18:20:58 -04:00
Ajay Ramachandran
2064afb235 Make hiding highlight button smooth 2021-09-30 18:15:06 -04:00
Ajay Ramachandran
ebcb600e99 Auto hide skip to highlight 2021-09-30 00:43:10 -04:00
Ajay Ramachandran
9ec984065e hide when buttons disabled and hide chapter prefix 2021-09-29 23:13:54 -04:00
Ajay Ramachandran
63cfe760b6 New Crowdin updates (#961) 2021-09-29 16:27:11 -04:00
Ajay Ramachandran
1a717542c7 Improve warning message 2021-09-28 20:05:48 -04:00
Ajay Ramachandran
de607d317f Hide segments with different video durations 2021-09-28 19:58:51 -04:00
Ajay Ramachandran
76d9a9afa9 Merge pull request #957 from mchangrh/update-workflow
Update workflow
2021-09-21 19:04:20 -04:00
FlorianZahn
22ecc05a55 Highlight Button now persists 2021-09-20 15:32:31 +02:00
Michael C
514ebe8660 update wiki links in README 2021-09-20 02:14:54 -04:00
Michael C
2f4722162b update workflows to newest versions 2021-09-20 02:13:41 -04:00
Ajay Ramachandran
f219122f00 bump version 2021-09-19 22:41:21 -04:00
Ajay Ramachandran
008671d97f New Crowdin updates (#938) 2021-09-19 22:40:43 -04:00
FlorianZahn
6fb3802fd4 Preview skip-lenth dependant on playbackspeed (#949)
* Preview button playback speed dependant

Pressing "Preview" will now jump 2 seconds in front of the segment start time, depending on the playback speed.
2021-09-19 10:24:37 -04:00
Ajay Ramachandran
73241a0bd1 Fix in the middle of mute 2021-09-16 23:21:59 -04:00
Ajay Ramachandran
cc995b9848 Merge pull request #942 from LofhJann/master
Fix username wrapping
2021-09-15 21:33:23 -04:00
Janne Löfhjelm
778379d294 Fix username wrapping 2021-09-11 03:33:41 +03:00
Ajay Ramachandran
1083520666 Add warning for submitting multiple highlights 2021-09-10 19:07:16 -04:00
Ajay Ramachandran
cad5cd97fc New Crowdin updates (#933) 2021-09-07 23:29:35 -04:00
Ajay Ramachandran
7f5728d4db bump version 2021-09-07 23:28:48 -04:00
Ajay Ramachandran
06fa2748fe Fix package-lock, fix #937 2021-09-07 18:54:37 -04:00
Ajay Ramachandran
8b50373eab Merge branch 'master' of https://github.com/ajayyy/SponsorBlock 2021-09-06 23:51:28 -04:00
Ajay Ramachandran
bdedf86d63 Fix selenium test to change category 2021-09-06 23:51:26 -04:00
Ajay Ramachandran
0fb84dc03d Merge pull request #934 from KarelVerschraegen/patch-2
Fix typo in SubmissionNoticeComponent
2021-09-06 16:11:03 -04:00
Ajay Ramachandran
041ccdaf11 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock 2021-09-06 16:10:34 -04:00
Ajay Ramachandran
1f967b3f69 Fix skips not being counted and crash on old browser 2021-09-06 16:10:32 -04:00
KarelVerschraegen
07f0b87379 Fix typo in SubmissionNoticeComponent 2021-09-06 15:50:13 +02:00
Ajay Ramachandran
840dbbde4a New Crowdin updates (#928) 2021-09-05 13:30:51 -04:00
Ajay Ramachandran
2b9000ff84 bump version 2021-09-05 13:29:45 -04:00
Ajay Ramachandran
0d0171530c Remove unused string 2021-09-04 02:17:57 -04:00
Ajay Ramachandran
6040d177fa Say muted instead of skipped for mute segments 2021-09-04 02:09:10 -04:00
Ajay Ramachandran
2c1f5f16c2 Only show mute option for supported categories 2021-09-04 01:44:09 -04:00
Ajay Ramachandran
0e7a298967 bump version 2021-09-03 17:01:03 -04:00
Ajay Ramachandran
9a9f151979 New Crowdin updates (#926) 2021-09-03 16:58:07 -04:00
Ajay Ramachandran
ca814c9dcc Merge pull request #917 from mchangrh/update-matrix
update matrix links
2021-09-03 16:36:58 -04:00
Ajay Ramachandran
976dbb9159 Merge branch 'master' into update-matrix 2021-09-03 16:36:51 -04:00
Ajay Ramachandran
90ce9808f1 New Crowdin updates (#924)
* New translations messages.json (Italian)

* New translations messages.json (Vietnamese)

* New translations messages.json (Swedish)

* New translations messages.json (Turkish)

* New translations messages.json (Chinese Simplified)

* New translations messages.json (Indonesian)

* New translations messages.json (Tamil)

* New translations messages.json (Polish)

* New translations messages.json (Croatian)

* New translations messages.json (Estonian)

* New translations messages.json (Malay)

* New translations messages.json (Telugu)

* New translations messages.json (Malayalam)

* New translations messages.json (Norwegian)

* New translations messages.json (Russian)

* New translations messages.json (French)

* New translations messages.json (Portuguese, Brazilian)

* New translations messages.json (Spanish)

* New translations messages.json (Czech)

* New translations messages.json (German)

* New translations messages.json (Japanese)

* New translations messages.json (Dutch)

* New translations messages.json (Slovak)

* New translations messages.json (Ukrainian)

* New translations messages.json (Chinese Traditional)

* New translations messages.json (Romanian)

* New translations messages.json (Bulgarian)

* New translations messages.json (Finnish)

* New translations messages.json (Hungarian)

* New translations messages.json (Italian)

* New translations messages.json (Korean)

* New translations messages.json (German)

* New translations messages.json (Dutch)

* New translations messages.json (Ukrainian)

* New translations messages.json (French)

* New translations messages.json (Korean)

* New translations messages.json (Turkish)
2021-09-03 16:35:11 -04:00
Ajay Ramachandran
ef942fca8e Merge pull request #923 from ajayyy/silent-skip
Mute segments
2021-09-02 13:22:44 -04:00
Ajay Ramachandran
3671c4bb69 Hide mute option for highlight 2021-09-02 13:20:50 -04:00
Ajay Ramachandran
ef15526dcd Explain how to get public userID 2021-09-02 12:00:18 -04:00
Ajay Ramachandran
096737dcbb bump version 2021-09-02 11:44:38 -04:00
Ajay Ramachandran
02360c1f3c Fix centering on submission notice 2021-09-02 11:44:25 -04:00
Ajay Ramachandran
ccd8342ddb Update top contibutors 2021-09-02 00:37:53 -04:00
Ajay Ramachandran
4ae2a42c8c New Crowdin updates (#902) 2021-09-02 00:19:36 -04:00
Ajay Ramachandran
206d7bc2bd bump version 2021-09-02 00:14:46 -04:00
Ajay Ramachandran
0fc9e9b2fb Fix UI issues when text is long
Fixes #914
2021-09-02 00:05:13 -04:00
Ajay Ramachandran
5ad809cfb4 Add e2e test for mute skip 2021-09-01 22:00:48 -04:00
Ajay Ramachandran
d1e46825af Fix mute skip failing on videos without segments 2021-09-01 22:00:48 -04:00
Ajay Ramachandran
2763b6b6aa Clarify muting option 2021-09-01 22:00:48 -04:00
Ajay Ramachandran
427b90a5e9 Add option to disable mute segments 2021-09-01 22:00:48 -04:00
Ajay Ramachandran
60e54ee129 Hide unmute buttons after segment is finished 2021-09-01 22:00:48 -04:00
Ajay Ramachandran
4092bf9b05 Make skip notice buttons work with mute segments 2021-09-01 22:00:48 -04:00
Ajay Ramachandran
f31c2985e2 Add silent skipping to scheduler 2021-09-01 22:00:48 -04:00
Ajay Ramachandran
34cfd14e74 Add UI for submitting mute segments and request mute segments 2021-09-01 21:59:44 -04:00
Ajay Ramachandran
3774ef9756 Fix preview sometimes not skipping
Fixes #915
2021-09-01 19:50:58 -04:00
Ajay Ramachandran
098d879fe2 Merge pull request #922 from ajayyy/basic-selenium
Basic selenium
2021-09-01 16:03:05 -04:00
Ajay Ramachandran
49406b7ac6 Make refresh button work when no segments found
Fixes #885
2021-09-01 15:50:22 -04:00
Ajay Ramachandran
5c704ad241 Fix multiple segments skipped not appearing
Fixes #909, #919, #905
2021-09-01 15:41:46 -04:00
Ajay Ramachandran
681eb61763 Fix highlight appearing as two timestamps in popup 2021-09-01 13:15:15 -04:00
Ajay Ramachandran
71cf9888e8 Fix disable skipping not working for highlight
Resolves #916
2021-09-01 04:24:10 -04:00
Ajay Ramachandran
b1aaa0ac5e Add copy public id button 2021-09-01 04:22:06 -04:00
Michael C
0367f7900f udpate discord link for consistency 2021-08-29 15:01:11 -04:00
Michael C
47261a360c update matrix links 2021-08-29 14:56:08 -04:00
Ajay Ramachandran
a2c3116bdd Merge branch 'master' of https://github.com/ajayyy/SponsorBlock 2021-08-26 18:20:35 -04:00
Ajay Ramachandran
48a49e4136 Make highlight hover text work better on preview bar 2021-08-26 18:20:33 -04:00
Ajay Ramachandran
6de1a58d88 bump version 2021-08-24 02:28:18 -04:00
Ajay Ramachandran
43a9ba0f9e Fix keybind being flaky 2021-08-23 19:51:58 -04:00
Ajay Ramachandran
c3489e54a6 Fix highlight category when minimum duration set 2021-08-23 18:23:03 -04:00
Ajay Ramachandran
75c003b204 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock 2021-08-23 15:46:36 -04:00
Ajay Ramachandran
da5de43121 Fix skipping with highlight on invidious 2021-08-23 15:46:35 -04:00
Ajay Ramachandran
d20a44751c bump version 2021-08-23 03:08:01 -04:00
Ajay Ramachandran
15706fd3c4 Fix issue with early highlight breaking skipping 2021-08-22 20:47:46 -04:00
Ajay Ramachandran
a9e43f95f5 Fix highlight auto skipping on music videos 2021-08-22 19:03:24 -04:00
Ajay Ramachandran
11fe87a09e Fix highlight category info appearing to new users 2021-08-22 19:03:05 -04:00
Ajay Ramachandran
52741b2c0a Merge branch 'master' of https://github.com/ajayyy/SponsorBlock 2021-08-22 14:13:03 -04:00
Ajay Ramachandran
09b18a4f6d Fix auto skip on music videos for show overlay 2021-08-22 14:13:02 -04:00
Ajay Ramachandran
326385f325 New Crowdin updates (#900) 2021-08-21 12:55:55 -04:00
Ajay Ramachandran
28884f5e9f Bump version 2021-08-21 12:54:09 -04:00
Ajay Ramachandran
50d5f956c6 Refetch when not found no matter the date 2021-08-20 18:56:08 -04:00
Ajay Ramachandran
585038c902 Close skip to highlight when changing videos 2021-08-20 18:43:44 -04:00
Ajay Ramachandran
c79b06aed3 add comment for highlight update 2021-08-20 14:29:28 -04:00
Ajay Ramachandran
8d2883b6e2 Increase version 2021-08-20 13:39:56 -04:00
Ajay Ramachandran
c96ce694b7 New Crowdin updates (#897) 2021-08-20 13:39:18 -04:00
Ajay Ramachandran
989b5c9370 New Crowdin updates (#883) 2021-08-20 03:57:46 -04:00
Ajay Ramachandran
032264d8bb Merge pull request #896 from ajayyy/improvements
More highlight improvements
2021-08-20 03:57:27 -04:00
Ajay Ramachandran
d089e43b8a Add tooltip about highlight feature 2021-08-20 03:54:49 -04:00
Ajay Ramachandran
b3336a218e Make help page localisable and make up to date
Closes https://github.com/ajayyy/SponsorBlock/issues/509
2021-08-20 02:00:15 -04:00
Ajay Ramachandran
bea943dc96 Add option to disable $ link 2021-08-20 00:04:42 -04:00
Ajay Ramachandran
12f41521f5 Merge pull request #895 from ajayyy/improvements
Highlight category improvements
2021-08-19 22:37:53 -04:00
Ajay Ramachandran
36aec560ca Add options for smaller and faded notice 2021-08-19 22:32:28 -04:00
Ajay Ramachandran
e8a106d36b Fix warnings 2021-08-19 13:23:28 -04:00
Ajay Ramachandran
2c52b9e600 Merge pull request #690 from ajayyy/improvements
Highlight category
2021-08-19 13:23:26 -04:00
Ajay Ramachandran
3c5316a11c Disable fading by default for now 2021-08-19 13:21:30 -04:00
Ajay Ramachandran
c5044d3ebd Decrease font size on help page 2021-08-19 11:45:32 -04:00
Ajay Ramachandran
db34f1fd5b Add keybind support to skip to highlight 2021-08-19 01:17:36 -04:00
Ajay Ramachandran
21f563fdb7 Fix confusing padding on options page 2021-08-18 13:33:28 -04:00
Ajay Ramachandran
3bbc699d98 Move highlight category on options page 2021-08-18 13:29:02 -04:00
Ajay Ramachandran
53d688f219 Fix skip button on control bar in firefox 2021-08-18 11:18:24 -04:00
Ajay Ramachandran
2231e2a345 Keep showing control bar button if hovered 2021-08-18 02:13:05 -04:00
Ajay Ramachandran
e126b59078 Added skip button in control bar instead of using skip notice 2021-08-18 02:07:24 -04:00
Ajay Ramachandran
2a0e893dfc Fix second notice fading too soon 2021-08-17 23:09:01 -04:00
Ajay Ramachandran
8b348a2aeb Rename highlight category to poi_highlight 2021-08-17 22:05:19 -04:00
Ajay Ramachandran
28096e1ba6 Don't show multiple skip notices after skipping highlight 2021-08-17 21:45:30 -04:00
Ajay Ramachandran
56b74d6863 Use "skipped to" for poi 2021-08-17 21:44:57 -04:00
Ajay Ramachandran
ffc8f0b6a0 Hide unskip by default on poi segments 2021-08-17 21:05:53 -04:00
Ajay Ramachandran
4fef6dcfa0 Remove preview category auto enable 2021-08-17 21:03:36 -04:00
Ajay Ramachandran
a3c80573fa Make unskip work with highlight segment 2021-08-17 20:47:40 -04:00
Ajay Ramachandran
a13f5d2359 Show skip notice when clicking poi segment in seek bar 2021-08-17 19:37:52 -04:00
Ajay Ramachandran
42beaf698c Make highlight larger on preview bar 2021-08-17 18:37:59 -04:00
Ajay Ramachandran
4e99754b8c Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into improvements 2021-08-17 18:25:18 -04:00
Ajay Ramachandran
422139f474 Link to new wiki 2021-08-17 01:45:03 -04:00
Ajay Ramachandran
93e5bf5033 Merge pull request #887 from maximmax42/patch-1
Fix for an "enable category" popup
2021-08-14 21:54:16 -04:00
Maxim
1bd78ec1c4 Fix for an "enable category" popup
If you choose any category when editing a segment, and then choose the "Choose a category" one, it triggers the enable category message with an empty category name. This is a fix for that.
2021-08-15 02:42:47 +05:00
Ajay Ramachandran
f01a1ae4ec Never show negative formatted time 2021-08-13 23:19:08 -04:00
Ajay Ramachandran
c8611adf50 bump version 2021-08-08 23:40:49 -04:00
Ajay Ramachandran
b974806514 New Crowdin updates (#866) 2021-08-08 23:40:01 -04:00
Ajay Ramachandran
668b956bb7 Don't allow changing userID if warned 2021-08-05 20:11:56 -04:00
Ajay Ramachandran
7b54b79f27 Merge pull request #875 from mchangrh/inspectSkipping
reduce precision of previewTime
2021-08-04 20:59:14 -04:00
Michael C
ef36c79092 reduce precision of previewTime to fix #874 2021-08-04 16:04:22 -04:00
Ajay Ramachandran
c1898d0db7 Fix rotating animations on popup 2021-08-03 16:20:32 -04:00
Ajay Ramachandran
e9e3114549 Update popup right away when refresh is pressed 2021-08-03 16:15:53 -04:00
Ajay Ramachandran
a56bba0612 Add skipping all segments when a non music segment exists 2021-08-03 15:19:29 -04:00
Ajay Ramachandran
afeba5f077 Don't break chat when no warning reason 2021-08-03 13:10:00 -04:00
Ajay Ramachandran
81d0c0cab1 Don't display pipe in chatr name if not needed 2021-08-03 12:45:34 -04:00
Ajay Ramachandran
de1f18612f Send user agent when getting segments 2021-08-01 17:33:37 -04:00
Ajay Ramachandran
ba37f5885a Submit user agent 2021-07-31 21:01:36 -04:00
Ajay Ramachandran
9c54d141e9 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into improvements 2021-07-31 01:02:41 -04:00
Ajay Ramachandran
4ef8e36821 Fix build step casing 2021-07-30 23:37:13 -04:00
Ajay Ramachandran
788d4bf73c Build before running test 2021-07-30 23:36:31 -04:00
Ajay Ramachandran
d73c666e1f Extract out setup steps 2021-07-30 23:34:15 -04:00
Ajay Ramachandran
3187efaf1a Add test for skipping preview segment 2021-07-30 16:00:59 -04:00
Ajay Ramachandran
b9bbbebc10 Add test for editing 2021-07-30 15:53:57 -04:00
Ajay Ramachandran
d93e9a7d8a Add basic selenium test 2021-07-30 15:04:05 -04:00
Ajay Ramachandran
2a3a04a504 Increase version number 2021-07-30 12:32:11 -04:00
Ajay Ramachandran
13ad7516c2 New Crowdin updates (#854) 2021-07-30 12:30:17 -04:00
Ajay Ramachandran
bcb981ae3d Fix type issue 2021-07-29 21:25:49 -04:00
Ajay Ramachandran
8d83076ea1 Fix popup on firefox 2021-07-29 21:25:16 -04:00
Ajay Ramachandran
17437870e7 Add context to string 2021-07-29 20:49:16 -04:00
Ajay Ramachandran
2373b34067 Merge pull request #862 from ajayyy/warning-chat
Add chat box when getting a warning
2021-07-29 20:20:24 -04:00
Ajay Ramachandran
839dd4613c Get username for warning chat 2021-07-29 19:29:34 -04:00
Ajay Ramachandran
c84a951acc Add chat for warnings after voting 2021-07-29 19:16:18 -04:00
Ajay Ramachandran
d0949452da Add close button 2021-07-29 18:34:31 -04:00
Ajay Ramachandran
1a855a6993 Add basic chat box when getting a warning 2021-07-29 18:16:44 -04:00
Ajay Ramachandran
1656fae2d4 Merge pull request #859 from rakleed/dark-scrollbar
Make dark scroll bar in Chromium-based browsers
2021-07-27 15:09:28 -04:00
Ajay Ramachandran
22be10d33f Merge branch 'master' of https://github.com/ajayyy/SponsorBlock 2021-07-27 13:21:05 -04:00
Ajay Ramachandran
324c28b867 remove log 2021-07-27 13:21:03 -04:00
Ajay Ramachandran
d56637cb14 Don't affect inline popup 2021-07-27 13:20:40 -04:00
Pavel Moiseenko
e720acc674 Make dark scroll bar in Chromium-based browsers 2021-07-27 16:37:43 +03:00
Ajay Ramachandran
c396d1690d New Crowdin updates (#825) 2021-07-21 13:12:52 -04:00
Ajay Ramachandran
2f5d4dfe03 Increase version number 2021-07-21 11:49:13 -04:00
Ajay Ramachandran
821c45a6b6 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock 2021-07-21 11:48:21 -04:00
Ajay Ramachandran
ff44016003 Remove unlisted experiment 2021-07-21 11:48:19 -04:00
Ajay Ramachandran
b11d99a196 Cleanup help page a bit 2021-07-21 02:26:15 -04:00
Ajay Ramachandran
6f548987a3 Update db link in help page 2021-07-21 02:21:00 -04:00
Ajay Ramachandran
c6438872e2 Add github link 2021-07-20 12:28:02 -04:00
Ajay Ramachandran
8c9424b6c5 Show notice in first slot if available 2021-07-18 15:42:54 -04:00
Ajay Ramachandran
caae61a6a8 Clear all skip notices when changing videos
Closes https://github.com/ajayyy/SponsorBlock/issues/726
2021-07-18 15:05:47 -04:00
Ajay Ramachandran
777f3a2769 Only show refresh button in popup if segments are found 2021-07-16 12:37:38 -04:00
Ajay Ramachandran
6fa5aea680 Use short skip notice for highlight category 2021-07-15 16:36:42 -04:00
Ajay Ramachandran
a839480a33 Add auto and manual skip at start 2021-07-15 16:01:22 -04:00
Ajay Ramachandran
797c9d67e4 Switch back to es6 2021-07-15 14:09:10 -04:00
Ajay Ramachandran
528b475429 Fix quotations not working in localisation 2021-07-14 15:28:38 -04:00
Ajay Ramachandran
e39b441c16 Fix unused import 2021-07-13 18:23:14 -04:00
Ajay Ramachandran
b8cbedbc4d Add animation to copy button
Closes https://github.com/ajayyy/SponsorBlock/issues/796
2021-07-13 18:22:56 -04:00
Ajay Ramachandran
76b78ef132 Add animation to refresh segments
Closes https://github.com/ajayyy/SponsorBlock/issues/839
2021-07-13 18:12:45 -04:00
Ajay Ramachandran
572fee265d Handle / in channel URL
Fixes https://github.com/ajayyy/SponsorBlock/issues/766
2021-07-11 22:12:08 -04:00
Ajay Ramachandran
bfe1e8307d Increase version number 2021-07-11 18:16:22 -04:00
Ajay Ramachandran
1b96e2107a Fix type in unlisted experiment 2021-07-07 16:09:18 -04:00
Ajay Ramachandran
3eccf855e5 Fix type in unlisted experiment 2021-07-07 13:12:22 -04:00
Ajay Ramachandran
069ae4bb58 Add issue assigning action 2021-07-05 20:50:59 -04:00
Ajay Ramachandran
7f8947dd0a Add refresh segments button 2021-07-04 16:12:41 -04:00
Ajay Ramachandran
0ae34c9603 Update more packages 2021-07-04 15:01:33 -04:00
Ajay Ramachandran
41a3c695dc Update packages 2021-07-04 14:35:46 -04:00
Ajay Ramachandran
5f92056b94 Increase version 2021-07-04 12:57:25 -04:00
Ajay Ramachandran
62a64791c6 New Crowdin updates (#809) 2021-07-04 12:56:46 -04:00
Ajay Ramachandran
bcf082d760 Allow voting on segments right after submitting 2021-07-03 23:42:08 -04:00
Ajay Ramachandran
0dd2d18b07 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into improvements 2021-07-02 21:21:25 -04:00
Ajay Ramachandran
2de822c97e Merge branch 'master' of https://github.com/ajayyy/SponsorBlock 2021-07-02 21:21:08 -04:00
Ajay Ramachandran
ad5248f65e Fix help page showing small options page 2021-07-02 21:21:04 -04:00
Ajay Ramachandran
8d3efb1a90 Add link to ToU 2021-07-01 01:21:18 -04:00
Ajay Ramachandran
798221606d Revert padding change 2021-07-01 01:13:06 -04:00
Ajay Ramachandran
55b38dc30e Fix x button position 2021-07-01 01:11:34 -04:00
Ajay Ramachandran
a1722db8d5 Fix key issues and remove redundant css property 2021-07-01 01:03:14 -04:00
Ajay Ramachandran
d27ddc85ae Move code for smaller notice into general notice component
Fixes other notices
2021-07-01 00:54:52 -04:00
Ajay Ramachandran
6d07abf6c8 Added basic PoC expanding notice
todo: move code to the general notice
2021-06-30 23:43:45 -04:00
Ajay Ramachandran
7adf0ad169 Added a notice that starts faded 2021-06-30 21:50:54 -04:00
Ajay Ramachandran
0086f00889 Remove printing 2021-06-30 21:28:14 -04:00
Ajay Ramachandran
d458bb0cdf Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into improvements
# Conflicts:
#	src/components/SkipNoticeComponent.tsx
#	src/config.ts
#	src/content.ts
2021-06-30 21:27:21 -04:00
Ajay Ramachandran
bd429f02a7 Fix autoHideInfoButton being reversed 2021-06-27 18:53:29 -04:00
Ajay Ramachandran
91f3ebed41 Add option to not auto-hide info button 2021-06-27 18:50:52 -04:00
Ajay Ramachandran
cc73d2a179 Add back help to localization file 2021-06-27 02:09:41 -04:00
Ajay Ramachandran
d9d2fc8e03 Fix errors breaking ts compilation 2021-06-26 23:20:09 -04:00
Ajay Ramachandran
3a9d0ad692 Submit video duration 2021-06-26 23:19:46 -04:00
Ajay Ramachandran
2843cb6916 Change step for skip notice duration option 2021-06-25 12:46:26 -04:00
Ajay Ramachandran
cbd1f43572 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock 2021-06-25 12:32:33 -04:00
Ajay Ramachandran
38bc6e2b1c make skip notice countdown customisable 2021-06-25 12:32:27 -04:00
Ajay Ramachandran
522dbd7e4d Add Safari link to readme 2021-06-25 12:18:56 -04:00
Ajay Ramachandran
31855f7501 Show all categories when voting to change category 2021-06-25 10:30:49 -04:00
Ajay Ramachandran
278394e48a Hide beta testing option on safari 2021-06-24 16:46:28 -04:00
Ajay Ramachandran
4f8166b809 New Crowdin updates (#792) 2021-06-24 13:30:04 -04:00
Ajay Ramachandran
c1a65a3383 Merge pull request #807 from ajayyy/unlisted-hotfix
Only show unlisted warning when there are no segments
2021-06-24 13:29:28 -04:00
Ajay Ramachandran
c3b82e7aa7 Merge branch 'master' into unlisted-hotfix 2021-06-24 13:21:31 -04:00
Ajay Ramachandran
ef435daf6d Only show unlisted warning when there are no segments 2021-06-24 13:14:47 -04:00
Ajay Ramachandran
e54ad07901 Merge pull request #805 from ajayyy/unlisted-hotfix
Unlisted hotfix
2021-06-24 00:17:19 -04:00
Ajay Ramachandran
99f1fc60ae Merge branch 'master' into unlisted-hotfix 2021-06-24 00:17:10 -04:00
Ajay Ramachandran
a2c0c3f79e Lower minimum view count 2021-06-23 23:51:20 -04:00
Ajay Ramachandran
551d9144b7 Add url to support page for unlisted videos experiment 2021-06-23 23:50:16 -04:00
Ajay Ramachandran
bd2dac69b9 Also send views, year and channelID 2021-06-23 23:46:21 -04:00
Ajay Ramachandran
db72e490df Chnage wording of experiment 2021-06-23 22:57:46 -04:00
Ajay Ramachandran
e9b0fae747 Increase version number 2021-06-23 22:23:23 -04:00
Ajay Ramachandran
693997d351 Clarify what submit means 2021-06-23 22:21:22 -04:00
Ajay Ramachandran
e7c92467bd Add localisation to unlisted experiement 2021-06-23 21:38:23 -04:00
Ajay Ramachandran
e80b7afe80 Add initial unlisted detection for getting a list of unlisted videos
A temporary measure which will be removed next month

https://support.google.com/youtube/answer/9230970
2021-06-23 21:09:59 -04:00
Ajay Ramachandran
a6728d34a0 Add more parameters to make get_video_info api work again
(cherry picked from commit 930911e2b9)
2021-06-23 19:22:03 -04:00
Ajay Ramachandran
43484ee656 Add back dollar sign to logo 2021-06-22 22:28:29 -04:00
Ajay Ramachandran
af5946195a Hide donate button on safari 2021-06-22 22:28:20 -04:00
Ajay Ramachandran
a7f4b66e22 Add 1024 icon 2021-06-22 19:22:03 -04:00
Ajay Ramachandran
5b59864639 Add 512 icon and remove $ sign 2021-06-22 17:46:40 -04:00
Ajay Ramachandran
d57d3e6b8b Move break lines into hidden elements on options page 2021-06-22 15:20:24 -04:00
Ajay Ramachandran
4dfef176db Fix popup elements not hiding 2021-06-22 15:19:06 -04:00
Ajay Ramachandran
9b8daa7a3e Add no safari to invidious checkbox too 2021-06-22 15:17:01 -04:00
Ajay Ramachandran
b6d6856ff0 Increase version number 2021-06-22 15:13:09 -04:00
Ajay Ramachandran
8fad730a77 Fix incorrect negation 2021-06-22 15:12:26 -04:00
Ajay Ramachandran
a118d80548 Hide invidious options on safari 2021-06-22 15:04:20 -04:00
Ajay Ramachandran
930911e2b9 Add more parameters to make get_video_info api work again 2021-06-20 20:56:42 -04:00
Ajay Ramachandran
47b90b2c2e Make info button hide automatically 2021-06-20 20:45:41 -04:00
Ajay Ramachandran
f2fa853f2c Increase version number 2021-06-20 13:24:31 -04:00
Ajay Ramachandran
ccc879bd56 Change preview colours 2021-06-20 13:20:23 -04:00
Ajay Ramachandran
46db01e734 Fix typo in 3rd party support text 2021-06-18 13:46:17 -04:00
Ajay Ramachandran
463cad4634 Remove shorter name for preview 2021-06-18 13:32:18 -04:00
Ajay Ramachandran
699566141b Merge branch 'master' of https://github.com/ajayyy/SponsorBlock 2021-06-18 01:26:19 -04:00
Ajay Ramachandran
b4e269bce6 Enable preview category by default for people with intermission enabled 2021-06-18 01:26:16 -04:00
Ajay Ramachandran
e9b908dacd Increase version number 2021-06-18 01:17:59 -04:00
Ajay Ramachandran
b9bb996c28 New Crowdin updates (#754) 2021-06-18 00:51:57 -04:00
Ajay Ramachandran
71ec724295 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into improvements 2021-06-18 00:46:55 -04:00
Ajay Ramachandran
a12ef41060 Make options page text copy pastable and searchable 2021-06-18 00:42:30 -04:00
Ajay Ramachandran
8da238f52a Fix some css issues on cloudtube 2021-06-18 00:23:58 -04:00
Ajay Ramachandran
18c1b74858 Fix centering on cloudtube
(cherry picked from commit a812b16da5)
2021-06-18 00:05:38 -04:00
Ajay Ramachandran
7451963ad6 Support CloudTube
(cherry picked from commit 4020cdc4f2)
2021-06-18 00:05:21 -04:00
Ajay Ramachandran
861ba4869e Add preview category
Closes https://github.com/ajayyy/SponsorBlock/issues/444

(cherry picked from commit a10d7c338c)
2021-06-18 00:02:03 -04:00
Ajay Ramachandran
e587addeee Merge pull request #790 from MRuy/fix/clipboard-icon
Fix clipboard icon #789
2021-06-17 13:06:01 -04:00
Nanobyte
6082411c75 Fix clipboard icon #789 2021-06-17 15:21:19 +02:00
Ajay Ramachandran
69e788dbc7 Fix style not applying to skip notice 2021-06-13 18:54:08 -04:00
Ajay Ramachandran
8cb212a77b Allow not counting time in private tabs
Closes https://github.com/ajayyy/SponsorBlock/issues/703
2021-06-11 18:17:40 -04:00
Ajay Ramachandran
29b29e3f6e Add type to getYouTubeVideoID 2021-06-11 17:55:24 -04:00
Ajay Ramachandran
8d9b6e8c1e Grow preview bar when the bar is hovered
Only for non chapter videos
2021-06-11 13:58:40 -04:00
Ajay Ramachandran
ac037c6f08 Make get_video_info work again
Resolve https://github.com/ajayyy/SponsorBlock/issues/751 for now

Potentially helps with https://github.com/ajayyy/SponsorBlock/issues/766 and https://github.com/ajayyy/SponsorBlock/issues/753
2021-06-11 13:28:42 -04:00
Ajay Ramachandran
b0400f98be Add better hotkey detection 2021-06-11 00:50:38 -04:00
Ajay Ramachandran
c3e1cfa04c Add note about newleaf 2021-06-10 16:58:55 -04:00
Ajay Ramachandran
8a58ae0fdd Merge pull request #783 from Atrate/readme-license-fix
Update README after license change
2021-06-10 16:57:44 -04:00
Atrate
12f42d12b9 Update README after license change
The README's license section has not been updated after the change to the LGPL. This PR fixes that.
2021-06-10 21:14:57 +02:00
Ajay Ramachandran
91959176f5 Revert "Add back header"
This reverts commit 5ef890cbee.
2021-06-09 20:07:03 -04:00
Ajay Ramachandran
5ef890cbee Add back header 2021-06-09 20:06:30 -04:00
Ajay Ramachandran
d5addb524f Try to get GitHub to recognise license 2021-06-09 20:05:09 -04:00
Ajay Ramachandran
34f4b14672 Remove unused config values 2021-06-09 19:22:02 -04:00
Ajay Ramachandran
2c78d3ad87 Increase version number 2021-06-09 16:54:16 -04:00
Ajay Ramachandran
3e672abbaa Merge branch 'master' of https://github.com/ajayyy/SponsorBlock 2021-06-09 16:53:34 -04:00
Ajay Ramachandran
6a02d62ccd Make options page work on mobile 2021-06-09 16:53:32 -04:00
Ajay Ramachandran
1dba081fde Merge pull request #780 from ajayyy/dependabot/npm_and_yarn/normalize-url-4.5.1
Bump normalize-url from 4.5.0 to 4.5.1
2021-06-09 15:07:19 -04:00
Ajay Ramachandran
315901f69b Use mutation listener on desktop too 2021-06-09 14:57:53 -04:00
Ajay Ramachandran
dacf766b4a Fix potential infinite loop in skip notice 2021-06-09 14:57:24 -04:00
dependabot[bot]
547acc89b9 Bump normalize-url from 4.5.0 to 4.5.1
Bumps [normalize-url](https://github.com/sindresorhus/normalize-url) from 4.5.0 to 4.5.1.
- [Release notes](https://github.com/sindresorhus/normalize-url/releases)
- [Commits](https://github.com/sindresorhus/normalize-url/commits)

---
updated-dependencies:
- dependency-name: normalize-url
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-09 18:28:15 +00:00
Ajay Ramachandran
4932fc6f45 Fix skipping on Firefox for Android
Resolves https://github.com/ajayyy/SponsorBlock/issues/659 and https://github.com/ajayyy/SponsorBlock/issues/588
2021-06-09 14:26:20 -04:00
Ajay Ramachandran
890b172cf1 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock 2021-06-09 13:31:28 -04:00
Ajay Ramachandran
97b6e0ee42 Change variable names 2021-06-09 13:31:26 -04:00
Ajay Ramachandran
919b72a590 Change to LGPL
https://github.com/ajayyy/SponsorBlock/issues/721
2021-06-08 22:29:58 -04:00
Ajay Ramachandran
8a1cab6765 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock 2021-06-08 22:14:00 -04:00
Ajay Ramachandran
d2847c6a77 Changes to preview bar 2021-06-08 22:13:57 -04:00
Ajay Ramachandran
df48705b67 Increase version number 2021-06-01 23:19:26 -04:00
Ajay Ramachandran
2e1b17f8bd Refresh segments when creating new segment to submit 2021-05-31 14:48:03 -04:00
Ajay Ramachandran
9478bfe6a4 Don't crash if bar types are missing 2021-05-31 14:45:39 -04:00
Ajay Ramachandran
42fa6c44c4 Prevent retry fetching in another place
https://github.com/ajayyy/SponsorBlock/issues/667
2021-05-31 14:37:12 -04:00
Ajay Ramachandran
a9a85d9816 Clean segment recieving code 2021-05-31 14:33:17 -04:00
Ajay Ramachandran
18161967fc Prevent retry fetch from potentially using the wrong videoID
Resolves https://github.com/ajayyy/SponsorBlock/issues/667
2021-05-31 14:26:08 -04:00
Ajay Ramachandran
6525f1ba87 Merge pull request #606 from MRuy/popup-design-changes
Change segment list layout in popup
2021-05-30 22:55:56 -04:00
Ajay Ramachandran
a6b9af62f9 Update matrix link 2021-05-30 12:34:03 -04:00
Ajay Ramachandran
fc3bd9bb77 Add funding info 2021-05-27 12:07:39 -04:00
Ajay Ramachandran
dabe3553a6 Change to stacked layout 2021-05-26 22:25:55 -04:00
Ajay Ramachandran
6da165d0c8 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into pr/MRuy/606
# Conflicts:
#	src/popup.ts
2021-05-26 22:19:15 -04:00
Ajay Ramachandran
0aa346e18e Remove unused declaration 2021-05-26 22:13:06 -04:00
Ajay Ramachandran
deb0e9b9be Fix issue with whitelist button 2021-05-26 22:05:05 -04:00
Ajay Ramachandran
da1d4bc1ce Improve centering when text is small 2021-05-26 22:04:38 -04:00
Ajay Ramachandran
283790874d Add link to pull request testing doc in wiki 2021-05-26 21:24:06 -04:00
Ajay Ramachandran
a929432ac6 Merge pull request #763 from GitMoleo/patch-3
edit old link to 3rd-party-ports in README.md
2021-05-25 11:29:34 -04:00
GitMoleo
99ecd32e82 edit old link to 3rd-party-ports in README.md
Since the README still contained the [old link to 3rd-party-ports in the wiki](https://github.com/ajayyy/SponsorBlock/wiki/Unofficial-Ports) , I edited it to be [the new one](https://github.com/ajayyy/SponsorBlock/wiki/3rd-Party-Ports)
2021-05-25 17:19:23 +02:00
Ajay Ramachandran
d27d91bc91 Merge pull request #758 from GitMoleo/patch-1
Change to "start/stop segment keybind"
2021-05-24 12:50:08 -04:00
GitMoleo
95cdb7f691 Change to "start/stop segment keybind"
Change "Set key for start segment keybind" to "Set key for start/stop segment keybind", since it is more accurate to the actual feature!
2021-05-23 19:43:09 +02:00
Ajay Ramachandran
d5abc1a9d9 Increase version number 2021-05-23 11:49:55 -04:00
Ajay Ramachandran
5472919866 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into improvements 2021-05-22 23:08:11 -04:00
Ajay Ramachandran
f6bbb1f2af Remove sponsor from element id 2021-05-22 23:07:57 -04:00
Ajay Ramachandran
92eafdb6f3 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into improvements 2021-05-22 01:52:05 -04:00
Ajay Ramachandran
60c0af2ae7 Don't break upload notice when clearing segments 2021-05-22 01:51:50 -04:00
Ajay Ramachandran
5fbb8c0d4a Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into improvements
# Conflicts:
#	manifest/manifest.json
#	src/components/SponsorTimeEditComponent.tsx
#	src/config.ts
#	src/content.ts
#	src/types.ts
2021-05-22 01:28:24 -04:00
Ajay Ramachandran
628871f037 Increase version number 2021-05-21 17:34:10 -04:00
Ajay Ramachandran
a5189014ad Make channel fetching error silent and don't wait for video info 2021-05-21 17:33:48 -04:00
Ajay Ramachandran
e70a8c724b Increase version number 2021-05-21 17:02:02 -04:00
Ajay Ramachandran
9d46c2d048 New Crowdin updates (#752)
* New translations messages.json (Chinese Traditional)

* New translations messages.json (Slovak)

* New translations messages.json (Amharic)
2021-05-21 17:01:53 -04:00
Ajay Ramachandran
25236f3a19 Don't show upload and delete button when no complete segments 2021-05-21 17:00:42 -04:00
Ajay Ramachandran
bcfe4924e2 Switch player buttons to svg 2021-05-21 16:56:39 -04:00
Ajay Ramachandran
60b9266a2a Use different icons for cancel and upload error 2021-05-21 16:13:54 -04:00
Ajay Ramachandran
9392d16617 Add partial segments to upload menu 2021-05-21 15:51:58 -04:00
Ajay Ramachandran
6879e90c16 Increase version number 2021-05-19 21:59:16 -04:00
Ajay Ramachandran
8674e85df5 New Crowdin updates (#749)
* New translations messages.json (Italian)

* New translations messages.json (Swedish)

* New translations messages.json (Ukrainian)

* New translations messages.json (Chinese Simplified)

* New translations messages.json (Chinese Traditional)

* New translations messages.json (Vietnamese)

* New translations messages.json (Portuguese, Brazilian)

* New translations messages.json (Indonesian)

* New translations messages.json (Tamil)

* New translations messages.json (Estonian)

* New translations messages.json (Malay)

* New translations messages.json (Telugu)

* New translations messages.json (Malayalam)

* New translations messages.json (Slovak)

* New translations messages.json (Turkish)

* New translations messages.json (Hungarian)

* New translations messages.json (Russian)

* New translations messages.json (Romanian)

* New translations messages.json (French)

* New translations messages.json (Spanish)

* New translations messages.json (Czech)

* New translations messages.json (German)

* New translations messages.json (Finnish)

* New translations messages.json (Korean)

* New translations messages.json (Dutch)

* New translations messages.json (Norwegian)

* New translations messages.json (Polish)
2021-05-19 21:58:59 -04:00
Ajay Ramachandran
be6e12d531 New Crowdin updates (#740)
* New translations messages.json (Swedish)

* New translations messages.json (Portuguese, Brazilian)

* New translations messages.json (Indonesian)

* New translations messages.json (Slovak)

* New translations messages.json (Russian)

* New translations messages.json (Spanish)

* New translations messages.json (Czech)

* New translations messages.json (Finnish)

* New translations messages.json (Japanese)

* New translations messages.json (Korean)

* New translations messages.json (Norwegian)

* New translations messages.json (Polish)

* New translations messages.json (German)

* New translations messages.json (Polish)

* New translations messages.json (Estonian)

* New translations messages.json (Chinese Traditional)

* New translations messages.json (Swedish)

* New translations messages.json (Chinese Traditional)

* New translations messages.json (Portuguese, Brazilian)

* New translations messages.json (Indonesian)

* New translations messages.json (Estonian)

* New translations messages.json (Slovak)

* New translations messages.json (Russian)

* New translations messages.json (Spanish)

* New translations messages.json (Czech)

* New translations messages.json (German)

* New translations messages.json (Finnish)

* New translations messages.json (Korean)

* New translations messages.json (Norwegian)

* New translations messages.json (Polish)

* New translations messages.json (Italian)

* New translations messages.json (Russian)

* New translations messages.json (Finnish)

* New translations messages.json (Dutch)

* New translations messages.json (German)

* New translations messages.json (Indonesian)

* New translations messages.json (Korean)

* New translations messages.json (Slovak)

* New translations messages.json (Portuguese, Brazilian)

* New translations messages.json (Czech)

* New translations messages.json (Estonian)

* New translations messages.json (Swedish)

* New translations messages.json (German)

* New translations messages.json (Italian)

* New translations messages.json (Swedish)

* New translations messages.json (Ukrainian)

* New translations messages.json (Chinese Simplified)

* New translations messages.json (Chinese Traditional)

* New translations messages.json (Vietnamese)

* New translations messages.json (Portuguese, Brazilian)

* New translations messages.json (Indonesian)

* New translations messages.json (Tamil)

* New translations messages.json (Estonian)

* New translations messages.json (Malay)

* New translations messages.json (Telugu)

* New translations messages.json (Malayalam)

* New translations messages.json (Slovak)

* New translations messages.json (Turkish)

* New translations messages.json (Hungarian)

* New translations messages.json (Russian)

* New translations messages.json (Romanian)

* New translations messages.json (French)

* New translations messages.json (Spanish)

* New translations messages.json (Czech)

* New translations messages.json (German)

* New translations messages.json (Finnish)

* New translations messages.json (Japanese)

* New translations messages.json (Korean)

* New translations messages.json (Dutch)

* New translations messages.json (Norwegian)

* New translations messages.json (Polish)

* New translations messages.json (Italian)

* New translations messages.json (Russian)

* New translations messages.json (Spanish)

* New translations messages.json (Portuguese, Brazilian)

* New translations messages.json (Indonesian)

* New translations messages.json (Estonian)

* New translations messages.json (Dutch)

* New translations messages.json (Swedish)

* New translations messages.json (Croatian)

* New translations messages.json (Indonesian)

* New translations messages.json (Amharic)
2021-05-19 17:26:04 -04:00
Ajay Ramachandran
32d3487b07 Increase version number 2021-05-19 16:25:32 -04:00
Ajay Ramachandran
3ef2673bfc Remove hash prefix option (always uses hash prefix) 2021-05-19 16:11:07 -04:00
Ajay Ramachandran
ac6cd2cec1 Add new channel ID detection logic 2021-05-19 16:08:09 -04:00
Ajay Ramachandran
995ed929ca Merge pull request #744 from wilkmaciej/master
Skip count sending and counting on manual skip
2021-05-19 11:18:25 -04:00
Ajay Ramachandran
592af4e20f Merge pull request #569 from opl-/cleanup/segment-creation
Clean up segment creation code
2021-05-16 20:48:22 -04:00
Ajay Ramachandran
ecfcb0b846 Make buttons not appear on invidious 2021-05-16 20:45:16 -04:00
Ajay Ramachandran
18d10ada5e Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into pr/opl-/569 2021-05-16 20:29:31 -04:00
Ajay Ramachandran
3a7b6b27c2 Change when close info menu is called 2021-05-16 20:27:46 -04:00
Ajay Ramachandran
fea8f93b5a Semicolon 2021-05-16 18:45:06 -04:00
Ajay Ramachandran
daa7a653c9 Merge pull request #747 from wilkmaciej/fix_saved_time_rounding
fix wrong saved time rounding
2021-05-16 18:43:54 -04:00
Ajay Ramachandran
ddf3f7c6ff Increase version number 2021-05-16 17:32:58 -04:00
Ajay Ramachandran
fbcff7f4c4 Change video info fetch error message 2021-05-16 17:31:58 -04:00
Ajay Ramachandran
59f63f1b4b Add semi colon 2021-05-14 21:15:36 -04:00
Ajay Ramachandran
e432abe79d Formatting changes + prevent negative value 2021-05-14 21:15:03 -04:00
Maciej Wilk
08a063b612 if(config.trackViewCount) changed 2021-05-15 01:05:45 +02:00
Maciej Wilk
2d14176542 added .DS_Store to not commit by mistake 2021-05-15 01:02:58 +02:00
Maciej Wilk
5fad4509f0 applied proposed fixes 2021-05-15 00:24:27 +02:00
Maciej Wilk
bd44c4721b Update public/help/index_en.html
Co-authored-by: Ajay Ramachandran <dev@ajay.app>
2021-05-15 00:10:30 +02:00
Maciej Wilk
606b2fbee3 fix wrong saved time rounding 2021-05-14 20:18:02 +02:00
Maciej Wilk
f18aa19172 updated help
changed few confusing names
deleted auto upvote information
fixed minor typos
2021-05-14 19:23:58 +02:00
Maciej Wilk
8337b54a44 telemetry sending and counting on manual skip 2021-05-14 14:32:32 +02:00
Ajay Ramachandran
ebf3b324b6 Added a smaller notice 2021-05-13 20:03:05 -04:00
Ajay Ramachandran
257098fd96 Fix description of error for force channel check 2021-05-13 12:20:39 -04:00
Ajay Ramachandran
0403393124 Increase version number 2021-05-12 17:01:54 -04:00
Ajay Ramachandran
11144fa77b Only ask for permission once 2021-05-12 17:00:31 -04:00
Ajay Ramachandran
e680099cec Scroll to category in options page 2021-05-11 01:09:01 -04:00
Ajay Ramachandran
616981a2b7 Update react to fix chrome warnings 2021-05-11 00:27:18 -04:00
Ajay Ramachandran
2aaee2c1c4 Only show skip keybind hint on one notice 2021-05-11 00:18:40 -04:00
Ajay Ramachandran
ef7e5d1312 Made highlight category work with hover text 2021-05-11 00:06:22 -04:00
Ajay Ramachandran
a8af7a0d78 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into improvements
# Conflicts:
#	public/_locales/en/messages.json
#	src/utils.ts
2021-05-10 20:17:17 -04:00
Ajay Ramachandran
dc5ecaded4 Merge pull request #737 from ajayyy/dependabot/npm_and_yarn/hosted-git-info-2.8.9
Bump hosted-git-info from 2.8.5 to 2.8.9
2021-05-10 20:12:48 -04:00
Ajay Ramachandran
60ae3111c2 Merge pull request #739 from ajayyy/dependabot/npm_and_yarn/lodash-4.17.21
Bump lodash from 4.17.19 to 4.17.21
2021-05-10 20:12:28 -04:00
Ajay Ramachandran
9f0f306439 Fix string 2021-05-10 18:06:59 -04:00
Ajay Ramachandran
08c5c73f4a Merge pull request #738 from ajayyy/fix-video
Prompt to accept youtube.com permission if video info fails to load
2021-05-10 16:25:17 -04:00
Ajay Ramachandran
35fc238891 New Crowdin updates (#697) 2021-05-10 16:24:36 -04:00
dependabot[bot]
8b7436320f Bump lodash from 4.17.19 to 4.17.21
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.19 to 4.17.21.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.19...4.17.21)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-10 20:24:09 +00:00
Ajay Ramachandran
081e03e4ba Increase version number 2021-05-10 16:24:03 -04:00
Ajay Ramachandran
bf84139ea7 Prompt to accept youtube.com permission if video info fails to load
Should fix #698, #687, #611 and #635

(cherry picked from commit 3ff5fdb3a1)
2021-05-10 16:22:46 -04:00
dependabot[bot]
7498c6cf1b Bump hosted-git-info from 2.8.5 to 2.8.9
Bumps [hosted-git-info](https://github.com/npm/hosted-git-info) from 2.8.5 to 2.8.9.
- [Release notes](https://github.com/npm/hosted-git-info/releases)
- [Changelog](https://github.com/npm/hosted-git-info/blob/v2.8.9/CHANGELOG.md)
- [Commits](https://github.com/npm/hosted-git-info/compare/v2.8.5...v2.8.9)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-10 20:21:58 +00:00
Ajay Ramachandran
abe3f0532a Merge pull request #728 from ajayyy/dependabot/npm_and_yarn/ssri-6.0.2
Bump ssri from 6.0.1 to 6.0.2
2021-05-10 16:20:53 -04:00
Ajay Ramachandran
97ed091432 Change highlight default 2021-05-06 15:58:27 -04:00
dependabot[bot]
90c78af59f Bump ssri from 6.0.1 to 6.0.2
Bumps [ssri](https://github.com/npm/ssri) from 6.0.1 to 6.0.2.
- [Release notes](https://github.com/npm/ssri/releases)
- [Changelog](https://github.com/npm/ssri/blob/v6.0.2/CHANGELOG.md)
- [Commits](https://github.com/npm/ssri/compare/v6.0.1...v6.0.2)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-30 15:52:26 +00:00
Ajay Ramachandran
756233a959 Update db link 2021-04-29 20:30:05 -04:00
Ajay Ramachandran
00045aa9d7 Move pull request template 2021-04-23 21:43:36 -04:00
Ajay Ramachandran
52f686977b Create pull_request_template.md 2021-04-23 21:39:52 -04:00
Ajay Ramachandran
9c13b7e8fd Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into improvements 2021-04-23 21:34:47 -04:00
Ajay Ramachandran
fd05281c09 Fix typo 2021-04-20 18:56:16 -04:00
Ajay Ramachandran
cc3e613396 Rename CONTRIBUTING to CONTRIBUTING.md 2021-04-20 18:55:59 -04:00
Ajay Ramachandran
a0bdcbaf11 Add LGPL licensing requirement for new contributors 2021-04-20 18:55:27 -04:00
Ajay Ramachandran
a812b16da5 Fix centering on cloudtube 2021-04-08 19:04:11 -04:00
Ajay Ramachandran
4020cdc4f2 Support CloudTube 2021-04-08 18:42:13 -04:00
Ajay Ramachandran
5cf6719681 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into improvements 2021-04-08 17:58:50 -04:00
Ajay Ramachandran
0a587ed98b Fix button visibility for highlight category and always show upload button 2021-04-07 21:44:42 -04:00
Ajay Ramachandran
a08dbf4da1 Add submitting for highlight category 2021-04-05 23:35:05 -04:00
Ajay Ramachandran
6ca031d9e7 Merge pull request #705 from ajayyy/dependabot/npm_and_yarn/y18n-4.0.1
Bump y18n from 4.0.0 to 4.0.1
2021-04-05 19:45:16 -04:00
Ajay Ramachandran
edcda31db4 Raise z index of notice to be in front of endcards 2021-04-01 21:15:11 -04:00
dependabot[bot]
0b560f3fbc Bump y18n from 4.0.0 to 4.0.1
Bumps [y18n](https://github.com/yargs/y18n) from 4.0.0 to 4.0.1.
- [Release notes](https://github.com/yargs/y18n/releases)
- [Changelog](https://github.com/yargs/y18n/blob/master/CHANGELOG.md)
- [Commits](https://github.com/yargs/y18n/commits)

Signed-off-by: dependabot[bot] <support@github.com>
2021-03-31 10:39:17 +00:00
Ajay Ramachandran
a10d7c338c Add preview category
Closes https://github.com/ajayyy/SponsorBlock/issues/444
2021-03-30 22:50:36 -04:00
Ajay Ramachandran
8dfa386cdb Merge pull request #701 from manualmanul/fix-youtube-tv
Partially fix YouTube TV support
2021-03-26 18:36:29 -04:00
Manual
719010db97 Don’t throw an exception if there’s no videoRoot
Suggested change by @ajayyy

Co-authored-by: Ajay Ramachandran <dev@ajay.app>
2021-03-27 00:08:02 +02:00
Manual
928c075416 fix exception when on youtube.com/tv 2021-03-26 12:00:47 +02:00
Ajay Ramachandran
4469eada54 Merge pull request #699 from TotalCaesar659/patch-1
Update URLs to HTTPS
2021-03-24 20:43:32 -04:00
TotalCaesar659
b630545702 Update URLs to HTTPS 2021-03-25 03:40:31 +03:00
Ajay Ramachandran
3ff5fdb3a1 Prompt to accept youtube.com permission if video info fails to load
Should fix #698, #687, #611 and #635
2021-03-24 20:13:33 -04:00
Ajay Ramachandran
1eb1574943 Fix shields 2021-03-23 20:38:48 -04:00
Ajay Ramachandran
80d014bc29 Fix shields 2021-03-23 20:38:04 -04:00
Ajay Ramachandran
cd52137454 Update README.md 2021-03-23 20:36:03 -04:00
Ajay Ramachandran
44c48ecfcc Increase version 2021-03-23 19:49:10 -04:00
Ajay Ramachandran
9b502b282f New Crowdin updates (#694)
* New translations messages.json (Polish)

* New translations messages.json (Ukrainian)
2021-03-23 19:48:47 -04:00
Ajay Ramachandran
590c8b2078 Merge pull request #695 from TotalCaesar659/patch-1
Update URLs to HTTPS
2021-03-23 19:40:28 -04:00
TotalCaesar659
41a0c12139 Update URLs to HTTPS 2021-03-23 22:10:14 +03:00
Ajay Ramachandran
cc935624e9 Add homepage url 2021-03-20 12:24:49 -04:00
Ajay Ramachandran
2681dc1890 Submit video duration 2021-03-20 11:50:15 -04:00
Ajay Ramachandran
af201fcbf0 New Crowdin updates (#638) 2021-03-15 22:37:48 -04:00
Ajay Ramachandran
89415029a4 Increase version number 2021-03-15 22:36:44 -04:00
Ajay Ramachandran
09ef9469a2 Merge pull request #676 from caneleex/feature/uuid-button
add uuid copy button to the popup
2021-03-15 22:36:26 -04:00
caneleex
ca3732315c remove unnecessary additional css 2021-03-12 11:23:25 +01:00
caneleex
3c50f70b3b add uuid copy button to the popup 2021-03-11 18:34:29 +01:00
Ajay Ramachandran
82f92c8cfa Merge pull request #672 from ajayyy/dependabot/npm_and_yarn/elliptic-6.5.4
Bump elliptic from 6.5.3 to 6.5.4
2021-03-10 23:17:10 -05:00
dependabot[bot]
2d7640f394 Bump elliptic from 6.5.3 to 6.5.4
Bumps [elliptic](https://github.com/indutny/elliptic) from 6.5.3 to 6.5.4.
- [Release notes](https://github.com/indutny/elliptic/releases)
- [Commits](https://github.com/indutny/elliptic/compare/v6.5.3...v6.5.4)

Signed-off-by: dependabot[bot] <support@github.com>
2021-03-10 06:34:38 +00:00
Ajay Ramachandran
8de4f904a5 Merge pull request #650 from ajayyy/improvements
Improvements
2021-03-07 14:23:28 -05:00
Ajay Ramachandran
26197d4ff9 Merge pull request #666 from ljoonal/invidious-embed-fix
Fix the videoRoot to also work on invidious embeds
2021-03-04 23:44:10 -05:00
LJ
f48e1895db Fix the videoRoot to also work on invidious embeds
The root div of the player is not `#player-container` in invidious embeds but just `#player`.
2021-03-04 15:26:25 +02:00
Ajay Ramachandran
f59b7516fc Merge pull request #657 from aaaeka/master
Fix options button icon in firefox
2021-02-27 19:29:53 -05:00
Ajay Ramachandran
9474424a1e make popup icons consistent 2021-02-22 22:17:23 -05:00
aaaeka
9772ea7d9d Fix options button icon in firefox 2021-02-22 12:00:24 +02:00
Ajay Ramachandran
50aee79f32 Add hours to popup time 2021-02-20 15:55:56 -05:00
Ajay Ramachandran
bbc94e9404 Update non music section description 2021-02-20 15:53:48 -05:00
opl-
3879cc6de3 Clean up segment creation code
Noteworthy changes:
- Adds ability to cancel creating a segment
- Makes segment creation fully the responsibility of the content script, with the popup script buttons simply doing RPC
- Adds types to the Utils.wait function
- Fixes segment timestamps backwards if user marks segment end earlier than the start
- Makes the info menu (in-page popup) workaround clearer and easier to remove in the future.
2021-02-20 15:52:13 +01:00
Ajay Ramachandran
cad77aef8e Add missing status code from known list 2021-02-18 21:30:09 -05:00
Ajay Ramachandran
3927fe5630 Lower retry frequency 2021-02-18 21:23:00 -05:00
Ajay Ramachandran
7b65b73711 Increase notice z index
Resolves #642
2021-02-14 20:12:45 -05:00
Ajay Ramachandran
e3b0be23a7 Show decimals in popup 2021-02-14 14:27:59 -05:00
Ajay Ramachandran
d1a7209d69 Switch from round to floor 2021-02-14 14:22:28 -05:00
Ajay Ramachandran
2fdd43f96f Enable hash prefix by default
Closes https://github.com/ajayyy/SponsorBlock/issues/529
2021-02-09 18:48:13 -05:00
Evan Gubarev
026858509a Fixed getFormattedTime sometimes returning (NaN:NaN) (#643)
* Fixed getFormattedTime sometimes returning (NaN:NaN)

getFormattedTime() with nothing passed into it and a couple other edge cases returned (NaN:NaN). This is a problem since on a slow machine getFormattedTime get called without anything passed into it around the time the computer is fetching the timing data. I haven't found the exact spot / place it is called wrongly, but this should fix it. I've have a slow machine so it's really been bugging me seeing (NaN:NaN) for a couple seconds before the page fully loads. Hopefully this should fix it.
2021-02-07 13:09:01 -05:00
Ajay Ramachandran
7ecc1b9e41 New Crowdin updates (#632) 2021-02-03 18:45:13 -05:00
Ajay Ramachandran
54ba0c0958 Merge pull request #637 from catearcher/patch-1
Fix German pronouns and typo
2021-02-03 18:44:56 -05:00
Ajay Ramachandran
27fe2ca8f0 Increase version number 2021-02-03 18:43:16 -05:00
Ajay Ramachandran
54b4681fc3 Fix invidious support
Fixes https://github.com/ajayyy/SponsorBlock/issues/636
2021-02-03 18:28:50 -05:00
Patrick Mladensich
2d550e99cb Fix German pronouns and typo
The rest of the file uses non-honorific pronouns, so this line should also use them (i.e. "du" instead of "Sie").

Plus: Fixed spelling error and changed word to reflect the way it is spelled in Google Chrome.
2021-02-03 13:12:21 +01:00
Ajay Ramachandran
318d00a9c4 Increase version number 2021-01-31 12:04:25 -05:00
Ajay Ramachandran
44571a67d9 Fix segments being deleted 2021-01-31 12:03:54 -05:00
Ajay Ramachandran
83955fc746 readme license fix 2021-01-30 15:01:43 -05:00
Ajay Ramachandran
647d46b7b4 license 2021-01-30 15:00:54 -05:00
Ajay Ramachandran
4f50ead08d Log returned data when video info failed to load 2021-01-27 22:27:23 -05:00
Ajay Ramachandran
c0a515d8f0 Increase version number 2021-01-26 21:58:37 -05:00
Ajay Ramachandran
2808703199 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock 2021-01-26 21:58:24 -05:00
Ajay Ramachandran
824d212a81 New Crowdin updates (#624) 2021-01-26 21:58:18 -05:00
Ajay Ramachandran
67f2798672 Add error message from server when voting 2021-01-26 21:57:43 -05:00
Ajay Ramachandran
41fee58ab9 Increase fetch frequency 2021-01-26 21:09:28 -05:00
Ajay Ramachandran
96f3264bff $ 2021-01-26 21:04:03 -05:00
Ajay Ramachandran
324565646a New Crowdin updates (#604) 2021-01-17 14:56:08 -05:00
Ajay Ramachandran
0c5ede6214 Merge pull request #570 from FoseFx/fosefx-eslint-ci
chore(ci): add linter to workflow
2021-01-17 14:55:47 -05:00
Ajay Ramachandran
b66ea934f9 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into fosefx-eslint-ci 2021-01-17 14:46:56 -05:00
Ajay Ramachandran
d2f377c8d7 Merge pull request #622 from ajayyy/fix-unsubmitted-list
Improvements
2021-01-17 14:46:27 -05:00
Ajay Ramachandran
551355d21a Made countdown timer better support video playback speeds 2021-01-17 14:39:29 -05:00
Ajay Ramachandran
e269b1aec6 Add skip keybind
https://github.com/ajayyy/SponsorBlock/issues/299
2021-01-17 14:25:45 -05:00
Ajay Ramachandran
ff0dc6e570 Never move old skip notice
Partially resolves https://github.com/ajayyy/SponsorBlock/issues/505
2021-01-17 13:10:33 -05:00
Ajay Ramachandran
209e42578f Fix eslint warnings 2021-01-17 13:01:57 -05:00
Ajay Ramachandran
2fcfc989cf Remove unsubmitted notification 2021-01-17 13:00:27 -05:00
Ajay Ramachandran
7bb8f446bf Fix type issues 2021-01-17 12:56:37 -05:00
Ajay Ramachandran
7307340afa Remove empty unsubmitted segments
Resolves https://github.com/ajayyy/SponsorBlock/issues/609
2021-01-17 12:53:31 -05:00
Ajay Ramachandran
e32a251ef3 Merge pull request #605 from ajayyy/youcap
Revert "Add notice about YouCap"
2021-01-10 21:02:34 -05:00
Ajay Ramachandran
edd8ac55d0 Merge branch 'master' into youcap 2021-01-06 17:33:21 -05:00
Ajay Ramachandran
33ec82882d Increase version number 2021-01-02 20:11:00 -05:00
Ajay Ramachandran
647a3839d0 Make link open in new tab 2021-01-02 20:10:47 -05:00
Nanobyte
87a7f85c24 Change segment list layout in popup 2020-12-31 20:59:12 +01:00
Ajay Ramachandran
2808b76655 Made youcap notice more general 2020-12-31 14:57:11 -05:00
Ajay Ramachandran
ece66522e5 Shrink youcap text on Firefox 2020-12-30 21:46:05 -05:00
Ajay Ramachandran
3ac68aa313 Revert "Add notice about YouCap"
This reverts commit e95029c229.
2020-12-29 23:06:50 -05:00
Ajay Ramachandran
bddbedbdd0 Increase version number 2020-12-29 22:54:25 -05:00
Ajay Ramachandran
1d83a4616d Merge pull request #603 from ajayyy/youcap
YouCap
2020-12-29 22:53:54 -05:00
Ajay Ramachandran
06f09f5fd9 Merge pull request #549 from opl-/feat/preview-bar-cleanup
Clean up Preview Bar
2020-12-29 22:51:50 -05:00
Ajay Ramachandran
e95029c229 Add notice about YouCap 2020-12-29 22:51:00 -05:00
Ajay Ramachandran
6d1c51e7ec New Crowdin updates (#579) 2020-12-29 22:14:09 -05:00
Ajay Ramachandran
83a9526e52 Prevent youtube page from overriding 2020-12-29 22:10:16 -05:00
opl-
0f68c503b3 Fix YouTube overriding player preview tooltip styles 2020-12-26 18:35:25 +01:00
Ajay Ramachandran
3828c00d27 Merge pull request #601 from ajayyy/translations
Remove some unused strings
2020-12-24 23:29:47 -05:00
Ajay Ramachandran
0baf01c1af Remove some unused strings 2020-12-24 23:27:25 -05:00
Ajay Ramachandran
edbbb9022b Don't filter segments 2020-12-24 12:43:21 -05:00
Ajay Ramachandran
73b81424b1 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into feat/preview-bar-cleanup
# Conflicts:
#	src/content.ts
#	src/js-components/previewBar.ts
2020-12-24 12:41:40 -05:00
Ajay Ramachandran
bd12ccb6f4 Merge pull request #589 from ajayyy/fix-mobile
Fix mobile support
2020-12-24 12:32:34 -05:00
Ajay Ramachandran
d81229a157 Merge pull request #599 from FoseFx/fosefx-no-this-alias
Replace self-equals-this code with arrow functions
2020-12-24 12:32:16 -05:00
Max Baumann
0e32042634 refactor(lint): replace self-equals-this code with arrow functions 2020-12-24 11:59:24 +01:00
Ajay Ramachandran
54c36e65ef Make popup work better on mobile 2020-12-22 01:20:22 -05:00
Ajay Ramachandran
979e7e7629 Fix mobile support 2020-12-22 01:10:57 -05:00
Ajay Ramachandran
cba0fc0a87 Merge pull request #580 from ajayyy/category-list
Lock category order and show all categories + more
2020-12-20 18:51:57 -05:00
Ajay Ramachandran
24df146c53 Merge pull request #586 from MRuy/master
Ensure correct start- endtime order
2020-12-20 18:51:44 -05:00
Nanobyte
bc10690304 Ensure correct start- endtime order
#585
2020-12-20 22:48:38 +01:00
Ajay Ramachandran
8dd9a79aa5 Merge branch 'master' into category-list 2020-12-20 14:39:03 -05:00
Ajay Ramachandran
1bab5063aa Merge pull request #582 from FoseFx/fosefx-ts-msg
Types for messages
2020-12-19 14:50:53 -05:00
Max Baumann
1d7dab6ea0 Merge master 2020-12-18 18:35:26 +01:00
Ajay Ramachandran
bbda730f78 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into fosefx-eslint-ci 2020-12-17 13:21:23 -05:00
Ajay Ramachandran
c30038fd26 Merge pull request #578 from FoseFx/fosefx-eslint-fix
Fix eslint warnings
2020-12-17 13:20:48 -05:00
Ajay Ramachandran
81926367b1 Revert "Don't include non signed Firefox extension in release assets"
This reverts commit 9bd5c971c6.
2020-12-16 13:41:23 -05:00
Ajay Ramachandran
5ac5b557b0 Fix manual skip going into directly adjacent segment
Resolves #531
2020-12-16 01:19:54 -05:00
Ajay Ramachandran
e5ec478e6a Update dependencies 2020-12-16 00:53:15 -05:00
Ajay Ramachandran
90d53a34b5 Move unlisted check request to background script
Resolves #566
2020-12-15 21:34:29 -05:00
Ajay Ramachandran
fbe64c115b Added cancel button when choosing a disable category 2020-12-15 16:32:38 -05:00
Ajay Ramachandran
9bd5c971c6 Don't include non signed Firefox extension in release assets 2020-12-15 16:22:30 -05:00
Ajay Ramachandran
41e5cb25aa Fix category list alert not being localized 2020-12-15 16:18:28 -05:00
Ajay Ramachandran
fd9116c81c Lock category order and show all categories 2020-12-15 16:13:56 -05:00
Ajay Ramachandran
1b4bee1b90 Increase version number 2020-12-15 14:25:44 -05:00
Ajay Ramachandran
608aa73ae4 New Crowdin updates (#577) 2020-12-15 14:25:23 -05:00
Ajay Ramachandran
3b07bc638a Merge pull request #576 from ajayyy/padding
Fix popup padding on YouTube page
2020-12-15 14:25:04 -05:00
Max Baumann
2afe510912 refactor(types): add PageElements type 2020-12-15 20:10:19 +01:00
Ajay Ramachandran
b6b109b226 Convert \n in localized strings to <br/> for html 2020-12-15 14:03:01 -05:00
Ajay Ramachandran
e31aaba24c Fix website text not using strings in popup 2020-12-15 14:02:08 -05:00
Max Baumann
c0d910decd refactor: more types and dead code removal 2020-12-15 19:54:33 +01:00
Ajay Ramachandran
17eead2bb6 Use short category name in popup 2020-12-15 13:50:06 -05:00
Max Baumann
cd4f5fc667 refactor(types): add strong types to messages 2020-12-15 19:37:48 +01:00
Max Baumann
09c527417d refactor: type 'config' Proxy 2020-12-15 18:29:47 +01:00
Max Baumann
094ef84f15 refactor(types): add StorageChangesObject type 2020-12-15 14:24:29 +01:00
Max Baumann
dc36e8097d refactor: remove unused function 2020-12-15 13:34:02 +01:00
Max Baumann
b7ea5689c7 refactor(types): add VideoInfo interface 2020-12-15 13:33:38 +01:00
Max Baumann
7756a89960 refactor: remove more unused variables 2020-12-15 12:58:44 +01:00
Ajay Ramachandran
865422eaaa Fix help link on popup 2020-12-14 23:56:56 -05:00
Ajay Ramachandran
9b572609f8 Fix popup padding on YouTube page 2020-12-14 23:51:23 -05:00
Ajay Ramachandran
ba01293067 Merge pull request #573 from ajayyy/padding
Lower popup padding
2020-12-14 23:41:52 -05:00
Ajay Ramachandran
59fbc84017 Go back to old names for channel whitelisting 2020-12-14 23:39:06 -05:00
Ajay Ramachandran
4b0c6b80f6 Lower popup padding 2020-12-14 23:26:08 -05:00
Ajay Ramachandran
881f46c65c New Crowdin updates (#567) 2020-12-14 22:36:35 -05:00
Ajay Ramachandran
a8714409a6 Increase version number 2020-12-14 22:32:37 -05:00
Ajay Ramachandran
ae6130259b Merge pull request #572 from ajayyy/video-speed
Listen to custom videospeed event
2020-12-14 22:32:03 -05:00
Ajay Ramachandran
bd51f5b621 Listen to custom videospeed event
https://github.com/igrigorik/videospeed/pull/740
2020-12-14 22:26:27 -05:00
Ajay Ramachandran
3b22733c1a Merge pull request #571 from ajayyy/firefox-replay
Potential fix for video replaying after browser stutters on Firefox.
2020-12-14 22:08:44 -05:00
Ajay Ramachandran
dbee744bd7 Potential fix for video replaying after browser stutters on Firefox.
Hopefully resolves #525
2020-12-14 22:05:53 -05:00
Max Baumann
5d0559aebd refactor: remove dead code, add more types 2020-12-14 23:37:35 +01:00
Ajay Ramachandran
120642667d Rename timestamp to segment 2020-12-14 17:24:35 -05:00
Max Baumann
1b92982f3b chore(ci): add linter to workflow 2020-12-14 22:34:18 +01:00
Ajay Ramachandran
70667a43d7 Merge pull request #568 from opl-/cleanup/unused-popup-code
Remove unused popup related code
2020-12-14 14:28:57 -05:00
opl-
b47a71c000 Remove unused popup related code 2020-12-14 20:16:45 +01:00
opl-
7078e1f033 Clean up Preview Bar
Fixes:
- Segments hidden by longer segments
- Duration with skips not accounting for segment overlaps
- Duration with skips not accounting for user's skip choices
- Segment category text in preview tooltip overlaps the seek bar
- Segment category text in preview tooltip breaks for timestamps over one hour
- `previewBar.ts` lacks function argument and return types
- Tooltip label not cleaned up on remove
- General code style issues
2020-12-14 19:58:00 +01:00
Ajay Ramachandran
59826aae6d Merge pull request #564 from FoseFx/fosefx-eslint
ESLint
2020-12-14 13:11:56 -05:00
Max Baumann
fd4452a078 chore(lint): apply eslint auto-fix 2020-12-14 11:10:41 +01:00
Max Baumann
c3f32aae26 Merge branch 'master' of github.com:ajayyy/SponsorBlock into fosefx-eslint 2020-12-14 11:08:56 +01:00
Ajay Ramachandran
55856c5566 New Crowdin updates (#548) 2020-12-14 01:38:52 -05:00
Ajay Ramachandran
57e6268fc7 Merge pull request #440 from mbledkowski/master
Design change of popup.html
2020-12-14 01:01:23 -05:00
Ajay Ramachandran
fd8a3a05fe Removed more unused code 2020-12-14 00:58:54 -05:00
Ajay Ramachandran
06d600c6d0 Remove legacy editing code from popup 2020-12-14 00:58:20 -05:00
Ajay Ramachandran
0253016871 Popup code cleanup 2020-12-14 00:57:15 -05:00
Ajay Ramachandran
03e34281f6 Add back show notice button 2020-12-14 00:44:21 -05:00
Ajay Ramachandran
125a83ac3f Don't show animations before loading 2020-12-14 00:35:49 -05:00
Ajay Ramachandran
1afabb934f Expand username textbox when editing. 2020-12-13 23:52:38 -05:00
Ajay Ramachandran
df84f328a7 Move whitelisting warning 2020-12-13 22:41:59 -05:00
Ajay Ramachandran
7cc8cd75d4 Set max size of popup for Firefox and fix padding issues 2020-12-13 22:10:52 -05:00
Ajay Ramachandran
b6fd1f0804 Add category name and color to popup 2020-12-13 21:51:55 -05:00
Ajay Ramachandran
3f19506137 Order segments in popup 2020-12-13 21:09:35 -05:00
Ajay Ramachandran
b23e6fa3d2 Remove commented lines 2020-12-13 15:55:38 -05:00
Ajay Ramachandran
7bf0090195 Change segment list layout 2020-12-13 15:46:48 -05:00
Max Baumann
bdcfec38c2 chore(lint): remove eslint rule 2020-12-13 21:19:39 +01:00
Max Baumann
042f2eb4e8 fix: remove unintended fallthrough 2020-12-13 21:12:26 +01:00
Max Baumann
7b27de279b chore(types): even more types 2020-12-13 21:11:23 +01:00
Max Baumann
dde6b44005 chore(types): strongly type BackgroundScriptContainer et al 2020-12-13 20:48:09 +01:00
Max Baumann
d80dad7963 fix(types): change wrong type of 'types' 2020-12-13 20:29:23 +01:00
Ajay Ramachandran
a150a97991 Add matrix link and fix help button 2020-12-12 19:07:15 -05:00
Ajay Ramachandran
141d8456d8 Merge pull request #563 from ajayyy/dependabot/npm_and_yarn/bl-1.2.3
chore(deps): bump bl from 1.2.2 to 1.2.3
2020-12-12 18:17:51 -05:00
Max Baumann
e353591a7b chore(lint): remove more linting rules 2020-12-13 00:11:52 +01:00
Max Baumann
e2ef7412a4 refactor(lint): fix trivial linting errors 2020-12-12 23:58:34 +01:00
Max Baumann
36558f5460 refactor(lint): apply automatic eslint fixes 2020-12-12 22:57:41 +01:00
Max Baumann
105c148ccc feat(lint): add default .eslintrc.js 2020-12-12 22:56:31 +01:00
Max Baumann
0854b74080 feat(lint): add default .eslintrc.js 2020-12-12 22:56:14 +01:00
dependabot[bot]
3c0f24a0f3 chore(deps): bump bl from 1.2.2 to 1.2.3
Bumps [bl](https://github.com/rvagg/bl) from 1.2.2 to 1.2.3.
- [Release notes](https://github.com/rvagg/bl/releases)
- [Commits](https://github.com/rvagg/bl/compare/v1.2.2...v1.2.3)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-12 20:57:45 +00:00
Ajay Ramachandran
f0152db605 Merge pull request #562 from ajayyy/dependabot/npm_and_yarn/ini-1.3.8
chore(deps): bump ini from 1.3.5 to 1.3.8
2020-12-12 15:56:42 -05:00
dependabot[bot]
c310e05ae0 chore(deps): bump ini from 1.3.5 to 1.3.8
Bumps [ini](https://github.com/isaacs/ini) from 1.3.5 to 1.3.8.
- [Release notes](https://github.com/isaacs/ini/releases)
- [Commits](https://github.com/isaacs/ini/compare/v1.3.5...v1.3.8)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-12 04:34:20 +00:00
Ajay Ramachandran
1d35ac913e Removed unused locale 2020-11-20 23:47:04 -05:00
Ajay Ramachandran
a3bcc8e3b0 Increase version 2020-11-20 23:34:30 -05:00
Ajay Ramachandran
b2ec8d5e61 Merge pull request #536 from opl-/feat/formatted-time-editor
Use formatted time inputs for segment editing
2020-11-20 23:33:55 -05:00
Ajay Ramachandran
3ccf7f6fff New Crowdin updates (#516)
* New translations messages.json (Malayalam)

* New translations messages.json (Malayalam)

* New translations messages.json (Malayalam)

* New translations messages.json (Korean)

* New translations messages.json (Japanese)

* New translations messages.json (Danish)

* New translations messages.json (Danish)

* New translations messages.json (Portuguese, Brazilian)

* New translations messages.json (Malay)

* New translations messages.json (Vietnamese)

* New translations messages.json (Vietnamese)

* New translations messages.json (Slovak)

* New translations messages.json (Slovak)

* New translations messages.json (Indonesian)

* New translations messages.json (Japanese)

* New translations messages.json (Japanese)

* New translations messages.json (Italian)

* New translations messages.json (Turkish)

* New translations messages.json (Turkish)

* New translations messages.json (Catalan)

* New translations messages.json (Turkish)

* New translations messages.json (Polish)

* New translations messages.json (Vietnamese)

* New translations messages.json (Slovak)

* New translations messages.json (Russian)

* New translations messages.json (Czech)

* New translations messages.json (Turkish)

* New translations messages.json (French)

* New translations messages.json (French)

* New translations messages.json (Czech)

* New translations messages.json (Polish)

* New translations messages.json (Czech)

* New translations messages.json (Spanish)

* New translations messages.json (Czech)
2020-11-20 23:28:18 -05:00
Ajay Ramachandran
e39de9fd85 Merge pull request #539 from SuspiciousActivity/patch-1
Fix: segment at the start not skipping
2020-11-08 18:38:54 -05:00
SuspiciousActivity
942f889360 Fix: segment at the start not skipping 2020-11-08 20:18:26 +01:00
opl-
cb5e770014 Add support for commas in the time editor
Makes numpad input easier on some locales.
2020-11-08 06:13:09 +01:00
opl-
618f8a52f7 Use formatted time inputs for segment editing
Additionally, removes unused util functions and saves the edits on changes to update the preview immediately
2020-11-07 22:28:55 +01:00
Ajay Ramachandran
637dcbee00 Fix background colour in popup 2020-10-26 00:08:32 -04:00
Ajay Ramachandran
e88de89e0f Merge pull request #518 from Joe-Dowd/no-audio-on-manual-skip
Only send audio notification if segment is automatically skipped
2020-10-19 11:14:35 -04:00
Joe Dowd
ff174f946a Only send audio notifcation if segment is manually skipped 2020-10-19 16:11:16 +01:00
Ajay Ramachandran
896dc602cd Merge pull request #512 from ajayyy/experimental
Increase version number
2020-10-15 13:54:40 -04:00
Ajay Ramachandran
c6e24c87b1 New Crowdin updates (#480)
* New translations messages.json (Romanian)

* New translations messages.json (Ukrainian)

* New translations messages.json (Chinese Simplified)

* New translations messages.json (Vietnamese)

* New translations messages.json (Portuguese, Brazilian)

* New translations messages.json (Indonesian)

* New translations messages.json (Swedish)

* New translations messages.json (Turkish)

* New translations messages.json (French)

* New translations messages.json (Spanish)

* New translations messages.json (German)

* New translations messages.json (Finnish)

* New translations messages.json (Italian)

* New translations messages.json (Korean)

* New translations messages.json (Dutch)

* New translations messages.json (Polish)

* New translations messages.json (Russian)

* New translations messages.json (Indonesian)

* New translations messages.json (Tamil)

* New translations messages.json (Dutch)

* New translations messages.json (Chinese Traditional)

* New translations messages.json (Telugu)

* New translations messages.json (Malayalam)

* New translations messages.json (Chinese Traditional)

* New translations messages.json (Chinese Traditional)

* New translations messages.json (Polish)

* New translations messages.json (Russian)

* New translations messages.json (Polish)

* New translations messages.json (Polish)

* New translations messages.json (French)

* New translations messages.json (Korean)

* New translations messages.json (Polish)

* New translations messages.json (Swedish)

* New translations messages.json (Italian)

* New translations messages.json (Swedish)

* New translations messages.json (Thai)

* New translations messages.json (Thai)

* New translations messages.json (Italian)

* New translations messages.json (Portuguese, Brazilian)

* New translations messages.json (Polish)

* New translations messages.json (Korean)

* New translations messages.json (Finnish)

* New translations messages.json (Finnish)

* New translations messages.json (Romanian)

* New translations messages.json (Ukrainian)

* New translations messages.json (Chinese Simplified)

* New translations messages.json (Vietnamese)

* New translations messages.json (Indonesian)

* New translations messages.json (Swedish)

* New translations messages.json (Turkish)

* New translations messages.json (French)

* New translations messages.json (Finnish)

* New translations messages.json (Italian)

* New translations messages.json (Korean)

* New translations messages.json (Dutch)

* New translations messages.json (Polish)

* New translations messages.json (Russian)

* New translations messages.json (German)

* New translations messages.json (Russian)

* New translations messages.json (Swedish)

* New translations messages.json (Polish)

* New translations messages.json (Korean)

* New translations messages.json (German)

* New translations messages.json (Polish)

* New translations messages.json (Polish)

* New translations messages.json (Tamil)

* New translations messages.json (German)

* New translations messages.json (Finnish)

* New translations messages.json (Dutch)

* New translations messages.json (Polish)

* New translations messages.json (Russian)

* New translations messages.json (Swedish)

* New translations messages.json (Ukrainian)

* New translations messages.json (Indonesian)

* New translations messages.json (Tamil)

* New translations messages.json (Portuguese, Brazilian)

* New translations messages.json (Persian)

* New translations messages.json (Spanish)

* New translations messages.json (Hungarian)

* New translations messages.json (Italian)

* New translations messages.json (Turkish)

* New translations messages.json (Telugu)

* New translations messages.json (Swedish)

* New translations messages.json (Dutch)

* New translations messages.json (Polish)

* New translations messages.json (Malayalam)

* New translations messages.json (Swedish)

* New translations messages.json (Malayalam)
2020-10-15 13:54:31 -04:00
Ajay Ramachandran
f59d8035d8 Increase version number 2020-10-15 13:36:05 -04:00
Ajay Ramachandran
8930f4cfeb Merge pull request #511 from Dainius14/master
Switch to browser native SubtleCrypt.digest()
2020-10-15 13:35:42 -04:00
Dainius Daukševičius
c1cdcbcb8f update attributions 2020-10-15 20:15:29 +03:00
Dainius Daukševičius
5bc12e52f3 remove js-sha256 dependency, use native hashing function 2020-10-15 20:15:11 +03:00
Ajay Ramachandran
b6e5fe461f Fix submission button colouring 2020-10-14 23:31:51 -04:00
Ajay Ramachandran
ad406d72e4 Improve username setting 2020-10-14 23:23:42 -04:00
Ajay Ramachandran
31d4c621d1 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into mbledkowski 2020-10-14 23:09:26 -04:00
Ajay Ramachandran
afa4cfa2c6 Convert hint from hardcoded string 2020-10-14 23:09:16 -04:00
Ajay Ramachandran
7c82a74e78 Shrink submit header 2020-10-14 23:07:17 -04:00
Ajay Ramachandran
5e4aed7afd Changed skipping status text 2020-10-14 23:01:04 -04:00
Ajay Ramachandran
21f4d2928f Changed back to "your work" and shrink text
I like it better haha
2020-10-14 23:00:31 -04:00
Ajay Ramachandran
a67c972e03 Change credits link to help.
More detailed credits are at the bottom of help.
2020-10-14 22:50:59 -04:00
Ajay Ramachandran
7a6f65803e Change leaderboard to link 2020-10-14 22:45:09 -04:00
Ajay Ramachandran
0ad1abb108 Hide whitelist button when not necessary and changed size of username 2020-10-14 20:42:06 -04:00
Ajay Ramachandran
4dc4160215 Merge pull request #490 from skyfrk/issue-447
fix: resolve translation template issue
2020-10-08 22:18:52 -04:00
Ajay Ramachandran
c5a37cf4d6 Merge pull request #502 from SuspiciousActivity/patch-1
Fix: skipping to the end of looped videos #426
2020-10-08 22:15:50 -04:00
SuspiciousActivity
34bcb120e5 Fix: skipping to the end of looped videos #426 2020-10-07 00:26:19 +02:00
github@esslinger.dev
ded5fa3f49 chore(i18n): add skip_category to locale zh_TW 2020-10-02 19:31:33 +02:00
github@esslinger.dev
905dfb0561 chore(i18n): add skip_category to locale zh_CN 2020-10-02 19:31:27 +02:00
github@esslinger.dev
bf59f3d96a chore(i18n): add skip_category to locale vi 2020-10-02 19:30:59 +02:00
github@esslinger.dev
3c353bd835 chore(i18n): add skip_category to locale uk 2020-10-02 19:30:54 +02:00
github@esslinger.dev
5a4392423e chore(i18n): add skip_category to locale tr 2020-10-02 19:30:49 +02:00
github@esslinger.dev
a671b4ab46 chore(i18n): add skip_category to locale sv 2020-10-02 19:30:45 +02:00
github@esslinger.dev
0db7379a17 chore(i18n): add skip_category to locale sk 2020-10-02 19:30:41 +02:00
github@esslinger.dev
0841d90451 chore(i18n): add skip_category to locale ru 2020-10-02 19:30:37 +02:00
github@esslinger.dev
5c9878c968 chore(i18n): add skip_category to locale ro 2020-10-02 19:30:33 +02:00
github@esslinger.dev
ebb3a82edc chore(i18n): add skip_category to locale pt_BR 2020-10-02 19:30:29 +02:00
github@esslinger.dev
bb7ab21503 chore(i18n): add skip_category to locale pl_PL 2020-10-02 19:29:56 +02:00
github@esslinger.dev
7c5fe424cd chore(i18n): add skip_category to locale pl 2020-10-02 19:29:47 +02:00
github@esslinger.dev
30c2cad4bd chore(i18n): add skip_category to locale nl 2020-10-02 19:29:42 +02:00
github@esslinger.dev
65d9ff857d chore(i18n): add skip_category to locale ko 2020-10-02 19:29:37 +02:00
github@esslinger.dev
39fd98e19a chore(i18n): add skip_category to locale ja 2020-10-02 19:29:32 +02:00
github@esslinger.dev
eb2722d0d3 chore(i18n): add skip_category to locale it 2020-10-02 19:29:27 +02:00
github@esslinger.dev
331cf16594 chore(i18n): add skip_category to locale id 2020-10-02 19:29:18 +02:00
github@esslinger.dev
bdb82279ae chore(i18n): add skip_category to locale fr 2020-10-02 19:29:13 +02:00
github@esslinger.dev
bc9b922820 chore(i18n): add skip_category to locale fi 2020-10-02 19:29:07 +02:00
github@esslinger.dev
910998e12b chore(i18n): add skip_category to locale es 2020-10-02 19:29:03 +02:00
github@esslinger.dev
e87bf736f1 chore(i18n): add skip_category to locale el 2020-10-02 19:28:58 +02:00
github@esslinger.dev
5dbaaaed96 fix: use skip_category i18n string
resolves #447
2020-10-02 17:32:19 +02:00
github@esslinger.dev
6fa0c44f7f chore(i18n): add skip_category string 2020-10-02 17:30:07 +02:00
github@esslinger.dev
2473f55091 Merge remote-tracking branch 'upstream/master' into issue-447 2020-10-02 17:27:58 +02:00
github@esslinger.dev
7564289dfa chore(i18n): remove unused messages 2020-10-02 17:27:21 +02:00
Ajay Ramachandran
43ea5cc3ec Merge pull request #492 from 1LiterZinalco/master
German translation hotfix
2020-10-02 10:55:06 -04:00
Ajay Ramachandran
51c4a8f5be Merge pull request #491 from 1LiterZinalco/master
Major improvement for German translation
2020-10-02 10:46:38 -04:00
1LiterZinalco
78a1e03857 Hotfix
fixes missing bracket on line 315
2020-10-02 16:46:34 +02:00
1LiterZinalco
739e6ad8a5 Major improvement for German translation
- [German has pronouns for both familiar/informal and polite/formal forms of address](https://en.wikipedia.org/wiki/German_honorifics). Half of the strings were formulated polite/formal, while the other half was not. Using the polite/formal forms is a little bit overkill for this use case. I've changed all sentences to use the familiar/informal forms.
- former translation was poor, made no sense, was too hard to understand or didn't contain the actual meaning
     - affected lines: 77, 137, 149, 158, 203, 290, 347, 425, 428, 489, 516, 522, 528, 543, 547, 599
- general improvements like small fixes, better grammar, easier to read sentences
     - applies to all edited lines, including the lines already mentioned above
2020-10-02 15:56:46 +02:00
github@esslinger.dev
010b501bac fix: resolve translation issue #447 2020-10-01 15:27:40 +02:00
github@esslinger.dev
dcc6f02a28 chore(i18n): add new strings for issue #447 to de locale 2020-10-01 15:26:02 +02:00
github@esslinger.dev
108f1f3379 chore(i18n): extend default locale template
add new strings for issue #447
2020-10-01 15:25:38 +02:00
Ajay Ramachandran
56136d598b Merge pull request #486 from SirCipherz/fr-translation
Fixing typo and removing 'anglisismes'
2020-09-26 11:23:43 -04:00
SirCipherz
9b8d4bd713 Fixing typo and removing 'anglisismes' 2020-09-26 13:49:31 +00:00
mmble
718666cdf0 Popup's background fixed 2020-09-25 14:53:40 +02:00
mmble
8cd3d92639 Small changes 2020-09-23 21:29:49 +02:00
mmble
e3fb851713 Merge branch 'master' of github.com:ajayyy/SponsorBlock 2020-09-23 20:22:27 +02:00
mmble
9bd4f12d2b Small changes 2020-09-23 20:18:20 +02:00
mmble
980e401628 Small changes 2020-09-23 20:17:26 +02:00
mmble
03cba1940c Small changes 2020-09-22 20:07:17 +02:00
mmble
7fecf2a8d4 Small fix 2020-09-22 19:26:14 +02:00
mmble
8f7ed9ce13 Popup - Vote buttons, Creating sponsor segments 2020-09-22 19:24:34 +02:00
Ajay Ramachandran
357d7562a6 Change unoffical ports to 3rd party ports 2020-09-20 16:04:22 -04:00
Ajay Ramachandran
15da1b86d3 Merge pull request #478 from ajayyy/expiremental
Increase version number
2020-09-16 13:57:14 -04:00
Ajay Ramachandran
56fd9b13ab Increase version number 2020-09-16 13:55:07 -04:00
Ajay Ramachandran
cc17ac7d5c Merge pull request #469 from ajayyy/crowdin_master
New Crowdin updates
2020-09-16 13:54:18 -04:00
Ajay Ramachandran
2f9ad95310 Merge pull request #476 from ajayyy/expiremental
Improvements
2020-09-16 13:54:02 -04:00
Ajay Ramachandran
b4e1cb0cfd Merge pull request #459 from Joe-Dowd/hash-prefix
Added hash prefix implementation (server code not yet merged)
2020-09-16 13:53:53 -04:00
Ajay Ramachandran
815b28ec06 New translations messages.json (Ukrainian) 2020-09-16 11:31:47 -04:00
Ajay Ramachandran
a7dbab771e New translations messages.json (Polish) 2020-09-16 11:31:45 -04:00
Ajay Ramachandran
f4016cee02 New translations messages.json (Tamil) 2020-09-15 23:27:11 -04:00
Ajay Ramachandran
db4b88ae1f New translations messages.json (Tamil) 2020-09-15 11:25:45 -04:00
Ajay Ramachandran
70a86e5a11 Don't unpause for inspect 2020-09-15 10:26:46 -04:00
Ajay Ramachandran
4d6456e406 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into expiremental 2020-09-15 10:24:29 -04:00
Ajay Ramachandran
41ce72cf0f New translations messages.json (Indonesian) 2020-09-14 03:09:49 -04:00
Ajay Ramachandran
0ad68b899e Fix typo in address incorrect error 2020-09-13 16:56:27 -04:00
Ajay Ramachandran
f0a9bf8fad Fix music warning text 2020-09-13 16:54:06 -04:00
Ajay Ramachandran
a5343797c3 New translations messages.json (German) 2020-09-13 15:08:20 -04:00
Ajay Ramachandran
643a0052fe New translations messages.json (Russian) 2020-09-12 22:56:37 -04:00
Ajay Ramachandran
81afeeb340 New translations messages.json (Korean) 2020-09-12 22:56:35 -04:00
Ajay Ramachandran
112413b8bc New translations messages.json (Italian) 2020-09-12 22:56:34 -04:00
Ajay Ramachandran
3d4b9c85c7 New translations messages.json (Korean) 2020-09-12 10:57:47 -04:00
Ajay Ramachandran
7c6c42a931 New translations messages.json (German) 2020-09-12 10:57:45 -04:00
Ajay Ramachandran
93e5fd68fe New translations messages.json (Persian) 2020-09-11 22:57:16 -04:00
Ajay Ramachandran
f4bbd40b93 Merge pull request #471 from ajayyy/expiremental
Fix release workflow
2020-09-11 18:12:10 -04:00
Ajay Ramachandran
8438dc06cd Increase version number 2020-09-11 18:09:13 -04:00
Ajay Ramachandran
e2718f1ebc Fix release workflow 2020-09-11 18:08:44 -04:00
Ajay Ramachandran
909110bee0 New translations messages.json (Polish) 2020-09-11 10:57:36 -04:00
Ajay Ramachandran
459b47aee4 New translations messages.json (Dutch) 2020-09-11 10:57:34 -04:00
Ajay Ramachandran
c87fafd332 New translations messages.json (Finnish) 2020-09-11 10:57:32 -04:00
Ajay Ramachandran
b7500a2040 New translations messages.json (Czech) 2020-09-11 10:57:31 -04:00
Ajay Ramachandran
4d631ae614 New translations messages.json (Romanian) 2020-09-11 10:57:28 -04:00
Ajay Ramachandran
924db3ef37 New translations messages.json (Polish) 2020-09-10 22:59:20 -04:00
Ajay Ramachandran
9e5a6a33c8 New translations messages.json (Spanish) 2020-09-10 22:59:11 -04:00
Ajay Ramachandran
c831608b1b New translations messages.json (Finnish) 2020-09-10 22:59:09 -04:00
Ajay Ramachandran
ce1652a6e5 Merge pull request #463 from ajayyy/expiremental
Improvements
2020-09-10 19:56:04 -04:00
Ajay Ramachandran
824066e692 New Crowdin updates (#446)
* New translations messages.json (German)

* New translations messages.json (Swedish)

* New translations messages.json (Turkish)

* New translations messages.json (Chinese Simplified)

* New translations messages.json (Portuguese, Brazilian)

* New translations messages.json (Hindi)

* New translations messages.json (Polish)

* New translations messages.json (Bulgarian)

* New translations messages.json (Russian)

* New translations messages.json (Indonesian)

* New translations messages.json (Spanish)

* New translations messages.json (French)

* New translations messages.json (Romanian)

* New translations messages.json (Italian)

* New translations messages.json (German)

* New translations messages.json (Polish)

* New translations messages.json (Russian)

* New translations messages.json (Romanian)

* New translations messages.json (Italian)

* New translations messages.json (Vietnamese)

* New translations messages.json (German)

* New translations messages.json (Russian)

* New translations messages.json (Indonesian)

* New translations messages.json (Vietnamese)

* New translations messages.json (Polish)

* New translations messages.json (Russian)

* New translations messages.json (Indonesian)

* New translations messages.json (Spanish)

* New translations messages.json (German)

* New translations messages.json (Polish)

* New translations messages.json (Romanian)

* New translations messages.json (Italian)

* New translations messages.json (Vietnamese)

* New translations messages.json (Chinese Traditional)

* New translations messages.json (Chinese Traditional)

* New translations messages.json (German)

* New translations messages.json (Polish)

* New translations messages.json (Vietnamese)

* New translations messages.json (Vietnamese)

* New translations messages.json (Korean)

* New translations messages.json (Japanese)

* New translations messages.json (Korean)

* New translations messages.json (Malay)

* New translations messages.json (Chinese Traditional)

* New translations messages.json (Korean)

* New translations messages.json (Chinese Traditional)

* New translations messages.json (Romanian)

* New translations messages.json (Korean)

* New translations messages.json (Dutch)

* New translations messages.json (Dutch)

* New translations messages.json (Dutch)

* New translations messages.json (Dutch)

* New translations messages.json (Dutch)

* New translations messages.json (Polish)
2020-09-10 19:53:16 -04:00
Ajay Ramachandran
7343986b1e Update version number 2020-09-10 19:53:11 -04:00
Ajay Ramachandran
2c5cc926ca Merge pull request #453 from thignus/add-review-button
Add review button to submission popup
2020-09-10 19:52:27 -04:00
mmble
508553b2e1 Merge branch 'master' of github.com:ajayyy/SponsorBlock 2020-09-07 17:36:42 +02:00
mmble
82815ca6ba Submit sponsor section in popup WIP 2020-09-06 20:04:50 +02:00
Ajay Ramachandran
39bf141e79 Merge pull request #461 from maximmax42/patch-1
Localization of the "Loading..." strings
2020-09-04 21:03:26 -04:00
Ajay Ramachandran
586cce5561 Remove invidio.us from default list 2020-09-04 21:02:07 -04:00
Ajay Ramachandran
633ae3b16f Remove log 2020-09-04 12:39:48 -04:00
Ajay Ramachandran
d0061985ca Separate refetch to a new option 2020-09-04 12:39:00 -04:00
Ajay Ramachandran
e0c6b687d3 Revert "Fix broken shadow ban check"
This reverts commit 65f7f9605f.
2020-09-04 12:17:09 -04:00
Ajay Ramachandran
65f7f9605f Fix broken shadow ban check 2020-09-04 12:14:38 -04:00
Maxim
18b257b031 "Loading" localized strings 2020-09-04 19:16:41 +05:00
Maxim
7d3593df30 "Loading" localization string 2020-09-04 19:14:22 +05:00
Joe Dowd
d8a48ed9bc Update src/content.ts
Co-authored-by: Ajay Ramachandran <dev@ajay.app>
2020-09-04 11:56:07 +01:00
Joe Dowd
b6206fabbc Update src/content.ts
Co-authored-by: Ajay Ramachandran <dev@ajay.app>
2020-09-04 11:55:42 +01:00
Joe Dowd
35651d2a50 Update src/content.ts
Co-authored-by: Ajay Ramachandran <dev@ajay.app>
2020-09-04 11:54:30 +01:00
Ajay Ramachandran
2798ac1254 Merge pull request #456 from ajayyy/expiremental
Improvements
2020-09-04 00:13:51 -04:00
Ajay Ramachandran
0f8739abc0 Switch color options to use input type=color and removed save button 2020-09-03 20:51:46 -04:00
Joe Dowd
1a48f556fa typo in comment 2020-09-04 00:39:41 +01:00
Joe Dowd
46e6b79b20 Added config option for query by hash prefix 2020-09-04 00:39:26 +01:00
Joe Dowd
40d522694d Added has prefix implementation (no config page) 2020-09-04 00:05:41 +01:00
Maciej Błędkowski
0126f44617 Update package-lock.json 2020-09-02 06:37:52 +02:00
Maciej Błędkowski
0c9573ae4c fixes merge conflict 2020-09-02 05:47:53 +02:00
mmble
c191132a01 Merge branch 'master' of github.com:ajayyy/SponsorBlock 2020-09-02 05:45:03 +02:00
mmble
4dec4df8e8 Merge branch 'master' of github.com:mbledkowski/SponsorBlock 2020-09-01 14:37:50 +02:00
mmble
76db584daf Small changes 2020-09-01 14:36:22 +02:00
Ajay Ramachandran
abe6c280a0 Moved notice on youtube music to area that is not click hijacking 2020-08-31 11:10:33 -04:00
Ajay Ramachandran
cdf6aa5e65 Don't send notifications on YouTube Music 2020-08-31 10:57:20 -04:00
Ajay Ramachandran
f419d73a96 Add missing break in popup 2020-08-31 10:48:07 -04:00
Ajay Ramachandran
76532539a9 Add YouTube music to the list of approved sites.
Resolves https://github.com/ajayyy/SponsorBlock/issues/449
2020-08-31 10:44:35 -04:00
Ajay Ramachandran
1904ecae12 Improved help page and credits 2020-08-31 10:12:40 -04:00
James Robinson
fc02816291 Add review button to submission popup 2020-08-30 14:19:06 -05:00
Ajay Ramachandran
3ec3a01128 Merge pull request #450 from maximmax42/patch-1
Missing localized messages
2020-08-27 21:35:06 -04:00
Ajay Ramachandran
d2e389296b Merge pull request #438 from MRuy/master
Dependencies updates, reload tip and .editorconfig added
2020-08-27 21:31:50 -04:00
Ajay Ramachandran
042c305cec Remove sponsor editing warning from language file 2020-08-27 21:31:02 -04:00
Ajay Ramachandran
03a1af813e Add back copy plugin changes 2020-08-27 21:27:43 -04:00
Ajay Ramachandran
9636fd72de Merge branch 'master' of https://github.com/MRuy/SponsorBlock into MRuy 2020-08-27 21:19:14 -04:00
Nanobyte
e0c11752e5 Revert dependency changes 2020-08-27 21:18:21 -04:00
Maxim
8c217746bb Localized Sponsor editing string 2020-08-28 00:05:50 +05:00
Maxim
2f2a4e70b7 Added sponsorEditingMoved 2020-08-28 00:05:09 +05:00
Maxim
0f8df07fe0 Localized "Close Popup" string 2020-08-28 00:00:08 +05:00
Maxim
5cb6f9335a closePopup message 2020-08-27 23:58:13 +05:00
Maxim
cc65dea4c5 Missing i18n strings for " to " between timecodes 2020-08-27 23:53:53 +05:00
Ajay Ramachandran
f84818dcb7 Fix popup having title when it should not 2020-08-25 20:05:37 -04:00
Ajay Ramachandran
f6110899fb Merge branch 'react' of https://github.com/ajayyy/SponsorBlock 2020-08-25 19:46:40 -04:00
Ajay Ramachandran
45f8c726b1 Update version number 2020-08-25 19:46:11 -04:00
Ajay Ramachandran
dd58dcb9ac New Crowdin updates (#433) 2020-08-25 19:43:05 -04:00
Ajay Ramachandran
306869f72a Merge pull request #443 from ajayyy/react
Improvements
2020-08-25 19:42:52 -04:00
Ajay Ramachandran
dcc9ed598a Update category descriptions to not talk about music videos 2020-08-25 19:40:41 -04:00
Ajay Ramachandran
a8f27fa3ae Rephrased non music warning 2020-08-23 11:08:47 -04:00
Ajay Ramachandran
31330b9863 Update link 2020-08-22 01:00:17 -04:00
Maciej Błędkowski
e64410df91 Merge branch 'master' into master 2020-08-19 21:45:34 +02:00
mmble
f2317caad2 Font size change - popup 2020-08-19 18:01:33 +02:00
mmble
25c4819bef Small changes - popup window 2020-08-19 17:57:46 +02:00
mmble
24c5253ab8 Numbers of skipped segments in popup window are now bolded. 2020-08-19 17:50:36 +02:00
mmble
abc6f70329 Fixed icons for popup.html embeded in YouTube 2020-08-19 16:57:43 +02:00
mmble
34ea13ecba Popup.html redesign 2020-08-19 05:15:22 +02:00
mmble
a4d9d83989 Popup.html redesign - almost done 2020-08-16 04:09:14 +02:00
Nanobyte
b073b3be8d Added .editorconfig
EditorConfig helps maintain consistent coding styles for multiple developers working on the same project across various editors and IDEs.
2020-08-13 23:32:38 +02:00
Nanobyte
fc48198ac4 Added extension reload tip for chromium 2020-08-13 23:31:48 +02:00
Nanobyte
7569de5ee3 jest removed
cleanup: jest dependency was never used
2020-08-13 23:30:35 +02:00
Nanobyte
2b8b72f4df Updates dependencies to fix vulnerabilities
38020 vulnerabilities fixed
2020-08-13 23:26:08 +02:00
Ajay Ramachandran
34d520c2ca Merge pull request #434 from ajayyy/react
Remove duplicate i18n strings
2020-08-07 20:59:21 -04:00
Ajay Ramachandran
b189dea299 Remove duplicate i18n strings 2020-08-07 20:57:22 -04:00
mmble
447445fcb0 Pop-up design update (WIP) 2020-08-08 01:43:04 +02:00
Ajay Ramachandran
df58e3670e Merge pull request #431 from ajayyy/react
General fixes
2020-08-06 22:35:32 -04:00
Ajay Ramachandran
f18d0762b3 New Crowdin updates (#417)
* New translations messages.json (Romanian)

* New translations messages.json (Turkish)

* New translations messages.json (Ukrainian)

* New translations messages.json (Chinese Simplified)

* New translations messages.json (Russian)

* New translations messages.json (German)

* New translations messages.json (French)

* New translations messages.json (Dutch)

* New translations messages.json (Portuguese, Brazilian)

* New translations messages.json (Finnish)

* New translations messages.json (Swedish)

* New translations messages.json (Bulgarian)

* New translations messages.json (Spanish)

* New translations messages.json (Portuguese)

* New translations messages.json (Italian)

* New translations messages.json (Polish)

* New translations messages.json (German)

* New translations messages.json (Polish)

* New translations messages.json (Portuguese, Brazilian)

* New translations messages.json (Polish)

* New translations messages.json (French)

* New translations messages.json (German)

* New translations messages.json (French)

* New translations messages.json (Polish)

* New translations messages.json (Polish)

* New translations messages.json (Polish)

* New translations messages.json (Italian)

* New translations messages.json (Polish)

* New translations messages.json (Italian)

* New translations messages.json (Italian)

* New translations messages.json (Polish)

* New translations messages.json (Polish)

* New translations messages.json (Polish)

* New translations messages.json (Polish)

* New translations messages.json (French)

* New translations messages.json (Polish)

* New translations messages.json (Polish)

* New translations messages.json (Polish)

* New translations messages.json (German)

* New translations messages.json (Polish)

* New translations messages.json (Polish)

* New translations messages.json (Polish)

* New translations messages.json (Polish)
2020-08-06 22:33:19 -04:00
Ajay Ramachandran
0dd7a41d85 Update version number 2020-08-06 22:32:25 -04:00
Ajay Ramachandran
834f6194ed Change call to use undefined to use default 2020-08-06 22:25:39 -04:00
Ajay Ramachandran
283342afb3 Fixed pausing and restarting the video not skipping 2020-08-06 22:21:09 -04:00
Ajay Ramachandran
87c9489c0e Fix popup appearing twice when there is a manual skip directly after a skip. 2020-08-05 22:42:43 -04:00
Ajay Ramachandran
24bb04e1ed Renamed instances of sponsor to segment or skip segment 2020-08-02 18:41:55 -04:00
Ajay Ramachandran
721faa7032 Fix issue with double notices sometimes appearing 2020-08-02 16:57:43 -04:00
Ajay Ramachandran
e349ac8e33 Don't show NaN as formatted time 2020-08-02 14:38:50 -04:00
Ajay Ramachandran
f4e8909a8d Merge pull request #428 from ajayyy/dependabot/npm_and_yarn/elliptic-6.5.3
Bump elliptic from 6.5.2 to 6.5.3
2020-08-01 11:13:50 -04:00
dependabot[bot]
506c4461e2 Bump elliptic from 6.5.2 to 6.5.3
Bumps [elliptic](https://github.com/indutny/elliptic) from 6.5.2 to 6.5.3.
- [Release notes](https://github.com/indutny/elliptic/releases)
- [Commits](https://github.com/indutny/elliptic/compare/v6.5.2...v6.5.3)

Signed-off-by: dependabot[bot] <support@github.com>
2020-08-01 12:45:27 +00:00
Ajay Ramachandran
3a49eda47f Added comma to description 2020-07-31 21:52:08 -04:00
Ajay Ramachandran
017e22e977 Clarified outro description. 2020-07-28 20:36:25 -04:00
Ajay Ramachandran
8de57309ea Merge pull request #416 from ajayyy/dependabot/npm_and_yarn/lodash-4.17.19
Bump lodash from 4.17.15 to 4.17.19
2020-07-19 12:54:12 -04:00
dependabot[bot]
fbb6963073 Bump lodash from 4.17.15 to 4.17.19
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.15 to 4.17.19.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.15...4.17.19)

Signed-off-by: dependabot[bot] <support@github.com>
2020-07-19 04:44:43 +00:00
Ajay Ramachandran
bf55b0f233 Merge pull request #415 from ajayyy/react
Fixed minutes not displaying zero when hours are displayed
2020-07-18 22:23:46 -04:00
Ajay Ramachandran
df1d3b401c Update version number 2020-07-18 22:19:47 -04:00
Ajay Ramachandran
4d55a71619 Fixed minutes not displaying zero when hours are displayed 2020-07-18 22:19:13 -04:00
Ajay Ramachandran
29e6ebab29 Merge pull request #414 from ajayyy/react
Improvements
2020-07-18 22:11:44 -04:00
Ajay Ramachandran
97e80c6f4e New Crowdin updates (#407)
* New translations messages.json (Romanian)

* New translations messages.json (German)

* New translations messages.json (French)

* New translations messages.json (Swedish)

* New translations messages.json (Japanese)

* New translations messages.json (Portuguese, Brazilian)

* New translations messages.json (Portuguese, Brazilian)

* New translations messages.json (French)

* New translations messages.json (German)
2020-07-18 21:22:23 -04:00
Ajay Ramachandran
3ac730c053 Fix errors when response fails 2020-07-18 21:21:53 -04:00
Ajay Ramachandran
d25951f313 Update version number 2020-07-18 21:20:36 -04:00
Ajay Ramachandran
886e134010 Made all preview segments auto skip 2020-07-18 21:20:18 -04:00
Ajay Ramachandran
cde50b0cb5 Update README.md 2020-07-18 17:52:47 -04:00
Ajay Ramachandran
19ac01a17c Updated description 2020-07-18 15:24:31 -04:00
Ajay Ramachandran
e9e53d1d43 Merge pull request #401 from ajayyy/react
Improvements
2020-07-12 23:09:43 -04:00
Ajay Ramachandran
07ab99a8d0 New Crowdin updates (#400)
* New translations messages.json (Romanian)

* New translations messages.json (German)

* New translations messages.json (Portuguese)

* New translations messages.json (Polish)

* New translations messages.json (Italian)

* New translations messages.json (French)

* New translations messages.json (Finnish)

* New translations messages.json (Spanish)

* New translations messages.json (Russian)

* New translations messages.json (Chinese Simplified)

* New translations messages.json (Ukrainian)

* New translations messages.json (Turkish)

* New translations messages.json (Swedish)

* New translations messages.json (Portuguese, Brazilian)

* New translations messages.json (German)
2020-07-12 23:08:04 -04:00
Ajay Ramachandran
896120d311 Update version number 2020-07-12 23:07:55 -04:00
Ajay Ramachandran
3dc6563048 Default to blank category when submitting 2020-07-12 20:59:35 -04:00
Ajay Ramachandran
2d74ce2093 Added hours to time with skips 2020-07-12 18:52:36 -04:00
Ajay Ramachandran
eac4ca4d71 Add edge 2020-07-08 21:43:26 -04:00
Ajay Ramachandran
399a5af990 Update README.md 2020-07-07 17:48:36 -04:00
Ajay Ramachandran
48861439b7 Don't run time without skips on mobile or invidious 2020-07-05 00:21:26 -04:00
Ajay Ramachandran
bd60875c66 Fix invidious css issues 2020-07-05 00:17:54 -04:00
Ajay Ramachandran
fe8f25fe23 Hide submit button on invidious 2020-07-05 00:11:29 -04:00
Ajay Ramachandran
87f3cf3881 Fixed invidious preview bar 2020-07-05 00:09:18 -04:00
Ajay Ramachandran
0b9df8a45c Remove submitting on mobile 2020-07-05 00:07:10 -04:00
Ajay Ramachandran
59c5b7eefe Remove unused function 2020-07-05 00:05:36 -04:00
Ajay Ramachandran
dea9dac20a Fix crashing on mobile youtube 2020-07-05 00:03:52 -04:00
Ajay Ramachandran
684cd676e5 Delete empty unsubmitted submissions when delete is called 2020-07-04 15:34:29 -04:00
Ajay Ramachandran
929e3396cd New Crowdin updates (#386)
* New translations messages.json (Romanian)

* New translations messages.json (German)

* New translations messages.json (Turkish)

* New translations messages.json (Ukrainian)

* New translations messages.json (Chinese Simplified)

* New translations messages.json (Slovak)

* New translations messages.json (Russian)

* New translations messages.json (French)

* New translations messages.json (Dutch)

* New translations messages.json (Portuguese, Brazilian)

* New translations messages.json (Finnish)

* New translations messages.json (Hungarian)

* New translations messages.json (Swedish)

* New translations messages.json (Bulgarian)

* New translations messages.json (Spanish)

* New translations messages.json (Gujarati)

* New translations messages.json (Polish)

* New translations messages.json (German)

* New translations messages.json (French)

* New translations messages.json (German)

* New translations messages.json (Swedish)

* New translations messages.json (Portuguese, Brazilian)

* New translations messages.json (Portuguese, Brazilian)

* New translations messages.json (German)

* New translations messages.json (Russian)

* New translations messages.json (Chinese Simplified)
2020-07-03 21:25:13 -04:00
Ajay Ramachandran
fad3284c4f Merge pull request #399 from ajayyy/react
Save category in preview submissions and other fixes
2020-07-03 21:20:53 -04:00
Ajay Ramachandran
c69047c7f9 Show short names when hovering the preview bar 2020-07-03 21:16:38 -04:00
Ajay Ramachandran
4fc7a69dd5 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into react 2020-07-03 20:58:15 -04:00
Ajay Ramachandran
dd4c903c6a Merge pull request #395 from NDevTK/patch-1
Added config option for excluding skipped content from the video duration
2020-07-03 20:58:01 -04:00
Ajay Ramachandran
c9a2edaf3d Remove unused function 2020-07-03 20:56:45 -04:00
Ajay Ramachandran
8d41af073d Added option to options page 2020-07-03 20:55:58 -04:00
Ajay Ramachandran
bfafcd07cc Fix font issue, NaN issue and remove hide real time 2020-07-03 19:56:08 -04:00
Ajay Ramachandran
77abc1d031 Reuse existing functions 2020-07-03 19:44:15 -04:00
Ajay Ramachandran
809de0e0fd Increased version number 2020-07-03 19:31:18 -04:00
Ajay Ramachandran
e55d1f5115 Removed intermission category and renamed intro to intermission. 2020-07-03 19:31:00 -04:00
Ajay Ramachandran
037bd511b0 Remove keybind restriction.
Closes https://github.com/ajayyy/SponsorBlock/issues/379
2020-07-03 19:07:05 -04:00
Ajay Ramachandran
1265eeb941 Save category with the preview submissions. 2020-07-02 23:34:13 -04:00
Ajay Ramachandran
b3a94142c3 Allow colon on invidious options 2020-07-02 21:39:00 -04:00
Ajay Ramachandran
367657e44e Added intermission category 2020-07-02 21:37:38 -04:00
Ajay Ramachandran
955ee32b46 Remove category update message 2020-07-02 21:13:07 -04:00
Ajay Ramachandran
cd0b1f4a31 Wait for permissions before reloading 2020-07-02 20:56:41 -04:00
Ajay Ramachandran
5c4f0c960c Reload after importing options 2020-07-02 20:50:06 -04:00
Ajay Ramachandran
5ac6dd1a7f Update description 2020-07-02 20:48:39 -04:00
NDevTK
8d53e776b8 Do not show if skipDuration is 0 2020-06-29 19:35:11 +01:00
NDevTK
ec2950786f Skip if skipDuration is 0 2020-06-29 17:52:28 +01:00
Ajay Ramachandran
f33fa2f621 Moved Android to official 2020-06-27 11:38:49 -04:00
NDevTK
fd77748b15 Updated config 2020-06-27 15:20:00 +01:00
NDevTK
3b59389cab Added different ui option 2020-06-27 15:16:36 +01:00
Ajay Ramachandran
e6f53a3ef9 Update README.md 2020-06-27 00:49:55 -04:00
Ajay Ramachandran
b2f1a737f5 Remove port without pre-built release 2020-06-27 00:44:38 -04:00
Ajay Ramachandran
e2c7f4d16f Merge pull request #397 from daniel11420/patch-2
Add more unofficial ports to the Unofficial Ports section in the README
2020-06-27 00:44:00 -04:00
Ajay Ramachandran
4a89dfaac5 Merge pull request #396 from daniel11420/patch-1
Fix typo in README
2020-06-27 00:42:50 -04:00
daniel11420
e47330a79c Add more unofficial ports to the Unofficial Ports section in the README 2020-06-27 06:38:29 +02:00
daniel11420
72fc3620bc Fix typo in README 2020-06-27 06:32:21 +02:00
NDevTK
0ebd7f4f8d Added duration override 2020-06-26 19:33:19 +01:00
NDevTK
beea8181a1 Added config option 2020-06-26 19:19:51 +01:00
Ajay Ramachandran
f0716e8bbb Merge pull request #389 from kittenparry/patch-1
Fix typo in Chrome Users badge
2020-06-22 18:51:02 -04:00
Edvin Boul
783ea5cf5b Fix typo in Chrome Users badge
Chome -> Chrome
2020-06-22 18:29:08 +03:00
Ajay Ramachandran
42a813d325 Merge pull request #388 from ajayyy/react
Another hotfix for name string issue
2020-06-21 15:54:25 -04:00
Ajay Ramachandran
e6dfb5041e Another hotfix for name string issue 2020-06-21 15:53:26 -04:00
Ajay Ramachandran
c857308038 Merge pull request #387 from ajayyy/react
Fixed wrong string removed
2020-06-21 12:55:27 -04:00
Ajay Ramachandran
f73abdbabc Fixed wrong string removed 2020-06-21 12:55:10 -04:00
Ajay Ramachandran
43184e466f Merge pull request #385 from ajayyy/react
Fixed options page issues
2020-06-20 00:20:01 -04:00
Ajay Ramachandran
627c7769b0 New Crowdin updates (#380)
* New translations messages.json (French)

* New translations messages.json (French)

* New translations messages.json (French)

* New translations messages.json (French)
2020-06-19 18:54:17 -04:00
Ajay Ramachandran
759dba9cd3 Increased version number 2020-06-19 18:53:39 -04:00
Ajay Ramachandran
7cac2c4045 Fix help page not hiding options title bar 2020-06-19 18:53:24 -04:00
Ajay Ramachandran
27bb44189f Remove name from localisation 2020-06-19 18:49:49 -04:00
Ajay Ramachandran
4c44f3da25 Merge pull request #378 from ajayyy/react
Fixed missing options from options page
2020-06-16 22:01:55 -04:00
Ajay Ramachandran
e917a3e94a New Crowdin translations (#369)
* New translations messages.json (French)

* New translations messages.json (French)

* New translations messages.json (Dutch)

* New translations messages.json (Portuguese, Brazilian)

* New translations messages.json (Finnish)

* New translations messages.json (German)

* New translations messages.json (German)

* New translations messages.json (Hungarian)

* New translations messages.json (Swedish)

* New translations messages.json (Swedish)

* New translations messages.json (Bulgarian)

* New translations messages.json (Finnish)

* New translations messages.json (French)
2020-06-16 22:01:08 -04:00
Ajay Ramachandran
1570bfdd0a Fixed missing options from options page 2020-06-16 22:00:49 -04:00
Ajay Ramachandran
e511de9f88 Update README.md 2020-06-14 20:29:12 -04:00
drlellinger
e694393edc Improve German translation (#371) 2020-06-10 19:53:35 -04:00
Ajay Ramachandran
e1cb86e6b4 New Crowdin translations (#368)
* New translations messages.json (Romanian)

* New translations messages.json (German)
2020-06-07 21:24:15 -04:00
Ajay Ramachandran
22221ba9bd Update version number 2020-06-07 21:21:38 -04:00
Ajay Ramachandran
9ad67c1a03 Merge pull request #363 from ajayyy/react
Category Improvements
2020-06-07 11:30:33 -04:00
Ajay Ramachandran
53071a9291 New Crowdin translations (#362)
* New translations messages.json (Portuguese, Brazilian)

* New translations messages.json (Swedish)

* New translations messages.json (Ukrainian)

* New translations messages.json (Chinese Simplified)

* New translations messages.json (Russian)

* New translations messages.json (Turkish)

* New translations messages.json (Bulgarian)

* New translations messages.json (French)

* New translations messages.json (Spanish)

* New translations messages.json (German)

* New translations messages.json (Finnish)

* New translations messages.json (Portuguese)

* New translations messages.json (Italian)

* New translations messages.json (Dutch)

* New translations messages.json (Polish)

* New translations messages.json (Turkish)

* New translations messages.json (Chinese Simplified)

* New translations messages.json (Romanian)

* New translations messages.json (Romanian)
2020-06-07 11:30:10 -04:00
Ajay Ramachandran
56e40b791f Increased version number 2020-06-07 11:28:41 -04:00
Ajay Ramachandran
93316bf463 Added option to disable notification 2020-06-07 11:27:35 -04:00
Ajay Ramachandran
3f98e2fc73 Remove options page header on help page 2020-06-07 11:21:21 -04:00
Ajay Ramachandran
9f4fec2a43 Added category update info on the notice 2020-06-07 11:16:24 -04:00
Ajay Ramachandran
89cc6ed184 Added "read the guidelines button. 2020-06-05 21:38:38 -04:00
Ajay Ramachandran
730d966019 Lowered category description width 2020-06-05 21:26:07 -04:00
Ajay Ramachandran
c509b8807c Shortened sponsor description 2020-06-05 19:37:39 -04:00
Ajay Ramachandran
7de907fa23 Added help button to submission notice 2020-06-04 21:46:56 -04:00
Ajay Ramachandran
b4e03ae055 Added category descriptions 2020-06-03 21:00:32 -04:00
Ajay Ramachandran
c9460bd6c6 Added short category names 2020-06-03 20:42:38 -04:00
Ajay Ramachandran
d9800b3c14 Added options page to help page as iframe 2020-06-03 20:31:14 -04:00
Ajay Ramachandran
fa7f577177 Fix skip options 2020-06-03 20:30:25 -04:00
Ajay Ramachandran
ca2727655e Added customizable seek bar colors 2020-06-03 20:20:02 -04:00
Ajay Ramachandran
28cddf92d5 Merge pull request #358 from ajayyy/react
Categories Improvements
2020-06-02 19:40:11 -04:00
Ajay Ramachandran
465a6dde9b New Crowdin translations (#355)
* New translations messages.json (Bulgarian)

* New translations messages.json (Italian)

* New translations messages.json (German)

* New translations messages.json (French)

* New translations messages.json (Bulgarian)

* New translations messages.json (Portuguese, Brazilian)

* New translations messages.json (Russian)

* New translations messages.json (Chinese Simplified)

* New translations messages.json (Ukrainian)

* New translations messages.json (Swedish)

* New translations messages.json (Slovak)

* New translations messages.json (Turkish)

* New translations messages.json (Portuguese)

* New translations messages.json (Polish)

* New translations messages.json (German)

* New translations messages.json (German)

* New translations messages.json (Russian)

* New translations messages.json (German)

* New translations messages.json (Dutch)

* New translations messages.json (Portuguese, Brazilian)

* New translations messages.json (Swedish)

* New translations messages.json (Ukrainian)

* New translations messages.json (Chinese Simplified)

* New translations messages.json (Russian)

* New translations messages.json (Turkish)

* New translations messages.json (Bulgarian)

* New translations messages.json (French)

* New translations messages.json (German)

* New translations messages.json (Portuguese)

* New translations messages.json (Italian)

* New translations messages.json (Dutch)

* New translations messages.json (Polish)

* New translations messages.json (Chinese Simplified)

* New translations messages.json (Finnish)

* New translations messages.json (Gujarati)

* New translations messages.json (Gujarati)

* New translations messages.json (Spanish)

* New translations messages.json (French)

* New translations messages.json (French)

* New translations messages.json (French)

* New translations messages.json (French)

* New translations messages.json (Spanish)

* New translations messages.json (French)

* New translations messages.json (Spanish)

* New translations messages.json (Polish)

* New translations messages.json (French)

* New translations messages.json (Polish)
2020-06-02 19:38:04 -04:00
Ajay Ramachandran
5336399365 Increase version number 2020-06-02 19:37:53 -04:00
Ajay Ramachandran
3f69b19e23 Remove duplicate vote error message 2020-05-25 22:27:39 -04:00
Ajay Ramachandran
23103f1274 Made preview submissions always autoskip 2020-05-25 22:21:11 -04:00
Ajay Ramachandran
9bfaf98dda Revised self-promo naming 2020-05-25 18:32:53 -04:00
Ajay Ramachandran
f21be82cce Fix local saved time tracking.
Also made it track when the notice is closed.
2020-05-24 23:00:39 -04:00
Ajay Ramachandran
39155fdf99 Moved requests to the background script.
This should avoid ad blockers messing with requests.

Helps with https://github.com/ajayyy/SponsorBlock/issues/354
2020-05-24 22:42:55 -04:00
Ajay Ramachandran
1676e50e15 Merge pull request #357 from ajayyy/react
Categories Improvements
2020-05-20 23:52:40 -04:00
Ajay Ramachandran
f165b3b602 Removed autoUpvote config 2020-05-20 23:50:26 -04:00
Ajay Ramachandran
0f82c16940 Fixed "voted" text. 2020-05-20 23:47:13 -04:00
Ajay Ramachandran
9ef3ef03a4 Added padding to vote buttons 2020-05-20 23:36:03 -04:00
Ajay Ramachandran
ef17cae9a1 Changed to upvote/downvote from report 2020-05-20 23:32:57 -04:00
Ajay Ramachandran
05acb1669e Added segment chooser when skipping multiple segments.
Now the skip notice supports skipping multiple segments.
2020-05-19 23:21:51 -04:00
Ajay Ramachandran
0850421afb Update config.json.example 2020-05-17 19:42:11 -04:00
Ajay Ramachandran
edf06ac908 Fixed typo: sever -> server 2020-05-17 11:31:35 -04:00
Ajay Ramachandran
842d35235a Gave web-ext the beta name and made signing happen at the end. 2020-05-17 00:23:44 -04:00
Ajay Ramachandran
45d20574d9 Merge pull request #356 from ajayyy/react
Fix preview sponsors not skipping
2020-05-17 00:00:08 -04:00
Ajay Ramachandran
252da8c56a Added the ability to stop the notice timer by clicking it 2020-05-16 23:58:02 -04:00
Ajay Ramachandran
99373c3e55 Added category names to notice 2020-05-16 23:48:41 -04:00
Ajay Ramachandran
dce69b3642 Incorrect -> Incorrect/Wrong Timing 2020-05-16 23:42:10 -04:00
Ajay Ramachandran
bb670b93e9 Fix preview sponsors not skipping 2020-05-16 23:39:04 -04:00
Ajay Ramachandran
c011ad105d Merge branch 'rafern' 2020-05-15 21:27:37 -04:00
Ajay Ramachandran
856125f7fd Merge pull request #350 from rafern/master
Don't skip ads, hide controls & sponsor times preview bar when ads are playing
2020-05-15 21:25:30 -04:00
Ajay Ramachandran
178b122ab8 Added back requested changes 2020-05-15 21:20:32 -04:00
Ajay Ramachandran
7b0488d068 Reverse "requested changes" 2020-05-15 21:15:50 -04:00
Ajay Ramachandran
02a9238869 Merge branch 'master' into master 2020-05-15 21:12:31 -04:00
Ajay Ramachandran
2fb97409a1 Changed where cd is used in release workflow 2020-05-15 21:08:52 -04:00
Ajay Ramachandran
3640463112 New Crowdin translations (#353)
* New translations messages.json (Portuguese, Brazilian)

* New translations messages.json (Portuguese, Brazilian)
2020-05-15 21:00:07 -04:00
Ajay Ramachandran
d872ed642d Merge pull request #351 from ajayyy/react
Category Improvements
2020-05-15 20:56:09 -04:00
Ajay Ramachandran
1ab1f33caf Change zip binary in release workflow 2020-05-15 20:51:24 -04:00
Ajay Ramachandran
ba13f5951e Increase version number 2020-05-15 19:40:24 -04:00
Ajay Ramachandran
f66e8ddf92 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into react 2020-05-15 19:40:12 -04:00
Ajay Ramachandran
cff72b19c7 Enable category vote on main server 2020-05-15 19:39:37 -04:00
rafern
c046df7d18 Requested changes 2020-05-14 10:58:30 +01:00
Ajay Ramachandran
941bd41cdb Added another check to prevent phantom skips 2020-05-13 21:11:00 -04:00
Rafael
dd5ed6ce42 Remove duplicate code 2020-05-13 17:45:08 +01:00
rafern
3a0d5221f6 Don't skip ads, hide controls & bar when ad playing 2020-05-13 17:29:34 +01:00
Ajay Ramachandran
a72f571bd4 Update manifest.json 2020-05-12 22:03:38 -04:00
Ajay Ramachandran
50c9c9fe8a Merge pull request #349 from ajayyy/react
Hotfixes for 1.2.28.1
2020-05-12 21:56:14 -04:00
Ajay Ramachandran
7f8badb34d New Crowdin translations (#348)
* New translations messages.json (Chinese Simplified)

* New translations messages.json (Chinese Simplified)
2020-05-12 21:55:43 -04:00
Ajay Ramachandran
f9d8daeca0 Upgraded web-ext 2020-05-12 21:18:07 -04:00
Ajay Ramachandran
55070d5852 Fixed mutation listener stack overflow on Firefox. 2020-05-12 21:17:52 -04:00
Ajay Ramachandran
789bd5939b Fixed zipping command in release workflow 2020-05-11 21:13:19 -04:00
Ajay Ramachandran
b591fbfc4b Removed log 2020-05-11 21:04:28 -04:00
Ajay Ramachandran
57eb122fce Changed rough time calculation to only use real time or end time.
Also fixed getting the replay button element.
2020-05-11 21:04:10 -04:00
Ajay Ramachandran
aec287f0cf Fixed preview bar hover text error 2020-05-11 20:59:30 -04:00
Ajay Ramachandran
c68aabaa40 Added null coalescence checks to video info 2020-05-11 20:45:48 -04:00
Ajay Ramachandran
167cff4693 New Crowdin translations (#346)
* New translations messages.json (French)

* New translations messages.json (German)

* New translations messages.json (Polish)

* New translations messages.json (Russian)

* New translations messages.json (Swedish)

* New translations messages.json (Chinese Simplified)

* New translations messages.json (Ukrainian)

* New translations messages.json (Turkish)

* New translations messages.json (Slovak)

* New translations messages.json (Turkish)
2020-05-11 19:31:11 -04:00
Ajay Ramachandran
99c343c2ce Merge pull request #347 from ajayyy/react
1.2.28 Hotfixes
2020-05-11 19:30:59 -04:00
Ajay Ramachandran
70239bc045 Increase version number 2020-05-11 19:28:02 -04:00
Ajay Ramachandran
d1748f1758 Changed endscreen check to use replay button instead. 2020-05-11 19:27:26 -04:00
Ajay Ramachandran
ac3d27bf88 Changed instances of splice to only remove one 2020-05-11 18:36:07 -04:00
Ajay Ramachandran
3fb5c1c14f Only splice 1 when removing offtopic category selection 2020-05-11 18:35:07 -04:00
Ajay Ramachandran
b1d9cde715 Added code to remove off-topic from category selections.
That category has been removed.
2020-05-11 18:28:27 -04:00
Ajay Ramachandran
aa8225c196 Fixed release CI 2020-05-10 23:16:35 -04:00
Ajay Ramachandran
918adc7c28 New Crowdin translations (#345)
* New translations messages.json (Turkish)

* New translations messages.json (Czech)

* New translations messages.json (Slovak)

* New translations messages.json (Turkish)

* New translations messages.json (Turkish)

* New translations messages.json (Hungarian)
2020-05-10 23:09:52 -04:00
Ajay Ramachandran
ab84b9d2e0 Merge pull request #332 from ajayyy/react
Categories Improvements
2020-05-10 23:09:40 -04:00
Ajay Ramachandran
9e0a9b4601 Increase version number 2020-05-10 22:12:13 -04:00
Ajay Ramachandran
98fd841a54 Fixed null whitelisted channel check happening after use 2020-05-10 21:28:01 -04:00
Ajay Ramachandran
3816313f1e Removed log 2020-05-10 21:26:21 -04:00
Ajay Ramachandran
a433dad080 Fix edit text on old YouTube dark theme 2020-05-10 21:23:25 -04:00
Ajay Ramachandran
dc04e045aa Use duration as current time if endcards or autoplay is visible when submitting 2020-05-10 21:06:15 -04:00
Ajay Ramachandran
2f842a0455 Remove config listener from EditComponent properly 2020-05-10 20:32:49 -04:00
Ajay Ramachandran
7c38b1f8f2 Fix new vote options table layout 2020-05-10 20:27:33 -04:00
Ajay Ramachandran
6942bcb418 Remove livestream category. 2020-05-10 20:12:35 -04:00
Ajay Ramachandran
a335ae2b72 Added warning when submitting non-music category on music video.
Also added a color for the music category.
2020-05-10 18:48:28 -04:00
Ajay Ramachandran
52020bcac6 Renamed outro category and added music and livestream categories 2020-05-10 16:59:42 -04:00
Ajay Ramachandran
5454861c78 Adjusted category names 2020-05-10 16:46:53 -04:00
Ajay Ramachandran
1217b9ed0b Added change category button for testing server 2020-05-10 16:44:53 -04:00
Ajay Ramachandran
e78a1b0fed New Crowdin translations (#342)
* New translations messages.json (Ukrainian)

* New translations messages.json (Turkish)
2020-05-07 23:34:07 -04:00
Ajay Ramachandran
a259949cd6 Update README.md 2020-05-06 20:22:11 -04:00
Ajay Ramachandran
ebf333b8c6 Removed cancel button 2020-05-05 23:36:06 -04:00
Ajay Ramachandran
9a5cb5ae0f Added another check to prevent scheduled skips from old videos 2020-05-04 16:39:01 -04:00
Ajay Ramachandran
20e1a96a84 Removed off-topic category 2020-05-04 16:27:36 -04:00
Ajay Ramachandran
822c7bda89 Added a category tooltip on hover. 2020-05-03 11:42:39 -04:00
Ajay Ramachandran
1526fbcbe8 New translations messages.json (Swedish) (#337) 2020-05-02 15:14:40 -04:00
Ajay Ramachandran
b8f4f8bebc New Crowdin translations (#334)
* New translations messages.json (Ukrainian)

* New translations messages.json (Chinese Simplified)
2020-04-29 22:50:36 -04:00
Ajay Ramachandran
e3698dcdca Fix release CI not zipping things properly 2020-04-27 16:32:26 -04:00
Ajay Ramachandran
fc3abc2b56 Fixed invidious message typo 2020-04-27 15:23:55 -04:00
Ajay Ramachandran
2a8a425627 Removed invidiou.sh from default instances 2020-04-27 15:22:19 -04:00
Ajay Ramachandran
9069f7cee6 Fixed indentation in release workflow 2020-04-27 14:07:09 -04:00
Ajay Ramachandran
a217831c22 Removed February info 2020-04-27 14:04:40 -04:00
Ajay Ramachandran
44e8b316a5 Added Firefox signing to CI 2020-04-27 00:01:45 -04:00
Ajay Ramachandran
885b38b682 New translations messages.json (Chinese Simplified) (#331) 2020-04-26 23:21:13 -04:00
Ajay Ramachandran
938db4b8e0 Merge pull request #322 from ajayyy/react
Categories Improvements
2020-04-26 23:16:53 -04:00
Ajay Ramachandran
ad361cdf28 Increase version number 2020-04-26 23:14:47 -04:00
Ajay Ramachandran
fbafb723cb Added option to force a whitelist check before allowing skipping. 2020-04-26 23:14:18 -04:00
Ajay Ramachandran
797fbf563b Fix start sponsor code not functioning as well as it should have 2020-04-26 21:46:38 -04:00
Ajay Ramachandran
d23c8b0e1f Fix adblocker error messages and increased unlisted check time 2020-04-26 21:12:56 -04:00
Ajay Ramachandran
18852d16ac isUnlisted now uses JSON data. 2020-04-26 20:40:11 -04:00
Ajay Ramachandran
6179278699 Improved options page descriptions 2020-04-26 18:18:55 -04:00
Ajay Ramachandran
8a6488f082 Added migration code for whitelisted channelIDs vs URLs 2020-04-26 18:07:10 -04:00
Ajay Ramachandran
89c4432b89 Revised delete button option description 2020-04-26 18:05:56 -04:00
Ajay Ramachandran
16896be97f Changed whitelisting to use channel JSON instead of page scraping.
It also only pulls data once. Uses channelID now instead of URLs.

Resolves https://github.com/ajayyy/SponsorBlock/issues/275

TODO: Add migration method to use channelID instead of channelURL
2020-04-26 15:16:00 -04:00
Ajay Ramachandran
8a9a19efeb Update README.md 2020-04-26 00:10:31 -04:00
Ajay Ramachandran
f3c786eb57 Fix Crowdin deleting translations >:( (#330)
(Portuguese, Brazilian)
2020-04-26 00:04:26 -04:00
Ajay Ramachandran
19ab83fee9 New Crowdin translations (#327)
* New translations messages.json (Chinese Simplified)

* New translations messages.json (Portuguese, Brazilian)

* New translations messages.json (French)

* New translations messages.json (German)

* New translations messages.json (Dutch)
2020-04-25 23:47:42 -04:00
Ajay Ramachandran
0f9e794428 Fix notice on old YouTube 2020-04-25 23:46:55 -04:00
Ajay Ramachandran
1b8af9da11 Redid hidden sponsor implementation + added info about being hid due to minimum duration
Fixes https://github.com/ajayyy/SponsorBlock/issues/326 and https://github.com/ajayyy/SponsorBlock/issues/325
2020-04-25 23:41:08 -04:00
Ajay Ramachandran
0b90539372 Fixed incorrect videoID check being in reverse. 2020-04-24 21:28:08 -04:00
Ajay Ramachandran
4131442066 Properly reset hiddenSponsorTimes.
Maybe related to https://github.com/ajayyy/SponsorBlock/issues/325
2020-04-24 21:27:45 -04:00
Ajay Ramachandran
e4f642e7d6 Merge pull request #324 from malmers/swedish
Swedish translation
2020-04-23 12:10:26 -04:00
Ajay Ramachandran
a65e40a87d Removed help page 2020-04-23 12:09:11 -04:00
Ajay Ramachandran
edf467a6b9 Removed help page 2020-04-23 12:07:29 -04:00
Pontus Malm
3fbb11191e Swedish translation 2020-04-22 22:45:59 +02:00
Ajay Ramachandran
54a67e6aba New Crowdin translations (#323)
* New translations messages.json (French)

* New translations messages.json (German)
2020-04-22 13:00:41 -04:00
Ajay Ramachandran
8912f88131 Fixed show on seekbar categories appearing in list of start times to skip. 2020-04-21 16:01:41 -04:00
Ajay Ramachandran
c31d30821b Call incorrect videoID check when scheduling a skip. 2020-04-21 14:16:09 -04:00
Ajay Ramachandran
7eb6f1c482 Changed popup look 2020-04-20 16:56:12 -04:00
Ajay Ramachandran
a7e2f83033 Fix Firefox popup scrolling issues 2020-04-20 15:57:07 -04:00
Ajay Ramachandran
0cfe0dc90f Fix submission count not being counted 2020-04-20 15:48:47 -04:00
Ajay Ramachandran
8c1d837770 Update README.md 2020-04-20 01:22:03 -04:00
Ajay Ramachandran
9a70599e60 Added end button to submission notice 2020-04-20 00:37:25 -04:00
Ajay Ramachandran
89f72c185c Update submission UI whenever there is a config update. 2020-04-20 00:33:41 -04:00
Ajay Ramachandran
2f5c239c82 Added path to release CI 2020-04-19 20:59:36 -04:00
Ajay Ramachandran
31b76553dc Merge pull request #317 from ajayyy/react
Categories Improvements
2020-04-19 20:54:25 -04:00
Ajay Ramachandran
eff73548e3 New Crowdin translations (#321)
* New translations messages.json (French)
2020-04-19 20:53:36 -04:00
Ajay Ramachandran
2ca98ad97b Increase version number. 2020-04-19 20:52:26 -04:00
Ajay Ramachandran
4e9b5ca0bc Fixed preview button 2020-04-19 20:48:43 -04:00
Ajay Ramachandran
3d7d291d9a Changed "show on overlay" wording 2020-04-19 20:38:21 -04:00
Ajay Ramachandran
195ed1f5fc Removed old submission method 2020-04-19 20:37:30 -04:00
Ajay Ramachandran
74f14b3bf8 Fixed polish folder 2020-04-14 23:50:20 -04:00
Ajay Ramachandran
290dff25f9 Update Crowdin configuration file 2020-04-14 23:44:15 -04:00
Ajay Ramachandran
64ab6b5768 Update Crowdin configuration file 2020-04-14 23:41:50 -04:00
Ajay Ramachandran
1b2bc6def4 Submission notice size now updates when the video size changes.
React listeners are properly cleaned up now.
2020-04-14 00:47:09 -04:00
Ajay Ramachandran
18c7be8161 Made submission notice max height dynamic 2020-04-14 00:31:47 -04:00
Ajay Ramachandran
638439a671 Moved notice closing to renderer (no leftover nodes) 2020-04-14 00:10:20 -04:00
Ajay Ramachandran
9fafb9cf54 Made the submission notice scroll when too large 2020-04-13 21:48:55 -04:00
Ajay Ramachandran
0223aa8307 Only show selected categories when submitting and added a "show more categories" button 2020-04-13 12:43:12 -04:00
131 changed files with 33215 additions and 17657 deletions

18
.editorconfig Normal file
View File

@@ -0,0 +1,18 @@
# EditorConfig is awesome: https://EditorConfig.org
# top-most EditorConfig file
root = true
# Unix-style newlines with a newline ending every file
[*]
end_of_line = lf
insert_final_newline = true
[*.{js,json,ts,tsx}]
charset = utf-8
indent_style = space
indent_size = 4
[package.json]
indent_style = space
indent_size = 2

33
.eslintrc.js Normal file
View File

@@ -0,0 +1,33 @@
module.exports = {
env: {
browser: true,
es2021: true,
node: true,
jest: true,
jasmine: true,
},
extends: [
"eslint:recommended",
"plugin:react/recommended",
"plugin:@typescript-eslint/recommended",
],
parser: "@typescript-eslint/parser",
parserOptions: {
ecmaFeatures: {
jsx: true,
},
ecmaVersion: 12,
sourceType: "module",
},
plugins: ["react", "@typescript-eslint"],
rules: {
// TODO: Remove warn rules when not needed anymore
"no-self-assign": "off",
"@typescript-eslint/no-empty-interface": "off",
},
settings: {
react: {
version: "detect",
},
},
};

3
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1,3 @@
github: ajayyy-org
patreon: ajayyy
custom: [sponsor.ajay.app/donate]

5
.github/pull_request_template.md vendored Normal file
View File

@@ -0,0 +1,5 @@
- [ ] I agree to license my contribution under LGPL-3.0 **or** my contribution is from another project with a license compatible with LGPL-3.0
To test this pull request, follow the [instructions in the wiki](https://github.com/ajayyy/SponsorBlock/wiki/Testing-a-Pull-Request).
***

View File

@@ -10,53 +10,59 @@ jobs:
steps:
# Initialization
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
- run: npm install
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: '16'
- run: npm ci
- name: Copy configuration
run: cp config.json.example config.json
# Run linter
- name: Lint
run: npm run lint
# Create Chrome artifacts
- name: Create Chrome artifacts
run: npm run build:chrome
- uses: actions/upload-artifact@v1
- uses: actions/upload-artifact@v2
with:
name: ChromeExtension
path: dist
- run: mkdir ./builds
- uses: montudor/action-zip@v0.1.0
- uses: montudor/action-zip@v1
with:
args: zip -qq -r ./builds/ChromeExtension.zip ./dist
# Create Firefox artifacts
- name: Create Firefox artifacts
run: npm run build:firefox
- uses: actions/upload-artifact@v1
- uses: actions/upload-artifact@v2
with:
name: FirefoxExtension
path: dist
- uses: montudor/action-zip@v0.1.0
- uses: montudor/action-zip@v1
with:
args: zip -qq -r ./builds/FirefoxExtension.zip ./dist
# Create Beta artifacts (Builds with the name changed to beta)
- name: Create Chrome Beta artifacts
run: npm run build:chrome -- --env.stream=beta
- uses: actions/upload-artifact@v1
run: npm run build:chrome -- --env stream=beta
- uses: actions/upload-artifact@v2
with:
name: ChromeExtensionBeta
path: dist
- uses: montudor/action-zip@v0.1.0
- uses: montudor/action-zip@v1
with:
args: zip -qq -r ./builds/ChromeExtensionBeta.zip ./dist
- name: Create Firefox Beta artifacts
run: npm run build:firefox -- --env.stream=beta
- uses: actions/upload-artifact@v1
run: npm run build:firefox -- --env stream=beta
- uses: actions/upload-artifact@v2
with:
name: FirefoxExtensionBeta
path: dist
- uses: montudor/action-zip@v0.1.0
- uses: montudor/action-zip@v1
with:
args: zip -qq -r ./builds/FirefoxExtensionBeta.zip ./dist

View File

@@ -12,67 +12,134 @@ jobs:
steps:
# Initialization
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
- run: npm install
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: '16'
- run: npm ci
- name: Copy configuration
run: cp config.json.example config.json
# Create Chrome artifacts
- name: Create Chrome artifacts
run: npm run build:chrome
- uses: actions/upload-artifact@v1
- uses: actions/upload-artifact@v2
with:
name: ChromeExtension
path: dist
- run: mkdir ./builds
- uses: montudor/action-zip@v0.1.0
with:
args: zip -qq -r ./builds/ChromeExtension.zip ./dist
- name: Zip Artifacts
run: cd ./dist ; zip -r ../builds/ChromeExtension.zip *
# Create Firefox artifacts
- name: Create Firefox artifacts
run: npm run build:firefox
- uses: actions/upload-artifact@v1
- uses: actions/upload-artifact@v2
with:
name: FirefoxExtension
path: dist
- uses: montudor/action-zip@v0.1.0
with:
args: zip -qq -r ./builds/FirefoxExtension.zip ./dist
- name: Zip Artifacts
run: cd ./dist ; zip -r ../builds/FirefoxExtension.zip *
# Create Beta artifacts (Builds with the name changed to beta)
- name: Create Chrome Beta artifacts
run: npm run build:chrome -- --env.stream=beta
- uses: actions/upload-artifact@v1
run: npm run build:chrome -- --env stream=beta
- uses: actions/upload-artifact@v2
with:
name: ChromeExtensionBeta
path: dist
- uses: montudor/action-zip@v0.1.0
with:
args: zip -qq -r ./builds/ChromeExtensionBeta.zip ./dist
- name: Zip Artifacts
run: cd ./dist ; zip -r ../builds/ChromeExtensionBeta.zip *
- name: Create Firefox Beta artifacts
run: npm run build:firefox -- --env.stream=beta
- uses: actions/upload-artifact@v1
# Create Safari artifacts
- name: Create Safari artifacts
run: npm run build:safari
- uses: actions/upload-artifact@v2
with:
name: FirefoxExtensionBeta
name: SafariExtension
path: dist
- uses: montudor/action-zip@v0.1.0
- name: Zip Artifacts
run: cd ./dist ; zip -r ../builds/SafariExtension.zip *
# Create Edge artifacts
- name: Clear dist for Edge
run: rm -rf ./dist
- name: Create Edge artifacts
run: npm run build:edge
- uses: actions/upload-artifact@v2
with:
args: zip -qq -r ./builds/FirefoxExtensionBeta.zip ./dist
name: EdgeExtension
path: dist
- name: Zip Artifacts
run: cd ./dist ; zip -r ../builds/EdgeExtension.zip *
# Upload each release asset
- name: Upload to release
- name: Upload ChromeExtension to release
uses: Shopify/upload-to-release@master
with:
args: builds/ChromeExtension.zip
name: ChromeExtension.zip
path: ./builds/ChromeExtension.zip
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Upload to release
- name: Upload ChromeExtensionBeta to release
uses: Shopify/upload-to-release@master
with:
args: builds/ChromeExtensionBeta.zip
name: ChromeExtensionBeta.zip
path: ./builds/ChromeExtensionBeta.zip
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Upload FirefoxExtension to release
uses: Shopify/upload-to-release@master
with:
args: builds/FirefoxExtension.zip
name: FirefoxExtension.zip
path: ./builds/FirefoxExtension.zip
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Upload SafariExtension to release
uses: Shopify/upload-to-release@master
with:
args: builds/SafariExtension.zip
name: SafariExtension.zip
path: ./builds/SafariExtension.zip
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Upload EdgeExtension to release
uses: Shopify/upload-to-release@master
with:
args: builds/EdgeExtension.zip
name: EdgeExtension.zip
path: ./builds/EdgeExtension.zip
repo-token: ${{ secrets.GITHUB_TOKEN }}
# Firefox Beta
- name: Create Firefox Beta artifacts
run: npm run build:firefox -- --env stream=beta
- uses: actions/upload-artifact@v2
with:
name: FirefoxExtensionBeta
path: dist
- name: Zip Artifacts
run: cd ./dist ; zip -r ../builds/FirefoxExtensionBeta.zip *
# Create Firefox Signed Beta version
- name: Create Firefox Signed Beta artifacts
run: npm run web-sign
env:
WEB_EXT_API_KEY: ${{ secrets.WEB_EXT_API_KEY }}
WEB_EXT_API_SECRET: ${{ secrets.WEB_EXT_API_SECRET }}
- name: Install rename
run: sudo apt-get install rename
- name: Rename signed file
run: cd ./web-ext-artifacts ; rename 's/.*/FirefoxSignedInstaller.xpi/' *
- uses: actions/upload-artifact@v2
with:
name: FirefoxExtensionSigned.xpi
path: ./web-ext-artifacts/FirefoxSignedInstaller.xpi
- name: Upload FirefoxSignedInstaller.xpi to release
uses: Shopify/upload-to-release@master
with:
args: web-ext-artifacts/FirefoxSignedInstaller.xpi
name: FirefoxSignedInstaller.xpi
path: ./web-ext-artifacts/FirefoxSignedInstaller.xpi
repo-token: ${{ secrets.GITHUB_TOKEN }}

14
.github/workflows/take-action.yml vendored Normal file
View File

@@ -0,0 +1,14 @@
# .github/workflows/take.yml
name: Assign issue to contributor
on:
issue_comment:
jobs:
assign:
name: Take an issue
runs-on: ubuntu-latest
steps:
- name: take the issue
uses: bdougie/take-action@main
env:
GITHUB_TOKEN: ${{ github.token }}

20
.github/workflows/tests.yml vendored Normal file
View File

@@ -0,0 +1,20 @@
name: Tests
on: [push, pull_request]
jobs:
build:
name: Run tests
runs-on: ubuntu-latest
steps:
# Initialization
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: '16'
- run: npm ci
- name: Run tests
run: npm run test-without-building

View File

@@ -0,0 +1,34 @@
name: update oss attributions
on:
push:
branches:
- master
paths:
- 'package.json'
- 'package-lock.json'
workflow_dispatch:
jobs:
update-oss:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: '16'
- name: Install and generate attribution
run: |
npm ci
npm i -g oss-attribution-generator
generate-attribution
mv ./oss-attribution/attribution.txt ./public/oss-attribution/attribution.txt
- name: Create pull request to update list
uses: peter-evans/create-pull-request@v3
with:
commit-message: Update OSS Attribution
author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
branch: ci/oss_attribution
title: Update OSS Attribution
body: Automated OSS Attribution update

28
.github/workflows/updateInvidous.yml vendored Normal file
View File

@@ -0,0 +1,28 @@
name: update invidious
on:
workflow_dispatch:
schedule:
- cron: '0 0 1 * *' # check every month
jobs:
check-list:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Download instance list
run: |
wget https://api.invidious.io/instances.json -O ci/data.json
- name: Install dependencies
run: npm ci
- name: "Run CI"
run: npm run ci:invidious
- name: Create pull request to update list
uses: peter-evans/create-pull-request@v3
with:
commit-message: Update Invidious List
author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
branch: ci/update_invidious_list
title: Update Invidious List
body: Automated Invidious list update

4
.gitignore vendored
View File

@@ -5,4 +5,6 @@ node_modules
web-ext-artifacts
.vscode/
dist/
tmp/
tmp/
.DS_Store
ci/data.json

1
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1 @@
If you make any contributions to SponsorBlock after this file was created, you are agreeing that any code you have contributed will be licensed under LGPL-3.0.

834
LICENSE
View File

@@ -1,679 +1,165 @@
SponsorBlock Copyright (C) 2019 Ajay Ramachandran and other SponsorBlock contributors.
Please refer to the license below.
GNU GENERAL PUBLIC LICENSE
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

View File

@@ -1,6 +1,6 @@
<p align="center">
<a href="https://sponsor.ajay.app"><img src="public/icons/LogoSponsorBlocker256px.png" alt="Logo"></img></a>
<br/>
<sub>Logo by <a href="https://github.com/munadikieh">@munadikieh</a></sub>
</p>
@@ -11,28 +11,36 @@
<b>Download:</b>
<a href="https://chrome.google.com/webstore/detail/mnjggcdmjocbbbhaepdhchncahnbgone">Chrome/Chromium</a> |
<a href="https://addons.mozilla.org/addon/sponsorblock/?src=external-github">Firefox</a> |
<a href="https://github.com/ajayyy/SponsorBlock/wiki/Android">Android</a> |
<a href="https://github.com/ajayyy/SponsorBlock/wiki/Edge">Edge</a> |
<a href="https://github.com/ajayyy/SponsorBlock/wiki/Safari">Safari for MacOS</a> |
<a href="https://sponsor.ajay.app">Website</a> |
<a href="https://sponsor.ajay.app/stats">Stats</a>
</p>
<p align="center">
<b>Unofficial Ports:</b>
<a href="https://github.com/ajayyy/SponsorBlock/wiki/Unofficial-Ports#mpv-media-player">MPV</a>
<b>3rd-Party Ports:</b>
<a href="https://github.com/ajayyy/SponsorBlock/wiki/3rd-Party-Ports#mpv-media-player">MPV</a> |
<a href="https://github.com/ajayyy/SponsorBlock/wiki/3rd-Party-Ports#kodi">Kodi</a> |
<a href="https://github.com/ajayyy/SponsorBlock/wiki/3rd-Party-Ports#Chromecast">Chromecast</a> |
<a href="https://github.com/ajayyy/SponsorBlock/wiki/3rd-Party-Ports#ios">iOS</a>
</p>
<p align="center">
<a href="https://addons.mozilla.org/addon/sponsorblock/?src=external-github"><img src="https://img.shields.io/amo/users/sponsorblock?label=Firefox%20Users" alt="Badge"></img></a>
<a href="https://chrome.google.com/webstore/detail/mnjggcdmjocbbbhaepdhchncahnbgone"><img src="https://img.shields.io/chrome-web-store/users/mnjggcdmjocbbbhaepdhchncahnbgone?label=Chome%20Users" alt="Badge"></img></a>
<a href="https://sponsor.ajay.app/stats"><img src="https://img.shields.io/badge/dynamic/json?label=Sponsors%20Submitted&query=totalSubmissions&suffix=%20sponsors&url=http%3A%2F%2Fsponsor.ajay.app%2Fapi%2FgetTotalStats&color=darkred" alt="Badge"></img></a>
<a href="https://sponsor.ajay.app/stats"><img src="https://img.shields.io/badge/dynamic/json?label=Contributing%20Users&query=userCount&url=http%3A%2F%2Fsponsor.ajay.app%2Fapi%2FgetTotalStats&color=darkblue" alt="Badge"></img></a>
<a href="https://chrome.google.com/webstore/detail/mnjggcdmjocbbbhaepdhchncahnbgone"><img src="https://img.shields.io/chrome-web-store/users/mnjggcdmjocbbbhaepdhchncahnbgone?label=Chrome%20Users" alt="Badge"></img></a>
<a href="https://sponsor.ajay.app/stats"><img src="https://img.shields.io/badge/dynamic/json?label=Submissions&query=totalSubmissions&suffix=%20segments&url=http%3A%2F%2Fsponsor.ajay.app%2Fapi%2FgetTotalStats&color=darkred" alt="Badge"></img></a>
<a href="https://sponsor.ajay.app/stats"><img src="https://img.shields.io/badge/dynamic/json?label=Active%20Users&query=apiUsers&url=http%3A%2F%2Fsponsor.ajay.app%2Fapi%2FgetTotalStats&color=darkblue" alt="Badge"></img></a>
<a href="https://sponsor.ajay.app/stats"><img src="https://img.shields.io/badge/dynamic/json?label=Time%20Saved%20From%20Skips&query=daysSaved&url=http%3A%2F%2Fsponsor.ajay.app%2Fapi%2FgetDaysSavedFormatted&color=darkgreen&suffix=%20days" alt="Badge"></img></a>
</p>
SponsorBlock is an extension that will skip over sponsored segments of YouTube videos. SponsorBlock is a crowdsourced browser extension that lets anyone submit the start and end times of sponsored segments of YouTube videos. Once one person submits this information, everyone else with this extension will skip right over the sponsored segment.
SponsorBlock is an open-source crowdsourced browser extension to skip sponsor segments in YouTube videos. Users submit when a sponsor happens from the extension, and the extension automatically skips sponsors it knows about. It also supports skipping other categories, such as intros, outros and reminders to subscribe.
Also support Invidio.us.
It also supports Invidio.us.
**Translate:** [![Crowdin](https://badges.crowdin.net/sponsorblock/localized.svg)](https://crowdin.com/project/sponsorblock)
# Important Links
@@ -42,38 +50,50 @@ See the [Wiki](https://github.com/ajayyy/SponsorBlock/wiki) for important links.
The backend server code is available here: https://github.com/ajayyy/SponsorBlockServer
It is a simple SQLite database that will hold all the timing data.
To make sure that this project doesn't die, I have made the database publicly downloadable at https://sponsor.ajay.app/database ([License](https://github.com/ajayyy/SponsorBlock/wiki/Database-and-API-License)). If you are planning on using the database in another project, please read the [API Docs](https://wiki.sponsor.ajay.app/index.php/API_Docs) page for more information.
To make sure that this project doesn't die, I have made the database publicly downloadable at https://sponsor.ajay.app/database.db. If you are planning on using the database in another project, please read the [API Docs](https://github.com/ajayyy/SponsorBlock/wiki/API-Docs) page for more information.
The dataset and API are now being used in some [ports](https://github.com/ajayyy/SponsorBlock/wiki/Unofficial-Ports) as well as a [neural network](https://github.com/andrewzlee/NeuralBlock).
A [previous project](https://github.com/Sponsoff/sponsorship_remover) attempted to create a neural network to predict when sponsored segments happen. That project is sadly abandoned now, so I have decided to attempt to revive this idea starting from a crowd-sourced system instead.
The dataset and API are now being used in some [ports](https://github.com/ajayyy/SponsorBlock/wiki/3rd-Party-Ports) as well as a [neural network](https://github.com/andrewzlee/NeuralBlock).
# API
You can read the API docs [here](https://github.com/ajayyy/SponsorBlockServer#api-docs).
You can read the API docs [here](https://wiki.sponsor.ajay.app/index.php/API_Docs).
# Building
There are also other build scripts available. Install `npm`, then run `npm install` in the repository to install dependencies.
You must have [Node.js 16](https://nodejs.org/) and npm installed.
Run `npm run build` to generate a Chrome extension.
1. Copy the file `config.json.example` to `config.json` and adjust configuration as desired.
Use `npm run build:firefox` to generate a Firefox extension.
- You will need to repeat this step in the future if you get build errors related to `CompileConfig`. This can happen for example when a new category is added.
The result is in `dist`. This can be loaded as an unpacked extension
2. Run `npm install` in the repository to install dependencies.
## Developing with a clean profile
3. Run `npm run build:dev` (for Chrome) or `npm run build:dev:firefox` (for Firefox) to generate a development version of the extension with source maps.
Run `npm run dev` to run the extension using a clean browser profile with hot reloading. Use `npm run dev:firefox` for Firefox. This uses [`web-ext run`](https://extensionworkshop.com/documentation/develop/web-ext-command-reference/#commands).
- You can also run `npm run build` (for Chrome) or `npm run build:firefox` (for Firefox) to generate a production build.
4. The built extension is now in `dist/`. You can load this folder directly in Chrome as an [unpacked extension](https://developer.chrome.com/docs/extensions/mv3/getstarted/#manifest), or convert it to a zip file to load it as a [temporary extension](https://developer.mozilla.org/en-US/docs/Tools/about:debugging#loading_a_temporary_extension) in Firefox.
### Developing with a clean profile and hot reloading
Run `npm run dev` (for Chrome) or `npm run dev:firefox` (for Firefox) to run the extension using a clean browser profile with hot reloading. This uses [`web-ext run`](https://extensionworkshop.com/documentation/develop/web-ext-command-reference/#commands).
Known chromium bug: Extension is not loaded properly on first start. Visit `chrome://extensions/` and reload the extension.
For Firefox for Android, use `npm run dev:firefox-android -- --adb-device <ip-address of the device>`. See the [Firefox documentation](https://extensionworkshop.com/documentation/develop/developing-extensions-for-firefox-for-android/#debug-your-extension) for more information.
# Credit
The awesome [Invidious API](https://github.com/omarroth/invidious/wiki/API) was previously used.
The awesome [Invidious API](https://docs.invidious.io/API.md) was previously used, and the server is now using [NewLeaf](https://git.sr.ht/~cadence/NewLeaf) as a to get video info from YouTube.
Originally forked from [YTSponsorSkip](https://github.com/OfficialNoob/YTSponsorSkip), but zero code remains.
Originally forked from [YTSponsorSkip](https://github.com/NDevTK/YTSponsorSkip), but very little code remains.
Some icons made by <a href="https://www.flaticon.com/authors/gregor-cresnar" title="Gregor Cresnar">Gregor Cresnar</a> from <a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a> and are licensed by <a href="http://creativecommons.org/licenses/by/3.0/" title="Creative Commons BY 3.0" target="_blank">CC 3.0 BY</a>
Icons made by:
* <a href="https://www.flaticon.com/authors/gregor-cresnar" title="Gregor Cresnar">Gregor Cresnar</a> from <a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a> and are licensed by <a href="https://creativecommons.org/licenses/by/3.0/" title="Creative Commons BY 3.0" target="_blank">CC 3.0 BY</a>
* <a href="https://www.flaticon.com/authors/freepik" title="Freepik">Freepik</a> from <a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a> and are licensed by <a href="https://creativecommons.org/licenses/by/3.0/" title="Creative Commons BY 3.0" target="_blank">CC 3.0 BY</a>
* <a href="https://iconmonstr.com/about/#creator">Alexander Kahlkopf</a> from <a href="https://iconmonstr.com/">iconmonstr.com</a> and are licensed by <a href="https://iconmonstr.com/license/">iconmonstr License</a>
Some icons made by <a href="https://www.flaticon.com/authors/freepik" title="Freepik">Freepik</a> from <a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a> are licensed by <a href="http://creativecommons.org/licenses/by/3.0/" title="Creative Commons BY 3.0" target="_blank">CC 3.0 BY</a>
### License
This project is licensed under GNU LGPL v3 or any later version

55
ci/invidiousCI.ts Normal file
View File

@@ -0,0 +1,55 @@
/*
This file is only ran by GitHub Actions in order to populate the Invidious instances list
This file should not be shipped with the extension
*/
import { writeFile, existsSync } from 'fs';
import { join } from 'path';
// import file from https://api.invidious.io/instances.json
if (!existsSync(join(__dirname, "data.json"))) {
process.exit(1);
}
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
import * as data from "../ci/data.json";
type instanceMap = {
name: string,
url: string,
dailyRatios: {ratio: string, label: string }[],
thirtyDayUptime: string
}[]
// only https servers
const mapped: instanceMap = data
// eslint-disable-next-line @typescript-eslint/no-explicit-any
.filter((i: any) => i[1]?.type === 'https')
// eslint-disable-next-line @typescript-eslint/no-explicit-any
.map((instance: any) => {
return {
name: instance[0],
url: instance[1].uri,
dailyRatios: instance[1].monitor.dailyRatios,
thirtyDayUptime: instance[1]?.monitor['30dRatio'].ratio,
}
})
// reliability and sanity checks
const reliableCheck = mapped
.filter((instance) => {
// 30d uptime >= 90%
const thirtyDayUptime = Number(instance.thirtyDayUptime) >= 90
// available for at least 80/90 days
const dailyRatioCheck = instance.dailyRatios.filter(status => status.label !== "black")
return (thirtyDayUptime && dailyRatioCheck.length >= 80)
})
// url includes name
.filter(instance => instance.url.includes(instance.name))
// finally map to array
const result: string[] = reliableCheck.map(instance => instance.name)
writeFile(join(__dirname, "./invidiouslist.json"), JSON.stringify(result), (err) => {
if (err) return console.log(err);
})

1
ci/invidiouslist.json Normal file
View File

@@ -0,0 +1 @@
["yewtu.be","invidious.snopyta.org","vid.puffyan.us","invidious.kavin.rocks","invidio.xamh.de","inv.riverside.rocks","invidious-us.kavin.rocks","invidious.osi.kr","tube.cthd.icu","yt.artemislena.eu","youtube.076.ne.jp","invidious.namazso.eu"]

View File

@@ -1,6 +1,32 @@
{
"serverAddress": "https://sponsor.ajay.app",
"testingServerAddress": "https://sponsor.ajay.app/test",
"serverAddressComment": "This specifies the default SponsorBlock server to conect to",
"categoryList": ["sponsor", "intro", "outro", "interaction", "selfpromo", "offtopic"]
"serverAddressComment": "This specifies the default SponsorBlock server to connect to",
"categoryList": ["sponsor", "selfpromo", "exclusive_access", "interaction", "poi_highlight", "intro", "outro", "preview", "filler", "music_offtopic"],
"categorySupport": {
"sponsor": ["skip", "mute", "full"],
"selfpromo": ["skip", "mute", "full"],
"exclusive_access": ["full"],
"interaction": ["skip", "mute"],
"intro": ["skip", "mute"],
"outro": ["skip", "mute"],
"preview": ["skip", "mute"],
"filler": ["skip", "mute"],
"music_offtopic": ["skip"],
"poi_highlight": ["poi"]
},
"wikiLinks": {
"sponsor": "https://wiki.sponsor.ajay.app/w/Sponsor",
"selfpromo": "https://wiki.sponsor.ajay.app/w/Unpaid/Self_Promotion",
"exclusive_access": "https://wiki.sponsor.ajay.app/w/Exclusive_Access",
"interaction": "https://wiki.sponsor.ajay.app/w/Interaction_Reminder_(Subscribe)",
"intro": "https://wiki.sponsor.ajay.app/w/Intermission/Intro_Animation",
"outro": "https://wiki.sponsor.ajay.app/w/Endcards/Credits",
"preview": "https://wiki.sponsor.ajay.app/w/Preview/Recap",
"filler": "https://wiki.sponsor.ajay.app/w/Filler_Tangent",
"music_offtopic": "https://wiki.sponsor.ajay.app/w/Music:_Non-Music_Section",
"poi_highlight": "https://wiki.sponsor.ajay.app/w/Highlight",
"guidelines": "https://wiki.sponsor.ajay.app/w/Guidelines",
"mute": "https://wiki.sponsor.ajay.app/w/Mute_Segment"
}
}

View File

@@ -1,10 +1,3 @@
files:
- source: /_locales/en/*
translation: /_locales/%two_letters_code%/%original_file_name%
languages_mapping:
two_letters_code:
pl-PL: "pl_PL"
pr-BR: "pt_BR"
pr-PT: "pt_PT"
zh-CN: "zh_CH"
zh-TW: "zh_TW"
- source: /public/_locales/en/*
translation: /public/_locales/%two_letters_code%/%original_file_name%

View File

@@ -1,6 +1,6 @@
module.exports = {
"roots": [
"src"
"test"
],
"transform": {
"^.+\\.ts$": "ts-jest"

View File

@@ -1,7 +1,7 @@
{
"browser_specific_settings": {
"gecko": {
"id": "sponsorBlocker@ajay.app"
"id": "sponsorLockAprilFools@ajay.app"
}
}
}

View File

@@ -1,9 +1,10 @@
{
"name": "__MSG_fullName__",
"short_name": "__MSG_Name__",
"version": "1.2.25",
"name": "SponsorLock - Give Back Control!",
"short_name": "SponsorLock",
"version": "4.2.1",
"default_locale": "en",
"description": "__MSG_Description__",
"description": "SponsorLock only shows you promotion, and skips all useful informaton.",
"homepage_url": "https://sponsor.ajay.app",
"content_scripts": [{
"run_at": "document_start",
"matches": [
@@ -24,30 +25,45 @@
"web_accessible_resources": [
"icons/LogoSponsorBlocker256px.png",
"icons/IconSponsorBlocker256px.png",
"icons/PlayerStartIconSponsorBlocker256px.png",
"icons/PlayerStopIconSponsorBlocker256px.png",
"icons/PlayerUploadIconSponsorBlocker256px.png",
"icons/PlayerUploadFailedIconSponsorBlocker256px.png",
"icons/PlayerStartIconSponsorBlocker.svg",
"icons/PlayerStopIconSponsorBlocker.svg",
"icons/PlayerUploadIconSponsorBlocker.svg",
"icons/PlayerUploadFailedIconSponsorBlocker.svg",
"icons/PlayerCancelSegmentIconSponsorBlocker.svg",
"icons/clipboard.svg",
"icons/settings.svg",
"icons/pencil.svg",
"icons/check.svg",
"icons/upvote.png",
"icons/downvote.png",
"icons/thumbs_down.svg",
"icons/thumbs_down_locked.svg",
"icons/thumbs_up.svg",
"icons/help.svg",
"icons/report.png",
"icons/close.png",
"icons/skipIcon.svg",
"icons/refresh.svg",
"icons/beep.ogg",
"icons/PlayerInfoIconSponsorBlocker256px.png",
"icons/PlayerDeleteIconSponsorBlocker256px.png",
"icons/pause.svg",
"icons/stop.svg",
"icons/heart.svg",
"icons/visible.svg",
"icons/not_visible.svg",
"icons/PlayerInfoIconSponsorBlocker.svg",
"icons/PlayerDeleteIconSponsorBlocker.svg",
"popup.html",
"content.css"
],
"permissions": [
"storage",
"notifications",
"https://sponsor.ajay.app/*"
],
"optional_permissions": [
"*://*/*"
],
"browser_action": {
"default_title": "__MSG_Name__",
"default_title": "SponsorBlock",
"default_popup": "popup.html"
},
"background": {
@@ -57,14 +73,16 @@
]
},
"icons": {
"16": "icons/IconSponsorBlocker16px.png",
"32": "icons/IconSponsorBlocker32px.png",
"16": "icons/LogoSponsorBlocker64px.png",
"32": "icons/LogoSponsorBlocker64px.png",
"64": "icons/LogoSponsorBlocker64px.png",
"128": "icons/LogoSponsorBlocker128px.png",
"256": "icons/LogoSponsorBlocker256px.png"
"256": "icons/LogoSponsorBlocker256px.png",
"512": "icons/LogoSponsorBlocker512px.png",
"1024": "icons/LogoSponsorBlocker1024px.png"
},
"options_ui": {
"page": "options/options.html",
"page": "options/lock-options.html",
"open_in_tab": true
},
"manifest_version": 2

View File

@@ -0,0 +1,5 @@
{
"background": {
"persistent": false
}
}

File diff suppressed because one or more lines are too long

31733
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -4,55 +4,85 @@
"description": "",
"main": "background.js",
"dependencies": {
"@types/react": "^16.9.22",
"@types/react-dom": "^16.9.5",
"babel": "^6.23.0",
"babel-core": "^6.26.3",
"babel-loader": "^8.0.6",
"babel-preset-env": "^1.7.0",
"concurrently": "^5.1.0",
"react": "^16.12.0",
"react-dom": "^16.12.0"
"react": "^17.0.2",
"react-dom": "^17.0.2"
},
"devDependencies": {
"web-ext": "^4.0.0",
"@types/chrome": "0.0.91",
"@types/firefox-webext-browser": "70.0.1",
"@types/jest": "^24.0.23",
"@types/jquery": "^3.3.31",
"copy-webpack-plugin": "^5.0.5",
"jest": "^24.9.0",
"ts-jest": "^24.2.0",
"rimraf": "^3.0.0",
"ts-loader": "^6.2.1",
"typescript": "~3.7.3",
"webpack": "~4.41.2",
"webpack-cli": "~3.3.10",
"webpack-merge": "~4.2.2"
"@types/chrome": "^0.0.178",
"@types/firefox-webext-browser": "^94.0.1",
"@types/jest": "^27.4.0",
"@types/wicg-mediasession": "^1.1.3",
"@types/react": "^17.0.39",
"@types/react-dom": "^17.0.11",
"@types/selenium-webdriver": "^4.0.17",
"@typescript-eslint/eslint-plugin": "^5.10.2",
"@typescript-eslint/parser": "^5.10.2",
"chromedriver": "^97.0.4",
"concurrently": "^7.0.0",
"copy-webpack-plugin": "^10.2.4",
"eslint": "^8.8.0",
"eslint-plugin-react": "^7.28.0",
"jest": "^27.5.0",
"rimraf": "^3.0.2",
"schema-utils": "^4.0.0",
"selenium-webdriver": "^4.1.1",
"ts-jest": "^27.1.3",
"ts-loader": "^9.2.6",
"ts-node": "^10.4.0",
"typescript": "4.5",
"web-ext": "^6.6.0",
"webpack": "^5.68.0",
"webpack-cli": "^4.9.2",
"webpack-merge": "^4.2.2"
},
"scripts": {
"web-run": "npm run web-run:chrome",
"web-sign": "web-ext sign -s dist",
"web-run:firefox": "cd dist && web-ext run --start-url https://addons.mozilla.org/firefox/addon/ublock-origin/",
"web-run:firefox-android": "cd dist && web-ext run -t firefox-android --firefox-apk org.mozilla.fenix",
"web-run:chrome": "cd dist && web-ext run --start-url https://chrome.google.com/webstore/detail/ublock-origin/cjpalhdlnbpafiamejdnhcphjbkeiagm -t chromium",
"build": "npm run build:chrome",
"build:chrome": "webpack --env.browser=chrome --config webpack/webpack.prod.js",
"build:firefox": "webpack --env.browser=firefox --config webpack/webpack.prod.js",
"build:chrome": "webpack --env browser=chrome --config webpack/webpack.prod.js",
"build:firefox": "webpack --env browser=firefox --config webpack/webpack.prod.js",
"build:safari": "webpack --env browser=safari --config webpack/webpack.prod.js",
"build:edge": "webpack --env browser=edge --config webpack/webpack.prod.js",
"build:dev": "npm run build:dev:chrome",
"build:dev:chrome": "webpack --env.browser=chrome --config webpack/webpack.dev.js",
"build:dev:firefox": "webpack --env.browser=firefox --config webpack/webpack.dev.js",
"build:dev:chrome": "webpack --env browser=chrome --config webpack/webpack.dev.js",
"build:dev:firefox": "webpack --env browser=firefox --config webpack/webpack.dev.js",
"build:watch": "npm run build:watch:chrome",
"build:watch:chrome": "webpack --env.browser=chrome --config webpack/webpack.dev.js --watch",
"build:watch:firefox": "webpack --env.browser=firefox --config webpack/webpack.dev.js --watch",
"build:watch:chrome": "webpack --env browser=chrome --config webpack/webpack.dev.js --watch",
"build:watch:firefox": "webpack --env browser=firefox --config webpack/webpack.dev.js --watch",
"ci:invidious": "ts-node ci/invidiousCI.ts",
"dev": "npm run build:dev && concurrently \"npm run web-run\" \"npm run build:watch\"",
"dev:firefox": "npm run build:dev:firefox && concurrently \"npm run web-run:firefox\" \"npm run build:watch:firefox\"",
"dev:firefox-android": "npm run build:dev:firefox && concurrently \"npm run web-run:firefox-android\" \"npm run build:watch:firefox\"",
"clean": "rimraf dist",
"test": "npx jest"
"test": "npm run build:chrome && npx jest",
"test-without-building": "npx jest",
"lint": "eslint src",
"lint:fix": "eslint src --fix"
},
"engines": {
"node": ">=12.20.0"
},
"funding": [{
"type": "individual",
"url": "hhttps://sponsor.ajay.app/donate"
}, {
"type": "github",
"url": "https://github.com/sponsors/ajayyy-org"
}, {
"type": "patreon",
"url": "https://www.patreon.com/ajayyy"
}, {
"type": "individual",
"url": "https://paypal.me/ajayyy"
}],
"repository": {
"type": "git",
"url": "git+https://github.com/ajayyy/SponsorBlock.git"
},
"author": "Ajay Ramachandran",
"license": "GPL-3.0-only",
"license": "LGPL-3.0-or-later",
"private": true
}

View File

@@ -1,318 +0,0 @@
{
"Name": {
"message": "SponsorBlock",
"description": "Name of the extension."
},
"fullName": {
"message": "SponsorBlock for YouTube - Skip Sponsorships",
"description": "Name of the extension."
},
"Description": {
"message": "Überspringe die gesponserten Inhalte in YouTube-Videos. Melde gesponsorte Inhalte in den von dir angesehenen Videos und erspare anderen die Zeit.",
"description": "Description of the extension."
},
"helpPage": {
"message": "index_en.html"
},
"400": {
"message": "Ungültige Anforderung"
},
"429": {
"message": "Du hast zu viele Segmente in diesem Video eingereicht. Bist du dir sicher?"
},
"409": {
"message": "Dieser Inhalt wurde bereits eingereicht."
},
"channelWhitelisted": {
"message": "Kanal auf Whitelist gesetzt!"
},
"Sponsor": {
"message": "Sponsor"
},
"Sponsors": {
"message": "Sponsoren"
},
"Segment": {
"message": "gesponsorter Inhalt"
},
"Segments": {
"message": "gesponsorte Inhalte"
},
"noticeTitle": {
"message": "Sponsor übersprungen"
},
"reportButtonTitle": {
"message": "Melden"
},
"reportButtonInfo": {
"message": "Melde dieses Segment als unzulässig."
},
"Dismiss": {
"message": "Abbrechen"
},
"Loading": {
"message": "Laden..."
},
"Mins": {
"message": "Minuten"
},
"Secs": {
"message": "Sekunden"
},
"Hide": {
"message": "Verstecken"
},
"hitGoBack": {
"message": "Klicke Zurück um die Aktion rückgängig zu machen."
},
"unskip": {
"message": "Zurück"
},
"reskip": {
"message": "Vorwärts"
},
"paused": {
"message": "Pausiert"
},
"confirmMSG": {
"message": "\n\nUm einzelne Werte zu löschen oder zu ändern, klicke auf den Info-Button, oder öffne die Erweiterungs-Übersicht, indem du das Erweiterungssymbol in der rechten oberen Ecke anklickst."
},
"clearThis": {
"message": "Bist du sicher, dass du Folgendes löschen möchtest?\n\n"
},
"Unknown": {
"message": "Deine Segmente konnten nicht gesendet werden, bitte versuche es später erneut."
},
"sponsorFound": {
"message": "Die gesponsorten Inhalte dieses Videos befinden sich bereits in der Datenbank!"
},
"sponsor404": {
"message": "Keine Sponsoren gefunden"
},
"sponsorStart": {
"message": "Gesponserter Inhalt beginnt"
},
"sponsorEnd": {
"message": "Gesponserter Inhalt endet"
},
"noVideoID": {
"message": "Keine YouTube-Videos in diesem Tab gefunden. Wenn dies ein Youtube-Tab ist, schließe dieses Pop-up und öffne es erneut. Wenn das nicht hilft, versuche den Tab neu zu laden."
},
"success": {
"message": "Erfolg!"
},
"voted": {
"message": "Abgestimmt!"
},
"voteFail": {
"message": "Du hast bereits so abgestimmt."
},
"serverDown": {
"message": "Der Server ist scheinbar offline. Bitte unverzüglich dem Entwickler melden."
},
"connectionError": {
"message": "Ein Verbindungsfehler ist aufgetreten. Fehlermeldung: "
},
"wantToSubmit": {
"message": "Möchtest du die Segmente für die Video ID senden?"
},
"leftTimes": {
"message": "Scheinbar hast du einige Segmente noch nicht gesendet. Kehre zur Seite zurück um sie zu senden (sie sind noch gespeichert)."
},
"clearTimes": {
"message": "Lösche Auswahl"
},
"openPopup": {
"message": "Öffne SponsorBlock-Popup"
},
"SubmitTimes": {
"message": "Sende Auswahl"
},
"submitCheck": {
"message": "Bist du sicher, dass die Auswahl abgeschickt werden soll?"
},
"whitelistChannel": {
"message": "Kanal auf Whitelist setzen "
},
"removeFromWhitelist": {
"message": "Kanal von Whitelist entfernen"
},
"voteOnTime": {
"message": "Stimme für Zeiten ab"
},
"recordTimes": {
"message": "Lege das Zeitfenster eines gesponsorten Inhalts fest"
},
"soFarUHSubmited": {
"message": "Gemeldet wurden von dir bisher"
},
"savedPeopleFrom": {
"message": "Du hast andere Benutzer bewahrt vor"
},
"viewLeaderboard": {
"message": "Siehe Rangliste"
},
"here": {
"message": "hier"
},
"recordTimesDescription": {
"message": "Klicke den Knopf unten, wenn der gesponsorte Inhalt beginnt und endet, um aufzunehmen und\n einzusenden"
},
"popupHint": {
"message": "Hinweis: In den Optionen lässt sich eine Taste für das Festlegen von Anfang/Ende des gesponsorten Inhalts, sowie für das Einsenden festlegen"
},
"lastTimes": {
"message": "Letzte ausgewählte Zeitabschnitte"
},
"clearTimesButton": {
"message": "Zeiten löschen"
},
"submitTimesButton": {
"message": "Zeiten einsenden"
},
"publicStats": {
"message": "Dies ist wichtig für die öffentliche Nutzerstatistik. Siehe"
},
"setUsername": {
"message": "Alias festlegen"
},
"discordAdvert": {
"message": "Tritt dem offiziellen Discord-Kanal bei und teile Anregungen und Feedback!"
},
"hideThis": {
"message": "Verstecken"
},
"Options": {
"message": "Optionen"
},
"showButtons": {
"message": "Knöpfe in YouTube-Leiste zeigen"
},
"hideButtons": {
"message": "Knöpfe in YouTube-Leiste verstecken"
},
"hideButtonsDescription": {
"message": "Die Einstellung versteckt den Einsende-Knopf in der Youtube-Leiste. Ich kann verstehen, weshalb manchen diese Funktion\n an dieser Stelle stört. Stattdessen kann dafür dieses Pop-up genutzt werden. Um die transparente Benachrichtigung zu verstecken, klicke auf den \"Verstecken\"-Knopf \n der Benachrichtigung. Diese Einstellungen können wieder rückgängig gemacht werden."
},
"showInfoButton": {
"message": "Zeige Info-Knopf in Youtube-Leiste"
},
"hideInfoButton": {
"message": "Verstecke Info-Knopf in Youtube-Leiste"
},
"whatInfoButton": {
"message": "Dieser Knopf öffnet ein Pop-up auf der Youtube-Seite."
},
"hideDeleteButton": {
"message": "Verstecke Löschen-Knopf in Youtube Leiste"
},
"showDeleteButton": {
"message": "Zeige Löschen-Knopf in Youtube Leiste"
},
"whatDeleteButton": {
"message": "Dieser Knopf entfernt sämtlich Segmente in der Youtube-Zeitleiste."
},
"disableViewTracking": {
"message": "Deaktiviere das Mitzählen übersprungener Sponsoren"
},
"enableViewTracking": {
"message": "Aktiviere das Mitzählen übersprungener Sponsoren"
},
"whatViewTracking": {
"message": "Diese Funktion hält fest, welche Sponsoren von dir übersprungen wurden und hilft anderen zu erfahren, was ihre Einsendungen bewirkt haben.\n Außerdem dienen die Werte zusammen mit positiven Rückmeldungen als Anti-Spam-Schutz. \n Wenn ein gesponsorter Inhalt übersprungen wird, sendet die Erweiterung eine Nachricht an den Server. \n Hoffentlich wird diese Funktion auch weiterhin genutzt, damit der Algorithmus funktioniert. :)"
},
"showNotice": {
"message": "Benachrichtigung wieder zeigen"
},
"longDescription": {
"message": "SponsorBlock ist eine Erweiterung, die gesponsorte Segmente in YouTube-Videos überspringt. SponsorBlock ist ein Benutzernetzwerk, bei dem jeder Anfang und Ende eines Werbeblocks einreichen kann. Sobald die Information von einem Nutzer eingereicht wurde, überspringen die Erweiterungen der anderen dieses Segment automatisch.",
"description": "Full description of the extension on the store pages."
},
"website": {
"message": "Webseite",
"description": "Used on Firefox Store Page"
},
"sourceCode": {
"message": "Quellcode",
"description": "Used on Firefox Store Page"
},
"noticeUpdate": {
"message": "Die Benachrichtigung wurde verbessert!",
"description": "The first line of the message displayed after the notice was upgraded."
},
"noticeUpdate2": {
"message": "Gefällt dir immer noch nicht? Dann klicke den Verstecken-Knopf.",
"description": "The second line of the message displayed after the notice was upgraded."
},
"setStartSponsorShortcut": {
"message": "Segment aufnehmen Taste festlegen"
},
"setSubmitKeybind": {
"message": "Segment einsenden Taste festlegen"
},
"keybindDescription": {
"message": "Taste drücken, um festzulegen"
},
"keybindDescriptionComplete": {
"message": "Die Taste wurde festgelegt auf: "
},
"0": {
"message": "Verbindungsüberschreibung. Überprüfe deine Internetverbindung. Bist du mit dem Internet verbunden, ist der Server wahrscheinlich offline."
},
"disableSkipping": {
"message": "SponsorBlock ausschalten"
},
"enableSkipping": {
"message": "SponsorBlock einschalten"
},
"yourWork": {
"message": "Deine Statistik",
"description": "Used to describe the section that will show you the statistics from your submissions."
},
"502": {
"message": "Der Server scheint überlastet zu sein. Probiere es in ein paar Sekunden erneut."
},
"errorCode": {
"message": "Fehlermeldung: "
},
"noticeTitleNotSkipped": {
"message": "Sponsor überspringen?"
},
"skip": {
"message": "Überspringen"
},
"disableAutoSkip": {
"message": "Auto-Überspringen deaktivieren"
},
"enableAutoSkip": {
"message": "Auto-Überspringen aktivieren"
},
"autoSkipDescription": {
"message": "Auto-Überspringen überspringt gesponsorte Inhalte für dich. Wenn deaktiviert, fragt die Benachrichtigung, ob übersprungen werden soll."
},
"youHaveSkipped": {
"message": "Du übersprangst "
},
"youHaveSaved": {
"message": "Du erspartest dir "
},
"minLower": {
"message": "Minute"
},
"minsLower": {
"message": "Minuten"
},
"hourLower": {
"message": "Stunde"
},
"hoursLower": {
"message": "Stunden"
},
"youHaveSavedTime": {
"message": "Du erspartest anderen"
},
"youHaveSavedTimeEnd": {
"message": " ihrer Zeit."
}
}

View File

@@ -1,20 +1,12 @@
{
"Name": {
"message": "SponsorBlock",
"description": "Name of the extension."
},
"fullName": {
"message": "SponsorBlock for YouTube - Skip Sponsorships",
"description": "Name of the extension."
},
"Description": {
"message": "Skip over sponsorship on YouTube videos. Report sponsors on videos you watch to save the time of others.",
"message": "Skip sponsorships, subscription begging and more on YouTube videos. Report sponsors on videos you watch to save others' time.",
"description": "Description of the extension."
},
"helpPage": {
"message": "index_en.html"
},
"400": {
"message": "Server said this request was invalid"
},
@@ -27,26 +19,20 @@
"channelWhitelisted": {
"message": "Channel Whitelisted!"
},
"Sponsor": {
"message": "sponsor"
},
"Sponsors": {
"message": "sponsors"
},
"Segment": {
"message": "sponsor segment"
"Segment": {
"message": "segment"
},
"Segments": {
"message": "sponsor segments"
"message": "segments"
},
"noticeTitle": {
"message": "Sponsor Skipped"
"upvoteButtonInfo": {
"message": "Upvote this submission"
},
"reportButtonTitle": {
"message": "Report"
},
"reportButtonInfo": {
"message": "Report this sponsor submission as incorrect."
"message": "Report this submission as incorrect."
},
"Dismiss": {
"message": "Dismiss"
@@ -54,12 +40,6 @@
"Loading": {
"message": "Loading..."
},
"Mins": {
"message": "Minutes"
},
"Secs": {
"message": "Seconds"
},
"Hide": {
"message": "Never Show"
},
@@ -72,9 +52,15 @@
"reskip": {
"message": "Reskip"
},
"unmute": {
"message": "Unmute"
},
"paused": {
"message": "Paused"
},
"manualPaused": {
"message": "Timer Stopped"
},
"confirmMSG": {
"message": "To edit or delete individual values, click the info button or open the extension popup by clicking the extension icon in the top right corner."
},
@@ -85,19 +71,25 @@
"message": "There was an error submitting your sponsor times, please try again later."
},
"sponsorFound": {
"message": "This video's sponsors are in the database!"
"message": "This video has segments in the database!"
},
"sponsor404": {
"message": "No sponsors found"
"message": "No segments found"
},
"sponsorStart": {
"message": "Sponsorship Starts Now"
"message": "Segment Starts Now"
},
"sponsorEnd": {
"message": "Sponsorship Ends Now"
"message": "Segment Ends Now"
},
"sponsorCancel": {
"message": "Cancel Creating Segment"
},
"noVideoID": {
"message": "No YouTube video found at this tab. If you know this is a YouTube tab, close this popup and open it again. If that does not work, try reloading the tab."
"message": "No YouTube video found.\nIf this is incorrect, refresh the tab."
},
"refreshSegments": {
"message": "Refresh segments"
},
"success": {
"message": "Success!"
@@ -105,65 +97,54 @@
"voted": {
"message": "Voted!"
},
"voteFail": {
"message": "You have already voted this way before."
},
"serverDown": {
"message": "It seems the sever is down. Contact the dev immediately."
"message": "It seems the server is down. Contact the dev immediately."
},
"connectionError": {
"message": "A connection error has occured. Error code: "
},
"wantToSubmit": {
"message": "Do you want to submit the sponsor times for video id"
},
"leftTimes": {
"message": "You seem to have left some sponsor times unsubmitted. Go back to that page to submit them (they are not deleted)."
},
"clearTimes": {
"message": "Clear Sponsor Times"
"message": "Clear Segments"
},
"openPopup": {
"message": "Open SponsorBlock Popup"
},
"closePopup": {
"message": "Close Popup"
},
"SubmitTimes": {
"message": "Submit Sponsor Times"
"message": "Submit Segments"
},
"submitCheck": {
"message": "Are you sure you want to submit this?"
},
"whitelistChannel": {
"message": "Whitelist Channel"
"message": "Whitelist channel"
},
"removeFromWhitelist": {
"message": "Remove Channel From Whitelist"
"message": "Remove channel from whitelist"
},
"voteOnTime": {
"message": "Vote On A Sponsor Time"
"message": "Vote On A Segment"
},
"recordTimes": {
"message": "Record the times of a sponsorship"
},
"soFarUHSubmited": {
"message": "So far, you've submitted"
"Submissions": {
"message": "Submissions"
},
"savedPeopleFrom": {
"message": "You have saved people from "
"message": "You've saved people from "
},
"viewLeaderboard": {
"message": "View the leaderboard"
},
"here": {
"message": "here"
"message": "Leaderboard"
},
"recordTimesDescription": {
"message": "Click the button below when the sponsorship starts and ends to record and\nsubmit it to the database."
"message": "Submit"
},
"submissionEditHint": {
"message": "Section editing will appear after you click submit",
"description": "Appears in the popup to inform them that editing has been moved to the video player."
},
"popupHint": {
"message": "Hint: Press the semicolon key while focused on a video to report the start/end of a sponsor and quote to submit. (This can be changed in the options)"
},
"lastTimes": {
"message": "Latest Sponsor Message Times Chosen"
"message": "Hint: You can setup keybinds for submitting in the options"
},
"clearTimesButton": {
"message": "Clear Times"
@@ -174,9 +155,15 @@
"publicStats": {
"message": "This is used on the public stats page to show off how much you've contributed. See it"
},
"Username": {
"message": "Username"
},
"setUsername": {
"message": "Set Username"
},
"copyPublicID": {
"message": "Copy Public UserID"
},
"discordAdvert": {
"message": "Come join the official discord server to give suggestions and feedback!"
},
@@ -193,7 +180,10 @@
"message": "Hide Buttons On YouTube Player"
},
"hideButtonsDescription": {
"message": "This hides the buttons that appear on the YouTube player to submit sponsors. I can see this being annoying for some\n people. Instead of using the button there, this popup can be used to submit sponsors. To hide the notice that appears, \n use the button that appears on the notice saying \"Don't show this again\". You can always enable these settings again later."
"message": "This hides the buttons that appear on the YouTube player to submit skip segments."
},
"showSkipButton": {
"message": "Keep Skip To Highlight Button On Player"
},
"showInfoButton": {
"message": "Show Info Button On YouTube Player"
@@ -201,8 +191,8 @@
"hideInfoButton": {
"message": "Hide Info Button On YouTube Player"
},
"whatInfoButton": {
"message": "This is the button that opens up a popup in the YouTube page."
"autoHideInfoButton": {
"message": "Auto-hide Info Button"
},
"hideDeleteButton": {
"message": "Hide Delete Button On YouTube Player"
@@ -210,23 +200,59 @@
"showDeleteButton": {
"message": "Show Delete Button On YouTube Player"
},
"whatDeleteButton": {
"message": "This is the button that allows you to clear all sponsors on the YouTube player."
},
"disableViewTracking": {
"message": "Disable Sponsor Skip Count Tracking"
},
"enableViewTracking": {
"message": "Enable Sponsor Skip Count Tracking"
"message": "Enable Skip Count Tracking"
},
"whatViewTracking": {
"message": "This feature tracks which sponsors you have skipped to let users know how much their submission has helped others and\nused as a metric along with upvotes to ensure that spam doesn't get into the database. The extension sends a message\nto the server each time you skip a sponsor. Hopefully most people don't change this setting so that the view numbers are accurate. :)"
"message": "This feature tracks which segments you have skipped to let users know how much their submission has helped others and used as a metric along with upvotes to ensure that spam doesn't get into the database. The extension sends a message to the server each time you skip a segment. Hopefully most people don't change this setting so that the view numbers are accurate. :)"
},
"enableViewTrackingInPrivate": {
"message": "Enable Skip Count Tracking In Private/Incognito tabs"
},
"enableTrackDownvotes": {
"message": "Store segment downvotes"
},
"whatTrackDownvotes": {
"message": "Any segments you downvote will remain hidden even after refreshing"
},
"trackDownvotesWarning": {
"message": "Warning: Disabling this will delete all previously stored downvotes"
},
"enableQueryByHashPrefix": {
"message": "Query By Hash Prefix"
},
"whatQueryByHashPrefix": {
"message": "Instead of requesting segments from the server using the videoID, the first 4 characters of the hash of the videoID are sent. This server will send back data for all videos with similar hashes."
},
"enableRefetchWhenNotFound": {
"message": "Refetch Segments On New Videos"
},
"whatRefetchWhenNotFound": {
"message": "If the video is new, and there are no segments found, it will keep refetching every few minutes while you watch."
},
"showNotice": {
"message": "Show Notice Again"
},
"showSkipNotice": {
"message": "Show Notice After A Segment Is Skipped"
},
"noticeVisibilityMode0": {
"message": "Full Size Skip Notices"
},
"noticeVisibilityMode1": {
"message": "Small Skip Notices for Auto Skip"
},
"noticeVisibilityMode2": {
"message": "All Small Skip Notices"
},
"noticeVisibilityMode3": {
"message": "Faded Skip Notices for Auto Skip"
},
"noticeVisibilityMode4": {
"message": "All Faded Skip Notices"
},
"longDescription": {
"message": "SponsorBlock is an extension that will skip over sponsored segments of YouTube videos. SponsorBlock is a crowdsourced browser extension that lets anyone submit the start and end times of sponsored segments of YouTube videos. Once one person submits this information, everyone else with this extension will skip right over the sponsored segment.",
"message": "SponsorBlock lets you skip over sponsors, intros, outros, subscription reminders, and other annoying parts of YouTube videos. SponsorBlock is a crowdsourced browser extension that lets anyone submit the start and end times of sponsored segments and other segments of YouTube videos. Once one person submits this information, everyone else with this extension will skip right over the sponsored segment. You can also skip over non music sections of music videos.",
"description": "Full description of the extension on the store pages."
},
"website": {
@@ -245,26 +271,29 @@
"message": "If you still don't like it, hit the never show button.",
"description": "The second line of the message displayed after the notice was upgraded."
},
"setSkipShortcut": {
"message": "Skip segment",
"description": "Keybind label"
},
"setStartSponsorShortcut": {
"message": "Set key for start sponsor keybind"
"message": "Start/stop segment",
"description": "Keybind label"
},
"setSubmitKeybind": {
"message": "Set key for submission keybind"
"message": "Submit segments",
"description": "Keybind label"
},
"keybindDescription": {
"message": "Select a key by typing it"
},
"keybindDescriptionComplete": {
"message": "The keybind has been set to: "
"message": "Select a key by typing it and choose any modifier keys you wish to use."
},
"0": {
"message": "Connection Timeout. Check your internet connection. If your internet is working, the server is probably overloaded or down."
},
"disableSkipping": {
"message": "Disable SponsorBlock"
"message": "Skipping is enabled"
},
"enableSkipping": {
"message": "Enable SponsorBlock"
"message": "Skipping is disabled"
},
"yourWork": {
"message": "Your Work",
@@ -276,32 +305,58 @@
"errorCode": {
"message": "Error Code: "
},
"noticeTitleNotSkipped": {
"message": "Skip Sponsor?"
},
"skip": {
"message": "Skip"
},
"mute": {
"message": "Mute"
},
"full": {
"message": "Full Video",
"description": "Used for the name of the option to label an entire video as sponsor or self promotion."
},
"skip_category": {
"message": "Skip {0}?"
},
"mute_category": {
"message": "Mute {0}?"
},
"skip_to_category": {
"message": "Skip to {0}?",
"description": "Used for skipping to things (Skip to Highlight)"
},
"skipped": {
"message": "{0} Skipped",
"description": "Example: Sponsor Skipped"
},
"muted": {
"message": "{0} Muted",
"description": "Example: Sponsor Muted"
},
"skipped_to_category": {
"message": "Skipped to {0}",
"description": "Used for skipping to things (Skipped to Highlight)"
},
"disableAutoSkip": {
"message": "Disable Auto Skip"
},
"enableAutoSkip": {
"message": "Enable Auto Skip"
},
"autoSkipDescription": {
"message": "Auto skip will skip sponsors for you. If disabled, a notice will appear asking if you'd like to skip."
},
"audioNotification": {
"message": "Audio Notification On Skip"
},
"audioNotificationDescription": {
"message": "Audio notification on skip will play a sound whenever a sponsor is skipped. If disabled (or auto skip is disabled), no sound will be played."
"message": "Audio notification on skip will play a sound whenever a segment is skipped. If disabled (or auto skip is disabled), no sound will be played."
},
"showTimeWithSkips": {
"message": "Show Time With Skips Removed"
},
"showTimeWithSkipsDescription": {
"message": "This time appears in brackets next to the current time on below the seekbar. This shows the total video duration minus any segments. This includes segments marked as only \"Show In Seekbar\"."
},
"youHaveSkipped": {
"message": "You have skipped "
},
"youHaveSaved": {
"message": "You have saved yourself "
"message": "You've skipped "
},
"minLower": {
"message": "minute"
@@ -316,13 +371,12 @@
"message": "hours"
},
"youHaveSavedTime": {
"message": "You have saved people"
"message": "You've saved people",
"description": "You've saved people from 887,362 segments (236d 15h 5.3 minutes of their lives)."
},
"youHaveSavedTimeEnd": {
"message": " of their lives."
},
"guildlinesSummary": {
"message": "- Make sure your segment only contains paid promotion segment, nothing else.\n- Make sure skipping this segment will not skip valuable content\n- If the whole video is a sponsor, please do not report it. A full video reporting system will come out soon.\n- Please do not report disclaimers that could show bias (if a review video is sponsored, don't skip when they mention that)."
"message": " of their lives",
"description": "You've saved people from 887,362 segments (236d 15h 5.3 minutes of their lives)."
},
"statusReminder": {
"message": "Check status.sponsor.ajay.app for server status."
@@ -331,7 +385,7 @@
"message": "Import/Export Your UserID"
},
"whatChangeUserID": {
"message": "This should be kept private. This is like a password and should not be shared with anyone. If someone has this, they can impersonate you."
"message": "This should be kept private. This is like a password and should not be shared with anyone. If someone has this, they can impersonate you. If you are looking for your public userID, click the clipboard icon in the popup."
},
"setUserID": {
"message": "Set UserID"
@@ -342,29 +396,24 @@
"createdBy": {
"message": "Created By"
},
"autoSkip": {
"message": "Auto Skip"
"supportOtherSites": {
"message": "Support 3rd Party YouTube-Sites"
},
"showSkipNotice": {
"message": "Show Notice After A Sponsor Is Skipped"
"supportOtherSitesDescription": {
"message": "Support third party YouTube clients. To enable support, you must accept the extra permissions. This does NOT work in incognito on Chrome and other Chromium variants.",
"description": "This replaces the 'supports Invidious' option because it now works on other YouTube sites such as Cloudtube"
},
"keybindCurrentlySet": {
"message": ". It is currently set to:"
},
"supportInvidious": {
"message": "Support Invidious"
},
"supportInvidiousDescription": {
"message": "Invidious (invidio.us) is a third party YouTube client. To enable support, you must accept the extra permissions. This does NOT work in incongnito on Chrome and other Chromium variants."
"supportedSites": {
"message": "Supported Sites: "
},
"optionsInfo": {
"message": "Enable Invidious support, disable autoskip, hide buttons and more."
},
"addInvidiousInstance": {
"message": "Add Invidious Instance"
"message": "Add 3rd-Party Client Instance"
},
"addInvidiousInstanceDescription": {
"message": "Add a custom instance of Invidious. This must be formatted with JUST the domain. Example: invidious.ajay.app"
"message": "Add a custom instance. This must be formatted with JUST the domain. Example: invidious.ajay.app"
},
"add": {
"message": "Add"
@@ -381,27 +430,27 @@
"currentInstances": {
"message": "Current Instances:"
},
"enableAutoUpvote": {
"message": "Auto Upvote"
},
"whatAutoUpvote": {
"message": "With this enabled, the extension will upvote all submissions you view if you do not report them. If the notice is disabled, this will not occur."
},
"minDuration": {
"message": "Minimum duration (seconds):"
},
"minDurationDescription": {
"message": "Sponsor segments shorter than the set value will not be skipped or show in the player."
},
"message": "Segments shorter than the set value will not be skipped or show in the player."
},
"skipNoticeDuration": {
"message": "Skip notice duration (seconds):"
},
"skipNoticeDurationDescription": {
"message": "The skip notice will stay on screen for at least this many seconds. For manual skipping, it may be visible for longer."
},
"shortCheck": {
"message": "The following submission is shorter than your minimum duration option. This could mean that this is already submitted, and just being ignored due to this option. Are you sure you would like to submit?"
},
"liveOrPremiere": {
"message": "Submitting on an active livestream or premiere is not allowed. Please wait until it finishes, then refresh the page and verify that the segments are still valid."
},
"showUploadButton": {
"message": "Show Upload Button"
},
"whatUploadButton": {
"message": "This button appears on the YouTube player after you have selected a timestamp and are ready to submit."
},
"customServerAddress": {
"message": "SponsorBlock Server Address"
},
@@ -415,26 +464,26 @@
"message": "Reset"
},
"customAddressError": {
"message": "This address is not in the right form. Make sure you have http:// or https:// at the begining and no trailing slashes."
"message": "This address is not in the right form. Make sure you have http:// or https:// at the beginning and no trailing slashes."
},
"areYouSureReset": {
"message": "Are you sure you would like to reset this?"
},
"confirmPrivacy": {
"message": "The video has been detected as unlisted. Click cancel if you do not want to check for sponsors."
},
"unlistedCheck": {
"message": "Ignore Unlisted Videos"
},
"whatUnlistedCheck": {
"message": "This setting will significantly slow down SponsorBlock. Sponsor lookups require sending the video ID to the server. If you are concerned about unlisted video IDs being sent over the internet, enable this option."
},
"mobileUpdateInfo": {
"message": "m.youtube.com is now supported"
},
"exportOptions": {
"message": "Import/Export All Options"
},
"exportOptionsCopy": {
"message": "Edit/copy"
},
"exportOptionsDownload": {
"message": "Save to file"
},
"exportOptionsUpload": {
"message": "Load from file"
},
"whatExportOptions": {
"message": "This is your entire configuration in JSON. This includes your userID, so be sure to share this wisely."
},
@@ -462,6 +511,12 @@
"preview": {
"message": "Preview"
},
"unsubmitted": {
"message": "Unsubmitted"
},
"inspect": {
"message": "Inspect"
},
"edit": {
"message": "Edit"
},
@@ -477,45 +532,142 @@
"copyDebugInformationComplete": {
"message": "The debug information has been copied to the clip board. Feel free to remove any information you would rather not share. Save this in a text file or paste into the bug report."
},
"theKey": {
"message": "The key"
},
"keyAlreadyUsedByYouTube": {
"message": "is already used by youtube. Please select another key."
},
"keyAlreadyUsed": {
"message": "is bound to another action. Please select another key."
"message": "This shortcut is bound to another action. Please select a different one."
},
"to": {
"message": "to",
"description": "Used between sponsor times. Example: 1:20 to 1:30"
"description": "Used between segments. Example: 1:20 to 1:30"
},
"category_sponsor": {
"message": "Sponsor"
"message": "Useful Content"
},
"category_intro": {
"message": "Intro"
},
"category_outro": {
"message": "Outro"
},
"category_interaction": {
"message": "Interaction (Redundant Like, Subscribe, Follow, etc.)"
"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_selfpromo": {
"message": "Self-Promotion and Merchandise"
"message": "Unpaid/Self Promotion"
},
"category_offtopic": {
"message": "Offtopic tangent (Subjective)"
"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."
},
"disable": {
"message": "Disable"
"category_exclusive_access": {
"message": "Exclusive Access"
},
"category_exclusive_access_description": {
"message": "Only for labeling entire videos. Used when a video showcases a product, service or location that they've received free or subsidized access to."
},
"category_exclusive_access_pill": {
"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_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_short": {
"message": "Interaction Reminder"
},
"category_intro": {
"message": "Intermission/Intro Animation"
},
"category_intro_description": {
"message": "An interval without actual content. Could be a pause, static frame, repeating animation. This should not be used for transitions containing information."
},
"category_intro_short": {
"message": "Intermission"
},
"category_outro": {
"message": "Endcards/Credits"
},
"category_outro_description": {
"message": "Credits or when the YouTube endcards appear. Not for conclusions with information."
},
"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_filler": {
"message": "Filler Tangent/Jokes"
},
"category_filler_description": {
"message": "Tangential scenes added only for filler or humor that are not required to understand the main content of the video. This should not include segments providing context or background details."
},
"category_filler_short": {
"message": "Filler"
},
"category_music_offtopic": {
"message": "Music: Non-Music Section"
},
"category_music_offtopic_description": {
"message": "Only for use in music videos. This only should be used for sections of music videos that aren't already covered by another category."
},
"category_music_offtopic_short": {
"message": "Non-Music"
},
"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_livestream_messages": {
"message": "Livestream: Donation/Message Readings"
},
"category_livestream_messages_short": {
"message": "Message Reading"
},
"autoSkip": {
"message": "Auto Skip"
},
"manualSkip": {
"message": "Manual Skip"
},
"showOverlay": {
"message": "Show Overlay On Player"
"message": "Show In Seek Bar"
},
"disable": {
"message": "Disable"
},
"autoSkip_POI": {
"message": "Auto skip to the start"
},
"manualSkip_POI": {
"message": "Ask when video loads"
},
"showOverlay_POI": {
"message": "Show In Seek Bar"
},
"showOverlay_full": {
"message": "Show Label"
},
"autoSkipOnMusicVideos": {
"message": "Auto skip all segments when there is a non-music segment"
},
"muteSegments": {
"message": "Allow segments that mute audio instead of skip"
},
"fullVideoSegments": {
"message": "Show an icon when a video is entirely an advertisement",
"description": "Referring to the category pill that is now shown on videos that are entirely sponsor or entirely selfpromo"
},
"previewColor": {
"message": "Unsubmitted Color",
"description": "Referring to submissions that have not been sent to the server yet."
},
"seekBarColor": {
"message": "Seek Bar Color"
},
"category": {
"message": "Category"
},
"skipOption": {
"message": "Skip Option",
"description": "Used on the options page to describe the ways to skip the segment (auto skip, manual, etc.)"
},
"enableTestingServer": {
"message": "Enable Beta Testing Server"
@@ -528,5 +680,254 @@
},
"bracketNow": {
"message": "(Now)"
},
"moreCategories": {
"message": "More Categories"
},
"chooseACategory": {
"message": "Choose a Category"
},
"enableThisCategoryFirst": {
"message": "To submit segments with the category of \"{0}\", you must enable it in the options. You will be redirected to the options now.",
"description": "Used when submitting segments to only let them select a certain category if they have it enabled in the options."
},
"poiOnlyOneSegment": {
"message": "Warning: This type of segment can have a maximum of one active at a time. Submitting multiple will cause a random one to be shown."
},
"youMustSelectACategory": {
"message": "You must select a category for all segments you are submitting!"
},
"bracketEnd": {
"message": "(End)"
},
"hiddenDueToDownvote": {
"message": "hidden: downvote"
},
"hiddenDueToDuration": {
"message": "hidden: too short"
},
"manuallyHidden": {
"message": "manually hidden"
},
"channelDataNotFound": {
"description": "This error appears in an alert when they try to whitelist a channel and the extension is unable to determine what channel they are looking at.",
"message": "Channel ID is not loaded yet. If you are using an embedded video, try using the YouTube homepage instead. This could also be caused by changes in the YouTube layout, if you think so, make a comment here:"
},
"videoInfoFetchFailed": {
"message": "It seems that something is blocking SponsorBlock's ability to get video data. Please see https://github.com/ajayyy/SponsorBlock/issues/741 for more info."
},
"youtubePermissionRequest": {
"message": "It seems that SponsorBlock is unable to reach the YouTube API. To fix this, accept the permission prompt that will appear next, wait a few seconds, and then reload the page."
},
"acceptPermission": {
"message": "Accept permission"
},
"permissionRequestSuccess": {
"message": "Permission request succeeded!"
},
"permissionRequestFailed": {
"message": "Permission request failed, did you click deny?"
},
"adblockerIssueWhitelist": {
"message": "If you are unable to resolve this, then disable the setting 'Force Channel Check Before Skipping', as SponsorBlock is unable to retrieve the channel information for this video"
},
"forceChannelCheck": {
"message": "Force Channel Check Before Skipping"
},
"whatForceChannelCheck": {
"message": "By default, it will skip segments right away before it even knows what the channel is. By default, some segments at the start of the video might be skipped on whitelisted channels. Enabling this option will prevent this but making all skipping have a slight delay as getting the channelID can take some time. This delay might be unnoticeable if you have fast internet."
},
"forceChannelCheckPopup": {
"message": "Consider Enabling \"Force Channel Check Before Skipping\""
},
"downvoteDescription": {
"message": "Incorrect/Wrong Timing"
},
"incorrectCategory": {
"message": "Change Category"
},
"nonMusicCategoryOnMusic": {
"message": "This video is categorized as music. Are you sure this has a sponsor? If this is actually a \"Non-Music segment\", open up the extension options and enable this category. Then, you can submit this segment as \"Non-Music\" instead of sponsor. Please read the guidelines if you are confused."
},
"multipleSegments": {
"message": "Multiple Segments"
},
"guidelines": {
"message": "Guidelines"
},
"readTheGuidelines": {
"message": "Read The Guidelines!!",
"description": "Show the first time they submit or if they are \"high risk\""
},
"categoryUpdate1": {
"message": "Categories are here!"
},
"categoryUpdate2": {
"message": "Open the options to skip intros, outros, merch, etc."
},
"help": {
"message": "Help"
},
"GotIt": {
"message": "Got it",
"description": "Used as the button to dismiss a tooltip"
},
"fullVideoTooltipWarning": {
"message": "This segment is large. If the whole video is about one topic, then change from \"Skip\" to \"Full Video\". See the guidelines for more information."
},
"categoryPillTitleText": {
"message": "This entire video is labeled as this category and is too tightly integrated to be able to separate"
},
"experiementOptOut": {
"message": "Opt-out of all future experiments",
"description": "This is used in a popup about a new experiment to get a list of unlisted videos to back up since all unlisted videos uploaded before 2017 will be set to private."
},
"hideForever": {
"message": "Hide forever"
},
"warningChatInfo": {
"message": "You got a warning and cannot submit segments temporarily. This means that we noticed you were making some common mistakes that are not malicious, please just confirm that you understand the rules and we will remove the warning. You can also join this chat using discord.gg/SponsorBlock or matrix.to/#/#sponsor:ajay.app"
},
"voteRejectedWarning": {
"message": "Vote rejected due to a warning. Click to open a chat to resolve it, or come back later when you have time.",
"description": "This is an integrated chat panel that will appearing allowing them to talk to the Discord/Matrix chat without leaving their browser."
},
"Donate": {
"message": "Donate"
},
"considerDonating": {
"message": "Help fund development"
},
"hideDonationLink": {
"message": "Hide Donation Link"
},
"darkModeOptionsPage": {
"message": "Dark Mode On Options Page"
},
"helpPageThanksForInstalling": {
"message": "Thanks for installing SponsorBlock."
},
"helpPageReviewOptions": {
"message": "Please review the options below"
},
"helpPageFeatureDisclaimer": {
"message": "Many features are disabled by default. If you want to skip intros, outros, use Invidious, etc., enable them below. You can also hide/show UI elements."
},
"helpPageHowSkippingWorks": {
"message": "How skipping works"
},
"helpPageHowSkippingWorks1": {
"message": "Video segments will automatically be skipped if they are found in the database. You can open the popup by clicking the extension icon to get a preview of what they are."
},
"helpPageHowSkippingWorks2": {
"message": "Whenever you skip a segment, you will get notice. If the timing seems wrong vote down by clicking downvote! You can also vote in the popup."
},
"Submitting": {
"message": "Submitting"
},
"helpPageSubmitting1": {
"message": "Submitting can either be done in the popup by hitting the \"Segment Starts Now\" button or in the video player with the buttons on the player."
},
"helpPageSubmitting2": {
"message": "Clicking the play button indicated the start of a segment and clicking the stop icon indicates the end. You can prepare multiple sponsors before hitting submit. Clicking the upload button will submit. Clicking the garbage can will delete."
},
"Editing": {
"message": "Editing"
},
"helpPageEditing1": {
"message": "If you messed up, you can edit or delete your segments after clicking the up arrow button."
},
"helpPageTooSlow": {
"message": "This is too slow"
},
"helpPageTooSlow1": {
"message": "There are hotkeys if you want to use them. Press the semicolon key to indicate the start/end of a sponsor segment and click the apostrophe to submit. These can be changed in the options. If you don't use QWERTY, you should probably change the keybinding."
},
"helpPageCopyOfDatabase": {
"message": "Can I get a copy of the Database? What happens if you disappear?"
},
"helpPageCopyOfDatabase1": {
"message": "The database is public and available at"
},
"helpPageCopyOfDatabase2": {
"message": "The source code is freely available. So, even if something happens to me, your submissions are not lost."
},
"helpPageNews": {
"message": "News and how it is made"
},
"helpPageSourceCode": {
"message": "Where can I get the source code?"
},
"Credits": {
"message": "Credits"
},
"LearnMore": {
"message": "Learn More"
},
"CopyDownvoteButtonInfo": {
"message": "Downvotes and creates a local copy for you to resubmit"
},
"OpenCategoryWikiPage": {
"message": "Open this category's wiki page."
},
"CopyAndDownvote": {
"message": "Copy and downvote"
},
"ContinueVoting": {
"message": "Continue Voting"
},
"ChangeCategoryTooltip": {
"message": "This will instantly apply to your segments"
},
"SponsorTimeEditScrollNewFeature": {
"message": "Use your mousewheel while hovering over the edit box to quickly adjust the time. Combinations of the ctrl or shift key can be used to fine tune the changes."
},
"categoryPillNewFeature": {
"message": "New! See when a video is entirely sponsored or self-promotion"
},
"dayAbbreviation": {
"message": "d",
"description": "100d"
},
"hourAbbreviation": {
"message": "h",
"description": "100h"
},
"optionsTabBehavior": {
"message": "Behavior",
"description": "Appears in Options as a tab header for options related to categories and skipping behavior. To fit inside the button, it should not be longer than ~20-25 characters (depending on their width)."
},
"optionsTabInterface": {
"message": "Interface",
"description": "Appears in Options as a tab header for options related to GUI and sounds. To fit inside the button, it should not be longer than ~20-25 characters (depending on their width)."
},
"optionsTabKeyBinds": {
"message": "Keyboard shortcuts",
"description": "Appears in Options as a tab header for keybinds. To fit inside the button, it should not be longer than ~20-25 characters (depending on their width)."
},
"optionsTabBackup": {
"message": "Backup/Restore",
"description": "Appears in Options as a tab header for options related to saving/restoring your settings. To fit inside the button, it should not be longer than ~20-25 characters (depending on their width)."
},
"optionsTabAdvanced": {
"message": "Miscellaneous",
"description": "Appears in Options as a tab header for advanced/niche options. To fit inside the button, it should not be longer than ~20-25 characters (depending on their width)."
},
"noticeVisibilityLabel": {
"message": "Skip notice appearance",
"description": "Option label"
},
"unbind": {
"message": "Unbind",
"description": "Unbind keyboard shortcut"
},
"notSet": {
"message": "Not set"
},
"change": {
"message": "Change"
},
"youtubeKeybindWarning": {
"message": "This is a built-in YouTube shortcut. Are you sure you want to use it?"
}
}

View File

@@ -1,263 +0,0 @@
{
"Name": {
"message": "SponsorBlock",
"description": "Name of the extension."
},
"fullName": {
"message": "SponsorBlock pour YouTube - Supprime les messages commerciaux et publicités intégrées",
"description": "Name of the extension."
},
"Description": {
"message": "Passe automatiquement les messages commerciaux intégrés dans les vidéos YouTube. Soumettez les segments commerciaux dans les vidéos que vous regardez pour aidez les autres.",
"description": "Description of the extension."
},
"helpPage": {
"message": "index_en.html"
},
"400": {
"message": "Soumission invalide"
},
"429": {
"message": "Vous cherchez à envoyer beaucoup de segments, y en a-t-il vraiment autant ?"
},
"409": {
"message": "Déja soumis"
},
"channelWhitelisted": {
"message": "Cette chaîne est sur la liste blanche !"
},
"Sponsor": {
"message": "message commercial"
},
"Sponsors": {
"message": "messages commerciaux"
},
"Segment": {
"message": "segment commercial"
},
"Segments": {
"message": "segments commerciaux"
},
"noticeTitle": {
"message": "Message commercial passé"
},
"reportButtonTitle": {
"message": "Incorrect"
},
"reportButtonInfo": {
"message": "Signaler que ce segment commercial est incorrect ou n'existe pas."
},
"Dismiss": {
"message": "Fermer"
},
"Loading": {
"message": "Chargement en cours..."
},
"Mins": {
"message": "Minutes"
},
"Secs": {
"message": "Secondes"
},
"Hide": {
"message": "Ne plus montrer"
},
"hitGoBack": {
"message": "Cliquez sur revenir en arrière pour revenir avant le saut du segment commercial"
},
"unskip": {
"message": "Revenir en arrière"
},
"reskip": {
"message": "Sauter"
},
"paused": {
"message": "En pause"
},
"confirmMSG": {
"message": "\n\nPour modifier ou supprimer des soumissions, cliquez sur le bouton d'info ou ouvrez la fenêtre de l'extension en cliquant sur son icône dans le coin en haut à droite."
},
"clearThis": {
"message": "Êtes-vous certain(e) de vouloir supprimer vos soumissions ?\n\n"
},
"Unknown": {
"message": "Une erreur s'est produite lors de la soumission, veuillez ré-essayer plus tard."
},
"sponsorFound": {
"message": "Les messages commerciaux sont déjà dans notre base de donnée pour cette vidéo !"
},
"sponsor404": {
"message": "Pas de messages commerciaux trouvés"
},
"sponsorStart": {
"message": "Début du message commercial"
},
"sponsorEnd": {
"message": "Fin du message commercial"
},
"noVideoID": {
"message": "Ceci n'est pas un onglet YouTube, ou vous avez cliqué trop tôt. \n Si vous êtes sûr(e) que c'est un onglet YouTube, fermez cette fenêtre et réessayez."
},
"success": {
"message": "Succès !"
},
"voted": {
"message": "A voté !"
},
"voteFail": {
"message": "Vous avez déjà voté pour ce choix."
},
"serverDown": {
"message": "Le serveur ne fonctionne pas. Contactez le développeur."
},
"connectionError": {
"message": "Erreur de connexion. Code d'erreur : "
},
"wantToSubmit": {
"message": "Voulez-vous soumettre les segments commerciaux pour cette vidéo"
},
"leftTimes": {
"message": "Vous avez laissé des segments commerciaux non soumis. Retournez sur la vidéo pour les soumettre (ils ont été conservés)."
},
"clearTimes": {
"message": "Supprimer les segments commerciaux"
},
"openPopup": {
"message": "Ouvrir l'encart SponsorBlock"
},
"SubmitTimes": {
"message": "Soumettre les segments commerciaux"
},
"submitCheck": {
"message": "Êtes-vous sûr de vouloir soumettre ces segments?"
},
"whitelistChannel": {
"message": "Ajouter la chaîne à la liste blanche"
},
"removeFromWhitelist": {
"message": "Supprimer la chaîne de la liste blanche"
},
"whitelistDescription": {
"message": "Ajouter à la liste blanche les chaînes qui publient des messages commerciaux de façon éthique pour encourager les bons comportements, ou qui publient des messages commerciaux divertissants ou drôles. Ou pas, c'est votre choix."
},
"voteOnTime": {
"message": "Voter sur un segment commercial"
},
"recordTimes": {
"message": "Enregistrer un segment commercial"
},
"soFarUHSubmited": {
"message": "Vous avez soumis jusqu'à présent"
},
"savedPeopleFrom": {
"message": "Vous avez fait gagner aux autres "
},
"viewLeaderboard": {
"message": "Consulter le classement"
},
"here": {
"message": "ici"
},
"recordTimesDescription": {
"message": "Cliquez sur le bouton ci-dessous quand le segment commercial commence puis \nse termine pour l'enregistrer et le soumettre à la base de données."
},
"popupHint": {
"message": "Astuce : utilisez la touche point-virgule lorsque la vidéo est sélectionnée pour enregistrer le début et la fin d'un segment commercial; utilisez la touche guillemet pour le soumettre. (Les touches peuvent être modifiées dans les options)"
},
"lastTimes": {
"message": "Derniers temps choisis pour le segment commercial"
},
"clearTimesButton": {
"message": "Supprimer les temps"
},
"submitTimesButton": {
"message": "Soumettre les temps"
},
"publicStats": {
"message": "Affiché sur le classement public pour montrer vos contributions. Voir sur"
},
"setUsername": {
"message": "Choisir pseudo"
},
"discordAdvert": {
"message": "Rejoignez le serveur Discord officiel pour toutes suggestions ou remarques!"
},
"hideThis": {
"message": "Cacher"
},
"Options": {
"message": "Options"
},
"showButtons": {
"message": "Montrer les boutons sur le lecteur YouTube"
},
"hideButtons": {
"message": "Cacher les boutons sur le lecteur YouTube"
},
"hideButtonsDescription": {
"message": "Cela permet de cacher du lecteur YouTube les boutons utilisés pour soumettre des segments commerciaux. Je peux \ncomprendre que certaines personnes les trouvent perturbants. Au lieu d'utiliser ces boutons, cette fenêtre peut être utilisée \npour soumettre des segments commerciaux. Pour cacher la notification, utilisez le bouton \"Ne plus montrer\" sur la notification. Vous pouvez toujours réactiver ces paramètres plus tard."
},
"showInfoButton": {
"message": "Montrer le bouton Info sur le lecteur YouTube"
},
"hideInfoButton": {
"message": "Cacher le bouton Info sur le lecteur YouTube"
},
"whatInfoButton": {
"message": "Il s'agit du bouton qui ouvre l'encart sur la page YouTube."
},
"hideDeleteButton": {
"message": "Cacher le bouton Supprimer sur le lecteur YouTube"
},
"showDeleteButton": {
"message": "Montrer le bouton Supprimer sur le lecteur YouTube"
},
"whatDeleteButton": {
"message": "Il s'agit du bouton qui permet de supprimer tous les segments commerciaux depuis le lecteur YouTube."
},
"disableViewTracking": {
"message": "Désactiver le suivi des vues de segments commerciaux"
},
"enableViewTracking": {
"message": "Activer le suivi des vues de segments commerciaux"
},
"whatViewTracking": {
"message": "Cette fonctionnalité suit quels segments commerciaux vous avez sautés afin de calculer le bénéfice des soumissions des \nautres utilisateurs. Elle est également utilisée comme métrique, avec les haut-votes, afin de s'assurer que les spams \nsont ignorés. L'extension envoie un message au serveur à chauqe fois qu'un segment commercial est sauté. Avec un peu de chance, peu de personnes désactiveront cette fonctionnalité afin d'obtenir des nombres de vues exacts. :)"
},
"showNotice": {
"message": "Afficher la notification"
},
"longDescription": {
"message": "SponsorBlock est une extension qui permet de passer les messages commerciaux des vidéos YouTube. SponsorBlock est une extension pour navigateur basée sur le crowdsourcing permettant à n'importe qui de soumettre le début et la fin des segments commerciaux sur les vidéos YouTube. Dès qu'une personne a soumis ces informations, les autres utilisateurs de l'extension en bénéficieront et verront les messages commerciaux automatiquement sautés.",
"description": "Full description of the extension on the store pages."
},
"website": {
"message": "Site web",
"description": "Used on Firefox Store Page"
},
"sourceCode": {
"message": "Code source",
"description": "Used on Firefox Store Page"
},
"noticeUpdate": {
"message": "La notification a été mise à jour !",
"description": "The first line of the message displayed after the notice was upgraded."
},
"noticeUpdate2": {
"message": "Si elle ne vous plaît pas, cliquez sur le bouton \"Ne plus montrer\"",
"description": "The second line of the message displayed after the notice was upgraded."
},
"setStartSponsorShortcut": {
"message": "Changer le raccourci pour enregistrer un segment"
},
"setSubmitKeybind": {
"message": "Changer le raccourci pour soumettre les segments"
},
"keybindDescription": {
"message": "Appuyez sur une touche"
},
"keybindDescriptionComplete": {
"message": "Le raccourci choisi est : "
}
}

View File

@@ -1,244 +0,0 @@
{
"Name": {
"message": "SponsorBlock",
"description": "Name of the extension."
},
"fullName": {
"message": "SponsorBlock per YouTube - Salta gli sponsor",
"description": "Name of the extension."
},
"Description": {
"message": "Salta i contenuti sponsorizzati nei video di YouTube. Segnala gli annunci incorporati nei video che guardi per far risparmiare tempo agli altri.",
"description": "Description of the extension."
},
"helpPage": {
"message": "index_en.html"
},
"400": {
"message": "Richiesta non valida"
},
"429": {
"message": "Stai inviando troppi spezzoni per questo video, sei sicuro che ce ne siano così tanti?"
},
"409": {
"message": "Questo spezzone è già stato inviato"
},
"channelWhitelisted": {
"message": "Canale aggiunto alla whitelist!"
},
"Sponsor": {
"message": "sponsorizzazione"
},
"Sponsors": {
"message": "sponsorizzazioni"
},
"Segment": {
"message": "spezzone sponsorizzato"
},
"Segments": {
"message": "spezzoni sponsorizzati"
},
"noticeTitle": {
"message": "Sponsorizzazione Saltata"
},
"reportButtonTitle": {
"message": "Segnala"
},
"reportButtonInfo": {
"message": "Segnala questo spezzone come non corretto."
},
"Dismiss": {
"message": "Chiudi"
},
"Loading": {
"message": "Caricamento..."
},
"Mins": {
"message": "Minuti"
},
"Secs": {
"message": "Secondi"
},
"Hide": {
"message": "Non mostrare più"
},
"hitGoBack": {
"message": "Premi non saltare per tornare da dove sei venuto."
},
"unskip": {
"message": "Non saltare"
},
"reskip": {
"message": "Salta ancora"
},
"paused": {
"message": "In pausa"
},
"confirmMSG": {
"message": "\n\nPer modificare o eliminare valori specifici, premi il pulsante delle informazioni o apri il popup cliccando l'icona dell'estensione nell'angolo in alto a destra."
},
"clearThis": {
"message": "Sei sicuro di volerlo cancellare?\n\n"
},
"Unknown": {
"message": "Si è verificato un errore durante l'invio dello spezzone sponsorizzato, per favore riprova più tardi."
},
"sponsorFound": {
"message": "I contenuti sponsorizzati di questo video sono nel database!"
},
"sponsor404": {
"message": "Nessuna sponsorizzazione trovata"
},
"sponsorStart": {
"message": "La sponsorizzazione inizia adesso"
},
"sponsorEnd": {
"message": "La sponsorizzazione finisce adesso"
},
"noVideoID": {
"message": "Probabilmente questa non è una scheda di YouTube, oppure hai cliccato troppo presto. \nSe sei sicuro di essere in una scheda di YouTube,\n riapri questo popup."
},
"success": {
"message": "Successo!"
},
"voted": {
"message": "Votato!"
},
"voteFail": {
"message": "Hai già votato."
},
"serverDown": {
"message": "Sembra che il server non funzioni. Contatta subito lo sviluppatore."
},
"connectionError": {
"message": "Si è verificato un errore durante la connessione. Codice errore: "
},
"wantToSubmit": {
"message": "Vuoi inviare gli spezzoni sponsorizzati per il video con id"
},
"leftTimes": {
"message": "Sembra che tu non abbia inviato alcuni spezzoni sponsorizzati. Ritorna alla pagina precedente per inviarli (non sono stati eliminati)."
},
"clearTimes": {
"message": "Cancella gli Spezzoni Sponsorizzati"
},
"openPopup": {
"message": "Apri il Popup di SponsorBlock"
},
"SubmitTimes": {
"message": "Invia gli Spezzoni Sponsorizzati"
},
"submitCheck": {
"message": "Sei sicuro di volerlo inviare?"
},
"whitelistChannel": {
"message": "Aggiungi Canale alla Whitelist"
},
"removeFromWhitelist": {
"message": "Rimuovi Canale dalla Whitelist"
},
"whitelistDescription": {
"message": "Aggiungi alla whitelist i canali che sponsorizzano eticamente per incoraggiare ad un comportamento corretto, oppure se sono semplicemente intrattenenti e divertenti. Oppure non farlo, decidi tu."
},
"voteOnTime": {
"message": "Vota uno Spezzone Sponsorizzato"
},
"recordTimes": {
"message": "Registra uno Spezzone Sponsorizzato"
},
"soFarUHSubmited": {
"message": "Fino ad ora hai inviato"
},
"savedPeopleFrom": {
"message": "Hai salvato le persone da "
},
"viewLeaderboard": {
"message": "Guarda la classifica"
},
"here": {
"message": "qui"
},
"recordTimesDescription": {
"message": "Premi il pulsante qui sotto quando inizia e finisce la sponsorizzazione per registrarla e\ninviarla al database."
},
"popupHint": {
"message": "Suggerimento: Premi il tasto punto e virgola mentre il video è attivo per segnalare l'inizio/fine di una sponsorizzazione e virgolette per inviare."
},
"lastTimes": {
"message": "Ultimi minutaggi sponsorizzati scelti"
},
"clearTimesButton": {
"message": "Cancella Minutaggi"
},
"submitTimesButton": {
"message": "Invia Minutaggi"
},
"publicStats": {
"message": "Viene utilizzato nelle pagine delle statistiche pubbliche che mostrano quanto hai contribuito. Vedi"
},
"setUsername": {
"message": "Imposta Username"
},
"discordAdvert": {
"message": "Entra nel server Discord ufficiale per darci suggerimenti e feedback!"
},
"hideThis": {
"message": "Nascondi"
},
"Options": {
"message": "Opzioni"
},
"showButtons": {
"message": "Mostra i Pulsanti nel Lettore di YouTube"
},
"hideButtons": {
"message": "Nascondi i Pulsanti nel Lettore di YouTube"
},
"hideButtonsDescription": {
"message": "Nasconde i pulsanti che appaiono nel lettore di YouTube per inviare spezzoni sponsorizzati. Capisco che può essere fastidioso per alcune\n persone. Invece di utilizzare quei pulsanti, è possibile utilizzare questo popup per inviare gli spezzoni sponsorizzati. Per nascondere l'avviso che appare, \nusa il bottone \"Non mostrare più\" nell'avviso. Potrai sempre abilitare nuovamente queste impostazioni in futuro."
},
"showInfoButton": {
"message": "Mostra il Pulsante Informazioni nel Lettore di YouTube"
},
"hideInfoButton": {
"message": "Nascondi il Pulsante Informazioni nel Lettore di YouTube"
},
"whatInfoButton": {
"message": "Questo è il pulsante che apre un popup nella pagina YouTube."
},
"hideDeleteButton": {
"message": "Nascondi il Pulsante Elimina nel Lettore di YouTube"
},
"showDeleteButton": {
"message": "Mostra il Pulsante Elimina nel Lettore di YouTube"
},
"whatDeleteButton": {
"message": "Questo è il pulsante che ti permette di cancellare tutti gli spezzoni sponsorizzati nel lettore di YouTube."
},
"disableViewTracking": {
"message": "Disattiva il Monitoraggio delle Sponsorizzazioni"
},
"enableViewTracking": {
"message": "Disattiva il Monitoraggio delle Sponsorizzazioni"
},
"whatViewTracking": {
"message": "Questa funzione tiene traccia di quali sponsorizzazioni hai saltato per far sapere agli utenti quanto è stato d'aiuto agli altri il loro contributo e\nviene utilizzato come metrica assieme ai voti positivi per filtrare lo spam dal database. L'estensione invia un messaggio\nal server ogni volta che salti una sponsorizzazione. Si spera che la maggior parte delle persone non modifichi questa impostazione così i numeri sono accurati. :)"
},
"showNotice": {
"message": "Mostra di Nuovo l'Avviso"
},
"longDescription": {
"message": "SponsorBlock è un'estensione che salta gli spezzoni con contenuti sponsorizzati nei video di YouTube. SponsorBlock è un'estensione crowdsourced per i browser che permette a chiunque di inviare i minutaggi degli spezzoni sponsorizzati nei video di YouTube. Quando una persona avrà inviato questa informazione, tutti gli utenti che utilizzano questa estensione potranno saltare lo spezzone sponsorizzato.",
"description": "Full description of the extension on the store pages."
},
"website": {
"message": "Sito Web",
"description": "Used on Firefox Store Page"
},
"sourceCode": {
"message": "Codice Sorgente",
"description": "Used on Firefox Store Page"
}
}

View File

@@ -1,390 +0,0 @@
{
"Name": {
"message": "SponsorBlock",
"description": "Nazwa rozszerzenia."
},
"fullName": {
"message": "SponsorBlock na YouTube - Omiń reklamy sponsorów",
"description": "Nazwa rozszerzenia."
},
"Description": {
"message": "Przewijaj reklamy sponsorów w filmach na YouTube. Zgłaszaj reklamy w nagraniach żeby nie marnować czasu innych.",
"description": "Opis rozszerzenia."
},
"helpPage": {
"message": "index_en.html"
},
"400": {
"message": "Serwer odpowiedział, że to zapytanie jest niepoprawne"
},
"429": {
"message": "Zgłosiłeś bardzo dużo segmentów reklamowych dla tego jednego nagrania, jesteś pewien, że jest ich tak dużo?"
},
"409": {
"message": "Treść została już wcześniej zgłoszona"
},
"channelWhitelisted": {
"message": "Kanał dodany do wyjątków!"
},
"Sponsor": {
"message": "sponsor"
},
"Sponsors": {
"message": "sponsorzy"
},
"Segment": {
"message": "segmet sponsorowany"
},
"Segments": {
"message": "segmenty sponsorowane"
},
"noticeTitle": {
"message": "Segment przewinięty"
},
"reportButtonTitle": {
"message": "Zgłoś"
},
"reportButtonInfo": {
"message": "Zgłoś ten segment reklamowy jako nieprawidłowy."
},
"Dismiss": {
"message": "Odrzuć"
},
"Loading": {
"message": "Ładowanie..."
},
"Mins": {
"message": "Minuty"
},
"Secs": {
"message": "Sekundy"
},
"Hide": {
"message": "Nigdy nie pokazuj"
},
"hitGoBack": {
"message": "Kliknij cofnij aby przenieść się do miejsca przed przewinięciem."
},
"unskip": {
"message": "Cofnij"
},
"reskip": {
"message": "Przewiń"
},
"paused": {
"message": "Zatrzymany"
},
"confirmMSG": {
"message": "Żeby zmienić lub usunąć wartości, kliknij na guzik informacji lub otwórz okienko rozszerzenia klikając w ikonę rozszerzenia znajdującą się w prawym górnym rogu."
},
"clearThis": {
"message": "Jesteś pewien, że chcesz to usunąć?\n\n"
},
"Unknown": {
"message": "Wystąpił błąd podczas przesyłania twojego zgłoszenia, proszę spróbować ponownie później."
},
"sponsorFound": {
"message": "Segmenty reklamowe dla tego nagrania są już w bazie!"
},
"sponsor404": {
"message": "Nie znaleziono segmentów reklamowych"
},
"sponsorStart": {
"message": "Reklama zaczyna się teraz"
},
"sponsorEnd": {
"message": "Reklama kończy się teraz"
},
"noVideoID": {
"message": "Nie znaleziono nagrania wideo w tej karcie. Jeśli wiesz, że to karta YouTube'a, zamknij to okienko i otwórz je ponownie. Jeśli to nie zadziała spróbuj przeładować stronę."
},
"success": {
"message": "Sukces!"
},
"voted": {
"message": "Zagłosowano!"
},
"voteFail": {
"message": "Już na to głosowałeś."
},
"serverDown": {
"message": "Wygląda na to, że serwer nie działa. Skontaktuj się z dewloperem."
},
"connectionError": {
"message": "Błąd z połączeniem. Kod błędu: "
},
"wantToSubmit": {
"message": "Chcesz zgłosić segment sponsorowany dla nagrania z id"
},
"leftTimes": {
"message": "Wygląda na to, że masz nie wysłane segmenty reklamowe. Cofnij się do tej strony i zgłoś je (nie zostały usunięte)."
},
"clearTimes": {
"message": "Wyczyść segmenty reklamowe"
},
"openPopup": {
"message": "Otwórz okienko SponsorBlock"
},
"SubmitTimes": {
"message": "Zgłoś segmenty reklamowe"
},
"submitCheck": {
"message": "Jesteś pewien, że chcesz to zgłosić?"
},
"whitelistChannel": {
"message": "Dodaj kanał do wyjątków"
},
"removeFromWhitelist": {
"message": "Usuń kanał z listy wyjątków"
},
"voteOnTime": {
"message": "Głosuj na segment reklamowy"
},
"recordTimes": {
"message": "Nagraj czasy segmentów reklamowych"
},
"soFarUHSubmited": {
"message": "Jak na razie zgłosiłeś:"
},
"savedPeopleFrom": {
"message": "Ocaliłeś ludzi przed "
},
"viewLeaderboard": {
"message": "Zobacz ranking użytkowników"
},
"here": {
"message": "tutaj"
},
"recordTimesDescription": {
"message": "Kliknij guzik poniżej kiedy segment reklamowy się zaczyna i kończy żeby go oznaczyć i wysłać do bazy danych."
},
"popupHint": {
"message": "Podpowiedź: Klikając średnik kiedy zaznaczone jest zgłaszanie wideo możesz oznaczyć początek reklamy, znakiem cytatu oznaczysz jej koniec. (Klawisze można zmienić w opcjach)"
},
"lastTimes": {
"message": "Ostanie wybrane czasy reklam"
},
"clearTimesButton": {
"message": "Usuń czasy"
},
"submitTimesButton": {
"message": "Zgłoś czasy"
},
"publicStats": {
"message": "Ten dane są używane na naszej stronie żeby pokazać twój wkład. Zobacz to"
},
"setUsername": {
"message": "Ustaw nazwę użytkownika"
},
"discordAdvert": {
"message": "Dołącz do oficjalnego serwera na discordzie i podziel się wrażeniami i sugestiami!"
},
"hideThis": {
"message": "Ukryj to"
},
"Options": {
"message": "Opcje"
},
"showButtons": {
"message": "Pokaż guziki w odtwarzaczu YouTube"
},
"hideButtons": {
"message": "Ukryj guziki w odtwarzaczu YouTube"
},
"hideButtonsDescription": {
"message": "Ta opcja ukrywa guziki zgłaszania reklamy w odtwarzaczu. Wiem, że mogą one irytować niektórych. Zamiast zgłaszania bezpośrednio w odtwarzaczu możesz to zrobić w tym okienku. Zawsze możesz zmienić te opcje później."
},
"showInfoButton": {
"message": "Pokaż guzik informacyjny w odtwarzaczu YouTube"
},
"hideInfoButton": {
"message": "Ukryj guzik informacyjny w odtwarzaczu YouTube"
},
"whatInfoButton": {
"message": "Jest to guzik otwierający popup na stronie YouTube."
},
"hideDeleteButton": {
"message": "Ukryj guzik usuwania w odtwarzaczu YouTube"
},
"showDeleteButton": {
"message": "Pokaż guzik usuwania w odtwarzaczu YouTube"
},
"whatDeleteButton": {
"message": "Ten guzik pozwala ci wyczyścić wszystkie segmenty reklamowe w odtwarzaczu YouTube."
},
"disableViewTracking": {
"message": "Wyłącz licznik przewinięć"
},
"enableViewTracking": {
"message": "Włącz licznik przewinięć"
},
"whatViewTracking": {
"message": "Ta opcja śledzi które segmenty pominąłeś i informuje zgłaszających ile czasu Ci zaoszczędzili, też wraz systemem głosowania pomaga wykrywać spam w zgłoszeniach. Rozszerzenie wysyła zapytanie do serwera za każdym razem kiedy przewinąłeś segment reklamowy. Miejmy nadzieję, że większość ludzi tego nie wyłączy i licznik wyświetleń będzie rzetelny. :)"
},
"showNotice": {
"message": "Pokaż informacje ponownie"
},
"longDescription": {
"message": "SponsorBlock jest rozszerzeniem które przewinie segmenty sponsorów w filmach na YouTube. SponsorBlock jest opartym na crowdsourcing rozszerzeniem które pozwala każdemu zgłaszać początek i koniec segmentu reklamowego w filmach na YouTube. Kiedy ktoś zgłosi taki fragment zostanie on pominięty przez innych użytkowników rozszerzenia.",
"description": "Pełny opis rozszerzenia na stronie w sklepie."
},
"website": {
"message": "Strona",
"description": "Używane w sklepie Firefoxa"
},
"sourceCode": {
"message": "Kod źródłowy",
"description": "Używane w sklepie Firefoxa"
},
"noticeUpdate": {
"message": "Informacje zostały zaktualizowane!",
"description": "Pierwsza linia po aktualizacji informacji."
},
"noticeUpdate2": {
"message": "Jeśli nadal jej nie lubisz wybierz opcje nie pokazuj więcej.",
"description": "Druga linia po aktualizacji informacji."
},
"setStartSponsorShortcut": {
"message": "Ustaw klawisz do oznaczania początku reklamy"
},
"setSubmitKeybind": {
"message": "Ustaw klawisz do wysyłania czasów"
},
"keybindDescription": {
"message": "Wybierz klawisz klikając go na klawiaturze"
},
"keybindDescriptionComplete": {
"message": "Ustawiony klawisz to: "
},
"0": {
"message": "Połączenie przerwane z powodu braku odpowiedzi. Sprawdź swoje połączenie z internetem. Jeśli wszystko z nim w porządku oznacza to, że serwer jest prawdopodobnie przeciążony lub nie działa."
},
"disableSkipping": {
"message": "Wyłącz SponsorBlock"
},
"enableSkipping": {
"message": "Włącz SponsorBlock"
},
"yourWork": {
"message": "Twój wkład",
"description": "Nagłowek sekcji ze statystykami użytkownika."
},
"502": {
"message": "Serwer jest prawdopodobnie przeciążony, spróbuj ponownie za kilka sekund."
},
"errorCode": {
"message": "Kod błędu: "
},
"noticeTitleNotSkipped": {
"message": "Przewinąć reklamę?"
},
"skip": {
"message": "Przewiń"
},
"disableAutoSkip": {
"message": "Wyłącz auto przewijanie"
},
"enableAutoSkip": {
"message": "Włącz auto przewijanie"
},
"autoSkipDescription": {
"message": "Auto przewijanie przewinie segment za ciebie, wyłączone wyświetli komunikat z pytaniem czy chcesz przewinąć reklamę."
},
"youHaveSkipped": {
"message": "Przewinąłeś "
},
"youHaveSaved": {
"message": "Oszczędziłeś sobie "
},
"minLower": {
"message": "minuta"
},
"minsLower": {
"message": "minuty"
},
"hourLower": {
"message": "godzina"
},
"hoursLower": {
"message": "godziny"
},
"youHaveSavedTime": {
"message": "Oszczędziłeś ludziom"
},
"youHaveSavedTimeEnd": {
"message": " czasu."
},
"guildlinesSummary": {
"message": "- Upewnij się, że zgłaszany fragment zawiera tylko reklamę i nic więcej.\n- Upewnij się, że nie zostanie przewinięta wartościowa treść\n- Jeśli całe nagranie to reklama, proszę nie zgłaszaj go. Blokowanie całych nagrań pojawi się wkrótce.\n- Nie ukrywaj treści które są istotne dla użytkownika (nie ukrywaj informacji, że recenzja produktu została opłacona przez producenta)"
},
"statusReminder": {
"message": "Wejdź na status.sponsor.ajay.app żeby sprawdzić czy serwer działa."
},
"changeUserID": {
"message": "Zaimportuj/Wyeksportuj swój UserID"
},
"whatChangeUserID": {
"message": "Ta informacja jest poufna i działa jak hasło, użytkownik który ma do niej dostęp może zgłaszać treści jako ty."
},
"setUserID": {
"message": "Ustaw UserID"
},
"userIDChangeWarning": {
"message": "Ostrzeżenie: Zmiana UserID jest nieodwracalna. Jesteś pewien, że chcesz to zrobić? Skopiuj obecny UserID na wszelki wypadek."
},
"createdBy": {
"message": "Stworzony przez"
},
"autoSkip": {
"message": "Auto przewijanie"
},
"showSkipNotice": {
"message": "Pokaż informację po przewiniętym fragmencie"
},
"keybindCurrentlySet": {
"message": ". Jest obecnie ustawione jako:"
},
"supportInvidious": {
"message": "Wesprzyj Invidious"
},
"supportInvidiousDescription": {
"message": "Invidious (invidio.us) to nieoficjalny klient YouTube. Aby go wesprzeć musisz przyznać dodatkowe uprawnienia rozszerzeniowi. Ta opcja nie działa w incognito i innych wersjach Chromium."
},
"optionsInfo": {
"message": "Wesprzyj Invidious, wyłącz auto przewijanie, ukryj guziki i więcej."
},
"addInvidiousInstance": {
"message": "Dodaj instancje Invidious"
},
"addInvidiousInstanceDescription": {
"message": "Dodaj niestandardową instancje Invidious. W formie domeny. Na przykład: invidious.ajay.app"
},
"add": {
"message": "Dodaj"
},
"addInvidiousInstanceError": {
"message": "Ta domena jest nieprawidłowa. Wartość powinna zawierać TYLKO domenę. Na przykład: invidious.ajay.app"
},
"resetInvidiousInstance": {
"message": "Zresetuj listę instancji Invidious"
},
"resetInvidiousInstanceAlert": {
"message": "Zresetujesz listę instancji Invidious"
},
"currentInstances": {
"message": "Obecne instancje:"
},
"enableAutoUpvote": {
"message": "Auto potwierdzanie"
},
"whatAutoUpvote": {
"message": "To ustawienie sprawia, że wszystkie przewinięte przez ciebie a nie zgłoszone jako błąd segmenty reklamowe zostaną potwierdzone jako prawidłowe. Ta opcja nie działa jeśli okienko z informacją o przewinięciu jest ukryte."
},
"invidiousInfo1": {
"message": "Invidious (nieoficjalny klient YouTube) została dodana do wspieranych!"
},
"invidiousInfo2": {
"message": "Musisz odblokować to w opcjach aby móc to zrobić."
}
}

View File

@@ -1,244 +0,0 @@
{
"Name": {
"message": "SponsorBlock",
"description": "Nome da extensão."
},
"fullName": {
"message": "SponsorBlock para YouTube - Pule patrocínios",
"description": "Nome da extensão."
},
"Description": {
"message": "Pule patrocinadores em vídeos do YouTube. Reporte patrocinadores em videos que você assiste para salvar o tempo dos outros.",
"description": "Descrição da extensão."
},
"helpPage": {
"message": "index_en.html"
},
"400": {
"message": "O servidor disse que esse pedido foi inválido"
},
"429": {
"message": "Você enviou muitos segmentos para esse vídeo, tem certeza que tem tantos assim?"
},
"409": {
"message": "Isso já foi enviado antes"
},
"channelWhitelisted": {
"message": "Canal adicionado à lista branca!"
},
"Sponsor": {
"message": "patrocinador"
},
"Sponsors": {
"message": "patrocinadores"
},
"Segment": {
"message": "segmento de patrocinador"
},
"Segments": {
"message": "segmentos de patrocinadores"
},
"noticeTitle": {
"message": "Patrocinador pulado"
},
"reportButtonTitle": {
"message": "Reportar"
},
"reportButtonInfo": {
"message": "Reportar essa subimissão como inválida."
},
"Dismiss": {
"message": "Ignorar"
},
"Loading": {
"message": "Carregando..."
},
"Mins": {
"message": "Minutos"
},
"Secs": {
"message": "Segundos"
},
"Hide": {
"message": "Nunca mostrar"
},
"hitGoBack": {
"message": "Aperta reverter pulo para voltar onde estava"
},
"unskip": {
"message": "Reverter pulo"
},
"reskip": {
"message": "Pular novamente"
},
"paused": {
"message": "Pausado"
},
"confirmMSG": {
"message": "\n\nPara editar ou remover linhas individuais, clique com o botão direito ou abra o popup da extensão pelo icone no canto superior direito."
},
"clearThis": {
"message": "Tem certeza que quer limpar isso?\n\n"
},
"Unknown": {
"message": "Teve um erro ao enviar seus segmentos, tente novamente depois."
},
"sponsorFound": {
"message": "Os patrocinadores desse vídeo estão no banco de dados!"
},
"sponsor404": {
"message": "Nenhum patrocinador encontrado"
},
"sponsorStart": {
"message": "Patrocínio começa agora"
},
"sponsorEnd": {
"message": "Patrocínio termina agora"
},
"noVideoID": {
"message": "Isso provavelmente não é uma tab do YouTube, ou você clicou muito cedo. \n Se sabe que é uma tab do YouTube,\n feche esse popup e abra de novo."
},
"success": {
"message": "Sucesso!"
},
"voted": {
"message": "Votado!"
},
"voteFail": {
"message": "Você já votou antes."
},
"serverDown": {
"message": "Parece que o servidor caiu. Contate o desenvolvedor o quanto antes."
},
"connectionError": {
"message": "Um erro de conexão aconteceu: Código: "
},
"wantToSubmit": {
"message": "Quer enviar os segmentos para o vídeo de ID"
},
"leftTimes": {
"message": "Parece que você se esqueceu de enviar alguns segmentos. Volta pra página para os enviar (não foram deletados)."
},
"clearTimes": {
"message": "Apagar intervalos dos patrocínios"
},
"openPopup": {
"message": "Abrir o Popup SponsorBlock"
},
"SubmitTimes": {
"message": "Submeter intervalos dos patrocínios"
},
"submitCheck": {
"message": "Tem a certeza que pretende submeter?"
},
"whitelistChannel": {
"message": "Meter canal na Whitelist"
},
"removeFromWhitelist": {
"message": "Remover canal da Whitelist"
},
"whitelistDescription": {
"message": "Colocar na Whitelist canais com patrocínios éticos que encoragem boas atitude, ou simplesmente canais com patrocínios engraçados. Ou não, é consigo."
},
"voteOnTime": {
"message": "Vote num intervalo de patrocínio"
},
"recordTimes": {
"message": "Registe um intervalo de patrocínio"
},
"soFarUHSubmited": {
"message": "Até agora submeteu"
},
"savedPeopleFrom": {
"message": "Poupaste a outros de "
},
"viewLeaderboard": {
"message": "Ver a leaderboard"
},
"here": {
"message": "aqui"
},
"recordTimesDescription": {
"message": "Carregue neste botão abaixo quando o patrocínio começar e quando\n acabar para registar e submetê-lo à base de dados"
},
"popupHint": {
"message": "Dica: Carregue na tecla ; enquanto num vídeo para registar o começo/fim de um patrocínio e \" para submeter"
},
"lastTimes": {
"message": "Intervalos de Patrocínios Escolhidos mais Recentemente"
},
"clearTimesButton": {
"message": "Limpar Intervalos"
},
"submitTimesButton": {
"message": "Submeter Intervalos"
},
"publicStats": {
"message": "Isto é usado na página pública de estatísticas que mostra o quanto já contríbuíu. Veje-a"
},
"setUsername": {
"message": "Criar nomde de utilizador"
},
"discordAdvert": {
"message": "Junte-se ao discord oficial para sugerir dicas e sugestões!"
},
"hideThis": {
"message": "Esconder isto"
},
"Options": {
"message": "Opções"
},
"showButtons": {
"message": "Mostrar botões no player do Youtube"
},
"hideButtons": {
"message": "Esconder botões no player do Youtube"
},
"hideButtonsDescription": {
"message": "Isto esconde os botões que aparecem no player do Youtube para submeter patrocínios. Entendemos que possa ser\n incómodo a algumas pessoas. Em vez de usar esses botões pode usar os do popup. Para esconder a mensagem que aparece, \n ususe o botão na mesma que diz \"Don't show this again\". Pode sempre reactivar estas definições novamente."
},
"showInfoButton": {
"message": "Mostrar botão de Informações no player do Youtube"
},
"hideInfoButton": {
"message": "Esconder botão de Informações no player do Youtube"
},
"whatInfoButton": {
"message": "Este é o botão que abre o popup na pagina do Youtube."
},
"hideDeleteButton": {
"message": "Esconder botão de Apagar no player do Youtube"
},
"showDeleteButton": {
"message": "Mostrar botão de Apagar no player do Youtube"
},
"whatDeleteButton": {
"message": "Este é o botão que lhe permite saltar todos os patrocínios do player do Youtube."
},
"disableViewTracking": {
"message": "Desactivar registo de visualização de patrocínios"
},
"enableViewTracking": {
"message": "Activar registo de visualização de patrocínios"
},
"whatViewTracking": {
"message": "Esta funcionalidade regista que patrocínios tem saltado para que outros utilizadores saibam o quanto as suas submições têm ajudado outros\n e é usado como métrica de votos para evitar spam na base de dados. A extenção \n envia uma notificação ao servidor sempre que salta um patrocínio. Quanto menos pessoas desactivarem esta funcionalidade mais precisas serão as estimativas :)"
},
"showNotice": {
"message": "Mostrar notificação outra vez"
},
"longDescription": {
"message": "SponsorBlock é uma extensão que salta segmentos patrocinados em vídeos do YouTube. SponsorBlock é uma extenção crowdfunded que permite a qualquer um submeter o início e o fim de segmentos patrocinados. Assim que uma pessoa submete essa informação todos com a extenção poderam saltar automaticamete o patrocínio.",
"description": "Descrição completa da extençao nas lojas dos browsers."
},
"website": {
"message": "Site",
"description": "Usado na pagina da loja do Firefox"
},
"sourceCode": {
"message": "Código fonte",
"description": "Usado na pagina da loja do Firefox"
}
}

View File

@@ -1,243 +0,0 @@
{
"Name": {
"message": "SponsorBlock",
"description": "Nome da extensão."
},
"fullName": {
"message": "SponsorBlock para o YouTube - Salte patrocínios",
"description": "Nome da extensão."
},
"Description": {
"message": "Salte patrocinadores em vídeos do YouTube. Reporte patrocinadores em vídeos que assista para poupar tempo a outros.",
"description": "Descrição da extensão."
},
"helpPage": {
"message": "index_en.html"
},
"400": {
"message": "O servidor disse que este pedido foi inválido"
},
"429": {
"message": "Enviou muitos segmentos para este vídeo, tem certeza que tem assim tantos?"
},
"409": {
"message": "Isso já foi enviado antes"
},
"channelWhitelisted": {
"message": "Canal adicionado à whitelist!"
},
"Sponsor": {
"message": "patrocinador"
},
"Sponsors": {
"message": "patrocinadores"
},
"Segment": {
"message": "segmento de patrocínio"
},
"Segments": {
"message": "segmentos de patrocínio"
},
"noticeTitle": {
"message": "Patrocínio saltado"
},
"reportButtonTitle": {
"message": "Reportar"
},
"reportButtonInfo": {
"message": "Reportar subimissão como inválida."
},
"Dismiss": {
"message": "Ignorar"
},
"Loading": {
"message": "A carregar..."
},
"Mins": {
"message": "Minutos"
},
"Secs": {
"message": "Segundos"
},
"Hide": {
"message": "Nunca mostrar"
},
"hitGoBack": {
"message": "Carregue em reverter salto para voltar a onde estava"
},
"unskip": {
"message": "Reverter salto"
},
"reskip": {
"message": "Saltar novamente"
},
"paused": {
"message": "Pausado"
},
"confirmMSG": {
"message": "\n\nPara editar ou remover linhas individuais, carregue com o botão direito ou abra o popup da extensão pelo icone no canto superior direito."
},
"clearThis": {
"message": "Tem certeza que deseja limpar isto?\n\n"
},
"Unknown": {
"message": "Erro ao enviar os seus segmentos, tente novamente mais tarde."
},
"sponsorFound": {
"message": "Os patrocinadores desse vídeo estão no banco de dados!"
},
"sponsor404": {
"message": "Nenhum patrocinador encontrado"
},
"sponsorStart": {
"message": "Patrocínio começa agora"
},
"sponsorEnd": {
"message": "Patrocínio termina agora"
},
"noVideoID": {
"message": "Isto provavelmente não é uma tab do YouTube, ou pode ter clicado muito cedo. \n Se sabe que é uma tab do YouTube,\n feche este popup e abra de novo."
},
"success": {
"message": "Sucesso!"
},
"voted": {
"message": "Votado!"
},
"voteFail": {
"message": "Já votou antes."
},
"serverDown": {
"message": "Parece que o servidor caiu. Contacte o desenvolvedor o quanto antes."
},
"connectionError": {
"message": "Deu-se um erro de conecção: Código: "
},
"wantToSubmit": {
"message": "Quer enviar os segmentos para o vídeo de ID"
},
"leftTimes": {
"message": "Parece que se esqueceu de enviar alguns segmentos. Retorne à página para os enviar (não foram apagados)."
},
"clearTimes": {
"message": "Apagar intervalos dos patrocínios"
},
"openPopup": {
"message": "Abrir o Popup SponsorBlock"
},
"SubmitTimes": {
"message": "Submeter intervalos dos patrocínios"
},
"submitCheck": {
"message": "Tem a certeza que pretende submeter?"
},
"whitelistChannel": {
"message": "Meter canal na Whitelist"
},
"removeFromWhitelist": {
"message": "Remover canal da Whitelist"
},
"whitelistDescription": {
"message": "Colocar na Whitelist canais com patrocínios éticos que encoragem boas atitude, ou simplesmente canais com patrocínios engraçados. Ou não, é consigo."
},
"voteOnTime": {
"message": "Vote num intervalo de patrocínio"
},
"recordTimes": {
"message": "Registe um intervalo de patrocínio"
},
"soFarUHSubmited": {
"message": "Até agora submeteu"
},
"savedPeopleFrom": {
"message": "Poupaste a outros de "
},
"viewLeaderboard": {
"message": "Ver a leaderboard"
},
"here": {
"message": "aqui"
},
"recordTimesDescription": {
"message": "Carregue neste botão abaixo quando o patrocínio começar e quando\n acabar para registar e submetê-lo à base de dados"
},
"popupHint": {
"message": "Dica: Carregue na tecla ; enquanto num vídeo para registar o começo/fim de um patrocínio e \" para submeter"
},
"lastTimes": {
"message": "Intervalos de Patrocínios Escolhidos mais Recentemente"
},
"clearTimesButton": {
"message": "Limpar Intervalos"
},
"submitTimesButton": {
"message": "Submeter Intervalos"
},
"publicStats": {
"message": "Isto é usado na página pública de estatísticas que mostra o quanto já contríbuíu. Veje-a"
},
"setUsername": {
"message": "Criar nomde de utilizador"
},
"discordAdvert": {
"message": "Junte-se ao discord oficial para sugerir dicas e sugestões!"
},
"hideThis": {
"message": "Esconder isto"
},
"Options": {
"message": "Opções"
},
"showButtons": {
"message": "Mostrar botões no player do Youtube"
},
"hideButtons": {
"message": "Esconder botões no player do Youtube"
},
"hideButtonsDescription": {
"message": "Isto esconde os botões que aparecem no player do Youtube para submeter patrocínios. Entendemos que possa ser\n incómodo a algumas pessoas. Em vez de usar esses botões pode usar os do popup. Para esconder a mensagem que aparece, \n ususe o botão na mesma que diz \"Don't show this again\". Pode sempre reactivar estas definições novamente."
},
"showInfoButton": {
"message": "Mostrar botão de Informações no player do Youtube"
},
"hideInfoButton": {
"message": "Esconder botão de Informações no player do Youtube"
},
"whatInfoButton": {
"message": "Este é o botão que abre o popup na pagina do Youtube."
},
"hideDeleteButton": {
"message": "Esconder botão de Apagar no player do Youtube"
},
"showDeleteButton": {
"message": "Mostrar botão de Apagar no player do Youtube"
},
"whatDeleteButton": {
"message": "Este é o botão que lhe permite saltar todos os patrocínios do player do Youtube."
},
"disableViewTracking": {
"message": "Desactivar registo de visualização de patrocínios"
},
"enableViewTracking": {
"message": "Activar registo de visualização de patrocínios"
},
"whatViewTracking": {
"message": "Esta funcionalidade regista que patrocínios tem saltado para que outros utilizadores saibam o quanto as suas submições têm ajudado outros\n e é usado como métrica de votos para evitar spam na base de dados. A extenção \n envia uma notificação ao servidor sempre que salta um patrocínio. Quanto menos pessoas desactivarem esta funcionalidade mais precisas serão as estimativas :)"
},
"showNotice": {
"message": "Mostrar notificação outra vez"
},
"longDescription": {
"message": "SponsorBlock é uma extensão que salta segmentos patrocinados em vídeos do YouTube. SponsorBlock é uma extenção crowdfunded que permite a qualquer um submeter o início e o fim de segmentos patrocinados. Assim que uma pessoa submete essa informação todos com a extenção poderam saltar automaticamete o patrocínio.",
"description": "Descrição completa da extençao nas lojas dos browsers."
},
"website": {
"message": "Site",
"description": "Usado na pagina da loja do Firefox"
},
"sourceCode": {
"message": "Código fonte",
"description": "Usado na pagina da loja do Firefox"
}
}

View File

@@ -1,421 +0,0 @@
{
"Name": {
"message": "SponsorBlock",
"description": "Название расширения, не переводится."
},
"fullName": {
"message": "SponsorBlock для YouTube - Пропускайте спонсорские вставки",
"description": "Название расширения."
},
"Description": {
"message": "Пропускайте спонсорские вставки в видео на YouTube. Сообщайте о спонсорских вставках в видео, которые Вы смотрите, чтобы сэкономить время других пользователей.",
"description": "Описание раширения."
},
"helpPage": {
"message": "index_en.html"
},
"400": {
"message": "Сервер отклонил этот запрос."
},
"429": {
"message": "Вы отправили слишком много спонсоров для этого видео. Вы уверены, что их так много?"
},
"409": {
"message": "Этот запрос был отправлен ранее."
},
"channelWhitelisted": {
"message": "Канал добавлен в белый список!"
},
"Sponsor": {
"message": "спонсора"
},
"Sponsors": {
"message": "спонсоров"
},
"Segment": {
"message": "спонсорская вставка"
},
"Segments": {
"message": "спонсорские вставки"
},
"noticeTitle": {
"message": "Спонсор пропущен"
},
"reportButtonTitle": {
"message": "Ошибка"
},
"reportButtonInfo": {
"message": "Сообщить, что информация об этом спонсорском сегменте ошибочна."
},
"Dismiss": {
"message": "Закрыть"
},
"Loading": {
"message": "Загрузка..."
},
"Mins": {
"message": "мин"
},
"Secs": {
"message": "сек"
},
"Hide": {
"message": "Не показывать"
},
"hitGoBack": {
"message": "Нажмите «Назад», чтобы вернуться обратно."
},
"unskip": {
"message": "Назад"
},
"reskip": {
"message": "Пропустить"
},
"paused": {
"message": "Пауза"
},
"confirmMSG": {
"message": "\n\nЧтобы изменить или удалить отдельные значения, нажмите кнопку «Информация» или откройте всплывающее окно расширения, щелкнув значок расширения в правом верхнем углу."
},
"clearThis": {
"message": "Вы уверены, что хотите удалить эту информацию?\n\n"
},
"Unknown": {
"message": "При отправке отчета о спонсорском сегменте произошла ошибка. Попытайтесь отправить его позже."
},
"sponsorFound": {
"message": "Спонсоры этого видео уже находятся в базе данных!"
},
"sponsor404": {
"message": "Спонсорские вставки не найдены"
},
"sponsorStart": {
"message": "Спонсорская вставка начинается сейчас"
},
"sponsorEnd": {
"message": "Спонсорская вставка оканчивается сейчас"
},
"noVideoID": {
"message": "Возможно, это не вкладка YouTube, или Вы нажали слишком рано. \n Если это вкладка YouTube,\n закройте это всплывающее окно и откройте его снова."
},
"success": {
"message": "Успех!"
},
"voted": {
"message": "Голос засчитан!"
},
"voteFail": {
"message": "Вы уже проголосовали таким образом раньше."
},
"serverDown": {
"message": "Кажется, сервер не работает. Свяжитесь с разработчиком."
},
"connectionError": {
"message": "Ошибка соединения. Код ошибки: "
},
"wantToSubmit": {
"message": "Вы точно хотите отправить отчёт о спонсорских вставках в видео с идентификатором"
},
"leftTimes": {
"message": "Вы ещё не отправили отчёты о некоторых спонсорских вставках. Хотите вернуться на эту страницу, чтобы отправить их (они не удаляются)."
},
"submitCheck": {
"message": "Вы уверены, что хотите отправить эту информацию?"
},
"whitelistChannel": {
"message": "Добавить канал в белый список"
},
"removeFromWhitelist": {
"message": "Удалить канал из белого списка"
},
"voteOnTime": {
"message": "Проголосовать за время спонсорской вставки"
},
"recordTimes": {
"message": "Записать время спонсорской вставки"
},
"soFarUHSubmited": {
"message": "На данный момент Вы отправили"
},
"savedPeopleFrom": {
"message": "Вы помогли людям сэкономить "
},
"viewLeaderboard": {
"message": "Посмотреть доску почёта"
},
"here": {
"message": "здесь"
},
"recordTimesDescription": {
"message": "Нажмите кнопку ниже, когда спонсорская вставка начинается и заканчивается, чтобы записать\nи отправить её в базу данных."
},
"popupHint": {
"message": "Подсказка: нажмите ;, чтобы сообщить начало/конец спонсорской вставки, и \", чтобы отправить. (Это можно изменить в настройках)"
},
"lastTimes": {
"message": "Последнее выбранное время спонсорской вставки"
},
"clearTimesButton": {
"message": "Очистить время"
},
"submitTimesButton": {
"message": "Отправить время"
},
"publicStats": {
"message": "Оно используется на публичной странице статистики, чтобы показать Ваш вклад. Её можно посмотреть "
},
"setUsername": {
"message": "Установить имя пользователя"
},
"discordAdvert": {
"message": "Присоединяйтесь к официальному серверу Discord, чтобы оставить предложения и обратную связь!"
},
"hideThis": {
"message": "Скрыть это"
},
"Options": {
"message": "Настройки"
},
"showButtons": {
"message": "Показывать кнопки в плеере YouTube"
},
"hideButtons": {
"message": "Скрыть кнопки в плеере YouTube"
},
"hideButtonsDescription": {
"message": "Эта настройка скрывает кнопки для отправки спонсорских вставок, которые появляются в плеере YouTube. Они могут раздражать\n некоторых. Вместо кнопок для отправки спонсорских вставок можно использовать это всплывающее окно. Чтобы скрыть\nуведомление, нажмите кнопку \"Не показывать снова\" в уведомлении. Вы всегда сможете включить эти настройки обратно."
},
"showInfoButton": {
"message": "Показывать кнопку информации в плеере YouTube"
},
"hideInfoButton": {
"message": "Скрыть кнопку информации в плеере YouTube"
},
"whatInfoButton": {
"message": "Эта кнопка открывает всплывающее окно на странице YouTube."
},
"hideDeleteButton": {
"message": "Скрыть кнопку удаления в плеере YouTube"
},
"showDeleteButton": {
"message": "Показывать кнопку удаления в плеере YouTube"
},
"whatDeleteButton": {
"message": "Эта кнопка позволяет Вам очистить все спонсорские вставки в плеере YouTube."
},
"disableViewTracking": {
"message": "Отключить отслеживание количества пропусков спонсорских вставок"
},
"enableViewTracking": {
"message": "Включить отслеживание количества пропусков спонсорских вставок"
},
"whatViewTracking": {
"message": "Эта возможность отслеживает, какие спонсорские вставки Вы пропустили, чтобы помочь пользователям узнать, насколько их\nвклад помог другим, и используется как метрика, чтобы убедиться, что спам не попадает в базу данных. Расширение отправляет\nсообщение на сервер каждый раз, когда Вы пропускаете спонсорскую вставку. Надеемся, большая часть пользователей не поменяет эту настройку, так что у нас будет точная статистика просмотров :)"
},
"showNotice": {
"message": "Показывать уведомление снова"
},
"longDescription": {
"message": "SponsorBlock — это расширение, которое пропускает спонсорские вставки в видео на YouTube. SponsorBlock — это краудсорсинговое расширение, которое позволяет каждому отправить время начала и конца спонсорских сегментов в видео на YouTube. После того, как кто-нибудь отправляет эту информацию, все остальные пользователи расширения будут автоматически пропускать спонсорские сегменты.",
"description": "Полное описание расширения на страницах магазинов."
},
"website": {
"message": "Сайт",
"description": "Используется на странице магазина Firefox"
},
"sourceCode": {
"message": "Исходный код",
"description": "Используется на странице магазина Firefox"
},
"noticeUpdate": {
"message": "Уведомление было обновлено!",
"description": "The first line of the message displayed after the notice was upgraded."
},
"noticeUpdate2": {
"message": "Если оно Вам всё равно не нравится, нажмите \"не показывать\".",
"description": "The second line of the message displayed after the notice was upgraded."
},
"setStartSponsorShortcut": {
"message": "Назначить горячую клавишу для начала спонсорской вставки"
},
"setSubmitKeybind": {
"message": "Назначить горячую клавишу для отправки"
},
"keybindDescription": {
"message": "Нажмите клавишу, чтобы выбрать её"
},
"keybindDescriptionComplete": {
"message": "Клавиша назначена на: "
},
"0": {
"message": "Таймаут подключения. Проверьте ваше соединение с интернетом. Если ваш интернет работает, сервер, скорее всего, перегружен или лежит."
},
"disableSkipping": {
"message": "Отключить SponsorBlock"
},
"enableSkipping": {
"message": "Включить SponsorBlock"
},
"yourWork": {
"message": "Ваша работа",
"description": "Used to describe the section that will show you the statistics from your submissions."
},
"502": {
"message": "Похоже, сервер перегружен. Попробуйте ещё раз через несколько секунд."
},
"errorCode": {
"message": "Код ошибки: "
},
"noticeTitleNotSkipped": {
"message": "Пропустить спонсорскую вставку?"
},
"skip": {
"message": "Пропустить"
},
"disableAutoSkip": {
"message": "Отключить автоматический пропуск"
},
"enableAutoSkip": {
"message": "Включить автоматический пропуск"
},
"autoSkipDescription": {
"message": "Автоматический пропуск будет пропускать спонсорские вставки за Вас. Если выключено, будет показываться уведомление с предложением пропустить."
},
"youHaveSkipped": {
"message": "Вы пропустили "
},
"youHaveSaved": {
"message": "Вы сэкономили "
},
"minLower": {
"message": "минуту"
},
"minsLower": {
"message": "минут"
},
"hourLower": {
"message": "час"
},
"hoursLower": {
"message": "часов"
},
"youHaveSavedTime": {
"message": "Вы сэкономили людям"
},
"youHaveSavedTimeEnd": {
"message": " их жизней."
},
"guildlinesSummary": {
"message": "- Убедитесь, что Ваш сегмент содержит только платную интеграцию, и больше ничего.\n- Убедитесь, что пропуск этого сегмента не пропустит никакой ценный контент\n- Если всё видео целиком спонсорское, пожалуйста, не сообщайте о нём. Система для сообщения о целых видео скоро выйдет.\n- Пожалуйста, не сообщайте об отказах от ответственности, которые могут показать предвзятость (если видео с обзором проплачено, не пропускайте, когда они это упоминают)."
},
"statusReminder": {
"message": "Смотрите состояние сервера на status.sponsor.ajay.app."
},
"changeUserID": {
"message": "Импортировать/экспортировать Ваш идентификатор пользователя"
},
"whatChangeUserID": {
"message": "Это нужно держать в секрете. Это как пароль, не стоит им ни с кем делиться. Если он у кого-то есть, он сможет выдать себя за Вас."
},
"setUserID": {
"message": "Установить идентификатор пользователя"
},
"userIDChangeWarning": {
"message": "Внимание: изменение идентификатора пользователя необратимо. Вы действительно хотите это сделать? Сделайте резервную копию вашего старого на всякий случай."
},
"createdBy": {
"message": "Создано"
},
"autoSkip": {
"message": "Автоматический пропуск"
},
"showSkipNotice": {
"message": "Показывать уведомление после пропуска спонсорской вставки"
},
"keybindCurrentlySet": {
"message": ". Он сейчас назначен на:"
},
"supportInvidious": {
"message": "Поддержка Invidious"
},
"supportInvidiousDescription": {
"message": "Invidious (invidio.us) — это неофициальный клиент YouTube. Чтобы включить поддержку, Вам понадобится принять дополнительные разрешения. Это НЕ работает в приватном режиме в Chrome и других вариантах Chromium."
},
"optionsInfo": {
"message": "Включить поддержку Invidious, выключить автоматический пропуск, скрыть кнопки и не только."
},
"addInvidiousInstance": {
"message": "Добавить инстанс Invidious"
},
"addInvidiousInstanceDescription": {
"message": "Добавить свой инстанс Invidious. Формат: ТОЛЬКО домен. Например, invidious.ajay.app"
},
"add": {
"message": "Добавить"
},
"addInvidiousInstanceError": {
"message": "Это неправильный домен. Введите ТОЛЬКО домен. Например, invidious.ajay.app"
},
"resetInvidiousInstance": {
"message": "Сбросить список инстансов Invidious"
},
"resetInvidiousInstanceAlert": {
"message": "Вы собираетесь сбросить список инстансов Invidious"
},
"currentInstances": {
"message": "Текущие инстансы:"
},
"enableAutoUpvote": {
"message": "Автоматически голосовать \"за\""
},
"whatAutoUpvote": {
"message": "Если это включено, расширение будет голосовать \"за\" все предложения других пользователей, если Вы на них не пожалуетесь. Если уведомление отключено, это не будет происходить."
},
"minDuration": {
"message": "Минимальная длительность (секунд):"
},
"minDurationDescription": {
"message": "Спонсорские сегменты короче этого значения не будут пропускаться и не будут показаны в плеере."
},
"shortCheck": {
"message": "Следующий диапазон времени короче, чем Ваша настройка минимальной длительности. Это может означать, что он уже был отправлен, и просто игнорируется из-за этой настройки. Вы действительно хотите отправить?"
},
"showUploadButton": {
"message": "Показывать кнопку отправки"
},
"whatUploadButton": {
"message": "Эта кнопка появляется в плеере YouTube после того, как Вы выбрали отметку времени и готовы к отправке."
},
"customServerAddress": {
"message": "Адрес сервера SponsorBlock"
},
"customServerAddressDescription": {
"message": "Адрес, по которому SponsorBlock обращается к серверу.\nМеняйте только если Вы подняли свой сервер."
},
"save": {
"message": "Сохранить"
},
"reset": {
"message": "Сбросить"
},
"customAddressError": {
"message": "Этот адрес неправильного формата. Убедитесь, что он начинается с http:// или https://, и что на конце нет слэшей."
},
"areYouSureReset": {
"message": "Вы действительно хотите это сбросить?"
},
"confirmPrivacy": {
"message": "Было обнаружено, что это видео непубличное. Нажмите \"отмена\", если не хотите проверять его на спонсоров."
},
"unlistedCheck": {
"message": "Игнорировать непубличные видео"
},
"whatUnlistedCheck": {
"message": "Эта настройка значительно замедлит SponsorBlock. Поиск спонсоров требует отправки идентификатора видео на сервер. Если Вас беспокоит отправка идентификаторов непубличных видео по интернету, включите эту настройку."
},
"mobileUpdateInfo": {
"message": "m.youtube.com теперь поддерживается"
}
}

View File

@@ -1,3 +1,7 @@
.hidden {
display: none;
}
#previewbar {
overflow: visible;
padding: 0;
@@ -9,6 +13,12 @@
height: 100%;
transform: scaleY(0.6) translateY(-30%) translateY(1.5px);
z-index: 40;
transition: transform .1s cubic-bezier(0,0,0.2,1);
}
#previewbar.hovered {
transform: scaleY(1)
}
.previewbar {
@@ -16,6 +26,40 @@
height: 100%;
}
/* Make sure settings are upfront */
.ytp-settings-menu {
z-index: 6000 !important;
}
/* Preview Bar page hacks */
.ytp-tooltip:not(.sponsorCategoryTooltipVisible) .sponsorCategoryTooltip {
display: none !important;
}
.ytp-tooltip.sponsorCategoryTooltipVisible {
transform: translateY(-1em) !important;
}
.ytp-big-mode .ytp-tooltip.sponsorCategoryTooltipVisible {
transform: translateY(-2em) !important;
}
#movie_player:not(.ytp-big-mode) .ytp-tooltip.sponsorCategoryTooltipVisible > .ytp-tooltip-text-wrapper {
transform: translateY(1em) !important;
}
.ytp-big-mode .ytp-tooltip.sponsorCategoryTooltipVisible > .ytp-tooltip-text-wrapper {
transform: translateY(0.5em) !important;
}
.ytp-big-mode .ytp-tooltip.sponsorCategoryTooltipVisible > .ytp-tooltip-text-wrapper > .ytp-tooltip-text {
display: block !important;
transform: translateY(1em) !important;
}
/* */
.popup {
z-index: 10;
width: 100%;
@@ -40,6 +84,28 @@
vertical-align: top;
}
.autoHiding {
overflow: visible !important;
}
.autoHiding:not(.hidden) {
transform: translateX(0%) scale(1);
/* opacity is from YouTube page */
transition: transform 0.2s, width 0.2s, opacity .1s cubic-bezier(0.4,0.0,1,1) !important;
}
.autoHiding.hidden {
transform: translateX(100%) scale(0);
/* opacity is from YouTube page */
transition: transform 0.2s, width 0.2s, opacity .1s cubic-bezier(0.4,0.0,1,1) !important;
width: 0px !important;
}
.autoHiding.hidden.autoHideLeft {
transform: translateX(-100%) scale(0);
}
.sponsorSkipObject {
font-family: Roboto, Arial, Helvetica, sans-serif;
@@ -55,12 +121,10 @@
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes fadeOut {
from { opacity: 1; }
to { opacity: 0; }
to { opacity: 0; }
}
.sponsorBlockSpacer {
@@ -70,47 +134,103 @@
margin-left: 5px;
}
.sponsorSkipNotice {
min-width: 350px;
background-color: rgba(28, 28, 28, 0.9);
position: absolute;
.sbChatNotice {
min-width: 350px;
height: 70%;
position: absolute;
right: 5px;
bottom: 100px;
right: 10px;
}
border-radius: 5px;
.sponsorSkipNoticeParent {
position: absolute;
bottom: 100px;
right: 10px;
}
.sponsorSkipNoticeParent, .sponsorSkipNotice {
min-width: 350px;
max-width: 50%;
border-spacing: 5px 10px;
padding-left: 5px;
padding-right: 5px;
border-collapse: unset;
}
.sponsorSkipNoticeTableContainer {
background-color: rgba(28, 28, 28, 0.9);
border-radius: 5px;
min-width: 100%;
}
.sponsorSkipNotice {
transition: all 0.1s ease-out;
}
.sponsorSkipNoticeLimitWidth {
min-width: calc(100% - 50px);
}
.sponsorSkipNotice .hidden {
display: none;
}
/* For Cloudtube */
.sponsorSkipNotice td, .sponsorSkipNotice table, .sponsorSkipNotice th {
border: none;
}
.sponsorSkipNoticeFadeIn {
animation: fadeIn 0.5s;
animation: fadeIn 0.5s ease-out;
}
.sponsorSkipNoticeFaded {
opacity: 0.5;
}
.sponsorSkipNoticeFadeOut {
animation: fadeOut 3s cubic-bezier(0.55, 0.055, 0.675, 0.19);
transition: opacity 3s cubic-bezier(0.55, 0.055, 0.675, 0.19);
opacity: 0 !important;
animation: none !important;
}
.sponsorSkipNoticeTimeLeft {
.sponsorSkipNotice .sponsorSkipNoticeTimeLeft {
color: #eeeeee;
border-radius: 4px;
padding: 2px 5px;
font-size: 12px;
display: flex;
align-items: center;
border: 1px solid #eeeeee;
}
.sponsorSkipNoticeTimeLeft img {
vertical-align: middle;
height: 13px;
padding-top: 7.8%;
padding-bottom: 7.8%;
}
/* if two are very close to eachother */
.secondSkipNotice {
bottom: 250px;
transition: bottom 0.2s;
bottom: 290px;
}
.sponsorSkipNoticeUnskipSection {
.noticeLeftIcon {
display: flex;
align-items: center;
}
.sponsorSkipNotice .sponsorSkipNoticeUnskipSection {
float: left;
border-left: 1px solid rgb(150, 150, 150);
@@ -121,6 +241,7 @@
color: rgb(235, 235, 235);
border: none;
display: inline-block;
font-size: 13.3333px !important;
cursor: pointer;
@@ -138,19 +259,25 @@
.sponsorTimesVoteButtonsContainer {
float: left;
vertical-align:middle;
padding: 2px 5px;
margin-right: 4px;
}
.sponsorTimesVoteButtonsContainer div{
display: inline-block;
}
.sponsorSkipNoticeRightSection {
right: 0;
position: absolute;
float: right;
margin-right: 5px;
margin-right: 10px;
display: flex;
align-items: center;
}
.sponsorSkipNoticeRightButton {
@@ -160,6 +287,7 @@
.sponsorSkipNoticeCloseButton {
height: 10px;
width: 10px;
box-sizing: unset;
padding: 2px 5px;
@@ -167,12 +295,19 @@
float: right;
}
.sponsorSkipNoticeCloseButton.biggerCloseButton {
padding: 20px;
}
.sponsorSkipMessage {
font-size: 14px;
font-weight: bold;
color: rgb(235, 235, 235);
margin-top: auto;
display: inline-block;
margin-right: 10px;
margin-bottom: auto;
}
.sponsorSkipInfo {
@@ -206,17 +341,21 @@
.sponsorTimesInfoMessage {
font-size: 13.3333px;
color: rgb(235, 235, 235);
text-align: center;
}
.voteButton {
height: 17px;
height: 24px;
width: 24px;
cursor: pointer;
}
.voteButton:hover {
filter: brightness(80%);
}
.segmentSummary {
outline: none !important;
}
.submitButton {
background-color:#ec1c1c;
-moz-border-radius:28px;
@@ -338,18 +477,21 @@ input::-webkit-inner-spin-button {
margin: 0;
}
.sponsorTimeMessagesRow {
max-height: 300px;
display: flex;
overflow: auto;
}
.sponsorTimeEdit {
font-size: 14px;
-moz-appearance: textfield;
}
.sponsorTimeEditMinutes {
width: 30px;
}
.sponsorTimeEditSeconds {
width: 60px;
.sponsorTimeEditInput {
width: 90px;
}
.sponsorNowButton {
@@ -359,7 +501,7 @@ input::-webkit-inner-spin-button {
text-decoration: underline;
}
.sponsorTimeCategories {
.sponsorTimeEditSelector {
margin-top: 5px;
margin-bottom: 5px;
@@ -368,4 +510,146 @@ input::-webkit-inner-spin-button {
color: white;
border-width: 3px;
padding: 3px;
}
.helpButton {
height: 25px;
cursor: pointer;
padding: 5px;
margin: auto;
top: 0;
bottom: 0;
position: absolute;
}
.helpButton:hover {
filter: brightness(80%);
}
.sbChatNotice iframe {
height: 32px;
cursor: pointer;
height: 100%;
}
.sbChatClose {
height: 14px;
cursor: pointer;
}
.skipButtonControlBarContainer {
cursor: pointer;
display: flex;
color: white;
}
.skipButtonControlBarContainer.hidden {
display: none !important;
}
.skipButtonControlBarContainer.mobile {
bottom: 30%;
margin-left: 5px;
position: absolute;
height: 20px;
background-color: #00000030;
opacity: 0.5;
border-radius: 10px;
padding: 4px;
}
.skipButtonControlBarContainer.mobile.textDisabled {
padding: 0;
background-color: transparent;
}
.skipButtonControlBarContainer.mobile > div {
margin: auto;
margin-left: 5px;
}
#sbSkipIconControlBarImage {
height: 60%;
top: 0px;
bottom: 0px;
display: block;
margin: auto;
}
.mobile #sbSkipIconControlBarImage {
height: 100%;
width: 20px;
}
.sponsorBlockTooltip {
position: absolute;
background-color: rgba(28, 28, 28, 0.7);
border-radius: 5px;
padding: 10px;
max-width: 300px;
white-space: normal;
line-height: 1.5em;
color: white;
font-size: 12px;
z-index: 1000;
}
.sponsorBlockTooltip a {
color: white;
}
.sponsorBlockTooltip.sbTriangle::after {
content: " ";
position: absolute;
top: 100%;
left: 15%;
margin-left: -15px;
border-width: 15px;
border-style: solid;
border-color: rgba(28, 28, 28, 0.7) transparent transparent transparent;
}
.sponsorBlockLockedColor {
color: #ffc83d;
}
.sponsorBlockRectangleTooltip {
position: absolute;
border-radius: 5px;
padding: 10px;
min-width: 250px;
min-height: 75px;
white-space: normal;
line-height: 1.5em;
}
.sponsorBlockCategoryPill {
border-radius: 25px;
padding-left: 8px;
padding-right: 8px;
margin-right: 3px;
cursor: pointer;
font-size: 75%;
height: 100%;
align-items: center;
inline-size: max-content;
}
.sponsorBlockCategoryPillTitleSection {
display: flex;
align-items: center;
}
.categoryPillClose {
display: none;
height: 10px;
width: 10px;
box-sizing: unset;
margin: 0px 0px 0px 5px;
}
.sponsorBlockCategoryPill:hover .categoryPillClose {
display: inherit;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

56
public/help/index.html Normal file
View File

@@ -0,0 +1,56 @@
<!DOCTYPE html>
<head>
<title> SponsorBlock </title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" href="../icons/LogoSponsorBlocker64px.png" type="image/png">
<link href="styles.css" rel="stylesheet"/>
<script src="../js/vendor.js"></script>
<script src="../js/help.js"></script>
</head>
<body>
<div id="title">
<img src="../icons/LogoSponsorBlocker256px.png" height="80" class="profilepic"/>
SponsorLock
</div>
<div class="container sponsorBlockPageBody">
<p>
By using this extension, you agree to the <a href="https://gist.github.com/ajayyy/aa9f8ded2b573d4f73a3ffa0ef74f796">Privacy Policy</a> and <a href="https://gist.github.com/ajayyy/9e8100f069348e0bc062641f34d6af12">Terms of Use</a>.
</p>
<p>
<b>Please uninstall regular SponsorBlock before trying this out.</b> Good luck! This extension was created for April 1st 2022.
</p>
<p style="margin-bottom: 0; margin-top: 0" class="bigText center">__MSG_helpPageReviewOptions__</p>
<iframe class="optionsFrame" src="../options/lock-options.html#embed" style="border: none"></iframe>
<h1>__MSG_helpPageSourceCode__</h1>
<h4 style="display: inline">Client:</h4>
<!-- Github logo -->
<a href="https://github.com/ajayyy/SponsorBlock/tree/april-fools-2022"><svg aria-hidden="true" version="1.1" viewBox="0 0 16 16" height="58px" style="padding-left: 15px"><path fill-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"></path></svg></a>
<h4 style="display: inline; padding-left: 20px">Server:</h4>
<!-- Github logo -->
<a href="https://github.com/ajayyy/SponsorBlockServer"><svg aria-hidden="true" version="1.1" viewBox="0 0 16 16" height="58px" style="padding-left: 15px"><path fill-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"></path></svg></a>
<h1>__MSG_Credits__</h1>
<p>Some icons made by <a href="https://www.flaticon.com/authors/gregor-cresnar" title="Gregor Cresnar">Gregor Cresnar</a> from <a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a> and are licensed by <a href="https://creativecommons.org/licenses/by/3.0/" title="Creative Commons BY 3.0" target="_blank">CC 3.0 BY</a></p>
<p>Some icons made by <a href="https://www.flaticon.com/authors/freepik" title="Freepik">Freepik</a> from <a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a> and are licensed by <a href="https://creativecommons.org/licenses/by/3.0/" title="Creative Commons BY 3.0" target="_blank">CC 3.0 BY</a></p>
<p style="text-align: center;"><a href="/oss-attribution/attribution.txt">Open Source Licenses</a></p>
</div>
</body>

View File

@@ -1,136 +0,0 @@
<!DOCTYPE html>
<head>
<title> SponsorBlock </title>
<meta charset="utf-8">
<link href="styles.css" rel="stylesheet"/>
</head>
<body>
<div id="title">
<img src="../icons/LogoSponsorBlocker256px.png" height="80" class="profilepic"/>
SponsorBlock
</div>
<div class="container">
<p class="createdBy">Created By <a href="https://ajay.app">Ajay Ramachandran</a> <img src="https://ajay.app/newprofilepic.jpg" height="30" class="profilepiccircle"/></p>
<p>
Thanks for installing SponsorBlock. Here are some quick tips for getting started. Feel free to contact me if you have any questions.
</p>
<p class="projectPreview">
<span class="projectPreviewImage">
<a href="https://discord.gg/QnmVMpU"><img width="80" src="https://www.logolynx.com/images/logolynx/1b/1bcc0f0aefe71b2c8ce66ffe8645d365.png"/></a>
</span>
Come contribute, make some suggestions and help out in the Discord: <a href="https://discord.gg/QnmVMpU">https://discord.gg/QnmVMpU</a>
</p>
<div class="center">
<a class="bigText" href="/options/options.html">Enable optional features</a>
</div>
<p>
Some features, such as support for non third-party YouTube sites, are disabled by default and can be enabled in the options. These can be enabled or disabled at any time.
You can also hide/show all UI elements added to the YouTube page.
</p>
<h1>How skipping works</h1>
<p class="projectPreview">
<span class="projectPreviewImageLarge">
<img src="https://i.imgur.com/caf5Bju.png">
</span>
Videos will automatically be skipped if they are found in the database. You can open the popup by clicking the extension icon to get a preview of what they are.
<br/>
<br/>
Whenever you skip a video, you will get a notice report that submission. If the timing seems wrong, report it! You can also vote in the popup. The extension auto upvotes it if you don't report it, so make sure to report when necessary (this can be disabled in the options).
</p>
<div class="center"><img height="120px" src="https://user-images.githubusercontent.com/12688112/63067735-5a638700-bede-11e9-8147-f321b57527ec.gif"></div>
<h1>Submitting</h1>
<p class="projectPreview">
<span class="projectPreviewImageLargeRight">
<img src="https://i.imgur.com/A1ilk6x.gif">
</span>
Submitting can either be done in the popup by hitting the "Sponsorship Starts Now" button or in the video player with the buttons on the player.
<br/>
<br/>
Clicking the play button indicated the start of a sponsorship section and clicking the stop icon indicates the end. You can prepare multiple sponsors before hitting submit. Clicking the upload button will submit. Clicking the garbage can will delete.
</p>
<h1>Editing</h1>
<p class="projectPreview">
<span class="projectPreviewImageLarge">
<img src="https://i.imgur.com/DZHqbsx.gif">
</span>
If you messed up, you can edit or delete your sponsor times in the popup or in the info menu (by hitting the info icon).
</p>
<h1>This is too slow</h1>
<p>
There are hotkeys if you want to use them. You must be focused on the YouTube player to use them. Press the semicolon key to indicate the start/end of a sponsor segment and click the appostrophe to submit.
These can be changed in the options. If you don't use QWERTY, you should probably change the keybinds.
</p>
<h1>I hate these buttons, they are so ugly</h1>
<p>
All player buttons can be hidden in the options.
</p>
<h1>Can I get a copy of the Database? What happens if you disappear?</h1>
<p>
The database is public and available at <a href="https://sponsor.ajay.app/database.db">https://sponsor.ajay.app/database.db</a>. The source code is freely available. So, even if something happens to me, your submissions are not lost.
</p>
<h1>News and how it is made</h1>
<p>
See <a href="https://sponsor.ajay.app/news">https://sponsor.ajay.app/news</a>.
</p>
<h1>I want more features!</h1>
<p>
Ask on Discord or make an Issue on GitHub. I am happy to hear suggestions or improvements you want. You may also contribute code or graphics if you would like.
</p>
<h1>Where can I get the source code?</h1>
<h4 style="display: inline">Client:</h4>
<!-- Github logo -->
<a href="https://github.com/ajayyy/SponsorBlock"><svg aria-hidden="true" version="1.1" viewBox="0 0 16 16" height="58px" style="padding-left: 15px"><path fill-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"></path></svg></a>
<h4 style="display: inline; padding-left: 20px">Server:</h4>
<!-- Github logo -->
<a href="https://github.com/ajayyy/SponsorBlockServer"><svg aria-hidden="true" version="1.1" viewBox="0 0 16 16" height="58px" style="padding-left: 15px"><path fill-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"></path></svg></a>
<h1>Credits</h1>
<p>The awesome <a href="https://github.com/omarroth/invidious/wiki/API">Invidious API</a> is used to grab the time the video was published.</p>
<p>Some icons made by <a href="https://www.flaticon.com/authors/gregor-cresnar" title="Gregor Cresnar">Gregor Cresnar</a> from <a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a> and are licensed by <a href="http://creativecommons.org/licenses/by/3.0/" title="Creative Commons BY 3.0" target="_blank">CC 3.0 BY</a></p>
<p>Some icons made by <a href="https://www.flaticon.com/authors/freepik" title="Freepik">Freepik</a> from <a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a> and are licensed by <a href="http://creativecommons.org/licenses/by/3.0/" title="Creative Commons BY 3.0" target="_blank">CC 3.0 BY</a></p>
</div>
</body>

View File

@@ -1,9 +1,39 @@
:root {
--color-scheme: dark;
--background: #333333;
--header-color: #212121;
--dialog-background: #181818;
--dialog-border: white;
--text: #c4c4c4;
--title: #dad8d8;
--disabled: #520000;
--black: black;
--white: white;
}
[data-theme="light"] {
--color-scheme: light;
--background: #f9f9f9;
--header-color: white;
--dialog-background: #f9f9f9;
--dialog-border: #282828;
--text: #262626;
--title: #707070;
--disabled: #ffcaca;
--black: white;
--white: black;
}
html {
color-scheme: var(--color-scheme);
}
.bigText {
font-size: 50px;
}
body {
background-color: #333333;
background-color: var(--background);
font-family: sans-serif;
}
@@ -11,6 +41,10 @@ body {
text-align: center;
}
.inline {
display: inline-block;
}
.container {
max-width: 60%;
margin: auto;
@@ -36,14 +70,6 @@ body {
transform: translateY(-20%);
}
.projectPreviewImageLargeRight {
position: absolute;
right: -210px;
width: 200px;
top: 50%;
transform: translateY(-50%);
}
.createdBy {
font-size: 14px;
text-align: center;
@@ -58,12 +84,14 @@ body {
vertical-align: middle;
font-size: 50px;
color: #212121;
color: var(--header-color);
padding: 20px;
text-decoration: none;
border-radius: 15px;
transition: font-size 1s;
}
@@ -125,9 +153,12 @@ a {
text-decoration: none;
}
p,li,a {
font-size: 20px;
color: #c4c4c4;
p,li {
font-size: 16px;
}
p,li,a,span,div {
color: var(--text);
}
p,li,code,a {
@@ -135,18 +166,9 @@ p,li,code,a {
overflow-wrap: break-word;
}
@media screen and (orientation:portrait) {
p,li,code,a {
max-width: 100%;
}
.projectPreviewImage {
position: unset;
width: 130px;
display: block;
margin: auto;
transform: none;
}
.optionsFrame {
width: 100%;
height: 500px;
}
.previewImage {
@@ -170,10 +192,134 @@ img {
}
h1,h2,h3,h4,h5,h6 {
color: #dad8d8;
color: var(--title);
text-align: center;
}
svg {
text-decoration: none;
}
#sbDonate {
font-size: 10px;
}
@media screen and (orientation:portrait) {
.projectPreviewImage {
position: unset;
width: 50%;
display: block;
margin: auto;
transform: none;
}
.projectPreviewImageLarge {
position: unset;
left: 0;
width: 50%;
display: block;
margin: auto;
transform: unset;
}
.container {
max-width: 100%;
margin: 5px;
text-align: center;
}
p,li,code,a {
text-align: center;
}
}
/* keybind dialog */
.key {
border-width: 1px;
border-style: solid;
border-radius: 5px;
display: inline-block;
min-width: 33px;
text-align: center;
font-weight: bold;
border-color: var(--white);
box-sizing: border-box;
}
.unbound, .key {
padding: 8px;
}
#keybind-dialog .dialog {
position: fixed;
border-width: 3px;
border-style: solid;
border-radius: 15px;
max-height: 100vh;
width: 400px;
overflow-x: auto;
z-index: 100;
padding: 15px;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
font-size: 14px;
background-color: var(--dialog-background);
border-color: var(--dialog-border);
}
#change-keybind-buttons {
float: right;
}
#change-keybind-buttons > .option-button {
margin: 0 2px;
}
#change-keybind-settings {
margin: 15px 15px 30px;
}
#change-keybind-settings .key {
vertical-align: top;
margin: 15px 0 0 40px;
height: 34px;
}
#change-keybind-error {
margin-bottom: 15px;
color: red;
font-weight: bold;
}
.blocker {
position: fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
z-index: 90;
background-color: #00000080;
}
.option-button {
cursor: pointer;
background-color: #c00000;
padding: 10px;
color: white;
border-radius: 5px;
font-size: 14px;
width: max-content;
}
.option-button:hover:not(.disabled) {
background-color: #fc0303;
}
.option-button.disabled {
cursor: default;
background-color: var(--disabled);
color: grey;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.1 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -0,0 +1,68 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
viewBox="0 0 565.15 568"
version="1.1"
id="svg16"
sodipodi:docname="PlayerCancelSegmentIconSponsorBlocker.svg"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
inkscape:export-filename="D:\Dell Data\_Projects\_____SponsorSkip\ignored\svg\SponsorBlocker4.png"
inkscape:export-xdpi="43.436523"
inkscape:export-ydpi="43.436523">
<metadata
id="metadata20">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>LogoSponsorBlocker2</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1001"
id="namedview18"
showgrid="false"
inkscape:zoom="0.83098592"
inkscape:cx="220.07455"
inkscape:cy="308.76246"
inkscape:window-x="477"
inkscape:window-y="961"
inkscape:window-maximized="1"
inkscape:current-layer="svg16"
inkscape:pagecheckerboard="true" />
<defs
id="defs4">
<style
id="style2">.cls-1{fill:red;}.cls-2{fill:#fff;}</style>
</defs>
<title
id="title6">LogoSponsorBlocker2</title>
<path
class="cls-1"
d="m 282.58,568 a 65,65 0 0 1 -34.14,-9.66 C 95.41,463.94 2.54,300.46 0,121 a 64.91,64.91 0 0 1 34,-58.09 522.56,522.56 0 0 1 497.16,0 64.91,64.91 0 0 1 34,58.12 c -2.53,179.43 -95.4,342.91 -248.42,437.3 A 65,65 0 0 1 282.58,568 Z m 0,-548.31 A 502.24,502.24 0 0 0 43.4,80.22 45.27,45.27 0 0 0 19.7,120.75 c 2.44,172.67 91.81,330 239.07,420.83 a 46.19,46.19 0 0 0 47.61,0 C 453.64,450.73 543,293.42 545.45,120.75 A 45.26,45.26 0 0 0 521.75,80.21 502.26,502.26 0 0 0 282.58,19.69 Z"
id="path8"
inkscape:connector-curvature="0"
style="fill:#ffffff" />
<path
style="fill:#ffffff"
d="M 284.70508 42.693359 A 479.9 479.9 0 0 0 54.369141 100.41992 A 22.53 22.53 0 0 0 42.669922 120.41992 C 45.069922 290.25992 135.67008 438.63977 270.83008 522.00977 A 22.48 22.48 0 0 0 294.32031 522.00977 C 429.48031 438.63977 520.08047 290.25992 522.48047 120.41992 A 22.53 22.53 0 0 0 510.7793 100.41992 A 479.9 479.9 0 0 0 284.70508 42.693359 z M 224.94922 162.35352 L 282.57422 219.98047 L 340.20117 162.35352 L 384.33984 206.49219 L 326.71484 264.11719 L 384.33984 321.74414 L 340.20117 365.88281 L 282.57422 308.25781 L 224.94922 365.88281 L 180.81055 321.74414 L 238.4375 264.11719 L 180.81055 206.49219 L 224.94922 162.35352 z "
id="path10" />
</svg>

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@@ -0,0 +1,88 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
viewBox="0 0 565.15 568"
version="1.1"
id="svg16"
sodipodi:docname="PlayerDeleteIconSponsorBlocker.svg"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
inkscape:export-filename="D:\Dell Data\_Projects\_____SponsorSkip\ignored\svg\SponsorBlocker4.png"
inkscape:export-xdpi="43.436523"
inkscape:export-ydpi="43.436523">
<metadata
id="metadata20">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>LogoSponsorBlocker2</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1001"
id="namedview18"
showgrid="false"
inkscape:zoom="0.83098592"
inkscape:cx="209.2657"
inkscape:cy="235.85704"
inkscape:window-x="477"
inkscape:window-y="961"
inkscape:window-maximized="1"
inkscape:current-layer="svg16" />
<defs
id="defs4">
<style
id="style2">.cls-1{fill:red;}.cls-2{fill:#fff;}</style>
</defs>
<title
id="title6">LogoSponsorBlocker2</title>
<path
class="cls-1"
d="m 282.58,568 a 65,65 0 0 1 -34.14,-9.66 C 95.41,463.94 2.54,300.46 0,121 a 64.91,64.91 0 0 1 34,-58.09 522.56,522.56 0 0 1 497.16,0 64.91,64.91 0 0 1 34,58.12 c -2.53,179.43 -95.4,342.91 -248.42,437.3 A 65,65 0 0 1 282.58,568 Z m 0,-548.31 A 502.24,502.24 0 0 0 43.4,80.22 45.27,45.27 0 0 0 19.7,120.75 c 2.44,172.67 91.81,330 239.07,420.83 a 46.19,46.19 0 0 0 47.61,0 C 453.64,450.73 543,293.42 545.45,120.75 A 45.26,45.26 0 0 0 521.75,80.21 502.26,502.26 0 0 0 282.58,19.69 Z"
id="path8"
inkscape:connector-curvature="0"
style="fill:#ffffff" />
<path
style="fill:#ffffff"
d="M 284.70508 42.693359 A 479.9 479.9 0 0 0 54.369141 100.41992 A 22.53 22.53 0 0 0 42.669922 120.41992 C 45.069922 290.25992 135.67008 438.63977 270.83008 522.00977 A 22.48 22.48 0 0 0 294.32031 522.00977 C 429.48031 438.63977 520.08047 290.25992 522.48047 120.41992 A 22.53 22.53 0 0 0 510.7793 100.41992 A 479.9 479.9 0 0 0 284.70508 42.693359 z M 184.84375 113.77344 L 380.30664 113.77344 L 380.30664 161.31836 L 184.84375 161.31836 L 184.84375 113.77344 z M 184.84375 174.45703 L 380.30469 174.45703 L 380.30469 430.16992 L 184.84375 430.16992 L 184.84375 174.45703 z "
id="path10" />
<g
id="g849"
transform="matrix(1.1485222,0,0,1.1485222,-41.968703,-56.737897)"
style="fill:#ffffff">
<g
id="g869"
style="fill:#ffffff">
<path
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.84762007;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 223.01024,230.22964 H 245.1343 V 395.01181 H 223.01024 Z"
id="rect857" />
<path
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.84762007;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 271.51297,230.22964 h 22.12406 v 164.78217 h -22.12406 z"
id="rect859" />
<path
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.84762007;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 317.46292,230.22964 h 22.12406 v 164.78217 h -22.12406 z"
id="rect861" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" id="svg16" version="1.1" viewBox="0 0 565.15 568">
<defs/>
<defs id="defs4"/>
<path id="path8" fill="#fff" d="M282.58 568a65 65 0 01-34.14-9.66C95.41 463.94 2.54 300.46 0 121a64.91 64.91 0 0134-58.09 522.56 522.56 0 01497.16 0 64.91 64.91 0 0134 58.12c-2.53 179.43-95.4 342.91-248.42 437.3a65 65 0 01-34.16 9.67zm0-548.31A502.24 502.24 0 0043.4 80.22a45.27 45.27 0 00-23.7 40.53c2.44 172.67 91.81 330 239.07 420.83a46.19 46.19 0 0047.61 0C453.64 450.73 543 293.42 545.45 120.75a45.26 45.26 0 00-23.7-40.54 502.26 502.26 0 00-239.17-60.52z"/>
<path id="path10" fill="#fff" d="M284.705 42.693A479.9 479.9 0 0054.37 100.42a22.53 22.53 0 00-11.7 20c2.4 169.84 93.001 318.22 228.161 401.59a22.48 22.48 0 0023.49 0c135.16-83.37 225.76-231.75 228.16-401.59a22.53 22.53 0 00-11.7-20 479.9 479.9 0 00-226.075-57.727zm-2.13 59.344c89.347 0 162.081 72.712 162.081 162.08 0 89.368-72.734 162.082-162.082 162.082-89.368 0-162.08-72.714-162.08-162.082s72.712-162.08 162.08-162.08zm0 30.389c-72.613 0-131.692 59.079-131.692 131.691 0 72.613 59.079 131.692 131.691 131.692 72.613 0 131.692-59.08 131.692-131.692 0-72.612-59.08-131.691-131.692-131.691zm-2.563 16.695c14.121 0 24.363 10.606 24.363 24.049 0 13.483-10.272 23.432-24.697 23.432-14.73 0-24.354-9.949-24.354-23.432 0-13.443 9.624-24.049 24.688-24.049zm-34.938 68.691h57.397l-.02 134.692 18.295.973v25.638h-76.32v-24.373l10.586-.953c5.754-.638 9.279-2.573 9.279-10.271v-89.155c0-7.08-1.905-9.32-8.014-9.32l-11.203-.629v-26.601z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -0,0 +1,76 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 565.15 568"
version="1.1"
id="svg16"
sodipodi:docname="PlayerStartIconSponsorBlocker.svg"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04, custom)"
inkscape:export-filename="/home/ajay/projects/sb-extension/public/icons/LogoSponsorBlocker1024px.png"
inkscape:export-xdpi="173.9155"
inkscape:export-ydpi="173.9155"
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"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<metadata
id="metadata20">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="983"
id="namedview18"
showgrid="false"
inkscape:zoom="0.83098592"
inkscape:cx="444.69697"
inkscape:cy="271.26356"
inkscape:window-x="380"
inkscape:window-y="768"
inkscape:window-maximized="1"
inkscape:current-layer="Layer_1-2"
inkscape:pagecheckerboard="0" />
<defs
id="defs4">
<style
id="style2">.cls-1{fill:red;}.cls-2{fill:#fff;}</style>
</defs>
<title
id="title6">LogoSponsorBlocker2</title>
<g
id="Layer_2"
data-name="Layer 2">
<g
id="Layer_1-2"
data-name="Layer 1"
style="fill:#ffffff">
<path
id="path953"
style="fill:none;stroke:#07a500;stroke-width:40"
d="M 279.39062,24.197266 C 179.21701,24.603169 98.318528,101.48391 98.605469,196.00391 c 0.159023,40.69515 15.666041,80.00792 43.744141,110.89843 V 147.87891 l 16.75935,97.00627 C 164.72335,211.06602 65.553309,180.55346 92.112522,170.56303 L 193.6089,410.46016 435.49163,328.41259 443.41016,147.87891 v 46.7539 l 18.32422,-0.0996 C 461.16135,100.01356 379.56507,23.790617 279.39062,24.197266 Z M 443.41016,195.51367 v 74.92188 c 12.04625,-23.34115 18.3128,-48.96032 18.32617,-74.92188 z"
sodipodi:nodetypes="cccccccccccccccc" />
<path
style="fill:#008000"
d="m 281.94584,119.65312 -239.275918,0.7668 c 0,0 -0.08983,-8.3148 0,0 2.4,169.84 93.000158,318.21985 228.160158,401.58985 7.20735,4.41633 16.28288,4.41633 23.49023,0 135.16,-83.37 225.76016,-231.74985 228.16016,-401.58985 v 0 z M 220.41016,145.74023 411.2793,255.93945 220.41016,366.14062 Z"
id="path10"
sodipodi:nodetypes="cccccccccccc" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

View File

@@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
viewBox="0 0 565.15 568"
version="1.1"
id="svg16"
sodipodi:docname="PlayerStopIconSponsorBlocker.svg"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
inkscape:export-filename="D:\Dell Data\_Projects\_____SponsorSkip\ignored\svg\SponsorBlocker4.png"
inkscape:export-xdpi="43.436523"
inkscape:export-ydpi="43.436523">
<metadata
id="metadata20">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>LogoSponsorBlocker2</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1001"
id="namedview18"
showgrid="false"
inkscape:zoom="0.83098595"
inkscape:cx="194.89884"
inkscape:cy="305.06785"
inkscape:window-x="477"
inkscape:window-y="961"
inkscape:window-maximized="1"
inkscape:current-layer="svg16" />
<defs
id="defs4">
<style
id="style2">.cls-1{fill:red;}.cls-2{fill:#fff;}</style>
</defs>
<title
id="title6">LogoSponsorBlocker2</title>
<path
class="cls-1"
d="m 282.58,568 a 65,65 0 0 1 -34.14,-9.66 C 95.41,463.94 2.54,300.46 0,121 a 64.91,64.91 0 0 1 34,-58.09 522.56,522.56 0 0 1 497.16,0 64.91,64.91 0 0 1 34,58.12 c -2.53,179.43 -95.4,342.91 -248.42,437.3 A 65,65 0 0 1 282.58,568 Z m 0,-548.31 A 502.24,502.24 0 0 0 43.4,80.22 45.27,45.27 0 0 0 19.7,120.75 c 2.44,172.67 91.81,330 239.07,420.83 a 46.19,46.19 0 0 0 47.61,0 C 453.64,450.73 543,293.42 545.45,120.75 A 45.26,45.26 0 0 0 521.75,80.21 502.26,502.26 0 0 0 282.58,19.69 Z"
id="path8"
inkscape:connector-curvature="0"
style="fill:#ffffff" />
<path
style="fill:#ffffff"
d="M 284.70508 42.693359 A 479.9 479.9 0 0 0 54.369141 100.41992 A 22.53 22.53 0 0 0 42.669922 120.41992 C 45.069922 290.25992 135.67008 438.63977 270.83008 522.00977 A 22.48 22.48 0 0 0 294.32031 522.00977 C 429.48031 438.63977 520.08047 290.25992 522.48047 120.41992 A 22.53 22.53 0 0 0 510.7793 100.41992 A 479.9 479.9 0 0 0 284.70508 42.693359 z M 187.11914 147.00977 L 378.03125 147.00977 L 378.03125 351.04102 L 187.11914 351.04102 L 187.11914 147.00977 z "
id="path10" />
</svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

View File

@@ -0,0 +1,71 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
viewBox="0 0 565.15 568"
version="1.1"
id="svg16"
sodipodi:docname="PlayerUploadFailedIconSponsorBlocker.svg"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
inkscape:export-filename="D:\Dell Data\_Projects\_____SponsorSkip\ignored\svg\SponsorBlocker4.png"
inkscape:export-xdpi="43.436523"
inkscape:export-ydpi="43.436523">
<metadata
id="metadata20">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>LogoSponsorBlocker2</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1001"
id="namedview18"
showgrid="false"
inkscape:zoom="0.83098592"
inkscape:cx="-277.20441"
inkscape:cy="286.71724"
inkscape:window-x="477"
inkscape:window-y="961"
inkscape:window-maximized="1"
inkscape:current-layer="svg16" />
<defs
id="defs4">
<style
id="style2">.cls-1{fill:red;}.cls-2{fill:#fff;}</style>
</defs>
<title
id="title6">LogoSponsorBlocker2</title>
<path
class="cls-1"
d="m 282.58,568 a 65,65 0 0 1 -34.14,-9.66 C 95.41,463.94 2.54,300.46 0,121 a 64.91,64.91 0 0 1 34,-58.09 522.56,522.56 0 0 1 497.16,0 64.91,64.91 0 0 1 34,58.12 c -2.53,179.43 -95.4,342.91 -248.42,437.3 A 65,65 0 0 1 282.58,568 Z m 0,-548.31 A 502.24,502.24 0 0 0 43.4,80.22 45.27,45.27 0 0 0 19.7,120.75 c 2.44,172.67 91.81,330 239.07,420.83 a 46.19,46.19 0 0 0 47.61,0 C 453.64,450.73 543,293.42 545.45,120.75 A 45.26,45.26 0 0 0 521.75,80.21 502.26,502.26 0 0 0 282.58,19.69 Z"
id="path8"
inkscape:connector-curvature="0"
style="fill:#ffffff" />
<path
style="fill:#ffffff"
d="M 284.70508 42.693359 A 479.9 479.9 0 0 0 54.369141 100.41992 A 22.53 22.53 0 0 0 42.669922 120.41992 C 45.069922 290.25992 135.67008 438.63977 270.83008 522.00977 A 22.48 22.48 0 0 0 294.32031 522.00977 C 429.48031 438.63977 520.08047 290.25992 522.48047 120.41992 A 22.53 22.53 0 0 0 510.7793 100.41992 A 479.9 479.9 0 0 0 284.70508 42.693359 z M 282.57422 123.27344 C 302.2486 123.27344 318.08789 139.67142 318.08789 160.03906 L 318.08789 310.16211 C 318.08789 330.52975 302.2486 346.92773 282.57422 346.92773 C 262.89984 346.92773 247.0625 330.52975 247.0625 310.16211 L 247.0625 160.03906 C 247.0625 139.67142 262.89984 123.27344 282.57422 123.27344 z M 282.57422 373.71094 C 302.2487 373.71094 318.08789 389.55014 318.08789 409.22461 C 318.08789 428.89909 302.2487 444.73633 282.57422 444.73633 C 262.89975 444.73633 247.06055 428.89909 247.06055 409.22461 C 247.06055 389.55014 262.89975 373.71094 282.57422 373.71094 z "
id="path10" />
<g
id="g821"
transform="translate(0,32.491428)"
style="fill:#ffffff" />
</svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
viewBox="0 0 565.15 568"
version="1.1"
id="svg16"
sodipodi:docname="PlayerUploadIconSponsorBlocker.svg"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
inkscape:export-filename="D:\Dell Data\_Projects\_____SponsorSkip\ignored\svg\SponsorBlocker4.png"
inkscape:export-xdpi="43.436523"
inkscape:export-ydpi="43.436523">
<metadata
id="metadata20">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>LogoSponsorBlocker2</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1001"
id="namedview18"
showgrid="false"
inkscape:zoom="0.83098595"
inkscape:cx="-374.9496"
inkscape:cy="291.99093"
inkscape:window-x="477"
inkscape:window-y="961"
inkscape:window-maximized="1"
inkscape:current-layer="svg16" />
<defs
id="defs4">
<style
id="style2">.cls-1{fill:red;}.cls-2{fill:#fff;}</style>
</defs>
<title
id="title6">LogoSponsorBlocker2</title>
<path
class="cls-1"
d="m 282.58,568 a 65,65 0 0 1 -34.14,-9.66 C 95.41,463.94 2.54,300.46 0,121 a 64.91,64.91 0 0 1 34,-58.09 522.56,522.56 0 0 1 497.16,0 64.91,64.91 0 0 1 34,58.12 c -2.53,179.43 -95.4,342.91 -248.42,437.3 A 65,65 0 0 1 282.58,568 Z m 0,-548.31 A 502.24,502.24 0 0 0 43.4,80.22 45.27,45.27 0 0 0 19.7,120.75 c 2.44,172.67 91.81,330 239.07,420.83 a 46.19,46.19 0 0 0 47.61,0 C 453.64,450.73 543,293.42 545.45,120.75 A 45.26,45.26 0 0 0 521.75,80.21 502.26,502.26 0 0 0 282.58,19.69 Z"
id="path8"
inkscape:connector-curvature="0"
style="fill:#ffffff" />
<path
style="fill:#ffffff"
d="M 284.70508 42.693359 A 479.9 479.9 0 0 0 54.369141 100.41992 A 22.53 22.53 0 0 0 42.669922 120.41992 C 45.069922 290.25992 135.67008 438.63977 270.83008 522.00977 A 22.48 22.48 0 0 0 294.32031 522.00977 C 429.48031 438.63977 520.08047 290.25992 522.48047 120.41992 A 22.53 22.53 0 0 0 510.7793 100.41992 A 479.9 479.9 0 0 0 284.70508 42.693359 z M 282.57422 112.11133 L 282.87109 112.11133 L 423.75977 365.75391 L 330.30273 365.75391 L 330.30273 409.21094 L 234.84766 409.21094 L 234.84766 365.75391 L 141.39062 365.75391 L 282.57422 112.11133 z "
id="path10" />
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

1
public/icons/check.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24"><path fill="#fff" d="M20.3 2L9 13.6l-5.3-5L0 12.3 9 21 24 5.7z"/></svg>

After

Width:  |  Height:  |  Size: 134 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="white" width="18px" height="18px"><path d="M0 0h24v24H0z" fill="none"/><path d="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm-1 4l6 6v10c0 1.1-.9 2-2 2H7.99C6.89 23 6 22.1 6 21l.01-14c0-1.1.89-2 1.99-2h7zm-1 7h5.5L14 6.5V12z"/></svg>

After

Width:  |  Height:  |  Size: 291 B

43
public/icons/heart.svg Normal file
View File

@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
height="24px"
viewBox="0 0 24 24"
width="24px"
fill="#000000"
version="1.1"
id="svg6"
sodipodi:docname="heart.svg"
inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20, 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="defs10" />
<sodipodi:namedview
id="namedview8"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="32.916667"
inkscape:cx="11.98481"
inkscape:cy="12.01519"
inkscape:window-width="1366"
inkscape:window-height="731"
inkscape:window-x="1366"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg6" />
<path
d="M0 0h24v24H0V0z"
fill="none"
id="path2" />
<path
d="M16.5 3c-1.74 0-3.41.81-4.5 2.09C10.91 3.81 9.24 3 7.5 3 4.42 3 2 5.42 2 8.5c0 3.78 3.4 6.86 8.55 11.54L12 21.35l1.45-1.32C18.6 15.36 22 12.28 22 8.5 22 5.42 19.58 3 16.5 3zm-4.4 15.55l-.1.1-.1-.1C7.14 14.24 4 11.39 4 8.5 4 6.5 5.5 5 7.5 5c1.54 0 3.04.99 3.57 2.36h1.87C13.46 5.99 14.96 5 16.5 5c2 0 3.5 1.5 3.5 3.5 0 2.89-3.14 5.74-7.9 10.05z"
id="path4"
style="fill:#800000" />
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

58
public/icons/help.svg Normal file
View File

@@ -0,0 +1,58 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
height="24"
viewBox="0 0 24 24"
width="24"
version="1.1"
id="svg6"
sodipodi:docname="help.svg"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)">
<metadata
id="metadata12">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs10" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="730"
inkscape:window-height="480"
id="namedview8"
showgrid="false"
inkscape:zoom="9.8333333"
inkscape:cx="12"
inkscape:cy="12"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="svg6" />
<path
d="M0 0h24v24H0z"
fill="none"
id="path2" />
<path
d="M11 18h2v-2h-2v2zm1-16C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm0-14c-2.21 0-4 1.79-4 4h2c0-1.1.9-2 2-2s2 .9 2 2c0 2-3 1.75-3 5h2c0-2.25 3-2.5 3-5 0-2.21-1.79-4-4-4z"
id="path4"
style="fill:#ffffff" />
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
height="24px"
viewBox="0 0 24 24"
width="24px"
fill="#000000"
version="1.1"
id="svg6"
sodipodi:docname="not_visible.svg"
inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20, 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="defs10" />
<sodipodi:namedview
id="namedview8"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="16.458334"
inkscape:cx="3.8582278"
inkscape:cy="9.1443037"
inkscape:window-width="1920"
inkscape:window-height="983"
inkscape:window-x="426"
inkscape:window-y="768"
inkscape:window-maximized="1"
inkscape:current-layer="svg6" />
<path
d="M12 7c2.76 0 5 2.24 5 5 0 .65-.13 1.26-.36 1.83l2.92 2.92c1.51-1.26 2.7-2.89 3.43-4.75-1.73-4.39-6-7.5-11-7.5-1.4 0-2.74.25-3.98.7l2.16 2.16C10.74 7.13 11.35 7 12 7zM2 4.27l2.28 2.28.46.46C3.08 8.3 1.78 10.02 1 12c1.73 4.39 6 7.5 11 7.5 1.55 0 3.03-.3 4.38-.84l.42.42L19.73 22 21 20.73 3.27 3 2 4.27zM7.53 9.8l1.55 1.55c-.05.21-.08.43-.08.65 0 1.66 1.34 3 3 3 .22 0 .44-.03.65-.08l1.55 1.55c-.67.33-1.41.53-2.2.53-2.76 0-5-2.24-5-5 0-.79.2-1.53.53-2.2zm4.31-.78l3.15 3.15.02-.16c0-1.66-1.34-3-3-3l-.17.01z"
id="path4"
style="fill:#ffffff" />
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

59
public/icons/pause.svg Normal file
View File

@@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
height="24px"
viewBox="0 0 24 24"
width="24px"
fill="#000000"
version="1.1"
id="svg6"
sodipodi:docname="pause.svg"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)">
<metadata
id="metadata12">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs10" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="730"
inkscape:window-height="480"
id="namedview8"
showgrid="false"
inkscape:zoom="9.8333333"
inkscape:cx="12"
inkscape:cy="12"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="svg6" />
<path
d="M0 0h24v24H0z"
fill="none"
id="path2" />
<path
d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"
id="path4"
style="fill:#ffffff" />
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

1
public/icons/pencil.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24"><path fill="#fff" d="M14.1 7.1l2.9 2.9L6.1 20.7l-3.6.7.7-3.6L14.1 7.1zm0-2.8L1.4 16.9 0 24l7.1-1.4L19.8 9.9l-5.7-5.7zm7.1 4.3L24 5.7 18.3 0l-2.8 2.8 5.7 5.7z"/></svg>

After

Width:  |  Height:  |  Size: 229 B

1
public/icons/refresh.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#FFFFFF"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M17.65 6.35C16.2 4.9 14.21 4 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08c-.82 2.33-3.04 4-5.65 4-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z"/></svg>

After

Width:  |  Height:  |  Size: 361 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24"><path fill="#fff" d="M24 13.6v-3.2c-1.7-.6-2.7-.8-3.2-2h0c-.5-1.3.1-2.1.8-3.7l-2.3-2.3c-1.6.7-2.4 1.4-3.7.8h0c-1.3-.5-1.4-1.6-2-3.2h-3.2c-.6 1.6-.7 2.7-2 3.2h0c-1.3.5-2.1-.1-3.7-.8L2.4 4.7c.7 1.6 1.4 2.4.8 3.7s-1.6 1.4-3.2 2v3.2c1.6.6 2.7.7 3.2 2 .5 1.3-.1 2.2-.8 3.7l2.3 2.3c1.6-.7 2.4-1.4 3.7-.8h0c1.3.5 1.4 1.6 2 3.2h3.2c.6-1.6.8-2.7 2-3.2h0c1.3-.5 2.1.1 3.7.9l2.3-2.3c-.7-1.6-1.4-2.4-.8-3.7s1.6-1.4 3.2-2zM12 16a4 4 0 1 1 0-8 4 4 0 1 1 0 8z"/></svg>

After

Width:  |  Height:  |  Size: 516 B

71
public/icons/skipIcon.svg Normal file
View File

@@ -0,0 +1,71 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
viewBox="0 0 565.15 568"
version="1.1"
id="svg16"
sodipodi:docname="skipIcon.svg"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
inkscape:export-filename="D:\Dell Data\_Projects\_____SponsorSkip\ignored\svg\SponsorBlocker4.png"
inkscape:export-xdpi="43.436523"
inkscape:export-ydpi="43.436523">
<metadata
id="metadata20">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>LogoSponsorBlocker2</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1001"
id="namedview18"
showgrid="false"
inkscape:zoom="1.6619718"
inkscape:cx="316.31071"
inkscape:cy="330.01409"
inkscape:window-x="477"
inkscape:window-y="961"
inkscape:window-maximized="1"
inkscape:current-layer="svg16"
inkscape:pagecheckerboard="true" />
<defs
id="defs4">
<style
id="style2">.cls-1{fill:red;}.cls-2{fill:#fff;}</style>
</defs>
<title
id="title6">LogoSponsorBlocker2</title>
<path
class="cls-1"
d="m 282.58,568 a 65,65 0 0 1 -34.14,-9.66 C 95.41,463.94 2.54,300.46 0,121 a 64.91,64.91 0 0 1 34,-58.09 522.56,522.56 0 0 1 497.16,0 64.91,64.91 0 0 1 34,58.12 c -2.53,179.43 -95.4,342.91 -248.42,437.3 A 65,65 0 0 1 282.58,568 Z m 0,-548.31 A 502.24,502.24 0 0 0 43.4,80.22 45.27,45.27 0 0 0 19.7,120.75 c 2.44,172.67 91.81,330 239.07,420.83 a 46.19,46.19 0 0 0 47.61,0 C 453.64,450.73 543,293.42 545.45,120.75 A 45.26,45.26 0 0 0 521.75,80.21 502.26,502.26 0 0 0 282.58,19.69 Z"
id="path8"
inkscape:connector-curvature="0"
style="fill:#ffffff" />
<path
style="fill:#ffffff"
d="M 284.70508 42.693359 A 479.9 479.9 0 0 0 54.369141 100.41992 A 22.53 22.53 0 0 0 42.669922 120.41992 C 45.069922 290.25992 135.67008 438.63977 270.83008 522.00977 A 22.48 22.48 0 0 0 294.32031 522.00977 C 429.48031 438.63977 520.08047 290.25992 522.48047 120.41992 A 22.53 22.53 0 0 0 510.7793 100.41992 A 479.9 479.9 0 0 0 284.70508 42.693359 z M 188.7168 140.07227 L 312.64844 264.00586 L 188.7168 387.9375 L 159.5918 358.8125 L 254.19336 264.00586 L 159.5918 169.19727 L 188.7168 140.07227 z M 305.625 140.07227 L 429.55859 264.00586 L 305.625 387.9375 L 276.50195 358.8125 L 371.10352 264.00586 L 276.50195 169.19727 L 305.625 140.07227 z "
id="path10" />
<g
id="g825"
transform="translate(-3.86549,36.564644)" />
</svg>

After

Width:  |  Height:  |  Size: 3.1 KiB

59
public/icons/stop.svg Normal file
View File

@@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
height="24px"
viewBox="0 0 24 24"
width="24px"
fill="#000000"
version="1.1"
id="svg6"
sodipodi:docname="stop.svg"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)">
<metadata
id="metadata12">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs10" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="730"
inkscape:window-height="480"
id="namedview8"
showgrid="false"
inkscape:zoom="9.8333333"
inkscape:cx="12"
inkscape:cy="12"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="svg6" />
<path
d="M0 0h24v24H0z"
fill="none"
id="path2" />
<path
d="M6 6h12v12H6z"
id="path4"
style="fill:#ffffff" />
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

1
public/icons/thumb.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24"><path fill="#fff" d="M21.4 9.6c-1.2 0-2.9-.3-4-.8.8-3.3 1.3-8.8-2.2-8.8-1.8 0-2.3 1.7-2.8 3.3-1.6 5.4-4 6.9-6.4 7.5V10H0v12h6v-.9a19.2 19.2 0 016.2 1.8c1.2.5 3 1.1 5.3 1.1 2.5 0 4.3-1 5-3.7.5-1.9 1.5-7.2 1.5-8.2 0-1.7-1.2-2.5-2.6-2.5zM4 20H2v-8h2v8zm15.9-5.6h1c1.2 0 1.1 1.5 0 1.6h-1.7c-.7.2-.7 1.3.1 1.2h1.2c1 0 1 1.4 0 1.5l-1.7.1c-.8.1-.7 1.3 0 1.2h.8c.9-.1 1 .8-.3 1.6-1.5.9-4.6.1-6.4-.6-2.2-1-4.4-2-7-2v-6c3.3-.8 6.4-2.3 8.4-9.1.9-3.1 1.7-2 1.7.6 0 2-.5 3.8-1 5.5 1.1.5 3.4 1.4 6.2 1.6 1 0 1 1.4 0 1.5l-1.5.2s-.6 1.1.2 1.1z"/></svg>

After

Width:  |  Height:  |  Size: 599 B

View File

@@ -0,0 +1,58 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
height="24"
viewBox="0 0 24 24"
width="24"
version="1.1"
id="svg6"
sodipodi:docname="thumbs_down.svg"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)">
<metadata
id="metadata12">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs10" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="730"
inkscape:window-height="480"
id="namedview8"
showgrid="false"
inkscape:zoom="9.8333333"
inkscape:cx="12"
inkscape:cy="12"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="svg6" />
<path
d="M0 0h24v24H0z"
fill="none"
id="path2" />
<path
d="M15 3H6c-.83 0-1.54.5-1.84 1.22l-3.02 7.05c-.09.23-.14.47-.14.73v2c0 1.1.9 2 2 2h6.31l-.95 4.57-.03.32c0 .41.17.79.44 1.06L9.83 23l6.59-6.59c.36-.36.58-.86.58-1.41V5c0-1.1-.9-2-2-2zm4 0v12h4V3h-4z"
id="path4"
style="fill:#ffffff" />
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -0,0 +1,58 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
height="24"
viewBox="0 0 24 24"
width="24"
version="1.1"
id="svg6"
sodipodi:docname="thumbs_down.svg"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)">
<metadata
id="metadata12">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs10" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="730"
inkscape:window-height="480"
id="namedview8"
showgrid="false"
inkscape:zoom="9.8333333"
inkscape:cx="12"
inkscape:cy="12"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="svg6" />
<path
d="M0 0h24v24H0z"
fill="none"
id="path2" />
<path
d="M15 3H6c-.83 0-1.54.5-1.84 1.22l-3.02 7.05c-.09.23-.14.47-.14.73v2c0 1.1.9 2 2 2h6.31l-.95 4.57-.03.32c0 .41.17.79.44 1.06L9.83 23l6.59-6.59c.36-.36.58-.86.58-1.41V5c0-1.1-.9-2-2-2zm4 0v12h4V3h-4z"
id="path4"
style="fill:#ffc83d" />
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
viewBox="0 0 24 24"
fill="black"
width="18px"
height="18px"
version="1.1"
id="svg6"
sodipodi:docname="thumbs_up.svg"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)">
<metadata
id="metadata12">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs10" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="730"
inkscape:window-height="480"
id="namedview8"
showgrid="false"
inkscape:zoom="13.111111"
inkscape:cx="9"
inkscape:cy="9"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="svg6" />
<path
d="M0 0h24v24H0V0z"
fill="none"
id="path2" />
<path
d="M1 21h4V9H1v12zm22-11c0-1.1-.9-2-2-2h-6.31l.95-4.57.03-.32c0-.41-.17-.79-.44-1.06L14.17 1 7.59 7.59C7.22 7.95 7 8.45 7 9v10c0 1.1.9 2 2 2h9c.83 0 1.54-.5 1.84-1.22l3.02-7.05c.09-.23.14-.47.14-.73v-2z"
id="path4"
style="fill:#ffffff" />
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

1
public/icons/visible.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#FFFFFF"><path d="M0 0h24v24H0z" fill="none"/><path d="M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z"/></svg>

After

Width:  |  Height:  |  Size: 366 B

View File

@@ -3,7 +3,7 @@
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 400;
src: local('Source Sans Pro Regular'), local('SourceSansPro-Regular'), url(https://fonts.gstatic.com/s/sourcesanspro/v12/6xK3dSBYKcSV-LCoeQqfX1RYOo3qNa7lqDY.woff2) format('woff2');
src: local('Source Sans Pro Regular'), local('SourceSansPro-Regular'), url(https://fonts.gstatic.com/s/sourcesanspro/v13/6xK3dSBYKcSV-LCoeQqfX1RYOo3qNa7lqDY.woff2) format('woff2');
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@@ -11,7 +11,7 @@
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 400;
src: local('Source Sans Pro Regular'), local('SourceSansPro-Regular'), url(https://fonts.gstatic.com/s/sourcesanspro/v12/6xK3dSBYKcSV-LCoeQqfX1RYOo3qPK7lqDY.woff2) format('woff2');
src: local('Source Sans Pro Regular'), local('SourceSansPro-Regular'), url(https://fonts.gstatic.com/s/sourcesanspro/v13/6xK3dSBYKcSV-LCoeQqfX1RYOo3qPK7lqDY.woff2) format('woff2');
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@@ -19,7 +19,7 @@
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 400;
src: local('Source Sans Pro Regular'), local('SourceSansPro-Regular'), url(https://fonts.gstatic.com/s/sourcesanspro/v12/6xK3dSBYKcSV-LCoeQqfX1RYOo3qNK7lqDY.woff2) format('woff2');
src: local('Source Sans Pro Regular'), local('SourceSansPro-Regular'), url(https://fonts.gstatic.com/s/sourcesanspro/v13/6xK3dSBYKcSV-LCoeQqfX1RYOo3qNK7lqDY.woff2) format('woff2');
unicode-range: U+1F00-1FFF;
}
/* greek */
@@ -27,7 +27,7 @@
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 400;
src: local('Source Sans Pro Regular'), local('SourceSansPro-Regular'), url(https://fonts.gstatic.com/s/sourcesanspro/v12/6xK3dSBYKcSV-LCoeQqfX1RYOo3qO67lqDY.woff2) format('woff2');
src: local('Source Sans Pro Regular'), local('SourceSansPro-Regular'), url(https://fonts.gstatic.com/s/sourcesanspro/v13/6xK3dSBYKcSV-LCoeQqfX1RYOo3qO67lqDY.woff2) format('woff2');
unicode-range: U+0370-03FF;
}
/* vietnamese */
@@ -35,15 +35,15 @@
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 400;
src: local('Source Sans Pro Regular'), local('SourceSansPro-Regular'), url(https://fonts.gstatic.com/s/sourcesanspro/v12/6xK3dSBYKcSV-LCoeQqfX1RYOo3qN67lqDY.woff2) format('woff2');
unicode-range: U+0102-0103, U+0110-0111, U+1EA0-1EF9, U+20AB;
src: local('Source Sans Pro Regular'), local('SourceSansPro-Regular'), url(https://fonts.gstatic.com/s/sourcesanspro/v13/6xK3dSBYKcSV-LCoeQqfX1RYOo3qN67lqDY.woff2) format('woff2');
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 400;
src: local('Source Sans Pro Regular'), local('SourceSansPro-Regular'), url(https://fonts.gstatic.com/s/sourcesanspro/v12/6xK3dSBYKcSV-LCoeQqfX1RYOo3qNq7lqDY.woff2) format('woff2');
src: local('Source Sans Pro Regular'), local('SourceSansPro-Regular'), url(https://fonts.gstatic.com/s/sourcesanspro/v13/6xK3dSBYKcSV-LCoeQqfX1RYOo3qNq7lqDY.woff2) format('woff2');
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@@ -51,6 +51,62 @@
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 400;
src: local('Source Sans Pro Regular'), local('SourceSansPro-Regular'), url(https://fonts.gstatic.com/s/sourcesanspro/v12/6xK3dSBYKcSV-LCoeQqfX1RYOo3qOK7l.woff2) format('woff2');
src: local('Source Sans Pro Regular'), local('SourceSansPro-Regular'), url(https://fonts.gstatic.com/s/sourcesanspro/v13/6xK3dSBYKcSV-LCoeQqfX1RYOo3qOK7l.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 700;
src: local('Source Sans Pro Bold'), local('SourceSansPro-Bold'), url(https://fonts.gstatic.com/s/sourcesanspro/v13/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwmhduz8A.woff2) format('woff2');
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 700;
src: local('Source Sans Pro Bold'), local('SourceSansPro-Bold'), url(https://fonts.gstatic.com/s/sourcesanspro/v13/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwkxduz8A.woff2) format('woff2');
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 700;
src: local('Source Sans Pro Bold'), local('SourceSansPro-Bold'), url(https://fonts.gstatic.com/s/sourcesanspro/v13/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwmxduz8A.woff2) format('woff2');
unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 700;
src: local('Source Sans Pro Bold'), local('SourceSansPro-Bold'), url(https://fonts.gstatic.com/s/sourcesanspro/v13/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwlBduz8A.woff2) format('woff2');
unicode-range: U+0370-03FF;
}
/* vietnamese */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 700;
src: local('Source Sans Pro Bold'), local('SourceSansPro-Bold'), url(https://fonts.gstatic.com/s/sourcesanspro/v13/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwmBduz8A.woff2) format('woff2');
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 700;
src: local('Source Sans Pro Bold'), local('SourceSansPro-Bold'), url(https://fonts.gstatic.com/s/sourcesanspro/v13/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwmRduz8A.woff2) format('woff2');
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 700;
src: local('Source Sans Pro Bold'), local('SourceSansPro-Bold'), url(https://fonts.gstatic.com/s/sourcesanspro/v13/6xKydSBYKcSV-LCoeQqfX1RYOo3ig4vwlxdu.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

View File

@@ -0,0 +1,41 @@
<!DOCTYPE html>
<!-- Link to specific tabs by using their ID in the URL like: options.html#keybinds -->
<head>
<title>__MSG_Options__ - SponsorBlock</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" href="../icons/LogoSponsorBlocker64px.png" type="image/png">
<link href="options.css" rel="stylesheet"/>
<script src="../js/vendor.js"></script>
<script src="../js/options.js"></script>
</head>
<body class="sponsorBlockPageBody">
<div id="options-container">
<div id="menubar" class="center">
<div id="title" class="titleBar">
<img src="../icons/LogoSponsorBlocker256px.png" class="profilepic" alt="SponsorBlock logo"/>
SponsorLock
<div id="version"></div>
</div>
</div>
</div>
<div id="options">
<div style="font-size: 75px;">
With SponsorLock, <b>we</b> decide for <b>you</b>!
</div>
Would you want it any other way?
</div>
</div>
</body>

View File

@@ -1,6 +1,232 @@
/* Options page CSS */
body {
:root {
--color-scheme: dark;
--background: #333333;
--menu-background: #181818;
--menu-foreground: white;
--dialog-background: #181818;
--dialog-border: white;
--tab-color: #242424;
--tab-button-hover: #4d0000;
--tab-hover: white;
--description: #dfdfdf;
--disabled: #520000;
--slider: #707070;
--title: #dad8d8;
--border-color: #484848;
--black: black;
--white: white;
}
[data-theme="light"] {
--color-scheme: light;
--background: #f9f9f9;
--menu-background: #dbdbdb;
--menu-foreground: #212121;
--dialog-background: #f9f9f9;
--dialog-border: #282828;
--tab-color: #ababab;
--tab-button-hover: #750000;
--tab-hover: #2e2e2e;
--description: #262626;
--disabled: #ffcaca;
--slider: #bfbebe;
--title: #707070;
--border-color: #d9d9d9;
--black: white;
--white: black;
}
.medium-description, .switch-container, .optionLabel, .categoryTableElement {
color: var(--white);
}
.small-description, p, li, span, div {
color: var(--description);
}
h1,h2,h3,h4,h5,h6 {
color: var(--title);
}
html, body {
color-scheme: var(--color-scheme);
font-family: sans-serif;
margin: 0;
font-size: 14px;
background-color: var(--background);
}
* {
box-sizing: border-box;
}
#options-container {
display: flex;
}
#menubar {
display: flex;
flex-direction: column;
gap: 20px;
flex-basis: 20%;
min-width: 300px;
max-width: 600px;
border-radius: 15px;
margin: 15px;
z-index: 10;
background-color: var(--menu-background);
color: var(--menu-foreground);
}
#navigation {
display: flex;
flex-direction: column;
gap: 30px;
}
.tab-heading {
font-size: 18px;
height: 55px;
line-height: 55px;
width: 80%;
margin: 0 auto;
border-radius: 15px;
cursor: pointer;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
background-color: var(--tab-color);
color: var(--white);
}
.tab-heading:hover {
background-color: var(--tab-button-hover);
color: white;
}
.tab-heading.selected {
background-color: #c00000;
color: white;
}
.tab-heading:active {
background-color: #950000;
color: white;
}
.option-group > div {
min-height: 50px;
padding: 20px 0;
border-bottom: 1px solid var(--border-color);
border-image: linear-gradient(to right, var(--border-color), #00000000 80%) 1;
}
.option-group > div:last-child, .option-group > #keybind-dialog {
border-bottom: inherit;
}
.optionLabel, #version {
font-size: 14px;
height: 15px;
}
div[data-type="keybind-change"] .optionLabel {
display: inline-block;
min-width: 150px;
margin-right: 20px;
}
input[type='number'] {
width: 50px;
}
.key {
border-width: 1px;
border-style: solid;
border-radius: 5px;
display: inline-block;
min-width: 33px;
text-align: center;
font-weight: bold;
border-color: var(--white);
}
.unbound, .key {
padding: 8px;
}
.keybind-buttons {
border-radius: 5px;
padding: 5px 3px;
cursor: pointer;
margin-right: 10px;
}
.keybind-buttons:hover {
background-color: #00000030;
}
.keybind-buttons > div, .keybind-buttons > span {
margin: 0 2px;
}
#keybind-dialog .dialog {
position: fixed;
border-width: 3px;
border-style: solid;
border-radius: 15px;
max-height: 100vh;
width: 400px;
overflow-x: auto;
z-index: 100;
padding: 15px;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
background-color: var(--dialog-background);
border-color: var(--dialog-border);
}
#change-keybind-buttons {
float: right;
}
#change-keybind-buttons > .option-button {
margin: 0 2px;
}
#change-keybind-settings {
margin: 15px 15px 30px;
}
#change-keybind-settings .key {
vertical-align: top;
margin: 15px 0 0 40px;
height: 34px;
}
#change-keybind-error {
margin-bottom: 15px;
color: red;
font-weight: bold;
}
.blocker {
position: fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
z-index: 90;
background-color: #00000080;
}
.low-profile {
height: 23px;
line-height: 5px;
vertical-align: middle;
}
.center {
@@ -11,25 +237,49 @@ body {
display: inline-block;
}
.next-line {
padding: 15px 0 0 0;
}
.bold {
font-weight: bold;
}
.hiding {
opacity: 0;
}
.hidden {
display: none !important;
}
.spacing {
margin-top: 15px;
}
.keybind-status {
display: inline;
}
.small-description {
color: white;
font-size: 13px;
padding: 15px 0 0 20px;
}
.small-description td {
padding: 10px 0 20px 20px;
}
.indent {
padding-left: 20px;
}
.categoryTableElement td {
padding-top: 10px;
border-top: 1px solid var(--border-color);
}
.medium-description {
color: white;
font-size: 15px;
}
@@ -49,36 +299,51 @@ body {
width: max-content;
}
.option-button:hover {
.option-button:hover:not(.disabled) {
background-color: #fc0303;
}
.option-button.disabled {
cursor: default;
background-color: #520000;
background-color: var(--disabled);
color: grey;
}
#options {
max-width: 60%;
height: 100vh;
flex-basis: 80%;
overflow: auto;
text-align: left;
display: inline-block;
padding: 80px 15% 0 3%;
box-sizing: border-box;
display: flex;
justify-content: center;
transition: padding 0.3s;
}
.switch-container:after {
#options.embed > div {
max-width: 100%;
}
#title .profilepic {
height: 60px;
}
.switch-container {
content: attr(label-name);
position: absolute;
padding: 4px;
width: max-content;
font-size: 14px;
color: white;
display: table;
}
.text-label-container {
font-size: 14px;
color: white;
.switch-container .switch-label {
display: table-cell;
vertical-align: middle;
padding: 4px;
}
.switch {
@@ -101,7 +366,7 @@ body {
left: 0;
right: 0;
bottom: 0;
background-color: #707070;
background-color: var(--slider);
}
.animated * {
@@ -144,11 +409,8 @@ input:checked + .slider:before {
}
/* Boilerplate CSS from https://ajay.app */
body {
background-color: #333333;
}
/* Boilerplate CSS from https://ajay.app (edited) */
.projectPreview {
position: relative;
@@ -178,29 +440,25 @@ body {
transform: translateY(-50%);
}
.createdBy {
font-size: 14px;
#createdBy {
text-align: center;
padding-top: 0px;
padding-bottom: 0px;
margin: auto 0 10px 0;
height: 50px;
}
display: inline-block;
#createdBy > * {
font-size: 14px;
}
#title {
background-color: #636363;
text-align: center;
vertical-align: middle;
font-size: 50px;
color: #212121;
font-size: 40px;
padding: 20px;
padding: 40px 20px;
text-decoration: none;
transition: font-size 1s;
}
.subtitle {
@@ -219,7 +477,6 @@ body {
}
.profilepic {
background-color: #636363 !important;
vertical-align: middle;
}
@@ -263,31 +520,9 @@ a {
p,li {
font-size: 20px;
color: #c4c4c4;
padding: 10px;
}
p,li,code,a {
max-width: 60%;
text-align: left;
overflow-wrap: break-word;
}
@media screen and (orientation:portrait) {
p,li,code,a {
max-width: 100%;
}
.projectPreviewImage {
position: unset;
width: 130px;
display: block;
margin: auto;
transform: none;
}
}
.previewImage {
max-height: 200px;
}
@@ -308,10 +543,6 @@ img {
color: #dad8d8;
}
h1,h2,h3,h4,h5,h6 {
color: #dad8d8;
}
svg {
text-decoration: none;
}
@@ -329,16 +560,17 @@ svg {
.categoryTableElement {
font-size: 16px;
color: white;
}
.categoryTableElement > * {
padding-right: 15px;
}
.categoryTableDescription > * {
padding-bottom: 15px;
}
.categoryOptionsSelector {
.optionsSelector {
background-color: #c00000;
color: white;
@@ -346,4 +578,96 @@ svg {
font-size: 14px;
padding: 5px;
border-radius: 5px;
}
.categoryColorTextBox {
width: 60px;
background: none;
border: none;
}
#sbDonate {
font-size: 10px;
}
/* Top bar navigation for smaller screens */
@media only screen and (max-height: 725px), only screen and (max-width: 1200px) {
#options-container {
flex-direction: column;
}
#menubar {
gap: 8px;
min-width: unset;
max-width: unset;
padding: 8px;
}
#navigation {
gap: 8px;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
}
#options {
padding: 0 50px;
}
#options > div {
max-width: 70%;
}
.tab-heading {
width: unset;
min-width: unset;
height: 35px;
line-height: 35px;
font-size: 16px;
padding: 0 10px;
margin: 0;
}
#title {
width: 100%;
font-size: 30px;
padding: 10px;
}
#title .profilepic {
height: 40px;
}
#createdBy {
margin: 10px 0 0 0;
height: unset;
width: 100%;
}
#createdBy > div {
display: inline-block;
}
#sbDonate {
position: absolute;
right: 30px;
margin-top: 10px;
}
#version {
font-size: 10px;
height: 10px;
transform: translate(-50px, -5px);
}
.sticky #menubar {
position: fixed;
left: 0;
right: 0;
margin: 0 15px;
}
.sticky #title, .sticky #createdBy {
display: none;
}
}
@media only screen and (max-width: 800px) {
#options {
padding: 0 15px;
}
#options > div {
max-width: 100%;
}
}

View File

@@ -1,9 +1,12 @@
<!DOCTYPE html>
<!-- Link to specific tabs by using their ID in the URL like: options.html#keybinds -->
<head>
<title>Options - SponsorBlock</title>
<title>__MSG_Options__ - SponsorBlock</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" href="../icons/LogoSponsorBlocker64px.png" type="image/png">
<link href="options.css" rel="stylesheet"/>
<script src="../js/vendor.js"></script>
@@ -12,386 +15,492 @@
<body class="sponsorBlockPageBody">
<div id="title">
<img src="../icons/LogoSponsorBlocker256px.png" height="80" class="profilepic"/>
SponsorBlock
</div>
<div id="options-container">
<div class="center">
<p class="createdBy">__MSG_createdBy__ <a href="https://ajay.app">Ajay Ramachandran</a> <img src="../icons/newprofilepic.jpg" height="30" class="profilepiccircle"/></p>
<h1>__MSG_Options__</h1>
<div id="options" class="hidden">
<div id="category-type" option-type="react-CategoryChooserComponent">
<div id="menubar" class="center">
<div id="title" class="titleBar">
<img src="../icons/LogoSponsorBlocker256px.png" class="profilepic" alt="SponsorBlock logo"/>
SponsorBlock
<div id="version"></div>
</div>
<br/>
<br/>
<div id="support-invidious" option-type="toggle" sync-option="supportInvidious">
<label class="switch-container" label-name="__MSG_supportInvidious__">
<label class="switch">
<input type="checkbox">
<span class="slider round"></span>
</label>
</label>
<br/>
<br/>
<div class="small-description">__MSG_supportInvidiousDescription__</div>
</div>
<br/>
<br/>
<div option-type="private-text-change" sync-option="invidiousInstances">
<div class="option-button trigger-button">
__MSG_addInvidiousInstance__
</div>
<br/>
<div class="small-description">__MSG_addInvidiousInstanceDescription__</div>
<div class="option-hidden-section hidden">
<br/>
<input class="option-text-box" type="text">
<br/>
<br/>
<div class="option-button text-change-set inline">
__MSG_add__
</div>
<div class="option-button invidious-instance-reset inline">
__MSG_resetInvidiousInstance__
</div>
<br/>
<br/>
<span class="small-description">__MSG_currentInstances__</span>
<span class="small-description" option-type="display" sync-option="invidiousInstances"></span>
</div>
</div>
<br/>
<br/>
<div option-type="keybind-change" sync-option="startSponsorKeybind">
<div class="option-button trigger-button">
__MSG_setStartSponsorShortcut__
</div>
<div class="option-hidden-section hidden">
<br/>
<div class="medium-description keybind-status">
__MSG_keybindDescription__
</div>
<span class="medium-description bold keybind-status-key">
</span>
</div>
</div>
<br/>
<br/>
<div option-type="keybind-change" sync-option="submitKeybind">
<div class="option-button trigger-button">
__MSG_setSubmitKeybind__
</div>
<div class="option-hidden-section hidden">
<br/>
<div class="medium-description keybind-status">
__MSG_keybindDescription__
</div>
<span class="medium-description bold keybind-status-key">
</span>
</div>
</div>
<br/>
<br/>
<div option-type="number-change" sync-option="minDuration">
<label class="number-container" label-name="__MSG_minDuration__">
<input type="number" step="0.1" min="0">
</label>
<br/>
<br/>
<div class="small-description">__MSG_minDurationDescription__</div>
</div>
<br/>
<br/>
<div option-type="toggle" toggle-type="reverse" sync-option="dontShowNotice">
<label class="switch-container" label-name="__MSG_showSkipNotice__">
<label class="switch">
<input type="checkbox" checked>
<span class="slider round"></span>
</label>
</label>
</div>
<br/>
<br/>
<div option-type="toggle" toggle-type="reverse" sync-option="hideVideoPlayerControls">
<label class="switch-container" label-name="__MSG_showButtons__">
<label class="switch">
<input type="checkbox" checked>
<span class="slider round"></span>
</label>
</label>
<br/>
<br/>
<div class="small-description">__MSG_hideButtonsDescription__</div>
</div>
<br/>
<br/>
<div option-type="toggle" toggle-type="reverse" sync-option="hideInfoButtonPlayerControls">
<label class="switch-container" label-name="__MSG_showInfoButton__">
<label class="switch">
<input type="checkbox" checked>
<span class="slider round"></span>
</label>
</label>
<br/>
<br/>
<div class="small-description">__MSG_whatInfoButton__</div>
</div>
<br/>
<br/>
<div option-type="toggle" toggle-type="reverse" sync-option="hideDeleteButtonPlayerControls">
<label class="switch-container" label-name="__MSG_showDeleteButton__">
<label class="switch">
<input type="checkbox" checked>
<span class="slider round"></span>
</label>
</label>
<br/>
<br/>
<div class="small-description">__MSG_whatDeleteButton__</div>
</div>
<br/>
<br/>
<div option-type="toggle" toggle-type="reverse" sync-option="hideUploadButtonPlayerControls">
<label class="switch-container" label-name="__MSG_showUploadButton__">
<label class="switch">
<input type="checkbox" checked>
<span class="slider round"></span>
</label>
</label>
<br/>
<br/>
<div class="small-description">__MSG_whatUploadButton__</div>
</div>
<br/>
<br/>
<div option-type="toggle" sync-option="audioNotificationOnSkip">
<label class="switch-container" label-name="__MSG_audioNotification__">
<label class="switch">
<input type="checkbox" checked>
<span class="slider round"></span>
</label>
</label>
<br/>
<br/>
<div class="small-description">__MSG_audioNotificationDescription__</div>
</div>
<br/>
<br/>
<div option-type="toggle" sync-option="autoUpvote">
<label class="switch-container" label-name="__MSG_enableAutoUpvote__">
<label class="switch">
<input type="checkbox" checked>
<span class="slider round"></span>
</label>
</label>
<br/>
<br/>
<div class="small-description">__MSG_whatAutoUpvote__</div>
</div>
<br/>
<br/>
<div option-type="toggle" sync-option="trackViewCount">
<label class="switch-container" label-name="__MSG_enableViewTracking__">
<label class="switch">
<input type="checkbox" checked>
<span class="slider round"></span>
</label>
</label>
<br/>
<br/>
<div class="small-description">__MSG_whatViewTracking__</div>
</div>
<br/>
<br/>
<div option-type="toggle" sync-option="checkForUnlistedVideos">
<label class="switch-container" label-name="__MSG_unlistedCheck__">
<label class="switch">
<input type="checkbox">
<span class="slider round"></span>
</label>
</label>
<br/>
<br/>
<div class="small-description">__MSG_whatUnlistedCheck__</div>
</div>
<br/>
<br/>
<div option-type="private-text-change" sync-option="userID" confirm-message="userIDChangeWarning">
<div class="option-button trigger-button">
__MSG_changeUserID__
</div>
<br/>
<div class="small-description">__MSG_whatChangeUserID__</div>
<div class="option-hidden-section hidden">
<br/>
<input class="option-text-box" type="text">
<br/>
<br/>
<div class="option-button text-change-set">
__MSG_setUserID__
</div>
</div>
</div>
<br/>
<br/>
<div option-type="private-text-change" sync-option="*" confirm-message="exportOptionsWarning">
<div class="option-button trigger-button">
__MSG_exportOptions__
</div>
<br/>
<div class="small-description">__MSG_whatExportOptions__</div>
<div class="option-hidden-section hidden">
<br/>
<input class="option-text-box" type="text">
<br/>
<br/>
<div class="option-button text-change-set">
__MSG_setOptions__
</div>
</div>
</div>
<br/>
<br/>
<div option-type="button-press" sync-option="copyDebugInformation" confirm-message="copyDebugInformation">
<div class="option-button trigger-button">
__MSG_copyDebugInformation__
</div>
<br/>
<div class="small-description">__MSG_copyDebugInformationOptions__</div>
</div>
<br/>
<br/>
<div option-type="toggle" sync-option="testingServer" confirm-message="testingServerWarning">
<label class="switch-container" label-name="__MSG_enableTestingServer__">
<label class="switch">
<input type="checkbox">
<span class="slider round"></span>
</label>
</label>
<br/>
<br/>
<div class="small-description">__MSG_whatEnableTestingServer__</div>
</div>
<br/>
<br/>
<div option-type="text-change" sync-option="serverAddress">
<label class="text-label-container">
<div>__MSG_customServerAddress__</div>
<input class="option-text-box" type="text">
</label>
<div class="option-button text-change-set inline">
__MSG_save__
<div id="navigation">
<div class="tab-heading" data-for="behavior">
__MSG_optionsTabBehavior__
</div>
<div class="option-button text-change-reset inline">
__MSG_reset__
<div class="tab-heading" data-for="interface">
__MSG_optionsTabInterface__
</div>
<div class="tab-heading" data-for="keybinds">
__MSG_optionsTabKeyBinds__
</div>
<div class="tab-heading" data-for="import">
__MSG_optionsTabBackup__
</div>
<div class="tab-heading" data-for="advanced">
__MSG_optionsTabAdvanced__
</div>
<br/>
<br/>
<div class="small-description">__MSG_customServerAddressDescription__</div>
</div>
</div>
<div id="createdBy" class="titleBar">
<div>
<img src="../icons/newprofilepic.jpg" height="30" class="profilepiccircle" alt="profile picture of creator"/>
__MSG_createdBy__
<a href="https://ajay.app">Ajay Ramachandran</a>
</div>
<a href="https://sponsor.ajay.app/donate" target="_blank" rel="noopener" id="sbDonate">(__MSG_Donate__)</a>
</div>
</div>
<div id="options">
<div id="behavior" class="option-group hidden">
<div id="category-type" data-type="react-CategoryChooserComponent">
</div>
<div data-type="toggle" data-sync="autoSkipOnMusicVideos">
<div class="switch-container">
<label class="switch">
<input id="autoSkipOnMusicVideos" type="checkbox" checked>
<span class="slider round"></span>
</label>
<label class="switch-label" for="autoSkipOnMusicVideos">
__MSG_autoSkipOnMusicVideos__
</label>
</div>
</div>
<div data-type="toggle" data-sync="muteSegments">
<div class="switch-container">
<label class="switch">
<input id="muteSegments" type="checkbox" checked>
<span class="slider round"></span>
</label>
<label class="switch-label" for="muteSegments">
__MSG_muteSegments__
</label>
</div>
</div>
<div data-type="toggle" data-sync="fullVideoSegments">
<div class="switch-container">
<label class="switch">
<input id="fullVideoSegments" type="checkbox" checked>
<span class="slider round"></span>
</label>
<label class="switch-label" for="fullVideoSegments">
__MSG_fullVideoSegments__
</label>
</div>
</div>
<div data-type="number-change" data-sync="minDuration">
<label class="number-container">
<span class="optionLabel">__MSG_minDuration__</span>
<input type="number" step="0.1" min="0">
</label>
<div class="small-description">__MSG_minDurationDescription__</div>
</div>
<div data-type="toggle" data-sync="forceChannelCheck">
<div class="switch-container">
<label class="switch">
<input id="forceChannelCheck" type="checkbox" checked>
<span class="slider round"></span>
</label>
<label class="switch-label" for="forceChannelCheck">
__MSG_forceChannelCheck__
</label>
</div>
<div class="small-description">__MSG_whatForceChannelCheck__</div>
</div>
<div data-type="toggle" data-sync="refetchWhenNotFound">
<div class="switch-container">
<label class="switch">
<input id="refetchWhenNotFound" type="checkbox" checked>
<span class="slider round"></span>
</label>
<label class="switch-label" for="refetchWhenNotFound">
__MSG_enableRefetchWhenNotFound__
</label>
</div>
<div class="small-description">__MSG_whatRefetchWhenNotFound__</div>
</div>
</div>
<div id="interface" class="option-group hidden">
<div data-type="number-change" data-sync="skipNoticeDuration">
<label class="number-container">
<span class="optionLabel">__MSG_skipNoticeDuration__</span>
<input type="number" step="1" min="1">
</label>
<div class="small-description">__MSG_skipNoticeDurationDescription__</div>
</div>
<div data-type="toggle" data-toggle-type="reverse" data-sync="dontShowNotice">
<div class="switch-container">
<label class="switch">
<input id="dontShowNotice" type="checkbox" checked>
<span class="slider round"></span>
</label>
<label class="switch-label" for="dontShowNotice">
__MSG_showSkipNotice__
</label>
</div>
</div>
<div data-type="selector" data-sync="noticeVisibilityMode">
<label class="optionLabel" for="noticeVisibilityMode">__MSG_noticeVisibilityLabel__:</label>
<select id="noticeVisibilityMode" class="selector-element optionsSelector" >
<option value="0">__MSG_noticeVisibilityMode0__</option>
<option value="1">__MSG_noticeVisibilityMode1__</option>
<option value="2">__MSG_noticeVisibilityMode2__</option>
<option value="3">__MSG_noticeVisibilityMode3__</option>
<option value="4">__MSG_noticeVisibilityMode4__</option>
</select>
</div>
<div data-type="toggle" data-toggle-type="reverse" data-sync="hideVideoPlayerControls">
<div class="switch-container">
<label class="switch">
<input id="hideVideoPlayerControls" type="checkbox" checked>
<span class="slider round"></span>
</label>
<label class="switch-label" for="hideVideoPlayerControls">
__MSG_showButtons__
</label>
</div>
<div class="small-description">__MSG_hideButtonsDescription__</div>
</div>
<div data-type="toggle" data-toggle-type="reverse" data-sync="hideDeleteButtonPlayerControls" data-dependent-on="hideVideoPlayerControls">
<div class="switch-container">
<label class="switch">
<input id="hideDeleteButtonPlayerControls" type="checkbox" checked>
<span class="slider round"></span>
</label>
<label class="switch-label" for="hideDeleteButtonPlayerControls">
__MSG_showDeleteButton__
</label>
</div>
</div>
<div data-type="toggle" data-toggle-type="reverse" data-sync="hideUploadButtonPlayerControls" data-dependent-on="hideVideoPlayerControls">
<div class="switch-container">
<label class="switch">
<input id="hideUploadButtonPlayerControls" type="checkbox" checked>
<span class="slider round"></span>
</label>
<label class="switch-label" for="hideUploadButtonPlayerControls">
__MSG_showUploadButton__
</label>
</div>
</div>
<div data-type="toggle" data-toggle-type="reverse" data-sync="hideSkipButtonPlayerControls">
<div class="switch-container">
<label class="switch">
<input id="hideSkipButtonPlayerControls" type="checkbox" checked>
<span class="slider round"></span>
</label>
<label class="switch-label" for="hideSkipButtonPlayerControls">
__MSG_showSkipButton__
</label>
</div>
</div>
<div data-type="toggle" data-toggle-type="reverse" data-sync="hideInfoButtonPlayerControls">
<div class="switch-container">
<label class="switch">
<input id="hideInfoButtonPlayerControls" type="checkbox" checked>
<span class="slider round"></span>
</label>
<label class="switch-label" for="hideInfoButtonPlayerControls">
__MSG_showInfoButton__
</label>
</div>
</div>
<div data-type="toggle" data-sync="autoHideInfoButton" data-dependent-on="hideInfoButtonPlayerControls">
<div class="switch-container">
<label class="switch">
<input id="autoHideInfoButton" type="checkbox" checked>
<span class="slider round"></span>
</label>
<label class="switch-label" for="autoHideInfoButton">
__MSG_autoHideInfoButton__
</label>
</div>
</div>
<div data-type="toggle" data-sync="audioNotificationOnSkip">
<div class="switch-container">
<label class="switch">
<input id="audioNotificationOnSkip" type="checkbox" checked>
<span class="slider round"></span>
</label>
<label class="switch-label" for="audioNotificationOnSkip">
__MSG_audioNotification__
</label>
</div>
<div class="small-description">__MSG_audioNotificationDescription__</div>
</div>
<div data-type="toggle" data-sync="showTimeWithSkips">
<div class="switch-container">
<label class="switch">
<input id="showTimeWithSkips" type="checkbox" checked>
<span class="slider round"></span>
</label>
<label class="switch-label" for="showTimeWithSkips">
__MSG_showTimeWithSkips__
</label>
</div>
<div class="small-description">__MSG_showTimeWithSkipsDescription__</div>
</div>
<div data-type="toggle" data-sync="darkMode">
<div class="switch-container">
<label class="switch">
<input id="darkMode" type="checkbox" checked>
<span class="slider round"></span>
</label>
<label class="switch-label" for="darkMode">
__MSG_darkModeOptionsPage__
</label>
</div>
</div>
<div data-type="toggle" data-toggle-type="reverse" data-sync="showDonationLink" data-no-safari="true">
<div class="switch-container">
<label class="switch">
<input id="showDonationLink" type="checkbox" checked>
<span class="slider round"></span>
</label>
<label class="switch-label" for="showDonationLink">
__MSG_hideDonationLink__
</label>
</div>
</div>
</div>
<div id="keybinds" class="option-group hidden">
<div data-type="keybind-change" data-sync="skipKeybind">
<label class="optionLabel">__MSG_setSkipShortcut__:</label>
<div class="inline"></div>
</div>
<div data-type="keybind-change" data-sync="startSponsorKeybind">
<label class="optionLabel">__MSG_setStartSponsorShortcut__:</label>
<div class="inline"></div>
</div>
<div data-type="keybind-change" data-sync="submitKeybind">
<label class="optionLabel">__MSG_setSubmitKeybind__:</label>
<div class="inline"></div>
</div>
</div>
<div id="import" class="option-group hidden">
<div data-type="private-text-change" data-sync="userID" data-confirm-message="userIDChangeWarning">
<div class="option-button trigger-button">
__MSG_changeUserID__
</div>
<div class="small-description">__MSG_whatChangeUserID__</div>
<div class="option-hidden-section hidden spacing indent">
<input class="option-text-box" type="text">
<div class="option-button text-change-set inline low-profile">
__MSG_setUserID__
</div>
</div>
</div>
<div data-type="private-text-change" data-sync="*" data-confirm-message="exportOptionsWarning">
<h2>__MSG_exportOptions__</h2>
<div>
<div class="option-button trigger-button inline">
__MSG_exportOptionsCopy__
</div>
<div class="option-button download-button inline">
__MSG_exportOptionsDownload__
</div>
<label for="importOptions" class="option-button inline">
__MSG_exportOptionsUpload__
</label>
<input id="importOptions" type="file" class="upload-button hidden" />
</div>
<div class="small-description">__MSG_whatExportOptions__</div>
<div class="option-hidden-section hidden spacing indent">
<textarea class="option-text-box" rows="10" style="width:80%"></textarea>
<div class="option-button text-change-set">
__MSG_setOptions__
</div>
</div>
</div>
</div>
<div id="advanced" class="option-group hidden">
<div id="support-invidious" data-type="toggle" data-sync="supportInvidious" data-no-safari="true">
<div class="switch-container">
<label class="switch">
<input id="supportInvidious" type="checkbox">
<span class="slider round"></span>
</label>
<label class="switch-label" for="supportInvidious">
__MSG_supportOtherSites__
</label>
</div>
<div class="small-description">(__MSG_supportedSites__ Invidious, CloudTube)</div>
<div class="small-description">__MSG_supportOtherSitesDescription__ </div>
</div>
<div data-type="private-text-change" data-sync="invidiousInstances" data-no-safari="true" data-dependent-on="supportInvidious">
<div class="option-button trigger-button">
__MSG_addInvidiousInstance__
</div>
<div class="small-description">__MSG_addInvidiousInstanceDescription__</div>
<div class="indent option-hidden-section hidden spacing">
<input class="option-text-box" type="text">
<div class="inline">
<div class="option-button text-change-set inline low-profile">
__MSG_add__
</div>
<div class="option-button text-change-reset inline low-profile">
__MSG_cancel__
</div>
</div>
</div>
<div style="margin-top:15px">
<span>__MSG_currentInstances__</span>
<span data-type="display" data-sync="invidiousInstances"></span>
<div class="option-button invidious-instance-reset spacing hidden">
__MSG_resetInvidiousInstance__
</div>
</div>
</div>
<div data-type="toggle" data-sync="trackViewCount">
<div class="switch-container">
<label class="switch">
<input id="trackViewCount" type="checkbox" checked>
<span class="slider round"></span>
</label>
<label class="switch-label" for="trackViewCount">
__MSG_enableViewTracking__
</label>
</div>
<div class="small-description">__MSG_whatViewTracking__</div>
</div>
<div data-type="toggle" data-sync="trackViewCountInPrivate" data-dependent-on="trackViewCount" data-private-only="true">
<div class="switch-container">
<label class="switch">
<input id="trackViewCountInPrivate" type="checkbox" checked>
<span class="slider round"></span>
</label>
<label class="switch-label" for="trackViewCountInPrivate">
__MSG_enableViewTrackingInPrivate__
</label>
</div>
</div>
<div data-type="toggle" data-sync="trackDownvotes" data-confirm-on="false" data-confirm-message="trackDownvotesWarning">
<div class="switch-container">
<label class="switch">
<input id="trackDownvotes" type="checkbox" checked>
<span class="slider round"></span>
</label>
<label class="switch-label" for="trackDownvotes">
__MSG_enableTrackDownvotes__
</label>
</div>
<div class="small-description">__MSG_whatTrackDownvotes__</div>
</div>
<div data-type="button-press" data-sync="copyDebugInformation" data-confirm-message="copyDebugInformation">
<div class="option-button trigger-button">
__MSG_copyDebugInformation__
</div>
<div class="small-description">__MSG_copyDebugInformationOptions__</div>
</div>
<div data-type="toggle" data-sync="testingServer" data-confirm-message="testingServerWarning" data-no-safari="true">
<div class="switch-container">
<label class="switch">
<input id="testingServer" type="checkbox">
<span class="slider round"></span>
</label>
<label class="switch-label" for="testingServer">
__MSG_enableTestingServer__
</label>
</div>
<div class="small-description">__MSG_whatEnableTestingServer__</div>
</div>
<div data-type="text-change" data-sync="serverAddress" data-dependent-on="testingServer" data-dependent-on-inverted="true">
<label class="optionLabel inline">
<span class="optionLabel">__MSG_customServerAddress__:</span>
<input class="option-text-box" type="text" style="margin-right:10px">
</label>
<div class="small-description">__MSG_customServerAddressDescription__</div>
<div class="next-line">
<div class="option-button text-change-set inline">
__MSG_save__
</div>
<div class="option-button text-change-reset inline">
__MSG_reset__
</div>
</div>
</div>
</div>
</div>
</div>
</body>

View File

@@ -0,0 +1,158 @@
js-tokens
4.0.0 <https://github.com/lydell/js-tokens>
The MIT License (MIT)
Copyright (c) 2014, 2015, 2016, 2017, 2018 Simon Lydell
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
******************************
loose-envify
1.4.0 <https://github.com/zertosh/loose-envify>
The MIT License (MIT)
Copyright (c) 2015 Andres Suarez <zertosh@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
******************************
object-assign
4.1.1 <https://github.com/sindresorhus/object-assign>
The MIT License (MIT)
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
******************************
react
17.0.2 <https://github.com/facebook/react>
MIT License
Copyright (c) Facebook, Inc. and its affiliates.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************
react-dom
17.0.2 <https://github.com/facebook/react>
MIT License
Copyright (c) Facebook, Inc. and its affiliates.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************
scheduler
0.20.2 <https://github.com/facebook/react>
MIT License
Copyright (c) Facebook, Inc. and its affiliates.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,28 @@
<!DOCTYPE html>
<head>
<title>Permissions - SponsorBlock</title>
<meta charset="utf-8">
<link href="styles.css" rel="stylesheet"/>
<script src="../js/vendor.js"></script>
<script src="../js/permissions.js"></script>
</head>
<body class="sponsorBlockPageBody">
<div id="title" class="titleBar">
<img src="../icons/LogoSponsorBlocker256px.png" height="80" class="profilepic"/>
SponsorBlock
</div>
<br/>
<div class="center">
<div id="acceptPermissionButton" class="option-button inline">
__MSG_acceptPermission__
</div>
</div>
</body>

View File

@@ -0,0 +1,360 @@
/* Options page CSS */
html {
color-scheme: dark;
}
body {
font-family: sans-serif;
}
.center {
text-align: center;
}
.inline {
display: inline-block;
}
.bold {
font-weight: bold;
}
.hidden {
display: none !important;
}
.keybind-status {
display: inline;
}
.small-description {
color: white;
font-size: 13px;
}
.medium-description {
color: white;
font-size: 15px;
}
.option-text-box {
width: 300px;
}
.option-button {
cursor: pointer;
background-color: #c00000;
padding: 10px;
color: white;
border-radius: 5px;
font-size: 14px;
width: max-content;
}
.option-button:hover {
background-color: #fc0303;
}
.option-button.disabled {
cursor: default;
background-color: #520000;
color: grey;
}
#options {
max-width: 60%;
text-align: left;
display: inline-block;
}
.switch-container:after {
content: attr(label-name);
position: absolute;
padding: 4px;
width: max-content;
font-size: 14px;
color: white;
}
.text-label-container {
font-size: 14px;
color: white;
}
.switch {
position: relative;
display: inline-block;
width: 40px;
height: 24px;
}
.switch input {
opacity: 0;
width: 0;
height: 0;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #707070;
}
.animated * {
-webkit-transition: .4s;
transition: .4s;
}
.slider:before {
position: absolute;
content: "";
height: 16px;
width: 16px;
left: 4px;
bottom: 4px;
background-color: white;
}
.animated .slider:before {
-webkit-transition: .4s;
transition: .4s;
}
input:checked + .slider {
background-color: #fc0303;
}
input:checked + .slider:before {
-webkit-transform: translateX(16px);
-ms-transform: translateX(16px);
transform: translateX(16px);
}
/* Rounded sliders */
.slider.round {
border-radius: 34px;
}
.slider.round:before {
border-radius: 50%;
}
/* Boilerplate CSS from https://ajay.app */
body {
background-color: #333333;
}
.projectPreview {
position: relative;
}
.projectPreviewImage {
position: absolute;
left: -90px;
width: 80px;
top: 50%;
transform: translateY(-50%);
}
.projectPreviewImageLarge {
position: absolute;
left: -210px;
width: 200px;
top: 50%;
transform: translateY(-20%);
}
.projectPreviewImageLargeRight {
position: absolute;
right: -210px;
width: 200px;
top: 50%;
transform: translateY(-50%);
}
.createdBy {
font-size: 14px;
text-align: center;
padding-top: 0px;
padding-bottom: 0px;
display: inline-block;
}
#title {
background-color: #636363;
text-align: center;
vertical-align: middle;
font-size: 50px;
color: #212121;
padding: 20px;
text-decoration: none;
transition: font-size 1s;
}
.subtitle {
font-size: 40px;
color: #dad8d8;
padding-top: 10px;
transition: font-size 0.4s;
}
.subtitle:hover {
font-size: 45px;
transition: font-size 0.4s;
}
.profilepic {
background-color: #636363 !important;
vertical-align: middle;
}
.profilepiccircle {
vertical-align: middle;
overflow: hidden;
border-radius: 50%;
}
a {
text-decoration: underline;
color: inherit;
}
.link {
padding: 20px;
height: 80px;
transition: height 0.2s;
}
.link:hover {
height: 95px;
transition: height 0.2s;
}
#contact,.smalllink {
font-size: 25px;
color: #e8e8e8;
text-align: center;
padding: 10px;
}
#contact {
text-decoration: none;
}
p,li {
font-size: 20px;
color: #c4c4c4;
padding: 10px;
}
p,li,code,a {
max-width: 60%;
text-align: left;
overflow-wrap: break-word;
}
@media screen and (orientation:portrait) {
p,li,code,a {
max-width: 100%;
}
.projectPreviewImage {
position: unset;
width: 130px;
display: block;
margin: auto;
transform: none;
}
}
.previewImage {
max-height: 200px;
}
img {
max-width: 100%;
text-align: center;
}
#recentPostTitle {
font-size: 30px;
color: #dad8d8;
}
#recentPostDate {
font-size: 15px;
color: #dad8d8;
}
h1,h2,h3,h4,h5,h6 {
color: #dad8d8;
}
svg {
text-decoration: none;
}
.number-container:before {
content: attr(label-name);
padding-right: 4px;
width: max-content;
font-size: 14px;
color: white;
}
/* React styles */
.categoryTableElement {
font-size: 16px;
color: white;
}
.categoryTableElement > * {
padding-right: 15px;
padding-bottom: 15px;
}
.categoryOptionsSelector {
background-color: #c00000;
color: white;
border: none;
font-size: 14px;
padding: 5px;
border-radius: 5px;
}
.categoryColorTextBox {
width: 60px;
background: none;
border: none;
}

View File

@@ -1,237 +1,546 @@
/* reset some properties to default (youtube messes with them */
p.popupElement {
margin-block-start: 1em;
margin-block-end: 1em;
margin-inline-start: 0px;
margin-inline-end: 0px;
:root {
--sb-main-font-family: "Source Sans Pro", sans-serif;
--sb-main-bg-color: #222626;
--sb-main-fg-color: #fff;
--sb-grey-bg-color: #333;
--sb-red-bg-color: #cc1717;
}
h1.popupElement {
margin-block-start: 0.67em;
margin-block-end: 0.67em;
margin-inline-start: 0px;
margin-inline-end: 0px;
font-weight: bold;
/*
* Container when popup displayed in-page
*/
#sponsorBlockPopupContainer {
position: relative;
margin-bottom: 16px;
}
h2.popupElement {
margin-block-start: 0.83em;
margin-block-end: 0.83em;
margin-inline-start: 0px;
margin-inline-end: 0px;
font-weight: bold;
/*
* Disable fixed popup width when displayed in-page
*/
#sponsorBlockPopupContainer #sponsorBlockPopupBody {
width: auto;
}
h3.popupElement {
margin-block-start: 1em;
margin-block-end: 1em;
margin-inline-start: 0px;
margin-inline-end: 0px;
font-weight: bold;
/*
* Main containers
*/
#sponsorBlockPopupHTML {
color-scheme: dark;
}
sub.popupElement {
font-size: smaller;
}
/* end reset */
#sponsorBlockPopupLogo {
vertical-align: text-bottom;
#sponsorBlockPopupBody {
margin: 0;
width: 374px;
font-family: var(--sb-main-font-family);
font-size: 14px;
background-color: var(--sb-main-bg-color);
color: var(--sb-main-fg-color);
color-scheme: dark;
}
.popupElement {
font-family: 'Source Sans Pro', sans-serif;
color: black;
#sponsorblockPopup {
text-align: center;
}
h1.popupElement {
margin-top: 0px;
margin-bottom: 10px;
/*
* Disable transition on all elements until the extension has loaded
*/
.sb-preload * {
transition: none !important;
}
.popupBody {
font-size: 14px;
background-color: #ffd9d9;
padding: 0px 5px;
/*
* Close popup button when displayed in-page
*/
.sbCloseButton {
background: transparent;
border: 0;
padding: 8px;
cursor: pointer;
position: absolute;
top: 5px;
right: 5px;
opacity: 0.5;
}
.discreteLink.popupElement {
color: black;
.sbCloseButton:hover {
opacity: 1;
}
.recordingSubtitle.popupElement {
margin-bottom: 10px;
/*
* Header logo
*/
.sbPopupLogo {
display: flex;
align-items: center;
font-size: 32px;
font-weight: bold;
justify-content: center;
user-select: none;
padding: 20px 0 10px;
}
.voteButton.popupElement {
height: 32px;
margin-right: 15px;
cursor: pointer;
}
.voteButton:hover.popupElement {
filter: brightness(80%);
.sbPopupLogo img {
margin-right: 8px;
}
#discordButtonContainer.popupElement {
font-size: 12px;
/*
* Refresh segments button
*/
#refreshSegmentsButton {
background: transparent;
border: 0;
border-radius: 50%;
cursor: pointer;
display: flex;
padding: 5px;
margin: 5px auto;
align-items: center;
}
.sponsorTime.popupElement {
font-size: 20px;
#refreshSegmentsButton:hover {
background-color: var(--sb-grey-bg-color);
}
.smallLink.popupElement {
font-size: 10px;
text-decoration: underline;
cursor: pointer;
/*
* <details> wrapper around each segment
*/
.votingButtons {
font-family: Arial, Helvetica, sans-serif;
}
.mediumLink.popupElement {
font-size: 15px;
margin-left: 25px;
margin-right: 25px;
text-decoration: underline;
cursor: pointer;
.votingButtons[open] {
padding-bottom: 5px;
}
.tinyLink.popupElement {
font-size: 10px;
text-decoration: underline;
cursor: pointer;
.votingButtons:hover {
background-color: var(--sb-grey-bg-color);
}
.whitelistButton.popupElement {
background-color:#3acc3a;
-moz-border-radius:28px;
-webkit-border-radius:28px;
border-radius:28px;
border: none;
display:inline-block;
cursor:pointer;
color:#ffffff;
font-size:16px;
padding:8px 37px;
text-decoration:none;
text-shadow:0px 0px 0px #27663c;
}
.whitelistButton:hover.popupElement {
background-color:#218b26;
}
.whitelistButton:focus.popupElement {
outline: none;
background-color:#218b26;
}
.whitelistButton:active.popupElement {
position:relative;
top:1px;
/*
* Individual segments summaries (clickable <summary>)
*/
.segmentSummary {
cursor: pointer;
font-weight: bold;
padding: 7px;
list-style: none;
white-space: nowrap;
}
.greenButton.popupElement {
background-color:#ec1c1c;
-moz-border-radius:28px;
-webkit-border-radius:28px;
border-radius:28px;
border:1px solid #d31919;
display:inline-block;
cursor:pointer;
color:#ffffff;
font-size:16px;
padding:8px 37px;
text-decoration:none;
text-shadow:0px 0px 0px #662727;
}
.greenButton:hover.popupElement {
background-color:#bf2a2a;
}
.greenButton:focus.popupElement {
outline: none;
background-color:#bf2a2a;
}
.greenButton:active.popupElement {
position:relative;
top:1px;
/*
* Category dot in segment
*/
.sponsorTimesCategoryColorCircle {
margin: 0 8px;
}
.dangerButton.popupElement {
-moz-box-shadow:inset 0px 1px 0px 0px #cf866c;
-webkit-box-shadow:inset 0px 1px 0px 0px #cf866c;
box-shadow:inset 0px 1px 0px 0px #cf866c;
background-color:#d0451b;
-moz-border-radius:3px;
-webkit-border-radius:3px;
border-radius:3px;
border:1px solid #942911;
display:inline-block;
cursor:pointer;
color:#ffffff;
font-size:13px;
padding:6px 24px;
text-decoration:none;
text-shadow:0px 1px 0px #854629;
}
.dangerButton:hover.popupElement {
background-color:#bc3315;
}
.dangerButton:focus.popupElement {
outline: none;
background-color:#bc3315;
}
.dangerButton:active.popupElement {
position:relative;
top:1px;
.dot {
width: 10px;
height: 10px;
border-radius: 50%;
display: inline-block;
}
.warningButton.popupElement {
-moz-box-shadow:inset 0px 1px 0px 0px #cfbd6c;
-webkit-box-shadow:inset 0px 1px 0px 0px #cfbd6c;
box-shadow:inset 0px 1px 0px 0px #cfbd6c;
background-color:#d0821b;
-moz-border-radius:3px;
-webkit-border-radius:3px;
border-radius:3px;
border:1px solid #948b11;
display:inline-block;
cursor:pointer;
color:#ffffff;
font-size:13px;
padding:6px 24px;
text-decoration:none;
text-shadow:0px 1px 0px #856829;
}
.warningButton:hover.popupElement {
background-color:#bc8215;
}
.warningButton:focus.popupElement {
outline: none;
background-color:#bc8215;
}
.warningButton:active.popupElement {
position:relative;
top:1px;
/*
* Buttons that appear under a segment on click
*/
.voteButton {
height: 20px;
padding: 0 5px;
cursor: pointer;
}
.smallButton.popupElement {
background-color:#f9902d;
-moz-border-radius:3px;
-webkit-border-radius:3px;
border-radius:3px;
border:1px solid #f9a72d;
display:inline-block;
cursor:pointer;
color:#ffffff;
font-size:14px;
padding:6px 10px;
text-decoration:none;
/*
* "Voted!" text that appears after voting on a segment
*/
.sponsorTimesThanksForVotingText {
font-size: large;
}
.smallButton:hover.popupElement {
background-color:#fa9806;
/*
* Main controls menu
*/
.sbControlsMenu {
background-color: var(--sb-grey-bg-color);
display: flex;
justify-content: space-evenly;
margin-top: 10px;
}
.smallButton:focus.popupElement {
outline: none;
background-color:#fa9806;
.sbControlsMenu-item {
background-color: var(--sb-grey-bg-color);
border: 0;
padding: 0;
cursor: pointer;
user-select: none;
padding: 10px 15px;
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.sbControlsMenu-item:hover {
background-color: #444;
}
.sbControlsMenu-itemIcon {
margin-bottom: 6px;
}
/*
* "Skipping is enabled" toggle
*/
.toggleSwitchContainer {
cursor: pointer;
display: flex;
flex-direction: column;
align-items: center;
}
.toggleSwitchContainer-switch {
display: flex;
margin-bottom: 6px;
}
.switchBg {
display: block;
width: 50px;
height: 23px;
border-radius: 18.5px;
}
.switchBg.shadow {
box-shadow: 0.75px 0.75px 10px 0px rgba(50, 50, 50, 0.5);
opacity: 1;
}
.switchBg.white {
position: absolute;
background-color: #ccc;
opacity: 1;
}
.switchBg.green {
position: absolute;
background-color: #00a205;
opacity: 0;
transition: opacity 0.2s ease-out;
}
.switchDot {
background-color: var(--sb-main-fg-color);
border-radius: 50%;
width: 15px;
height: 15px;
margin: 4px;
position: absolute;
box-shadow: 0.75px 0.75px 3.8px 0px rgba(50, 50, 50, 0.45);
transition: transform 0.2s ease-out;
}
#toggleSwitch:checked ~ .switchDot {
transform: translateX(27px);
}
#toggleSwitch:checked ~ .switchBg.green {
opacity: 1;
}
#toggleSwitch:checked ~ .switchBg.white {
opacity: 0;
transition: opacity 0.2s step-end;
}
/*
* Whitelist add/remove icon
*/
.SBWhitelistIcon > path {
fill: var(--sb-main-fg-color);
}
.SBWhitelistIcon.rotated {
transform: rotate(45deg);
}
@keyframes rotate {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
/*
* Notice that appears when whitelisting a channel, that recommends
* enabling the "Force Channel Check Before Skipping" option
*/
#whitelistForceCheck {
font-weight: bold;
text-decoration: underline;
font-size: large;
cursor: pointer;
padding: 10px 0;
}
/*
* Container around the "Segment Starts Now" and "Submit Times" buttons
*/
#mainControls {
flex-flow: column;
align-items: center;
margin-bottom: 12px;
}
/*
* Generic buttons used for "Segment Starts Now" and "Submit Times"
*/
.sbMediumButton {
background-color: var(--sb-red-bg-color);
border: 0;
-moz-border-radius: 28px;
-webkit-border-radius: 28px;
border-radius: 28px;
display: inline-block;
cursor: pointer;
color: var(--sb-main-fg-color);
font-size: 16px;
padding: 8px 37px;
font-family: var(--sb-main-font-family);
transition: 0.01s background-color;
}
.sbMediumButton:hover,
.sbMediumButton:focus {
outline: none;
background-color: #ec1c1c;
}
.sbMediumButton:active {
position: relative;
top: 1px;
}
/*
* "Submit Times" button
*/
#submitTimes {
margin-top: 12px;
}
/*
* Heading utility class
*/
.sbHeader {
font-size: 20px;
font-weight: bold;
margin: 10px 0 5px;
}
/*
* Side-by-side section of "Your Work"
*/
.sbYourWorkCols {
display: flex;
margin: 0 20px 12px;
}
.sbYourWorkCols > div {
display: flex;
align-items: center;
width: 50%;
justify-content: center;
}
/*
* <button> elements that have icons
*/
#setUsernameButton,
#submitUsername,
#copyUserID {
background: transparent;
border: 0;
cursor: pointer;
padding: 0;
color: var(--sb-main-fg-color);
width: fit-content;
}
/*
* Prevent username from wrapping
*/
#setUsernameButton {
flex: 0 1;
margin-right: 5px;
}
/*
* Set username button
*/
#submitUsername {
padding-left: 7px;
}
/*
* Increase font size of username input and display
*/
#usernameValue,
#usernameInput,
#sponsorTimesContributionsDisplay {
font-size: 16px;
flex: 1 0;
}
/*
* Left align "Username" and "Submissions" labels
*/
#usernameElement > div > p,
#sponsorTimesContributionsContainer {
text-align: start;
}
/*
* Enable flexbox for buttons with SVG icon
*/
#setUsernameContainer > button {
display: flex;
}
/*
* Improve position of "Copy User ID" button
*/
#copyUserID {
width: 100%;
flex: 0 1;
}
/*
* Container around username display and edit
*/
#setUsernameContainer {
display: flex;
}
/*
* Improve alignment of username and submissions
*/
#usernameElement > div,
#sponsorTimesContributionsContainer > div {
display: flex;
flex-flow: column nowrap;
align-items: flex-start;
}
/*
* Truncate username display
*/
#usernameValue {
overflow: hidden;
text-overflow: ellipsis;
max-width: 130px;
margin-right: 8px;
}
/*
* Set username form container with "expanded" state
*/
#setUsername {
display: flex;
}
#setUsername.SBExpanded {
width: 200%;
}
/*
* Set username input
*/
#usernameInput {
background: transparent;
padding: 2px;
border: var(--sb-main-fg-color) 1px solid;
color: var(--sb-main-fg-color);
width: calc(100% - 24px);
text-overflow: ellipsis;
}
/*
* Footer
*/
#sbFooter {
margin-top: 10px;
padding-bottom: 20px;
}
#sbFooter a {
color: var(--sb-main-fg-color);
cursor: pointer;
text-decoration: none;
}
/*
* "Show Notice Again" button
*/
#showNoticeAgain {
background: transparent;
border: 1px solid #fff;
border-radius: 5px;
color: var(--sb-main-fg-color);
cursor: pointer;
margin-bottom: 20px;
padding: 5px;
}
/*
* Generic spacing classes
*/
.u-mZ {
margin: 0 !important;
}
/*
* Generic hide utility classes
*/
#sponsorBlockPopupBody .hidden {
display: none !important;
}
.smallButton:active.popupElement {
position:relative;
top:1px;
}

View File

@@ -1,200 +1,160 @@
<html>
<!DOCTYPE html>
<html id="sponsorBlockPopupHTML">
<head>
<meta charset="utf-8" />
<title>__MSG_openPopup__</title>
<link id="sponsorBlockPopupFont" rel="stylesheet" type="text/css" href="/libs/Source+Sans+Pro.css"/>
<link id="sponsorBlockStyleSheet" rel="stylesheet" type="text/css" href="popup.css"/>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link id="sponsorBlockPopupFont" href="/libs/Source+Sans+Pro.css" rel="stylesheet">
<link id="sponsorBlockStyleSheet" href="popup.css" rel="stylesheet">
</head>
<body class="popupBody">
<center>
<div id="app" class="popupBody sponsorBlockPageBody">
<h1 class="popupElement">
<img src="icons/IconSponsorBlocker256px.png" height="32px" id="sponsorBlockPopupLogo"/>
__MSG_Name__
</h1>
<body id="sponsorBlockPopupBody">
<div id="sponsorblockPopup" class="sponsorBlockPageBody sb-preload">
<!-- Loading text -->
<p id="loadingIndicator" class="popupElement">__MSG_noVideoID__</p>
<!-- Hidden until loading complete -->
<div id="mainControls" class="main popupElement" style="display: none">
<!-- If the video was found in the database -->
<div id="videoFound">
</div>
<header class="sbPopupLogo">
<img src="icons/IconSponsorBlocker256px.png" alt="SponsorBlock" width="40" height="40" id="sponsorBlockPopupLogo">
<p class="u-mZ">SponsorLock</p>
</header>
<div id="downloadedSponsorMessageTimes" class="popupElement">
</div>
<p class="popupElement">
__MSG_recordTimesDescription__
</p>
<div>
<button id="sponsorStart" class="greenButton popupElement">__MSG_sponsorStart__</button>
</div>
<sub class="popupElement">__MSG_popupHint__</sub>
<div id="submissionSection" class="popupElement" style="display: none">
<h3 class="popupElement">__MSG_lastTimes__</h3>
<b>Sponsor Editing has been moved and will appear after you click submit</b>
<br/>
<div id="submitTimesContainer" class="popupElement" style="display: none">
<button id="submitTimes" class="smallButton popupElement">__MSG_submitTimesButton__</button>
</div>
</div>
<div id="discordButtonContainer" class="popupElement" style="display: none">
<br/>
<a href="https://discord.gg/QnmVMpU" class="popupElement" target="_blank"><img src="https://www.logolynx.com/images/logolynx/1b/1bcc0f0aefe71b2c8ce66ffe8645d365.png" height="32px"/></a>
<br/>
__MSG_discordAdvert__
<br/>
<span id="hideDiscordButton" class="smallLink popupElement">__MSG_hideThis__</span>
</div>
<div>
<br/>
<button id="whitelistChannel" class="whitelistButton popupElement">__MSG_whitelistChannel__</button>
<button id="unwhitelistChannel" class="whitelistButton popupElement" style="display: none">__MSG_removeFromWhitelist__</button>
</div>
<br/>
<button id="reportAnIssue" class="dangerButton popupElement">__MSG_voteOnTime__</button>
<div id="issueReporterContainer" class="popupElement" style="display: none">
<h3 style="margin-top: 0px" class="popupElement">__MSG_voteOnTime__</h3>
<div id="issueReporterTimeButtons" class="popupElement">
</div>
</div>
<br/>
<br/>
</div>
<div>
<button id="disableSkipping" class="greenButton popupElement">__MSG_disableSkipping__</button>
<button id="enableSkipping" class="whitelistButton popupElement" style="display: none">__MSG_enableSkipping__</button>
</div>
<h2 class="recordingSubtitle popupElement">__MSG_yourWork__</h2>
<p class="popupElement">
<span id="sponsorTimesContributionsContainer" class="popupElement" style="display: none">
__MSG_soFarUHSubmited__
<span id="sponsorTimesContributionsDisplay" class="popupElement">
0
</span>
<span id="sponsorTimesContributionsDisplayEndWord" class="popupElement">__MSG_Sponsors__</span>.
</span>
<span id="sponsorTimesViewsContainer" class="popupElement" style="display: none">
__MSG_savedPeopleFrom__
<span id="sponsorTimesViewsDisplay" class="popupElement">
0
</span>
<span id="sponsorTimesViewsDisplayEndWord" class="popupElement">__MSG_Segments__</span>.
</span>
<span id="sponsorTimesOthersTimeSavedContainer" class="popupElement" style="display: none">
__MSG_youHaveSavedTime__
<span id="sponsorTimesOthersTimeSavedDisplay" class="popupElement">
0
</span>
<span id="sponsorTimesOthersTimeSavedEndWord" class="popupElement">__MSG_minsLower__</span>
<span class="popupElement">__MSG_youHaveSavedTimeEnd__</span>
</span>
<div id="sponsorTimesSkipsDoneContainer" class="popupElement" style="display: none">
__MSG_youHaveSkipped__
<span id="sponsorTimesSkipsDoneDisplay" class="popupElement">
0
</span>
<span id="sponsorTimesSkipsDoneEndWord" class="popupElement">__MSG_Segments__</span> (since February).
</div>
<div id="sponsorTimeSavedContainer" class="popupElement" style="display: none">
__MSG_youHaveSaved__
<span id="sponsorTimeSavedDisplay" class="popupElement">
0
</span>
<span id="sponsorTimeSavedEndWord" class="popupElement">__MSG_minsLower__</span>.
</br/>
</br/>
</div>
<div class="popupElement">
__MSG_viewLeaderboard__ <a class="popupElement discreteLink" href="https://sponsor.ajay.app/stats" target="_blank">__MSG_here__</a>.
</div>
</p>
<div id="setUsernameContainer" class="popupElement">
<button id="setUsernameButton" class="warningButton popupElement">__MSG_setUsername__</button>
<br/>
<sub class="popupElement">
__MSG_publicStats__ <a class="popupElement discreteLink" href="https://sponsor.ajay.app/stats" target="_blank">__MSG_here__</a>.
</sub>
</div>
<div id="setUsername" class="popupElement" style="display: none">
<h3>__MSG_setUsername__</h3>
<div id="setUsernameStatusContainer" style="display: none">
<h2 id="setUsernameStatus"></h2>
</div>
<input id="usernameInput" hint="Username"></input>
<br/>
<br/>
<button id="submitUsername" class="warningButton popupElement">__MSG_setUsername__</button>
</div>
<div id="optionsButtonContainer" class="popupElement">
<br/>
<br/>
<button id="optionsButton" class="dangerButton popupElement">__MSG_Options__</button>
<br/>
<sub class="popupElement">
__MSG_optionsInfo__
</sub>
<br/>
</div>
<button id="showNoticeAgain" style="display: none" class="dangerButton popupElement">__MSG_showNotice__</button>
<div id="videoInfo">
<!-- Loading text -->
<p id="loadingIndicator" class="u-mZ">__MSG_noVideoID__</p>
<!-- If the video was found in the database -->
<p id="videoFound" class="u-mZ"></p>
<button id="refreshSegmentsButton" title="__MSG_refreshSegments__">
<img src="/icons/refresh.svg" alt="Refresh icon" id="refreshSegments" />
</button>
<div id="issueReporterContainer">
<div id="issueReporterTimeButtons"></div>
</div>
</center>
</body>
</div>
<!-- Scripts that need to load after the html -->
<script src="./js/vendor.js"></script>
<script src="./js/popup.js"></script>
<div class="sbControlsMenu">
<label style="display: none" id="whitelistButton" for="whitelistToggle" class="hidden sbControlsMenu-item" title="__MSG_forceChannelCheckPopup__">
<input type="checkbox" style="display:none;" id="whitelistToggle">
<svg viewBox="0 0 24 24" width="23" height="23" class="SBWhitelistIcon sbControlsMenu-itemIcon">
<path d="M24 10H14V0h-4v10H0v4h10v10h4V14h10z" />
</svg>
<span id="whitelistChannel">__MSG_whitelistChannel__</span>
<span id="unwhitelistChannel" style="display: none">__MSG_removeFromWhitelist__</span>
</label>
<!--github: mbledkowski/toggle-switch-->
<label id="disableExtension" for="toggleSwitch" class="toggleSwitchContainer sbControlsMenu-item">
<span class="toggleSwitchContainer-switch">
<input type="checkbox" style="display:none;" id="toggleSwitch" checked>
<span class="switchBg shadow"></span>
<span class="switchBg white"></span>
<span class="switchBg green"></span>
<span class="switchDot"></span>
</span>
<span id="disableSkipping">__MSG_disableSkipping__</span>
<span id="enableSkipping" style="display: none">__MSG_enableSkipping__</span>
</label>
<button id="optionsButton" class="sbControlsMenu-item" title="__MSG_optionsInfo__">
<img src="/icons/settings.svg" alt="Settings icon" width="23" height="23" class="sbControlsMenu-itemIcon" id="sbPopupIconSettings" />
__MSG_Options__
</button>
</div>
<p id="whitelistForceCheck" class="u-mZ hidden">
__MSG_forceChannelCheckPopup__
</p>
<div id="mainControls" style="display: none">
<p class="sbHeader">
__MSG_recordTimesDescription__
</p>
<sub style="margin-bottom: 12px;">__MSG_popupHint__</sub>
<div>
<button id="sponsorStart" class="sbMediumButton">__MSG_sponsorStart__</button>
</div>
<div id="submissionSection" style="display: none">
<b style="display: block; margin-top: 12px;">__MSG_submissionEditHint__</b>
<button id="submitTimes" class="sbMediumButton">__MSG_submitTimesButton__</button>
</div>
</div>
<h1 class="recordingSubtitle sbHeader" style="display: none">__MSG_yourWork__</h1>
<div class="sbYourWorkCols" style="display: none">
<div id="usernameElement">
<div>
<p class="u-mZ">__MSG_Username__:</p>
<div id="setUsernameContainer">
<p id="usernameValue" class="u-mZ"></p>
<button id="setUsernameButton" title="__MSG_setUsername__">
<img src="/icons/pencil.svg" alt="__MSG_setUsername__" width="16" height="16" id="sbPopupIconEdit">
</button>
<button id="copyUserID" title="__MSG_copyPublicID__">
<img src="/icons/clipboard.svg" alt="__MSG_copyPublicID__" width="16" height="16" id="sbPopupIconCopyUserID">
</button>
</div>
<div id="setUsername" style="display: none">
<div id="setUsernameStatusContainer" style="display: none">
<p id="setUsernameStatus" class="u-mZ"></p>
</div>
<input id="usernameInput" placeholder="Username">
<button id="submitUsername">
<img src="/icons/check.svg" alt="__MSG_setUsername__" width="16" height="16" id="sbPopupIconCheck">
</button>
</div>
</div>
</div>
<div id="sponsorTimesContributionsContainer" class="hidden">
<div>
<p class="u-mZ">__MSG_Submissions__:</p>
<span id="sponsorTimesContributionsDisplay">
0
</span>
</div>
</div>
</div>
<p id="sponsorTimesViewsContainer" style="display: none" class="u-mZ">
__MSG_savedPeopleFrom__
<b><span id="sponsorTimesViewsDisplay">
0
</span></b>
<span id="sponsorTimesViewsDisplayEndWord">__MSG_Segments__</span>
<br>
(<b><span id="sponsorTimesOthersTimeSavedDisplay">0</span>
<span id="sponsorTimesOthersTimeSavedEndWord">__MSG_minsLower__</span></b>
<span>__MSG_youHaveSavedTimeEnd__</span>).
</p>
<p id="sponsorTimesSkipsDoneContainer" style="display: none" class="u-mZ">
__MSG_youHaveSkipped__
<b><span id="sponsorTimesSkipsDoneDisplay">
0
</span></b>
<span id="sponsorTimesSkipsDoneEndWord">__MSG_Segments__</span>
(<b><span id="sponsorTimeSavedDisplay">
0
</span>
<span id="sponsorTimeSavedEndWord">__MSG_minsLower__</span></b>).
</p>
<footer id="sbFooter" style="display: none">
<div id="sponsorTimesDonateContainer" style="display: none; align-items: center; justify-content: center;">
<img class="sbHeart" src="/icons/heart.svg" alt="Heart icon" />
<a id="sbConsiderDonateLink" href="https://sponsor.ajay.app/donate" target="_blank" rel="noopener">
__MSG_considerDonating__
</a>
<img id="sbCloseDonate" src="/icons/close.png" alt="Close icon" height="8" style="padding-left: 5px; cursor: pointer;" />
</div>
<a href="https://sponsor.ajay.app" target="_blank" rel="noopener">__MSG_website__</a> |
<a href="https://sponsor.ajay.app/stats" target="_blank" rel="noopener">__MSG_viewLeaderboard__</a> |
<a href="https://github.com/ajayyy/SponsorBlock" target="_blank" rel="noopener">GitHub</a>
<br/>
<a href="https://discord.gg/SponsorBlock" target="_blank" rel="noopener">Discord</a> |
<a href="https://matrix.to/#/#sponsor:ajay.app?via=ajay.app&via=matrix.org&via=mozilla.org" target="_blank" rel="noopener">Matrix</a> |
<a id="helpButton">__MSG_help__</a>
</footer>
<button id="showNoticeAgain" style="display: none">__MSG_showNotice__</button>
</div>
<!-- Scripts that need to load after the html -->
<script src="./js/vendor.js" async></script>
<script src="./js/popup.js" async></script>
</body>
</html>

View File

@@ -1,17 +1,20 @@
import * as Types from "./types";
import * as CompileConfig from "../config.json";
import Config from "./config";
import { Registration } from "./types";
// Make the config public for debugging purposes
(<any> window).SB = Config;
window.SB = Config;
import Utils from "./utils";
var utils = new Utils({
const utils = new Utils({
registerFirefoxContentScript,
unregisterFirefoxContentScript
});
// Used only on Firefox, which does not support non persistent background pages.
var contentScriptRegistrations = {};
const contentScriptRegistrations = {};
// Register content script if needed
if (utils.isFirefox()) {
@@ -29,40 +32,29 @@ chrome.tabs.onUpdated.addListener(function(tabId) {
chrome.runtime.onMessage.addListener(function (request, sender, callback) {
switch(request.message) {
case "openConfig":
chrome.runtime.openOptionsPage();
return
case "submitTimes":
submitTimes(request.videoID, callback);
//this allows the callback to be called later by the submitTimes function
return true;
case "addSponsorTime":
addSponsorTime(request.time, request.videoID, callback);
//this allows the callback to be called later
return true;
case "getSponsorTimes":
getSponsorTimes(request.videoID, function(sponsorTimes) {
chrome.tabs.create({url: chrome.runtime.getURL('options/lock-options.html' + (request.hash ? '#' + request.hash : ''))});
return;
case "openHelp":
chrome.tabs.create({url: chrome.runtime.getURL('help/index.html')});
return;
case "openPage":
chrome.tabs.create({url: chrome.runtime.getURL(request.url)});
return;
case "sendRequest":
sendRequestToCustomServer(request.type, request.url, request.data).then(async (response) => {
callback({
sponsorTimes
responseText: await response.text(),
status: response.status,
ok: response.ok
});
});
//this allows the callback to be called later
return true;
case "submitVote":
submitVote(request.type, request.UUID, callback);
submitVote(request.type, request.UUID, request.category).then(callback);
//this allows the callback to be called later
return true;
case "alertPrevious":
chrome.notifications.create("stillThere" + Math.random(), {
type: "basic",
title: chrome.i18n.getMessage("wantToSubmit") + " " + request.previousVideoID + "?",
message: chrome.i18n.getMessage("leftTimes"),
iconUrl: "./icons/LogoSponsorBlocker256px.png"
});
case "registerContentScript":
registerFirefoxContentScript(request);
return false;
@@ -73,7 +65,7 @@ chrome.runtime.onMessage.addListener(function (request, sender, callback) {
});
//add help page on install
chrome.runtime.onInstalled.addListener(function (object) {
chrome.runtime.onInstalled.addListener(function () {
// This let's the config sync to run fully before checking.
// This is required on Firefox
setTimeout(function() {
@@ -82,12 +74,15 @@ chrome.runtime.onInstalled.addListener(function (object) {
// If there is no userID, then it is the first install.
if (!userID){
//open up the install page
chrome.tabs.create({url: chrome.extension.getURL("/help/index_en.html")});
chrome.tabs.create({url: chrome.extension.getURL("/help/index.html")});
//generate a userID
const newUserID = utils.generateUserID();
//save this UUID
Config.config.userID = newUserID;
// Don't show update notification
Config.config.categoryPillUpdate = true;
}
}, 1500);
});
@@ -98,8 +93,8 @@ chrome.runtime.onInstalled.addListener(function (object) {
*
* @param {JSON} options
*/
function registerFirefoxContentScript(options) {
let oldRegistration = contentScriptRegistrations[options.id];
function registerFirefoxContentScript(options: Registration) {
const oldRegistration = contentScriptRegistrations[options.id];
if (oldRegistration) oldRegistration.unregister();
browser.contentScripts.register({
@@ -120,39 +115,7 @@ function unregisterFirefoxContentScript(id: string) {
delete contentScriptRegistrations[id];
}
//gets the sponsor times from memory
function getSponsorTimes(videoID, callback) {
let sponsorTimes = [];
let sponsorTimesStorage = Config.config.sponsorTimes.get(videoID);
if (sponsorTimesStorage != undefined && sponsorTimesStorage.length > 0) {
sponsorTimes = sponsorTimesStorage;
}
callback(sponsorTimes);
}
function addSponsorTime(time, videoID, callback) {
getSponsorTimes(videoID, function(sponsorTimes) {
//add to sponsorTimes
if (sponsorTimes.length > 0 && sponsorTimes[sponsorTimes.length - 1].length < 2) {
//it is an end time
sponsorTimes[sponsorTimes.length - 1][1] = time;
} else {
//it is a start time
let sponsorTimesIndex = sponsorTimes.length;
sponsorTimes[sponsorTimesIndex] = [];
sponsorTimes[sponsorTimesIndex][0] = time;
}
//save this info
Config.config.sponsorTimes.set(videoID, sponsorTimes);
callback();
});
}
function submitVote(type, UUID, callback) {
async function submitVote(type: number, UUID: string, category: string) {
let userID = Config.config.userID;
if (userID == undefined || userID === "undefined") {
@@ -161,82 +124,62 @@ function submitVote(type, UUID, callback) {
Config.config.userID = userID;
}
//publish this vote
utils.sendRequestToServer("POST", "/api/voteOnSponsorTime?UUID=" + UUID + "&userID=" + userID + "&type=" + type, function(xmlhttp, error) {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
callback({
successType: 1
});
} else if (xmlhttp.readyState == 4 && xmlhttp.status == 405) {
//duplicate vote
callback({
successType: 0,
statusCode: xmlhttp.status
});
} else if (error) {
//error while connect
callback({
successType: -1,
statusCode: xmlhttp.status
});
}
const typeSection = (type !== undefined) ? "&type=" + type : "&category=" + category;
});
//publish this vote
const response = await asyncRequestToServer("POST", "/api/voteOnSponsorTime?UUID=" + UUID + "&userID=" + userID + typeSection);
if (response.ok) {
return {
successType: 1,
responseText: await response.text()
};
} else if (response.status == 405) {
//duplicate vote
return {
successType: 0,
statusCode: response.status,
responseText: await response.text()
};
} else {
//error while connect
return {
successType: -1,
statusCode: response.status,
responseText: await response.text()
};
}
}
async function submitTimes(videoID: string, callback) {
//get the video times from storage
let sponsorTimes = Config.config.sponsorTimes.get(videoID);
let userID = Config.config.userID;
if (sponsorTimes != undefined && sponsorTimes.length > 0) {
let durationResult = <Types.VideoDurationResponse> await new Promise((resolve, reject) => {
chrome.tabs.query({
active: true,
currentWindow: true
}, function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, {
message: "getVideoDuration"
}, (response) => resolve(response));
});
});
async function asyncRequestToServer(type: string, address: string, data = {}) {
const serverAddress = Config.config.testingServer ? CompileConfig.testingServerAddress : Config.config.serverAddress;
//check if a sponsor exceeds the duration of the video
for (let i = 0; i < sponsorTimes.length; i++) {
if (sponsorTimes[i][1] > durationResult.duration) {
sponsorTimes[i][1] = durationResult.duration;
}
}
return await (sendRequestToCustomServer(type, serverAddress + address, data));
}
//submit these times
for (let i = 0; i < sponsorTimes.length; i++) {
//to prevent it from happeneing twice
let increasedContributionAmount = false;
/**
* Sends a request to the specified url
*
* @param type The request type "GET", "POST", etc.
* @param address The address to add to the SponsorBlock server address
* @param callback
*/
async function sendRequestToCustomServer(type: string, url: string, data = {}) {
// If GET, convert JSON to parameters
if (type.toLowerCase() === "get") {
url = utils.objectToURI(url, data, true);
//submit the sponsorTime
utils.sendRequestToServer("GET", "/api/postVideoSponsorTimes?videoID=" + videoID + "&startTime=" + sponsorTimes[i][0] + "&endTime=" + sponsorTimes[i][1]
+ "&userID=" + userID, function(xmlhttp, error) {
if (xmlhttp.readyState == 4 && !error) {
callback({
statusCode: xmlhttp.status,
responseText: xmlhttp.responseText
});
if (xmlhttp.status == 200) {
//save the amount contributed
if (!increasedContributionAmount) {
increasedContributionAmount = true;
Config.config.sponsorTimesContributed = Config.config.sponsorTimesContributed + sponsorTimes.length;
}
}
} else if (error) {
callback({
statusCode: -1
});
}
});
}
data = null;
}
const response = await fetch(url, {
method: type,
headers: {
'Content-Type': 'application/json'
},
redirect: 'follow',
body: data ? JSON.stringify(data) : null
});
return response;
}

View File

@@ -1,7 +1,7 @@
import * as React from "react";
import Config from "../config"
import * as CompileConfig from "../../config.json";
import { Category } from "../types";
import CategorySkipOptionsComponent from "./CategorySkipOptionsComponent";
export interface CategoryChooserProps {
@@ -23,11 +23,34 @@ class CategoryChooserComponent extends React.Component<CategoryChooserProps, Cat
}
}
render() {
render(): React.ReactElement {
return (
<table id="categoryChooserTable"
className="categoryChooserTable">
<tbody>
{/* Headers */}
<tr id={"CategoryOptionsRow"}
className="categoryTableElement categoryTableHeader">
<th id={"CategoryOptionName"}>
{chrome.i18n.getMessage("category")}
</th>
<th id={"CategorySkipOption"}
className="skipOption">
{chrome.i18n.getMessage("skipOption")}
</th>
<th id={"CategoryColorOption"}
className="colorOption">
{chrome.i18n.getMessage("seekBarColor")}
</th>
<th id={"CategoryPreviewColorOption"}
className="previewColorOption">
{chrome.i18n.getMessage("previewColor")}
</th>
</tr>
{this.getCategorySkipOptions()}
</tbody>
</table>
@@ -35,12 +58,11 @@ class CategoryChooserComponent extends React.Component<CategoryChooserProps, Cat
}
getCategorySkipOptions(): JSX.Element[] {
let elements: JSX.Element[] = [];
const elements: JSX.Element[] = [];
for (const category of CompileConfig.categoryList) {
elements.push(
<CategorySkipOptionsComponent category={category}
defaultColor={"00d400"}
<CategorySkipOptionsComponent category={category as Category}
key={category}>
</CategorySkipOptionsComponent>
);

View File

@@ -0,0 +1,168 @@
import * as React from "react";
import Config from "../config";
import { Category, SegmentUUID, SponsorTime } from "../types";
import ThumbsUpSvg from "../svg-icons/thumbs_up_svg";
import ThumbsDownSvg from "../svg-icons/thumbs_down_svg";
import { downvoteButtonColor, SkipNoticeAction } from "../utils/noticeUtils";
import { VoteResponse } from "../messageTypes";
import { AnimationUtils } from "../utils/animationUtils";
import { GenericUtils } from "../utils/genericUtils";
import { Tooltip } from "../render/Tooltip";
export interface CategoryPillProps {
vote: (type: number, UUID: SegmentUUID, category?: Category) => Promise<VoteResponse>;
}
export interface CategoryPillState {
segment?: SponsorTime;
show: boolean;
open?: boolean;
}
class CategoryPillComponent extends React.Component<CategoryPillProps, CategoryPillState> {
tooltip?: Tooltip;
constructor(props: CategoryPillProps) {
super(props);
this.state = {
segment: null,
show: false,
open: false
};
}
render(): React.ReactElement {
const style: React.CSSProperties = {
backgroundColor: this.getColor(),
display: this.state.show ? "flex" : "none",
color: this.getTextColor(),
}
return (
<span style={style}
className={"sponsorBlockCategoryPill"}
aria-label={this.getTitleText()}
onClick={(e) => this.toggleOpen(e)}
onMouseEnter={() => this.openTooltip()}
onMouseLeave={() => this.closeTooltip()}>
<span className="sponsorBlockCategoryPillTitleSection">
<img className="sponsorSkipLogo sponsorSkipObject"
src={chrome.extension.getURL("icons/IconSponsorBlocker256px.png")}>
</img>
<span className="sponsorBlockCategoryPillTitle">
{chrome.i18n.getMessage("category_" + this.state.segment?.category)}
</span>
</span>
{this.state.open && (
<>
{/* Upvote Button */}
<div id={"sponsorTimesDownvoteButtonsContainerUpvoteCategoryPill"}
className="voteButton"
style={{marginLeft: "5px"}}
title={chrome.i18n.getMessage("upvoteButtonInfo")}
onClick={(e) => this.vote(e, 1)}>
<ThumbsUpSvg fill={Config.config.colorPalette.white} />
</div>
{/* Downvote Button */}
<div id={"sponsorTimesDownvoteButtonsContainerDownvoteCategoryPill"}
className="voteButton"
title={chrome.i18n.getMessage("reportButtonInfo")}
onClick={(event) => this.vote(event, 0)}>
<ThumbsDownSvg fill={downvoteButtonColor(null, null, SkipNoticeAction.Downvote)} />
</div>
</>
)}
{/* Close Button */}
<img src={chrome.extension.getURL("icons/close.png")}
className="categoryPillClose"
onClick={() => this.setState({ show: false })}>
</img>
</span>
);
}
private toggleOpen(event: React.MouseEvent): void {
event.stopPropagation();
if (this.state.show) {
this.setState({ open: !this.state.open });
}
}
private async vote(event: React.MouseEvent, type: number): Promise<void> {
event.stopPropagation();
if (this.state.segment) {
const stopAnimation = AnimationUtils.applyLoadingAnimation(event.currentTarget as HTMLElement, 0.3);
const response = await this.props.vote(type, this.state.segment.UUID);
await stopAnimation();
if (response.successType == 1 || (response.successType == -1 && response.statusCode == 429)) {
this.setState({
open: false,
show: type === 1
});
} else if (response.statusCode !== 403) {
alert(GenericUtils.getErrorMessage(response.statusCode, response.responseText));
}
}
}
private getColor(): string {
const configObject = Config.config.barTypes["preview-" + this.state.segment?.category]
|| Config.config.barTypes[this.state.segment?.category];
return configObject?.color;
}
private getTextColor(): string {
const color = this.getColor();
if (!color) return null;
const existingCalculatedColor = Config.config.categoryPillColors[this.state.segment?.category];
if (existingCalculatedColor && existingCalculatedColor.lastColor === color) {
return existingCalculatedColor.textColor;
} else {
const luminance = GenericUtils.getLuminance(color);
const textColor = luminance > 128 ? "black" : "white";
Config.config.categoryPillColors[this.state.segment?.category] = {
lastColor: color,
textColor
};
return textColor;
}
}
private openTooltip(): void {
const tooltipMount = document.querySelector("ytd-video-primary-info-renderer > #container") as HTMLElement;
if (tooltipMount) {
this.tooltip = new Tooltip({
text: this.getTitleText(),
referenceNode: tooltipMount,
bottomOffset: "70px",
opacity: 0.95,
displayTriangle: false,
showLogo: false,
showGotIt: false
});
}
}
private closeTooltip(): void {
this.tooltip?.close();
this.tooltip = null;
}
getTitleText(): string {
const shortDescription = chrome.i18n.getMessage(`category_${this.state.segment?.category}_pill`);
return (shortDescription ? shortDescription + ". ": "") + chrome.i18n.getMessage("categoryPillTitleText");
}
}
export default CategoryPillComponent;

View File

@@ -1,15 +1,20 @@
import * as React from "react";
import Config from "../config"
import { CategorySkipOption } from "../types";
import * as CompileConfig from "../../config.json";
import { Category, CategorySkipOption } from "../types";
import { getCategorySuffix } from "../utils/categoryUtils";
export interface CategorySkipOptionsProps {
category: string;
defaultColor: string;
category: Category;
defaultColor?: string;
defaultPreviewColor?: string;
}
export interface CategorySkipOptionsState {
color: string;
previewColor: string;
}
class CategorySkipOptionsComponent extends React.Component<CategorySkipOptionsProps, CategorySkipOptionsState> {
@@ -19,11 +24,12 @@ class CategorySkipOptionsComponent extends React.Component<CategorySkipOptionsPr
// Setup state
this.state = {
color: props.defaultColor
color: props.defaultColor || Config.config.barTypes[this.props.category]?.color,
previewColor: props.defaultPreviewColor || Config.config.barTypes["preview-" + this.props.category]?.color,
}
}
render() {
render(): React.ReactElement {
let defaultOption = "disable";
// Set the default opton properly
for (const categorySelection of Config.config.categorySelections) {
@@ -39,28 +45,65 @@ class CategorySkipOptionsComponent extends React.Component<CategorySkipOptionsPr
defaultOption = "autoSkip";
break;
}
break;
}
}
return (
<tr id={this.props.category + "OptionsRow"}
className="categoryTableElement">
<td id={this.props.category + "OptionName"}
className="categoryTableLabel">
{chrome.i18n.getMessage("category_" + this.props.category)}
</td>
<>
<tr id={this.props.category + "OptionsRow"}
className="categoryTableElement">
<td id={this.props.category + "OptionName"}
className="categoryTableLabel">
{chrome.i18n.getMessage("category_" + this.props.category)}
</td>
<td id={this.props.category + "SkipOption"}>
<select
className="categoryOptionsSelector"
defaultValue={defaultOption}
onChange={this.skipOptionSelected.bind(this)}>
{this.getCategorySkipOptions()}
</select>
</td>
<td id={this.props.category + "SkipOption"}
className="skipOption">
<select
className="optionsSelector"
defaultValue={defaultOption}
onChange={this.skipOptionSelected.bind(this)}>
{this.getCategorySkipOptions()}
</select>
</td>
<td id={this.props.category + "ColorOption"}
className="colorOption">
<input
className="categoryColorTextBox option-text-box"
type="color"
onChange={(event) => this.setColorState(event, false)}
value={this.state.color} />
</td>
{/* TODO: Add colour chooser */}
</tr>
{this.props.category !== "exclusive_access" &&
<td id={this.props.category + "PreviewColorOption"}
className="previewColorOption">
<input
className="categoryColorTextBox option-text-box"
type="color"
onChange={(event) => this.setColorState(event, true)}
value={this.state.previewColor} />
</td>
}
</tr>
<tr id={this.props.category + "DescriptionRow"}
className="small-description categoryTableDescription">
<td
colSpan={2}>
{chrome.i18n.getMessage("category_" + this.props.category + "_description")}
{' '}
<a href={CompileConfig.wikiLinks[this.props.category]} target="_blank" rel="noreferrer">
{`${chrome.i18n.getMessage("LearnMore")}`}
</a>
</td>
</tr>
</>
);
}
@@ -111,20 +154,42 @@ class CategorySkipOptionsComponent extends React.Component<CategorySkipOptionsPr
}
getCategorySkipOptions(): JSX.Element[] {
let elements: JSX.Element[] = [];
""
const elements: JSX.Element[] = [];
let optionNames = ["disable", "showOverlay", "manualSkip", "autoSkip"];
if (this.props.category === "exclusive_access") optionNames = ["disable", "showOverlay"];
for (const optionName of optionNames) {
elements.push(
<option key={optionName} value={optionName}>
{chrome.i18n.getMessage(optionName)}
{chrome.i18n.getMessage(optionName !== "disable" ? optionName + getCategorySuffix(this.props.category)
: optionName)}
</option>
);
}
return elements;
}
setColorState(event: React.FormEvent<HTMLInputElement>, preview: boolean): void {
if (preview) {
this.setState({
previewColor: event.currentTarget.value
});
Config.config.barTypes["preview-" + this.props.category].color = event.currentTarget.value;
} else {
this.setState({
color: event.currentTarget.value
});
Config.config.barTypes[this.props.category].color = event.currentTarget.value;
}
// Make listener get called
Config.config.barTypes = Config.config.barTypes;
}
}
export default CategorySkipOptionsComponent;

View File

@@ -0,0 +1,75 @@
import * as React from "react";
import * as ReactDOM from "react-dom";
import Config from "../config";
import { Keybind } from "../types";
import KeybindDialogComponent from "./KeybindDialogComponent";
import { keybindEquals, keybindToString, formatKey } from "../utils/configUtils";
export interface KeybindProps {
option: string;
}
export interface KeybindState {
keybind: Keybind;
}
let dialog;
class KeybindComponent extends React.Component<KeybindProps, KeybindState> {
constructor(props: KeybindProps) {
super(props);
this.state = {keybind: Config.config[this.props.option]};
}
render(): React.ReactElement {
return(
<>
<div className="keybind-buttons inline" title={chrome.i18n.getMessage("change")} onClick={() => this.openEditDialog()}>
{this.state.keybind?.ctrl && <div className="key keyControl">Ctrl</div>}
{this.state.keybind?.ctrl && <span className="keyControl">+</span>}
{this.state.keybind?.alt && <div className="key keyAlt">Alt</div>}
{this.state.keybind?.alt && <span className="keyAlt">+</span>}
{this.state.keybind?.shift && <div className="key keyShift">Shift</div>}
{this.state.keybind?.shift && <span className="keyShift">+</span>}
{this.state.keybind?.key != null && <div className="key keyBase">{formatKey(this.state.keybind.key)}</div>}
{this.state.keybind == null && <span className="unbound">{chrome.i18n.getMessage("notSet")}</span>}
</div>
{this.state.keybind != null &&
<div className="option-button trigger-button inline" onClick={() => this.unbind()}>
{chrome.i18n.getMessage("unbind")}
</div>
}
</>
);
}
equals(other: Keybind): boolean {
return keybindEquals(this.state.keybind, other);
}
toString(): string {
return keybindToString(this.state.keybind);
}
openEditDialog(): void {
dialog = parent.document.createElement("div");
dialog.id = "keybind-dialog";
parent.document.body.prepend(dialog);
ReactDOM.render(<KeybindDialogComponent option={this.props.option} closeListener={(updateWith) => this.closeEditDialog(updateWith)} />, dialog);
}
closeEditDialog(updateWith: Keybind): void {
ReactDOM.unmountComponentAtNode(dialog);
dialog.remove();
if (updateWith != null)
this.setState({keybind: updateWith});
}
unbind(): void {
this.setState({keybind: null});
Config.config[this.props.option] = null;
}
}
export default KeybindComponent;

View File

@@ -0,0 +1,165 @@
import * as React from "react";
import { ChangeEvent } from "react";
import Config from "../config";
import { Keybind } from "../types";
import { keybindEquals, formatKey } from "../utils/configUtils";
export interface KeybindDialogProps {
option: string;
closeListener: (updateWith) => void;
}
export interface KeybindDialogState {
key: Keybind;
error: ErrorMessage;
}
interface ErrorMessage {
message: string;
blocking: boolean;
}
class KeybindDialogComponent extends React.Component<KeybindDialogProps, KeybindDialogState> {
constructor(props: KeybindDialogProps) {
super(props);
this.state = {
key: {
key: null,
code: null,
ctrl: false,
alt: false,
shift: false
},
error: {
message: null,
blocking: false
}
};
}
render(): React.ReactElement {
return(
<>
<div className="blocker"></div>
<div className="dialog">
<div id="change-keybind-description">{chrome.i18n.getMessage("keybindDescription")}</div>
<div id="change-keybind-settings">
<div id="change-keybind-modifiers" className="inline">
<div>
<input id="change-keybind-ctrl" type="checkbox" onChange={this.keybindModifierChecked} />
<label htmlFor="change-keybind-ctrl">Ctrl</label>
</div>
<div>
<input id="change-keybind-alt" type="checkbox" onChange={this.keybindModifierChecked} />
<label htmlFor="change-keybind-alt">Alt</label>
</div>
<div>
<input id="change-keybind-shift" type="checkbox" onChange={this.keybindModifierChecked} />
<label htmlFor="change-keybind-shift">Shift</label>
</div>
</div>
<div className="key inline">{formatKey(this.state.key.key)}</div>
</div>
<div id="change-keybind-error">{this.state.error?.message}</div>
<div id="change-keybind-buttons">
<div className={"option-button save-button inline" + ((this.state.error?.blocking || this.state.key.key == null) ? " disabled" : "")} onClick={() => this.save()}>
{chrome.i18n.getMessage("save")}
</div>
<div className="option-button cancel-button inline" onClick={() => this.props.closeListener(null)}>
{chrome.i18n.getMessage("cancel")}
</div>
</div>
</div>
</>
);
}
componentDidMount(): void {
parent.document.addEventListener("keydown", this.keybindKeyPressed);
document.addEventListener("keydown", this.keybindKeyPressed);
}
componentWillUnmount(): void {
parent.document.removeEventListener("keydown", this.keybindKeyPressed);
document.removeEventListener("keydown", this.keybindKeyPressed);
}
keybindKeyPressed = (e: KeyboardEvent): void => {
if (!e.altKey && !e.shiftKey && !e.ctrlKey && !e.metaKey && !e.getModifierState("AltGraph")) {
if (e.code == "Escape") {
this.props.closeListener(null);
return;
}
this.setState({
key: {
key: e.key,
code: e.code,
ctrl: this.state.key.ctrl,
alt: this.state.key.alt,
shift: this.state.key.shift}
}, () => this.setState({ error: this.isKeybindAvailable() }));
}
}
keybindModifierChecked = (e: ChangeEvent<HTMLInputElement>): void => {
const id = e.target.id;
const val = e.target.checked;
this.setState({
key: {
key: this.state.key.key,
code: this.state.key.code,
ctrl: id == "change-keybind-ctrl" ? val: this.state.key.ctrl,
alt: id == "change-keybind-alt" ? val: this.state.key.alt,
shift: id == "change-keybind-shift" ? val: this.state.key.shift}
}, () => this.setState({ error: this.isKeybindAvailable() }));
}
isKeybindAvailable(): ErrorMessage {
if (this.state.key.key == null)
return null;
let youtubeShortcuts: Keybind[];
if (/[a-zA-Z0-9,.+\-\][:]/.test(this.state.key.key)) {
youtubeShortcuts = [{key: "k"}, {key: "j"}, {key: "l"}, {key: "p", shift: true}, {key: "n", shift: true}, {key: ","}, {key: "."}, {key: ",", shift: true}, {key: ".", shift: true},
{key: "ArrowRight"}, {key: "ArrowLeft"}, {key: "ArrowUp"}, {key: "ArrowDown"}, {key: "ArrowRight", ctrl: true}, {key: "ArrowLeft", ctrl: true}, {key: "c"}, {key: "o"},
{key: "w"}, {key: "+"}, {key: "-"}, {key: "f"}, {key: "t"}, {key: "i"}, {key: "m"}, {key: "a"}, {key: "s"}, {key: "d"}, {key: "Home"}, {key: "End"},
{key: "0"}, {key: "1"}, {key: "2"}, {key: "3"}, {key: "4"}, {key: "5"}, {key: "6"}, {key: "7"}, {key: "8"}, {key: "9"}, {key: "]"}, {key: "["}];
} else {
youtubeShortcuts = [{key: null, code: "KeyK"}, {key: null, code: "KeyJ"}, {key: null, code: "KeyL"}, {key: null, code: "KeyP", shift: true}, {key: null, code: "KeyN", shift: true},
{key: null, code: "Comma"}, {key: null, code: "Period"}, {key: null, code: "Comma", shift: true}, {key: null, code: "Period", shift: true}, {key: null, code: "Space"},
{key: null, code: "KeyC"}, {key: null, code: "KeyO"}, {key: null, code: "KeyW"}, {key: null, code: "Equal"}, {key: null, code: "Minus"}, {key: null, code: "KeyF"}, {key: null, code: "KeyT"},
{key: null, code: "KeyI"}, {key: null, code: "KeyM"}, {key: null, code: "KeyA"}, {key: null, code: "KeyS"}, {key: null, code: "KeyD"}, {key: null, code: "BracketLeft"}, {key: null, code: "BracketRight"}];
}
for (const shortcut of youtubeShortcuts) {
const withShift = Object.assign({}, shortcut);
if (!/[0-9]/.test(this.state.key.key)) //shift+numbers don't seem to do anything on youtube, all other keys do
withShift.shift = true;
if (this.equals(shortcut) || this.equals(withShift))
return {message: chrome.i18n.getMessage("youtubeKeybindWarning"), blocking: false};
}
if (this.props.option != "skipKeybind" && this.equals(Config.config['skipKeybind']) ||
this.props.option != "submitKeybind" && this.equals(Config.config['submitKeybind']) ||
this.props.option != "startSponsorKeybind" && this.equals(Config.config['startSponsorKeybind']))
return {message: chrome.i18n.getMessage("keyAlreadyUsed"), blocking: true};
return null;
}
equals(other: Keybind): boolean {
return keybindEquals(this.state.key, other);
}
save(): void {
if (this.state.key.key != null && !this.state.error?.blocking) {
Config.config[this.props.option] = this.state.key;
this.props.closeListener(this.state.key);
}
}
}
export default KeybindDialogComponent;

View File

@@ -1,42 +1,65 @@
import * as React from "react";
import Config from "../config";
enum CountdownMode {
Timer,
Paused,
Stopped
}
export interface NoticeProps {
noticeTitle: string,
maxCountdownTime?: () => number,
amountOfPreviousNotices?: number,
showInSecondSlot?: boolean,
timed?: boolean,
idSuffix?: string,
fadeIn?: boolean,
startFaded?: boolean,
firstColumn?: React.ReactElement,
firstRow?: React.ReactElement,
bottomRow?: React.ReactElement[],
smaller?: boolean,
limitWidth?: boolean,
// Callback for when this is closed
closeListener?: () => void,
closeListener: () => void,
onMouseEnter?: (e: React.MouseEvent<HTMLElement, MouseEvent>) => void,
zIndex?: number
zIndex?: number,
style?: React.CSSProperties
biggerCloseButton?: boolean;
}
export interface NoticeState {
noticeTitle: string,
maxCountdownTime?: () => number,
maxCountdownTime: () => number,
countdownTime: number,
countdownText: string,
countdownMode: CountdownMode,
mouseHovering: boolean;
startFaded: boolean;
}
class NoticeComponent extends React.Component<NoticeProps, NoticeState> {
countdownInterval: NodeJS.Timeout;
idSuffix: any;
idSuffix: string;
amountOfPreviousNotices: number;
constructor(props: NoticeProps) {
super(props);
let maxCountdownTime = () => {
const maxCountdownTime = () => {
if (this.props.maxCountdownTime) return this.props.maxCountdownTime();
else return 4;
else return Config.config.skipNoticeDuration;
};
//the id for the setInterval running the countdown
@@ -54,78 +77,184 @@ class NoticeComponent extends React.Component<NoticeProps, NoticeState> {
//the countdown until this notice closes
countdownTime: maxCountdownTime(),
countdownText: null,
countdownMode: CountdownMode.Timer,
mouseHovering: false,
startFaded: this.props.startFaded ?? false
}
}
componentDidMount() {
componentDidMount(): void {
this.startCountdown();
}
render() {
let noticeStyle: React.CSSProperties = {
zIndex: this.props.zIndex || (50 + this.amountOfPreviousNotices)
render(): React.ReactElement {
const noticeStyle: React.CSSProperties = {
zIndex: this.props.zIndex || (1000 + this.amountOfPreviousNotices),
...(this.props.style ?? {})
}
return (
<table id={"sponsorSkipNotice" + this.idSuffix}
className={"sponsorSkipObject sponsorSkipNotice" + (this.props.fadeIn ? " sponsorSkipNoticeFadeIn" : "")}
style={noticeStyle}
onMouseEnter={this.pauseCountdown.bind(this)}
onMouseLeave={this.startCountdown.bind(this)}>
<tbody>
<div id={"sponsorSkipNotice" + this.idSuffix}
className={"sponsorSkipObject sponsorSkipNoticeParent"
+ (this.props.showInSecondSlot ? " secondSkipNotice" : "")}
onMouseEnter={(e) => this.onMouseEnter(e) }
onMouseLeave={() => this.timerMouseLeave()}
style={noticeStyle} >
<div className={"sponsorSkipNoticeTableContainer"
+ (this.props.fadeIn ? " sponsorSkipNoticeFadeIn" : "")
+ (this.state.startFaded ? " sponsorSkipNoticeFaded" : "") }>
<table className={"sponsorSkipObject sponsorSkipNotice"
+ (this.props.limitWidth ? " sponsorSkipNoticeLimitWidth" : "")}>
<tbody>
{/* First row */}
<tr id={"sponsorSkipNoticeFirstRow" + this.idSuffix}>
{/* Left column */}
<td>
{/* Logo */}
<img id={"sponsorSkipLogo" + this.idSuffix}
className="sponsorSkipLogo sponsorSkipObject"
src={chrome.extension.getURL("icons/IconSponsorBlocker256px.png")}>
</img>
{/* First row */}
<tr id={"sponsorSkipNoticeFirstRow" + this.idSuffix}
className="sponsorSkipNoticeFirstRow">
{/* Left column */}
<td className="noticeLeftIcon">
{/* Logo */}
<img id={"sponsorSkipLogo" + this.idSuffix}
className="sponsorSkipLogo sponsorSkipObject"
src={chrome.extension.getURL("icons/IconSponsorBlocker256px.png")}>
</img>
<span id={"sponsorSkipMessage" + this.idSuffix}
className="sponsorSkipMessage sponsorSkipObject">
<span id={"sponsorSkipMessage" + this.idSuffix}
style={{float: "left"}}
className="sponsorSkipMessage sponsorSkipObject">
{this.state.noticeTitle}
</span>
{this.props.firstColumn}
</td>
{this.props.firstRow}
{/* Right column */}
<td className="sponsorSkipNoticeRightSection"
style={{top: "9.32px"}}>
{/* Time left */}
{this.props.timed ? (
<span id={"sponsorSkipNoticeTimeLeft" + this.idSuffix}
onClick={() => this.toggleManualPause()}
className="sponsorSkipObject sponsorSkipNoticeTimeLeft">
{this.getCountdownElements()}
</span>
) : ""}
{this.state.noticeTitle}
</span>
</td>
{/* Right column */}
<td className="sponsorSkipNoticeRightSection"
style={{top: "11px"}}>
{/* Time left */}
{this.props.timed ? (
<span id={"sponsorSkipNoticeTimeLeft" + this.idSuffix}
className="sponsorSkipObject sponsorSkipNoticeTimeLeft">
{/* Close button */}
<img src={chrome.extension.getURL("icons/close.png")}
className={"sponsorSkipObject sponsorSkipNoticeButton sponsorSkipNoticeCloseButton sponsorSkipNoticeRightButton"
+ (this.props.biggerCloseButton ? " biggerCloseButton" : "")}
onClick={() => this.close()}>
</img>
</td>
</tr>
{this.state.countdownText || (this.state.countdownTime + "s")}
</span>
) : ""}
{this.props.children}
{/* Close button */}
<img src={chrome.extension.getURL("icons/close.png")}
className="sponsorSkipObject sponsorSkipNoticeButton sponsorSkipNoticeCloseButton sponsorSkipNoticeRightButton"
onClick={() => this.close()}>
</img>
</td>
</tr>
{!this.props.smaller && this.props.bottomRow ?
this.props.bottomRow
: null}
{this.props.children}
</tbody>
</table>
</div>
</tbody>
</table>
{/* Add as a hidden table to keep the height constant */}
{this.props.smaller && this.props.bottomRow ?
<table style={{visibility: "hidden", paddingTop: "14px"}}>
<tbody>
{this.props.bottomRow}
</tbody>
</table>
: null}
</div>
);
}
getCountdownElements(): React.ReactElement[] {
return [(
<span
id={"skipNoticeTimerText" + this.idSuffix}
key="skipNoticeTimerText"
className={this.state.countdownMode !== CountdownMode.Timer ? "hidden" : ""} >
{this.state.countdownTime + "s"}
</span>
),(
<img
id={"skipNoticeTimerPaused" + this.idSuffix}
key="skipNoticeTimerPaused"
className={this.state.countdownMode !== CountdownMode.Paused ? "hidden" : ""}
src={chrome.runtime.getURL("icons/pause.svg")}
alt={chrome.i18n.getMessage("paused")} />
),(
<img
id={"skipNoticeTimerStopped" + this.idSuffix}
key="skipNoticeTimerStopped"
className={this.state.countdownMode !== CountdownMode.Stopped ? "hidden" : ""}
src={chrome.runtime.getURL("icons/stop.svg")}
alt={chrome.i18n.getMessage("manualPaused")} />
)];
}
onMouseEnter(event: React.MouseEvent<HTMLElement, MouseEvent>): void {
if (this.props.onMouseEnter) this.props.onMouseEnter(event);
this.fadedMouseEnter();
this.timerMouseEnter();
}
fadedMouseEnter(): void {
if (this.state.startFaded) {
this.setState({
startFaded: false
});
}
}
timerMouseEnter(): void {
if (this.state.countdownMode === CountdownMode.Stopped) return;
this.pauseCountdown();
this.setState({
mouseHovering: true
});
}
timerMouseLeave(): void {
if (this.state.countdownMode === CountdownMode.Stopped) return;
this.startCountdown();
this.setState({
mouseHovering: false
});
}
toggleManualPause(): void {
this.setState({
countdownMode: this.state.countdownMode === CountdownMode.Stopped ? CountdownMode.Timer : CountdownMode.Stopped
}, () => {
if (this.state.countdownMode === CountdownMode.Stopped || this.state.mouseHovering) {
this.pauseCountdown();
} else {
this.startCountdown();
}
});
}
//called every second to lower the countdown before hiding the notice
countdown() {
countdown(): void {
if (!this.props.timed) return;
let countdownTime = this.state.countdownTime - 1;
const countdownTime = Math.min(this.state.countdownTime - 1, this.state.maxCountdownTime());
if (countdownTime <= 0) {
//remove this from setInterval
@@ -139,36 +268,40 @@ class NoticeComponent extends React.Component<NoticeProps, NoticeState> {
if (countdownTime == 3) {
//start fade out animation
let notice = document.getElementById("sponsorSkipNotice" + this.idSuffix);
notice.style.removeProperty("animation");
notice.classList.add("sponsorSkipNoticeFadeOut");
const notice = document.getElementById("sponsorSkipNotice" + this.idSuffix);
notice?.style.removeProperty("animation");
notice?.classList.add("sponsorSkipNoticeFadeOut");
}
this.setState({
countdownTime
})
}
removeFadeAnimation(): void {
//remove the fade out class if it exists
const notice = document.getElementById("sponsorSkipNotice" + this.idSuffix);
notice.classList.remove("sponsorSkipNoticeFadeOut");
notice.style.animation = "none";
}
pauseCountdown() {
pauseCountdown(): void {
if (!this.props.timed) return;
//remove setInterval
clearInterval(this.countdownInterval);
if (this.countdownInterval) clearInterval(this.countdownInterval);
this.countdownInterval = null;
//reset countdown and inform the user
this.setState({
countdownTime: this.state.maxCountdownTime(),
countdownText: chrome.i18n.getMessage("paused")
countdownMode: this.state.countdownMode === CountdownMode.Timer ? CountdownMode.Paused : this.state.countdownMode
});
//remove the fade out class if it exists
let notice = document.getElementById("sponsorSkipNotice" + this.idSuffix);
notice.classList.remove("sponsorSkipNoticeFadeOut");
notice.style.animation = "none";
this.removeFadeAnimation();
}
startCountdown() {
startCountdown(): void {
if (!this.props.timed) return;
//if it has already started, don't start it again
@@ -176,60 +309,64 @@ class NoticeComponent extends React.Component<NoticeProps, NoticeState> {
this.setState({
countdownTime: this.state.maxCountdownTime(),
countdownText: null
countdownMode: CountdownMode.Timer
});
this.setupInterval();
}
setupInterval(): void {
if (this.countdownInterval) clearInterval(this.countdownInterval);
this.countdownInterval = setInterval(this.countdown.bind(this), 1000);
}
resetCountdown() {
resetCountdown(): void {
if (!this.props.timed) return;
this.setupInterval();
this.setState({
countdownTime: this.state.maxCountdownTime(),
countdownText: null
countdownMode: CountdownMode.Timer
});
this.removeFadeAnimation();
}
/**
* @param silent If true, the close listener will not be called
*/
close(silent?: boolean) {
//TODO: Change to a listener in the renderer (not component)
let notice = document.getElementById("sponsorSkipNotice" + this.idSuffix);
if (notice != null) {
notice.remove();
}
close(silent?: boolean): void {
//remove setInterval
if (this.countdownInterval !== null) clearInterval(this.countdownInterval);
if (this.props.closeListener && !silent) this.props.closeListener();
if (!silent) this.props.closeListener();
}
changeNoticeTitle(title) {
changeNoticeTitle(title: string): void {
this.setState({
noticeTitle: title
});
}
addNoticeInfoMessage(message: string, message2: string = "") {
addNoticeInfoMessage(message: string, message2 = ""): void {
//TODO: Replace
let previousInfoMessage = document.getElementById("sponsorTimesInfoMessage" + this.idSuffix);
const previousInfoMessage = document.getElementById("sponsorTimesInfoMessage" + this.idSuffix);
if (previousInfoMessage != null) {
//remove it
document.getElementById("sponsorSkipNotice" + this.idSuffix).removeChild(previousInfoMessage);
}
let previousInfoMessage2 = document.getElementById("sponsorTimesInfoMessage" + this.idSuffix + "2");
const previousInfoMessage2 = document.getElementById("sponsorTimesInfoMessage" + this.idSuffix + "2");
if (previousInfoMessage2 != null) {
//remove it
document.getElementById("sponsorSkipNotice" + this.idSuffix).removeChild(previousInfoMessage2);
}
//add info
let thanksForVotingText = document.createElement("p");
const thanksForVotingText = document.createElement("p");
thanksForVotingText.id = "sponsorTimesInfoMessage" + this.idSuffix;
thanksForVotingText.className = "sponsorTimesInfoMessage";
thanksForVotingText.innerText = message;
@@ -238,7 +375,7 @@ class NoticeComponent extends React.Component<NoticeProps, NoticeState> {
document.querySelector("#sponsorSkipNotice" + this.idSuffix + " > tbody").insertBefore(thanksForVotingText, document.getElementById("sponsorSkipNoticeSpacer" + this.idSuffix));
if (message2 !== undefined) {
let thanksForVotingText2 = document.createElement("p");
const thanksForVotingText2 = document.createElement("p");
thanksForVotingText2.id = "sponsorTimesInfoMessage" + this.idSuffix + "2";
thanksForVotingText2.className = "sponsorTimesInfoMessage";
thanksForVotingText2.innerText = message2;
@@ -249,4 +386,4 @@ class NoticeComponent extends React.Component<NoticeProps, NoticeState> {
}
}
export default NoticeComponent;
export default NoticeComponent;

View File

@@ -2,7 +2,8 @@ import * as React from "react";
export interface NoticeTextSelectionProps {
text: string,
idSuffix: string
idSuffix: string,
onClick?: (event: React.MouseEvent) => unknown
}
export interface NoticeTextSelectionState {
@@ -15,9 +16,17 @@ class NoticeTextSelectionComponent extends React.Component<NoticeTextSelectionPr
super(props);
}
render() {
render(): React.ReactElement {
const style: React.CSSProperties = {};
if (this.props.onClick) {
style.cursor = "pointer";
style.textDecoration = "underline"
}
return (
<p id={"sponsorTimesInfoMessage" + this.props.idSuffix}
onClick={this.props.onClick}
style={style}
className="sponsorTimesInfoMessage">
{this.props.text}
</p>

View File

@@ -1,105 +1,152 @@
import * as React from "react";
import * as CompileConfig from "../../config.json";
import Config from "../config"
import { ContentContainer } from "../types";
import Utils from "../utils";
var utils = new Utils();
import { Category, ContentContainer, SponsorHideType, SponsorTime, NoticeVisbilityMode, ActionType, SponsorSourceType, SegmentUUID } from "../types";
import NoticeComponent from "./NoticeComponent";
import NoticeTextSelectionComponent from "./NoticeTextSectionComponent";
import Utils from "../utils";
const utils = new Utils();
import { getSkippingText } from "../utils/categoryUtils";
import { keybindToString } from "../utils/configUtils";
import ThumbsUpSvg from "../svg-icons/thumbs_up_svg";
import ThumbsDownSvg from "../svg-icons/thumbs_down_svg";
import PencilSvg from "../svg-icons/pencil_svg";
import { downvoteButtonColor, SkipNoticeAction } from "../utils/noticeUtils";
export interface SkipNoticeProps {
segments: SponsorTime[];
export interface SkipNoticeProps {
UUID: string;
autoSkip: boolean;
// Contains functions and variables from the content script needed by the skip notice
contentContainer: ContentContainer;
closeListener: () => void;
showKeybindHint?: boolean;
smaller: boolean;
unskipTime?: number;
}
export interface SkipNoticeState {
noticeTitle: string,
noticeTitle?: string;
messages: string[],
messages?: string[];
messageOnClick?: (event: React.MouseEvent) => unknown;
countdownTime: number,
maxCountdownTime: () => number;
countdownText: string,
countdownTime?: number;
maxCountdownTime?: () => number;
countdownText?: string;
skipButtonText?: string;
skipButtonCallback?: (index: number) => void;
showSkipButton?: boolean;
editing?: boolean;
choosingCategory?: boolean;
thanksForVotingText?: string; //null until the voting buttons should be hidden
actionState?: SkipNoticeAction;
showKeybindHint?: boolean;
smaller?: boolean;
voted?: SkipNoticeAction[];
copied?: SkipNoticeAction[];
unskipText: string,
unskipCallback: () => void
}
class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeState> {
UUID: string;
segments: SponsorTime[];
autoSkip: boolean;
// Contains functions and variables from the content script needed by the skip notice
contentContainer: ContentContainer;
amountOfPreviousNotices: number;
audio: HTMLAudioElement;
showInSecondSlot: boolean;
idSuffix: any;
idSuffix: string;
noticeRef: React.MutableRefObject<NoticeComponent>;
categoryOptionRef: React.RefObject<HTMLSelectElement>;
selectedColor: string;
unselectedColor: string;
lockedColor: string;
// Used to update on config change
configListener: () => void;
constructor(props: SkipNoticeProps) {
super(props);
this.noticeRef = React.createRef();
this.categoryOptionRef = React.createRef();
this.UUID = props.UUID;
this.segments = props.segments;
this.autoSkip = props.autoSkip;
this.contentContainer = props.contentContainer;
this.audio = null;
let noticeTitle = chrome.i18n.getMessage("noticeTitle");
if (!this.autoSkip) {
noticeTitle = chrome.i18n.getMessage("noticeTitleNotSkipped");
const noticeTitle = getSkippingText(this.segments, this.props.autoSkip);
const previousSkipNotices = document.getElementsByClassName("sponsorSkipNoticeParent");
this.amountOfPreviousNotices = previousSkipNotices.length;
// If there is at least one already in the first slot
this.showInSecondSlot = previousSkipNotices.length > 0 && [...previousSkipNotices].some(notice => !notice.classList.contains("secondSkipNotice"));
// Sort segments
if (this.segments.length > 1) {
this.segments.sort((a, b) => a.segment[0] - b.segment[0]);
}
//add notice
this.amountOfPreviousNotices = document.getElementsByClassName("sponsorSkipNotice").length;
//this is the suffix added at the end of every id
this.idSuffix = this.UUID + this.amountOfPreviousNotices;
if (this.amountOfPreviousNotices > 0) {
//another notice exists
let previousNotice = document.getElementsByClassName("sponsorSkipNotice")[0];
previousNotice.classList.add("secondSkipNotice")
// This is the suffix added at the end of every id
for (const segment of this.segments) {
this.idSuffix += segment.UUID;
}
this.idSuffix += this.amountOfPreviousNotices;
this.selectedColor = Config.config.colorPalette.red;
this.unselectedColor = Config.config.colorPalette.white;
this.lockedColor = Config.config.colorPalette.locked;
// Setup state
this.state = {
noticeTitle,
messages: [],
messageOnClick: null,
//the countdown until this notice closes
maxCountdownTime: () => 4,
countdownTime: 4,
maxCountdownTime: () => Config.config.skipNoticeDuration,
countdownTime: Config.config.skipNoticeDuration,
countdownText: null,
unskipText: chrome.i18n.getMessage("unskip"),
unskipCallback: this.unskip.bind(this)
skipButtonText: this.getUnskipText(),
skipButtonCallback: (index) => this.unskip(index),
showSkipButton: true,
editing: false,
choosingCategory: false,
thanksForVotingText: null,
actionState: SkipNoticeAction.None,
showKeybindHint: this.props.showKeybindHint ?? true,
smaller: this.props.smaller ?? false,
// Keep track of what segment the user interacted with.
voted: new Array(this.props.segments.length).fill(SkipNoticeAction.None),
copied: new Array(this.props.segments.length).fill(SkipNoticeAction.None),
}
if (!this.autoSkip) {
Object.assign(this.state, this.getUnskippedModeInfo(chrome.i18n.getMessage("skip")));
// Assume manual skip is only skipping 1 submission
Object.assign(this.state, this.getUnskippedModeInfo(0, this.getSkipText()));
}
}
componentDidMount() {
if (Config.config.audioNotificationOnSkip && this.audio) {
this.audio.volume = this.contentContainer().v.volume * 0.1;
this.audio.play();
}
}
render() {
let noticeStyle: React.CSSProperties = {
zIndex: 50 + this.amountOfPreviousNotices
}
render(): React.ReactElement {
const noticeStyle: React.CSSProperties = { }
if (this.contentContainer().onMobileYouTube) {
noticeStyle.bottom = "4em";
noticeStyle.transform = "scale(0.8) translate(10%, 10%)";
@@ -108,211 +155,589 @@ class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeSta
return (
<NoticeComponent noticeTitle={this.state.noticeTitle}
amountOfPreviousNotices={this.amountOfPreviousNotices}
showInSecondSlot={this.showInSecondSlot}
idSuffix={this.idSuffix}
fadeIn={true}
startFaded={Config.config.noticeVisibilityMode >= NoticeVisbilityMode.FadedForAll
|| (Config.config.noticeVisibilityMode >= NoticeVisbilityMode.FadedForAutoSkip && this.autoSkip)}
timed={true}
maxCountdownTime={this.state.maxCountdownTime}
ref={this.noticeRef}>
{(Config.config.audioNotificationOnSkip) && <audio ref={(source) => { this.audio = source; }}>
<source src={chrome.extension.getURL("icons/beep.ogg")} type="audio/ogg"></source>
</audio>}
{/* Text Boxes */}
{this.getMessageBoxes()}
{/* Last Row */}
<tr id={"sponsorSkipNoticeSecondRow" + this.idSuffix}>
{/* Vote Button Container */}
<td id={"sponsorTimesVoteButtonsContainer" + this.idSuffix}
className="sponsorTimesVoteButtonsContainer">
{/* Report Text */}
<span id={"sponsorTimesReportText" + this.idSuffix}
className="sponsorTimesInfoMessage sponsorTimesVoteButtonMessage"
title={chrome.i18n.getMessage("reportButtonInfo")}
style={{marginRight: "5px"}}>
{chrome.i18n.getMessage("reportButtonTitle")}
</span>
{/* Report Button */}
<img id={"sponsorTimesDownvoteButtonsContainer" + this.idSuffix}
className="sponsorSkipObject voteButton"
src={chrome.extension.getURL("icons/report.png")}
title={chrome.i18n.getMessage("reportButtonInfo")}
onClick={() => this.contentContainer().vote(0, this.UUID, this)}>
</img>
</td>
{/* Unskip Button */}
<td className="sponsorSkipNoticeUnskipSection">
<button id={"sponsorSkipUnskipButton" + this.idSuffix}
className="sponsorSkipObject sponsorSkipNoticeButton"
style={{marginLeft: "4px"}}
onClick={this.state.unskipCallback}>
{this.state.unskipText}
</button>
</td>
{/* Never show button if autoSkip is enabled */}
{!this.autoSkip ? "" :
<td className="sponsorSkipNoticeRightSection">
<button className="sponsorSkipObject sponsorSkipNoticeButton sponsorSkipNoticeRightButton"
onClick={this.contentContainer().dontShowNoticeAgain}>
{chrome.i18n.getMessage("Hide")}
</button>
</td>
}
</tr>
style={noticeStyle}
biggerCloseButton={this.contentContainer().onMobileYouTube}
ref={this.noticeRef}
closeListener={() => this.closeListener()}
smaller={this.state.smaller}
limitWidth={true}
bottomRow={[...this.getMessageBoxes()]}
onMouseEnter={() => this.onMouseEnter() } >
</NoticeComponent>
);
}
getMessageBoxes(): JSX.Element[] | JSX.Element {
if (this.state.messages.length === 0) {
// Add a spacer if there is no text
return (
<tr id={"sponsorSkipNoticeSpacer" + this.idSuffix}
className="sponsorBlockSpacer">
getBottomRow(): JSX.Element[] {
return [
/* Bottom Row */
(<tr id={"sponsorSkipNoticeSecondRow" + this.idSuffix}
key={0}>
{/* Vote Button Container */}
{!this.state.thanksForVotingText ?
<td id={"sponsorTimesVoteButtonsContainer" + this.idSuffix}
className="sponsorTimesVoteButtonsContainer">
{/* Upvote Button */}
<div id={"sponsorTimesDownvoteButtonsContainerUpvote" + this.idSuffix}
className="voteButton"
style={{marginRight: "5px"}}
title={chrome.i18n.getMessage("upvoteButtonInfo")}
onClick={() => this.prepAction(SkipNoticeAction.Upvote)}>
<ThumbsUpSvg fill={(this.state.actionState === SkipNoticeAction.Upvote) ? this.selectedColor : this.unselectedColor} />
</div>
{/* Report Button */}
<div id={"sponsorTimesDownvoteButtonsContainerDownvote" + this.idSuffix}
className="voteButton"
style={{marginRight: "5px", marginLeft: "5px"}}
title={chrome.i18n.getMessage("reportButtonInfo")}
onClick={() => this.prepAction(SkipNoticeAction.Downvote)}>
<ThumbsDownSvg fill={downvoteButtonColor(this.segments, this.state.actionState, SkipNoticeAction.Downvote)} />
</div>
{/* Copy and Downvote Button */}
<div id={"sponsorTimesDownvoteButtonsContainerCopyDownvote" + this.idSuffix}
className="voteButton"
style={{marginLeft: "5px"}}
onClick={() => this.openEditingOptions()}>
<PencilSvg fill={this.state.editing === true
|| this.state.actionState === SkipNoticeAction.CopyDownvote
|| this.state.choosingCategory === true
? this.selectedColor : this.unselectedColor} />
</div>
</td>
:
<td id={"sponsorTimesVoteButtonInfoMessage" + this.idSuffix}
className="sponsorTimesInfoMessage sponsorTimesVoteButtonMessage"
style={{marginRight: "10px"}}>
{/* Submitted string */}
<span style={{marginRight: "10px"}}>
{this.state.thanksForVotingText}
</span>
{/* Continue Voting Button */}
<button id={"sponsorTimesContinueVotingContainer" + this.idSuffix}
className="sponsorSkipObject sponsorSkipNoticeButton"
title={"Continue Voting"}
onClick={() => this.setState({
thanksForVotingText: null,
messages: []
})}>
{chrome.i18n.getMessage("ContinueVoting")}
</button>
</td>
}
{/* Unskip/Skip Button */}
{!this.props.smaller ? this.getSkipButton() : null}
{/* Never show button if autoSkip is enabled */}
{!this.autoSkip ? "" :
<td className="sponsorSkipNoticeRightSection"
key={1}>
<button className="sponsorSkipObject sponsorSkipNoticeButton sponsorSkipNoticeRightButton"
onClick={this.contentContainer().dontShowNoticeAgain}>
{chrome.i18n.getMessage("Hide")}
</button>
</td>
}
</tr>),
/* Edit Segments Row */
(this.state.editing && !this.state.thanksForVotingText && !(this.state.choosingCategory || this.state.actionState === SkipNoticeAction.CopyDownvote) &&
<tr id={"sponsorSkipNoticeEditSegmentsRow" + this.idSuffix}
key={2}>
<td id={"sponsorTimesEditSegmentsContainer" + this.idSuffix}>
{/* Copy Segment */}
<button className="sponsorSkipObject sponsorSkipNoticeButton"
title={chrome.i18n.getMessage("CopyDownvoteButtonInfo")}
style={{color: downvoteButtonColor(this.segments, this.state.actionState, SkipNoticeAction.Downvote)}}
onClick={() => this.prepAction(SkipNoticeAction.CopyDownvote)}>
{chrome.i18n.getMessage("CopyAndDownvote")}
</button>
{/* Category vote */}
<button className="sponsorSkipObject sponsorSkipNoticeButton"
title={chrome.i18n.getMessage("ChangeCategoryTooltip")}
style={{color: (this.state.actionState === SkipNoticeAction.CategoryVote && this.state.editing == true) ? this.selectedColor : this.unselectedColor}}
onClick={() => this.resetStateToStart(SkipNoticeAction.CategoryVote, true, true)}>
{chrome.i18n.getMessage("incorrectCategory")}
</button>
</td>
</tr>
),
/* Category Chooser Row */
(this.state.choosingCategory && !this.state.thanksForVotingText &&
<tr id={"sponsorSkipNoticeCategoryChooserRow" + this.idSuffix}
key={3}>
<td>
{/* Category Selector */}
<select id={"sponsorTimeCategories" + this.idSuffix}
className="sponsorTimeCategories sponsorTimeEditSelector"
defaultValue={this.segments[0].category}
ref={this.categoryOptionRef}>
{this.getCategoryOptions()}
</select>
{/* Submit Button */}
{this.segments.length === 1 &&
<button className="sponsorSkipObject sponsorSkipNoticeButton"
onClick={() => this.prepAction(SkipNoticeAction.CategoryVote)}>
{chrome.i18n.getMessage("submit")}
</button>
}
</td>
</tr>
),
/* Segment Chooser Row */
(this.state.actionState !== SkipNoticeAction.None && this.segments.length > 1 && !this.state.thanksForVotingText &&
<tr id={"sponsorSkipNoticeSubmissionOptionsRow" + this.idSuffix}
key={4}>
<td id={"sponsorTimesSubmissionOptionsContainer" + this.idSuffix}>
{this.getSubmissionChooser()}
</td>
</tr>
)
];
}
getSkipButton(): JSX.Element {
if (this.state.showSkipButton && (this.segments.length > 1
|| this.segments[0].actionType !== ActionType.Poi
|| this.props.unskipTime)) {
const style: React.CSSProperties = {
marginLeft: "4px",
color: (this.state.actionState === SkipNoticeAction.Unskip) ? this.selectedColor : this.unselectedColor
};
if (this.contentContainer().onMobileYouTube) {
style.padding = "20px";
style.minWidth = "100px";
}
return (
<span className="sponsorSkipNoticeUnskipSection">
<button id={"sponsorSkipUnskipButton" + this.idSuffix}
className="sponsorSkipObject sponsorSkipNoticeButton"
style={style}
onClick={() => this.prepAction(SkipNoticeAction.Unskip)}>
{this.state.skipButtonText + (this.state.showKeybindHint ? " (" + keybindToString(Config.config.skipKeybind) + ")" : "")}
</button>
</span>
);
}
}
let elements: JSX.Element[] = [];
getSubmissionChooser(): JSX.Element[] {
const elements: JSX.Element[] = [];
for (let i = 0; i < this.segments.length; i++) {
elements.push(
<button className="sponsorSkipObject sponsorSkipNoticeButton"
style={{opacity: this.getSubmissionChooserOpacity(i),
color: this.getSubmissionChooserColor(i)}}
onClick={() => this.performAction(i)}
key={"submission" + i + this.segments[i].category + this.idSuffix}>
{(i + 1) + ". " + chrome.i18n.getMessage("category_" + this.segments[i].category)}
</button>
);
}
return elements;
}
getSubmissionChooserOpacity(index: number): number {
const isUpvote = this.state.actionState === SkipNoticeAction.Upvote;
const isDownvote = this.state.actionState == SkipNoticeAction.Downvote;
const isCopyDownvote = this.state.actionState == SkipNoticeAction.CopyDownvote;
const shouldBeGray: boolean = (isUpvote && this.state.voted[index] == SkipNoticeAction.Upvote) ||
(isDownvote && this.state.voted[index] == SkipNoticeAction.Downvote) ||
(isCopyDownvote && this.state.copied[index] == SkipNoticeAction.CopyDownvote);
return shouldBeGray ? 0.35 : 1;
}
getSubmissionChooserColor(index: number): string {
const isDownvote = this.state.actionState == SkipNoticeAction.Downvote;
const isCopyDownvote = this.state.actionState == SkipNoticeAction.CopyDownvote;
const shouldWarnUser = Config.config.isVip && (isDownvote || isCopyDownvote)
&& this.segments[index].locked === 1;
return shouldWarnUser ? this.lockedColor : this.unselectedColor;
}
onMouseEnter(): void {
// if (this.state.smaller) {
// this.setState({
// smaller: false
// });
// }
}
getMessageBoxes(): JSX.Element[] {
if (this.state.messages.length === 0) {
// Add a spacer if there is no text
return [
<tr id={"sponsorSkipNoticeSpacer" + this.idSuffix}
className="sponsorBlockSpacer"
key={"messageBoxSpacer"}>
</tr>
];
}
const elements: JSX.Element[] = [];
for (let i = 0; i < this.state.messages.length; i++) {
elements.push(
<NoticeTextSelectionComponent idSuffix={this.idSuffix}
text={this.state.messages[i]}
key={i}>
</NoticeTextSelectionComponent>
<tr key={i + "_messageBox"}>
<td key={i + "_messageBox"}>
<NoticeTextSelectionComponent idSuffix={this.idSuffix}
text={this.state.messages[i]}
onClick={this.state.messageOnClick}
key={i + "_messageBox"}>
</NoticeTextSelectionComponent>
</td>
</tr>
)
}
return elements;
}
unskip() {
this.contentContainer().unskipSponsorTime(this.UUID);
this.unskippedMode(chrome.i18n.getMessage("reskip"));
}
/** Sets up notice to be not skipped yet */
unskippedMode(buttonText: string) {
//setup new callback and reset countdown
this.setState(this.getUnskippedModeInfo(buttonText), () => {
this.noticeRef.current.resetCountdown();
});
}
getUnskippedModeInfo(buttonText: string) {
let maxCountdownTime = function() {
let sponsorTime = utils.getSponsorTimeFromUUID(this.contentContainer().sponsorTimes, this.UUID);
let duration = Math.round((sponsorTime.segment[1] - this.contentContainer().v.currentTime) * (1 / this.contentContainer().v.playbackRate));
return Math.max(duration, 4);
}.bind(this);
return {
unskipText: buttonText,
unskipCallback: this.reskip.bind(this),
//change max duration to however much of the sponsor is left
maxCountdownTime: maxCountdownTime,
countdownTime: maxCountdownTime()
}
}
reskip() {
this.contentContainer().reskipSponsorTime(this.UUID);
//reset countdown
this.setState({
unskipText: chrome.i18n.getMessage("unskip"),
unskipCallback: this.unskip.bind(this),
maxCountdownTime: () => 4,
countdownTime: 4
});
// See if the title should be changed
if (!this.autoSkip) {
this.setState({
noticeTitle: chrome.i18n.getMessage("noticeTitle")
});
if(Config.config.autoUpvote) this.contentContainer().vote(1, this.UUID);
}
}
afterDownvote() {
this.addVoteButtonInfo(chrome.i18n.getMessage("voted"));
this.setNoticeInfoMessage(chrome.i18n.getMessage("hitGoBack"));
//remove this sponsor from the sponsors looked up
//find which one it is
for (let i = 0; i < this.contentContainer().sponsorTimes.length; i++) {
if (this.contentContainer().sponsorTimes[i].UUID == this.UUID) {
//this one is the one to hide
//add this as a hidden sponsorTime
this.contentContainer().hiddenSponsorTimes.push(i);
this.contentContainer().updatePreviewBar();
break;
prepAction(action: SkipNoticeAction): void {
if (this.segments.length === 1) {
this.performAction(0, action);
} else {
switch (action ?? this.state.actionState) {
case SkipNoticeAction.None:
this.resetStateToStart();
break;
case SkipNoticeAction.Upvote:
this.resetStateToStart(SkipNoticeAction.Upvote);
break;
case SkipNoticeAction.Downvote:
this.resetStateToStart(SkipNoticeAction.Downvote);
break;
case SkipNoticeAction.CategoryVote:
this.resetStateToStart(SkipNoticeAction.CategoryVote, true, true);
break;
case SkipNoticeAction.CopyDownvote:
this.resetStateToStart(SkipNoticeAction.CopyDownvote, true);
break;
case SkipNoticeAction.Unskip:
this.resetStateToStart(SkipNoticeAction.Unskip);
break;
}
}
}
setNoticeInfoMessage(...messages: string[]) {
/**
* Performs the action from the current state
*
* @param index
*/
performAction(index: number, action?: SkipNoticeAction): void {
switch (action ?? this.state.actionState) {
case SkipNoticeAction.None:
this.noAction(index);
break;
case SkipNoticeAction.Upvote:
this.upvote(index);
break;
case SkipNoticeAction.Downvote:
this.downvote(index);
break;
case SkipNoticeAction.CategoryVote:
this.categoryVote(index);
break;
case SkipNoticeAction.CopyDownvote:
this.copyDownvote(index);
break;
case SkipNoticeAction.Unskip:
this.unskipAction(index);
break;
default:
this.resetStateToStart();
break;
}
}
noAction(index: number): void {
const voted = this.state.voted;
voted[index] = SkipNoticeAction.None;
this.setState({
voted
});
}
upvote(index: number): void {
if (this.segments.length === 1) this.resetStateToStart();
this.contentContainer().vote(1, this.segments[index].UUID, undefined, this);
}
downvote(index: number): void {
if (this.segments.length === 1) this.resetStateToStart();
this.contentContainer().vote(0, this.segments[index].UUID, undefined, this);
}
categoryVote(index: number): void {
this.contentContainer().vote(undefined, this.segments[index].UUID, this.categoryOptionRef.current.value as Category, this)
}
copyDownvote(index: number): void {
const sponsorVideoID = this.props.contentContainer().sponsorVideoID;
const sponsorTimesSubmitting : SponsorTime = {
segment: this.segments[index].segment,
UUID: utils.generateUserID() as SegmentUUID,
category: this.segments[index].category,
actionType: this.segments[index].actionType,
source: SponsorSourceType.Local
};
const segmentTimes = Config.config.unsubmittedSegments[sponsorVideoID] || [];
segmentTimes.push(sponsorTimesSubmitting);
Config.config.unsubmittedSegments[sponsorVideoID] = segmentTimes;
Config.forceSyncUpdate("unsubmittedSegments");
this.props.contentContainer().sponsorTimesSubmitting.push(sponsorTimesSubmitting);
this.props.contentContainer().updatePreviewBar();
this.props.contentContainer().resetSponsorSubmissionNotice();
this.props.contentContainer().updateEditButtonsOnPlayer();
this.contentContainer().vote(0, this.segments[index].UUID, undefined, this);
const copied = this.state.copied;
copied[index] = SkipNoticeAction.CopyDownvote;
this.setState({
copied
});
}
unskipAction(index: number): void {
this.state.skipButtonCallback(index);
}
openEditingOptions(): void {
this.resetStateToStart(undefined, true);
}
getCategoryOptions(): React.ReactElement[] {
const elements = [];
const categories = (CompileConfig.categoryList.filter((cat => CompileConfig.categorySupport[cat].includes(ActionType.Skip)))) as Category[];
for (const category of categories) {
elements.push(
<option value={category}
key={category}
className={this.getCategoryNameClass(category)}>
{chrome.i18n.getMessage("category_" + category)}
</option>
);
}
return elements;
}
getCategoryNameClass(category: string): string {
return this.props.contentContainer().lockedCategories.includes(category) ? "sponsorBlockLockedColor" : ""
}
unskip(index: number): void {
this.contentContainer().unskipSponsorTime(this.segments[index], this.props.unskipTime);
this.unskippedMode(index, this.getReskipText());
}
reskip(index: number): void {
this.contentContainer().reskipSponsorTime(this.segments[index]);
const newState: SkipNoticeState = {
skipButtonText: this.getUnskipText(),
skipButtonCallback: this.unskip.bind(this),
maxCountdownTime: () => Config.config.skipNoticeDuration,
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();
});
}
/** Sets up notice to be not skipped yet */
unskippedMode(index: number, buttonText: string): void {
//setup new callback and reset countdown
this.setState(this.getUnskippedModeInfo(index, buttonText), () => {
this.noticeRef.current.resetCountdown();
});
}
getUnskippedModeInfo(index: number, buttonText: string): SkipNoticeState {
const changeCountdown = this.segments[index].actionType !== ActionType.Poi;
const maxCountdownTime = changeCountdown ? () => {
const sponsorTime = this.segments[index];
const duration = Math.round((sponsorTime.segment[1] - this.contentContainer().v.currentTime) * (1 / this.contentContainer().v.playbackRate));
return Math.max(duration, Config.config.skipNoticeDuration);
} : this.state.maxCountdownTime;
return {
skipButtonText: buttonText,
skipButtonCallback: (index) => this.reskip(index),
// change max duration to however much of the sponsor is left
maxCountdownTime: maxCountdownTime,
countdownTime: maxCountdownTime()
} as SkipNoticeState;
}
afterVote(segment: SponsorTime, type: number, category: Category): void {
const index = utils.getSponsorIndexFromUUID(this.segments, segment.UUID);
const wikiLinkText = CompileConfig.wikiLinks[segment.category];
const voted = this.state.voted;
switch (type) {
case 0:
this.clearConfigListener();
this.setNoticeInfoMessageWithOnClick(() => window.open(wikiLinkText), chrome.i18n.getMessage("OpenCategoryWikiPage"));
voted[index] = SkipNoticeAction.Downvote;
break;
case 1:
voted[index] = SkipNoticeAction.Upvote;
break;
case 20:
voted[index] = SkipNoticeAction.None;
break;
}
this.setState({
voted
});
this.addVoteButtonInfo(chrome.i18n.getMessage("voted"));
if (segment && category) {
// This is the segment inside the skip notice
this.segments[index].category = category;
}
}
setNoticeInfoMessageWithOnClick(onClick: (event: React.MouseEvent) => unknown, ...messages: string[]): void {
this.setState({
messages,
messageOnClick: (event) => onClick(event)
});
}
setNoticeInfoMessage(...messages: string[]): void {
this.setState({
messages
})
});
}
addVoteButtonInfo(message) {
this.resetVoteButtonInfo();
//hide report button and text for it
let downvoteButton = document.getElementById("sponsorTimesDownvoteButtonsContainer" + this.idSuffix);
if (downvoteButton != null) {
downvoteButton.style.display = "none";
}
let downvoteButtonText = document.getElementById("sponsorTimesReportText" + this.idSuffix);
if (downvoteButtonText != null) {
downvoteButtonText.style.display = "none";
}
//add info
let thanksForVotingText = document.createElement("td");
thanksForVotingText.id = "sponsorTimesVoteButtonInfoMessage" + this.idSuffix;
thanksForVotingText.className = "sponsorTimesInfoMessage sponsorTimesVoteButtonMessage";
thanksForVotingText.innerText = message;
//add element to div
document.getElementById("sponsorSkipNoticeSecondRow" + this.idSuffix).prepend(thanksForVotingText);
addVoteButtonInfo(message: string): void {
this.setState({
thanksForVotingText: message
});
}
resetVoteButtonInfo() {
let previousInfoMessage = document.getElementById("sponsorTimesVoteButtonInfoMessage" + this.idSuffix);
if (previousInfoMessage != null) {
//remove it
document.getElementById("sponsorSkipNoticeSecondRow" + this.idSuffix).removeChild(previousInfoMessage);
}
resetVoteButtonInfo(): void {
this.setState({
thanksForVotingText: null
});
}
//show button again
document.getElementById("sponsorTimesDownvoteButtonsContainer" + this.idSuffix).style.removeProperty("display");
closeListener(): void {
this.clearConfigListener();
this.props.closeListener();
}
clearConfigListener(): void {
if (this.configListener) {
Config.configSyncListeners.splice(Config.configSyncListeners.indexOf(this.configListener), 1);
this.configListener = null;
}
}
unmutedListener(): void {
if (this.props.segments.length === 1
&& this.props.segments[0].actionType === ActionType.Mute
&& this.contentContainer().v.currentTime >= this.props.segments[0].segment[1]) {
this.setState({
showSkipButton: false
});
}
}
resetStateToStart(actionState: SkipNoticeAction = SkipNoticeAction.None, editing = false, choosingCategory = false): void {
this.setState({
actionState: actionState,
editing: editing,
choosingCategory: choosingCategory,
thanksForVotingText: null,
messages: []
});
}
private getUnskipText(): string {
switch (this.props.segments[0].actionType) {
case ActionType.Mute: {
return chrome.i18n.getMessage("unmute");
}
case ActionType.Skip:
default: {
return chrome.i18n.getMessage("unskip");
}
}
}
private getReskipText(): string {
switch (this.props.segments[0].actionType) {
case ActionType.Mute: {
return chrome.i18n.getMessage("mute");
}
case ActionType.Skip:
default: {
return chrome.i18n.getMessage("reskip");
}
}
}
private getSkipText(): string {
switch (this.props.segments[0].actionType) {
case ActionType.Mute: {
return chrome.i18n.getMessage("mute");
}
case ActionType.Skip:
default: {
return chrome.i18n.getMessage("skip");
}
}
}
}
export default SkipNoticeComponent;
export default SkipNoticeComponent;

View File

@@ -1,12 +1,13 @@
import * as React from "react";
import Config from "../config";
import * as CompileConfig from "../../config.json";
import Config from "../config";
import { ActionType, Category, ContentContainer, SponsorTime } from "../types";
import Utils from "../utils";
import { ContentContainer, SponsorTime } from "../types";
import SubmissionNoticeComponent from "./SubmissionNoticeComponent";
var utils = new Utils();
import { RectangleTooltip } from "../render/RectangleTooltip";
const utils = new Utils();
export interface SponsorTimeEditProps {
index: number,
@@ -16,41 +17,77 @@ export interface SponsorTimeEditProps {
contentContainer: ContentContainer,
submissionNotice: SubmissionNoticeComponent;
categoryList?: Category[];
}
export interface SponsorTimeEditState {
editing: boolean;
sponsorTimeEdits: string[][];
sponsorTimeEdits: [string, string];
selectedCategory: Category;
}
const DEFAULT_CATEGORY = "chooseACategory";
class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, SponsorTimeEditState> {
idSuffix: string;
categoryOptionRef: React.RefObject<HTMLSelectElement>;
actionTypeOptionRef: React.RefObject<HTMLSelectElement>;
configUpdateListener: () => void;
previousSkipType: ActionType;
// Used when selecting POI or Full
timesBeforeChanging: number[] = [];
fullVideoWarningShown = false;
constructor(props: SponsorTimeEditProps) {
super(props);
this.categoryOptionRef = React.createRef();
this.actionTypeOptionRef = React.createRef();
this.idSuffix = this.props.idSuffix;
this.previousSkipType = ActionType.Skip;
this.state = {
editing: false,
sponsorTimeEdits: [[null, null], [null, null]]
sponsorTimeEdits: [null, null],
selectedCategory: DEFAULT_CATEGORY as Category
};
}
componentDidMount() {
componentDidMount(): void {
// Prevent inputs from triggering key events
document.getElementById("sponsorTimesContainer" + this.idSuffix).addEventListener('keydown', function (event) {
event.stopPropagation();
});
// Prevent scrolling while changing times
document.getElementById("sponsorTimesContainer" + this.idSuffix).addEventListener('wheel', function (event) {
event.preventDefault();
}, {passive: false});
// Add as a config listener
if (!this.configUpdateListener) {
this.configUpdateListener = () => this.configUpdate();
Config.configSyncListeners.push(this.configUpdate.bind(this));
}
this.checkToShowFullVideoWarning();
}
render() {
let style: React.CSSProperties = {
componentWillUnmount(): void {
if (this.configUpdateListener) {
Config.configSyncListeners.splice(Config.configSyncListeners.indexOf(this.configUpdate.bind(this)), 1);
}
}
render(): React.ReactElement {
this.checkToShowFullVideoWarning();
const style: React.CSSProperties = {
textAlign: "center"
};
@@ -58,13 +95,24 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
style.marginTop = "15px";
}
// This method is required to get !important
// https://stackoverflow.com/a/45669262/1985387
const oldYouTubeDarkStyles = (node) => {
if (node) {
node.style.setProperty("color", "black", "important");
node.style.setProperty("text-shadow", "none", "important");
}
};
// Create time display
let timeDisplay: JSX.Element;
let sponsorTime = this.props.contentContainer().sponsorTimesSubmitting[this.props.index];
let segment = sponsorTime.segment;
const timeDisplayStyle: React.CSSProperties = {};
const sponsorTime = this.props.contentContainer().sponsorTimesSubmitting[this.props.index];
const segment = sponsorTime.segment;
if (sponsorTime?.actionType === ActionType.Full) timeDisplayStyle.display = "none";
if (this.state.editing) {
timeDisplay = (
<div id={"sponsorTimesContainer" + this.idSuffix}
style={timeDisplayStyle}
className="sponsorTimeDisplay">
<span id={"nowButton0" + this.idSuffix}
@@ -72,73 +120,55 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
onClick={() => this.setTimeToNow(0)}>
{chrome.i18n.getMessage("bracketNow")}
</span>
<input id={"submittingTimeMinutes0" + this.idSuffix}
className="sponsorTimeEdit sponsorTimeEditMinutes"
type="number"
value={this.state.sponsorTimeEdits[0][0]}
onChange={(e) => {
let sponsorTimeEdits = this.state.sponsorTimeEdits;
sponsorTimeEdits[0][0] = e.target.value;
this.setState({sponsorTimeEdits});
}}>
</input>
<input id={"submittingTimeSeconds0" + this.idSuffix}
className="sponsorTimeEdit sponsorTimeEditSeconds"
type="number"
value={this.state.sponsorTimeEdits[0][1]}
onChange={(e) => {
let sponsorTimeEdits = this.state.sponsorTimeEdits;
sponsorTimeEdits[0][1] = e.target.value;
this.setState({sponsorTimeEdits});
}}>
</input>
<span>
{" " + chrome.i18n.getMessage("to") + " "}
</span>
<input id={"submittingTimeMinutes1" + this.idSuffix}
className="sponsorTimeEdit sponsorTimeEditMinutes"
<input id={"submittingTime0" + this.idSuffix}
className="sponsorTimeEdit sponsorTimeEditInput"
ref={oldYouTubeDarkStyles}
type="text"
value={this.state.sponsorTimeEdits[1][0]}
onChange={(e) => {
let sponsorTimeEdits = this.state.sponsorTimeEdits;
sponsorTimeEdits[1][0] = e.target.value;
this.setState({sponsorTimeEdits});
}}>
value={this.state.sponsorTimeEdits[0]}
onChange={(e) => {this.handleOnChange(0, e, sponsorTime, e.target.value)}}
onWheel={(e) => {this.changeTimesWhenScrolling(0, e, sponsorTime)}}>
</input>
<input id={"submittingTimeSeconds1" + this.idSuffix}
className="sponsorTimeEdit sponsorTimeEditSeconds"
type="text"
value={this.state.sponsorTimeEdits[1][1]}
onChange={(e) => {
let sponsorTimeEdits = this.state.sponsorTimeEdits;
sponsorTimeEdits[1][1] = e.target.value;
{sponsorTime.actionType !== ActionType.Poi ? (
<span>
<span>
{" " + chrome.i18n.getMessage("to") + " "}
</span>
this.setState({sponsorTimeEdits});
}}>
</input>
<input id={"submittingTime1" + this.idSuffix}
className="sponsorTimeEdit sponsorTimeEditInput"
ref={oldYouTubeDarkStyles}
type="text"
value={this.state.sponsorTimeEdits[1]}
onChange={(e) => {this.handleOnChange(1, e, sponsorTime, e.target.value)}}
onWheel={(e) => {this.changeTimesWhenScrolling(1, e, sponsorTime)}}>
</input>
<span id={"nowButton1" + this.idSuffix}
className="sponsorNowButton"
onClick={() => this.setTimeToNow(1)}>
{chrome.i18n.getMessage("bracketNow")}
</span>
<span id={"nowButton1" + this.idSuffix}
className="sponsorNowButton"
onClick={() => this.setTimeToNow(1)}>
{chrome.i18n.getMessage("bracketNow")}
</span>
<span id={"endButton" + this.idSuffix}
className="sponsorNowButton"
onClick={() => this.setTimeToEnd()}>
{chrome.i18n.getMessage("bracketEnd")}
</span>
</span>
): ""}
</div>
);
} else {
timeDisplay = (
<div id={"sponsorTimesContainer" + this.idSuffix}
style={timeDisplayStyle}
className="sponsorTimeDisplay"
onClick={this.toggleEditTime.bind(this)}>
{utils.getFormattedTime(segment[0], true) +
((!isNaN(segment[1])) ? " " + chrome.i18n.getMessage("to") + " " + utils.getFormattedTime(segment[1], true) : "")}
((!isNaN(segment[1]) && sponsorTime.actionType !== ActionType.Poi)
? " " + chrome.i18n.getMessage("to") + " " + utils.getFormattedTime(segment[1], true) : "")}
</div>
);
}
@@ -149,14 +179,40 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
{timeDisplay}
{/* Category */}
<div style={{position: "relative"}}>
<select id={"sponsorTimeCategories" + this.idSuffix}
className="sponsorTimeEditSelector sponsorTimeCategories"
defaultValue={sponsorTime.category}
ref={this.categoryOptionRef}
onChange={this.categorySelectionChange.bind(this)}>
{this.getCategoryOptions()}
</select>
<select id={"sponsorTimeCategories" + this.idSuffix}
className="sponsorTimeCategories"
defaultValue={sponsorTime.category}
ref={this.categoryOptionRef}
onChange={this.saveEditTimes.bind(this)}>
{this.getCategoryOptions()}
</select>
{/* open in new tab */}
<a href={CompileConfig.wikiLinks[sponsorTime.category]
|| "https://wiki.sponsor.ajay.app/index.php/Segment_Categories"}
target="_blank" rel="noreferrer">
<img id={"sponsorTimeCategoriesHelpButton" + this.idSuffix}
className="helpButton"
src={chrome.extension.getURL("icons/help.svg")}
title={chrome.i18n.getMessage("categoryGuidelines")} />
</a>
</div>
{/* Action Type */}
{CompileConfig.categorySupport[sponsorTime.category] &&
(CompileConfig.categorySupport[sponsorTime.category]?.length > 1
|| CompileConfig.categorySupport[sponsorTime.category]?.[0] === ActionType.Full) ? (
<div style={{position: "relative"}}>
<select id={"sponsorTimeActionTypes" + this.idSuffix}
className="sponsorTimeEditSelector sponsorTimeActionTypes"
defaultValue={sponsorTime.actionType}
ref={this.actionTypeOptionRef}
onChange={(e) => this.actionTypeSelectionChange(e)}>
{this.getActionTypeOptions(sponsorTime)}
</select>
</div>
): ""}
<br/>
@@ -168,15 +224,23 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
{chrome.i18n.getMessage("delete")}
</span>
{(!isNaN(segment[1])) ? (
{(!isNaN(segment[1]) && ![ActionType.Poi, ActionType.Full].includes(sponsorTime.actionType)) ? (
<span id={"sponsorTimePreviewButton" + this.idSuffix}
className="sponsorTimeEditButton"
onClick={this.previewTime.bind(this)}>
onClick={(e) => this.previewTime(e.ctrlKey, e.shiftKey)}>
{chrome.i18n.getMessage("preview")}
</span>
): ""}
{(!isNaN(segment[1])) ? (
{(!isNaN(segment[1]) && sponsorTime.actionType != ActionType.Full) ? (
<span id={"sponsorTimeInspectButton" + this.idSuffix}
className="sponsorTimeEditButton"
onClick={this.inspectTime.bind(this)}>
{chrome.i18n.getMessage("inspect")}
</span>
): ""}
{(!isNaN(segment[1]) && sponsorTime.actionType != ActionType.Full) ? (
<span id={"sponsorTimeEditButton" + this.idSuffix}
className="sponsorTimeEditButton"
onClick={this.toggleEditTime.bind(this)}>
@@ -187,15 +251,107 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
);
}
getCategoryOptions() {
let elements = [];
handleOnChange(index: number, e: React.ChangeEvent, sponsorTime: SponsorTime, targetValue: string): void {
const sponsorTimeEdits = this.state.sponsorTimeEdits;
// check if change is small engough to show tooltip
const before = utils.getFormattedTimeToSeconds(sponsorTimeEdits[index]);
const after = utils.getFormattedTimeToSeconds(targetValue);
const difference = Math.abs(before - after);
if (0 < difference && difference< 0.5) this.showScrollToEditToolTip();
//TODO: Remove this when testing server is not needed
let categoryList = Config.config.testingServer ? CompileConfig.categoryList : ["sponsor"];
for (const category of categoryList) {
sponsorTimeEdits[index] = targetValue;
if (index === 0 && sponsorTime.actionType === ActionType.Poi) sponsorTimeEdits[1] = targetValue;
this.setState({sponsorTimeEdits});
this.saveEditTimes();
}
changeTimesWhenScrolling(index: number, e: React.WheelEvent, sponsorTime: SponsorTime): void {
let step = 0;
// shift + ctrl = 1
// ctrl = 0.1
// default = 0.01
// shift = 0.001
if (e.shiftKey) {
step = (e.ctrlKey) ? 1 : 0.001;
} else {
step = (e.ctrlKey) ? 0.1 : 0.01;
}
const sponsorTimeEdits = this.state.sponsorTimeEdits;
let timeAsNumber = utils.getFormattedTimeToSeconds(this.state.sponsorTimeEdits[index]);
if (timeAsNumber !== null && e.deltaY != 0) {
if (e.deltaY < 0) {
timeAsNumber += step;
} else if (timeAsNumber >= step) {
timeAsNumber -= step;
} else {
timeAsNumber = 0;
}
sponsorTimeEdits[index] = utils.getFormattedTime(timeAsNumber, true);
if (sponsorTime.actionType === ActionType.Poi) sponsorTimeEdits[1] = sponsorTimeEdits[0];
this.setState({sponsorTimeEdits});
this.saveEditTimes();
}
}
showScrollToEditToolTip(): void {
if (!Config.config.scrollToEditTimeUpdate && document.getElementById("sponsorRectangleTooltip" + "sponsorTimesContainer" + this.idSuffix) === null) {
this.showToolTip(chrome.i18n.getMessage("SponsorTimeEditScrollNewFeature"), () => { Config.config.scrollToEditTimeUpdate = true });
}
}
showToolTip(text: string, buttonFunction?: () => void): boolean {
const element = document.getElementById("sponsorTimesContainer" + this.idSuffix);
if (element) {
new RectangleTooltip({
text,
referenceNode: element.parentElement,
prependElement: element,
timeout: 15,
bottomOffset: 0 + "px",
leftOffset: -318 + "px",
backgroundColor: "rgba(28, 28, 28, 1.0)",
htmlId: "sponsorTimesContainer" + this.idSuffix,
buttonFunction,
fontSize: "14px",
maxHeight: "200px"
});
return true;
} else {
return false;
}
}
checkToShowFullVideoWarning(): void {
const sponsorTime = this.props.contentContainer().sponsorTimesSubmitting[this.props.index];
const segmentDuration = sponsorTime.segment[1] - sponsorTime.segment[0];
const videoPercentage = segmentDuration / this.props.contentContainer().v.duration;
if (videoPercentage > 0.6 && !this.fullVideoWarningShown
&& (sponsorTime.category === "sponsor" || sponsorTime.category === "selfpromo" || sponsorTime.category === "chooseACategory")) {
if (this.showToolTip(chrome.i18n.getMessage("fullVideoTooltipWarning"))) {
this.fullVideoWarningShown = true;
}
}
}
getCategoryOptions(): React.ReactElement[] {
const elements = [(
<option value={DEFAULT_CATEGORY}
key={DEFAULT_CATEGORY}>
{chrome.i18n.getMessage(DEFAULT_CATEGORY)}
</option>
)];
for (const category of (this.props.categoryList ?? CompileConfig.categoryList)) {
elements.push(
<option value={category}
key={category}>
key={category}
className={this.getCategoryLockedClass(category)}>
{chrome.i18n.getMessage("category_" + category)}
</option>
);
@@ -204,11 +360,107 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
return elements;
}
setTimeToNow(index: number) {
let sponsorTime = this.props.contentContainer().sponsorTimesSubmitting[this.props.index];
getCategoryLockedClass(category: string): string {
return this.props.contentContainer().lockedCategories.includes(category) ? "sponsorBlockLockedColor" : "";
}
sponsorTime.segment[index] =
this.props.contentContainer().v.currentTime;
categorySelectionChange(event: React.ChangeEvent<HTMLSelectElement>): void {
// 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
if (confirm(chrome.i18n.getMessage("enableThisCategoryFirst")
.replace("{0}", chrome.i18n.getMessage("category_" + chosenCategory)))) {
// Open options page
chrome.runtime.sendMessage({message: "openConfig", hash: "behavior"});
}
return;
}
const sponsorTime = this.props.contentContainer().sponsorTimesSubmitting[this.props.index];
this.handleReplacingLostTimes(event.target.value as Category, sponsorTime.actionType, sponsorTime);
this.saveEditTimes();
}
actionTypeSelectionChange(event: React.ChangeEvent<HTMLSelectElement>): void {
const sponsorTime = this.props.contentContainer().sponsorTimesSubmitting[this.props.index];
this.handleReplacingLostTimes(sponsorTime.category, event.target.value as ActionType, sponsorTime);
this.saveEditTimes();
}
private handleReplacingLostTimes(category: Category, actionType: ActionType, segment: SponsorTime): void {
if (CompileConfig.categorySupport[category]?.includes(ActionType.Poi)) {
if (this.previousSkipType !== ActionType.Poi) {
this.timesBeforeChanging = [null, segment.segment[1]];
}
this.setTimeTo(1, null);
this.props.contentContainer().updateEditButtonsOnPlayer();
if (this.props.contentContainer().sponsorTimesSubmitting
.some((segment, i) => segment.category === category && i !== this.props.index)) {
alert(chrome.i18n.getMessage("poiOnlyOneSegment"));
}
this.previousSkipType = ActionType.Poi;
} else if (CompileConfig.categorySupport[category]?.length === 1
&& CompileConfig.categorySupport[category]?.[0] === ActionType.Full) {
if (this.previousSkipType !== ActionType.Full) {
this.timesBeforeChanging = [...segment.segment];
}
this.previousSkipType = ActionType.Full;
} else if ((category === "chooseACategory" || (CompileConfig.categorySupport[category]?.includes(ActionType.Skip)
&& ![ActionType.Poi, ActionType.Full].includes(this.getNextActionType(category, actionType))))
&& this.previousSkipType !== ActionType.Skip) {
if (this.timesBeforeChanging[0]) {
this.setTimeTo(0, this.timesBeforeChanging[0]);
}
if (this.timesBeforeChanging[1]) {
this.setTimeTo(1, this.timesBeforeChanging[1]);
}
this.previousSkipType = ActionType.Skip;
}
}
getActionTypeOptions(sponsorTime: SponsorTime): React.ReactElement[] {
const elements = [];
for (const actionType of CompileConfig.categorySupport[sponsorTime.category]) {
elements.push(
<option value={actionType}
key={actionType}>
{chrome.i18n.getMessage(actionType)}
</option>
);
}
return elements;
}
setTimeToNow(index: number): void {
this.setTimeTo(index, this.props.contentContainer().getRealCurrentTime());
}
setTimeToEnd(): void {
this.setTimeTo(1, this.props.contentContainer().v.duration);
}
/**
* @param index
* @param time If null, will set time to the first index's time
*/
setTimeTo(index: number, time: number): void {
const sponsorTime = this.props.contentContainer().sponsorTimesSubmitting[this.props.index];
if (time === null) time = sponsorTime.segment[0];
sponsorTime.segment[index] = time;
if (sponsorTime.actionType === ActionType.Poi) sponsorTime.segment[1] = time;
this.setState({
sponsorTimeEdits: this.getFormattedSponsorTimesEdits(sponsorTime)
@@ -224,7 +476,7 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
this.saveEditTimes();
} else {
let sponsorTime = this.props.contentContainer().sponsorTimesSubmitting[this.props.index];
const sponsorTime = this.props.contentContainer().sponsorTimesSubmitting[this.props.index];
this.setState({
editing: true,
@@ -233,70 +485,105 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
}
}
/** Returns an array in the sponsorTimeEdits form (minutes and seconds) from a normal seconds sponsor time */
getFormattedSponsorTimesEdits(sponsorTime: SponsorTime): string[][] {
return [[String(utils.getFormattedMinutes(sponsorTime.segment[0])), String(utils.getFormattedSeconds(sponsorTime.segment[0]))],
[String(utils.getFormattedMinutes(sponsorTime.segment[1])), String(utils.getFormattedSeconds(sponsorTime.segment[1]))]];
/** Returns an array in the sponsorTimeEdits form (formatted time string) from a normal seconds sponsor time */
getFormattedSponsorTimesEdits(sponsorTime: SponsorTime): [string, string] {
return [utils.getFormattedTime(sponsorTime.segment[0], true),
utils.getFormattedTime(sponsorTime.segment[1], true)];
}
saveEditTimes() {
let sponsorTimesSubmitting = this.props.contentContainer().sponsorTimesSubmitting;
saveEditTimes(): void {
const sponsorTimesSubmitting = this.props.contentContainer().sponsorTimesSubmitting;
if (this.state.editing) {
sponsorTimesSubmitting[this.props.index].segment =
[utils.getRawSeconds(parseFloat(this.state.sponsorTimeEdits[0][0]), parseFloat(this.state.sponsorTimeEdits[0][1])),
utils.getRawSeconds(parseFloat(this.state.sponsorTimeEdits[1][0]), parseFloat(this.state.sponsorTimeEdits[1][1]))];
const startTime = utils.getFormattedTimeToSeconds(this.state.sponsorTimeEdits[0]);
const endTime = utils.getFormattedTimeToSeconds(this.state.sponsorTimeEdits[1]);
// Change segment time only if the format was correct
if (startTime !== null && endTime !== null) {
sponsorTimesSubmitting[this.props.index].segment = [startTime, endTime];
}
}
sponsorTimesSubmitting[this.props.index].category = this.categoryOptionRef.current.value;
const category = this.categoryOptionRef.current.value as Category
sponsorTimesSubmitting[this.props.index].category = category;
Config.config.sponsorTimes.set(this.props.contentContainer().sponsorVideoID, utils.getSegmentsFromSponsorTimes(sponsorTimesSubmitting));
const inputActionType = this.actionTypeOptionRef?.current?.value as ActionType;
sponsorTimesSubmitting[this.props.index].actionType = this.getNextActionType(category, inputActionType);
Config.config.unsubmittedSegments[this.props.contentContainer().sponsorVideoID] = sponsorTimesSubmitting;
Config.forceSyncUpdate("unsubmittedSegments");
this.props.contentContainer().updatePreviewBar();
if (sponsorTimesSubmitting[this.props.index].actionType === ActionType.Full
&& (sponsorTimesSubmitting[this.props.index].segment[0] !== 0 || sponsorTimesSubmitting[this.props.index].segment[1] !== 0)) {
this.setTimeTo(0, 0);
this.setTimeTo(1, 0);
}
}
previewTime(): void {
let sponsorTimes = this.props.contentContainer().sponsorTimesSubmitting;
let index = this.props.index;
private getNextActionType(category: Category, actionType: ActionType): ActionType {
return actionType && CompileConfig.categorySupport[category]?.includes(actionType) ? actionType
: CompileConfig.categorySupport[category]?.[0] ?? ActionType.Skip
}
let skipTime = sponsorTimes[index][0];
previewTime(ctrlPressed = false, shiftPressed = false): void {
const sponsorTimes = this.props.contentContainer().sponsorTimesSubmitting;
const index = this.props.index;
if (this.state.editing) {
// Save edits before previewing
this.saveEditTimes();
}
const skipTime = sponsorTimes[index].segment[0];
this.props.contentContainer().previewTime(skipTime - 2);
let seekTime = 2;
if (ctrlPressed) seekTime = 0.5;
if (shiftPressed) seekTime = 0.25;
this.props.contentContainer().previewTime(skipTime - (seekTime * this.props.contentContainer().v.playbackRate));
}
inspectTime(): void {
const sponsorTimes = this.props.contentContainer().sponsorTimesSubmitting;
const index = this.props.index;
const skipTime = sponsorTimes[index].segment[0];
this.props.contentContainer().previewTime(skipTime + 0.0001, false);
}
deleteTime(): void {
let sponsorTimes = this.props.contentContainer().sponsorTimesSubmitting;
let index = this.props.index;
const sponsorTimes = this.props.contentContainer().sponsorTimesSubmitting;
const index = this.props.index;
const removingIncomplete = sponsorTimes[index].segment.length < 2;
//if it is not a complete sponsor time
if (sponsorTimes[index].segment.length < 2) {
//update video player
this.props.contentContainer().changeStartSponsorButton(true, false);
}
sponsorTimes.splice(index, 1);
//save this
Config.config.sponsorTimes.set(this.props.contentContainer().sponsorVideoID, sponsorTimes);
if (sponsorTimes.length > 0) {
Config.config.unsubmittedSegments[this.props.contentContainer().sponsorVideoID] = sponsorTimes;
} else {
delete Config.config.unsubmittedSegments[this.props.contentContainer().sponsorVideoID];
}
Config.forceSyncUpdate("unsubmittedSegments");
this.props.contentContainer().updatePreviewBar();
//if they are all removed
if (sponsorTimes.length == 0) {
this.props.submissionNotice.cancel();
//update video player
this.props.contentContainer().changeStartSponsorButton(true, false);
} else {
//update display
this.props.submissionNotice.forceUpdate();
}
//if it is not a complete segment, or all are removed
if (sponsorTimes.length === 0 || removingIncomplete) {
//update video player
this.props.contentContainer().updateEditButtonsOnPlayer();
}
}
configUpdate(): void {
this.forceUpdate();
}
}
export default SponsorTimeEditComponent;
export default SponsorTimeEditComponent;

View File

@@ -10,24 +10,28 @@ export interface SubmissionNoticeProps {
// Contains functions and variables from the content script needed by the skip notice
contentContainer: ContentContainer;
callback: () => any;
callback: () => unknown;
closeListener: () => void;
}
export interface SubmissionNoticeeState {
export interface SubmissionNoticeState {
noticeTitle: string,
messages: string[],
idSuffix: string;
}
class SubmissionNoticeComponent extends React.Component<SubmissionNoticeProps, SubmissionNoticeeState> {
class SubmissionNoticeComponent extends React.Component<SubmissionNoticeProps, SubmissionNoticeState> {
// Contains functions and variables from the content script needed by the skip notice
contentContainer: ContentContainer;
callback: () => any;
callback: () => unknown;
noticeRef: React.MutableRefObject<NoticeComponent>;
timeEditRefs: React.RefObject<SponsorTimeEditComponent>[];
videoObserver: MutationObserver;
constructor(props: SubmissionNoticeProps) {
super(props);
this.noticeRef = React.createRef();
@@ -35,7 +39,7 @@ class SubmissionNoticeComponent extends React.Component<SubmissionNoticeProps, S
this.contentContainer = props.contentContainer;
this.callback = props.callback;
let noticeTitle = chrome.i18n.getMessage("confirmNoticeTitle");
const noticeTitle = chrome.i18n.getMessage("confirmNoticeTitle");
// Setup state
this.state = {
@@ -45,35 +49,55 @@ class SubmissionNoticeComponent extends React.Component<SubmissionNoticeProps, S
}
}
render() {
componentDidMount(): void {
// Catch and rerender when the video size changes
//TODO: Use ResizeObserver when it is supported in TypeScript
this.videoObserver = new MutationObserver(() => {
this.forceUpdate();
});
this.videoObserver.observe(this.contentContainer().v, {
attributes: true
});
}
componentWillUnmount(): void {
if (this.videoObserver) {
this.videoObserver.disconnect();
}
}
render(): React.ReactElement {
return (
<NoticeComponent noticeTitle={this.state.noticeTitle}
idSuffix={this.state.idSuffix}
ref={this.noticeRef}
closeListener={this.cancel.bind(this)}
zIndex={50000}>
zIndex={5000}>
{/* Text Boxes */}
{this.getMessageBoxes()}
{/* Sponsor Time List */}
<tr id={"sponsorSkipNoticeMiddleRow" + this.state.idSuffix}>
<td>
<tr id={"sponsorSkipNoticeMiddleRow" + this.state.idSuffix}
className="sponsorTimeMessagesRow"
style={{maxHeight: (this.contentContainer().v.offsetHeight - 200) + "px"}}>
<td style={{width: "100%"}}>
{this.getSponsorTimeMessages()}
</td>
</tr>
{/* Last Row */}
<tr id={"sponsorSkipNoticeSecondRow" + this.state.idSuffix}>
<td className="sponsorSkipNoticeRightSection"
style={{position: "relative"}}>
{/* Cancel Button */}
{/* Guidelines button */}
<button className="sponsorSkipObject sponsorSkipNoticeButton sponsorSkipNoticeRightButton"
onClick={this.cancel.bind(this)}>
onClick={() => window.open("https://wiki.sponsor.ajay.app/w/Guidelines")}>
{chrome.i18n.getMessage("cancel")}
{chrome.i18n.getMessage(Config.config.submissionCountSinceCategories > 3 ? "guidelines" : "readTheGuidelines")}
</button>
{/* Submit Button */}
@@ -90,16 +114,16 @@ class SubmissionNoticeComponent extends React.Component<SubmissionNoticeProps, S
}
getSponsorTimeMessages(): JSX.Element[] | JSX.Element {
let elements: JSX.Element[] = [];
const elements: JSX.Element[] = [];
this.timeEditRefs = [];
let sponsorTimes = this.props.contentContainer().sponsorTimesSubmitting;
const sponsorTimes = this.props.contentContainer().sponsorTimesSubmitting;
for (let i = 0; i < sponsorTimes.length; i++) {
let timeRef = React.createRef<SponsorTimeEditComponent>();
const timeRef = React.createRef<SponsorTimeEditComponent>();
elements.push(
<SponsorTimeEditComponent key={i}
<SponsorTimeEditComponent key={sponsorTimes[i].UUID}
idSuffix={this.state.idSuffix + i}
index={i}
contentContainer={this.props.contentContainer}
@@ -115,7 +139,7 @@ class SubmissionNoticeComponent extends React.Component<SubmissionNoticeProps, S
}
getMessageBoxes(): JSX.Element[] | JSX.Element {
let elements: JSX.Element[] = [];
const elements: JSX.Element[] = [];
for (let i = 0; i < this.state.messages.length; i++) {
elements.push(
@@ -129,22 +153,43 @@ class SubmissionNoticeComponent extends React.Component<SubmissionNoticeProps, S
return elements;
}
cancel() {
cancel(): void {
this.noticeRef.current.close(true);
this.contentContainer().resetSponsorSubmissionNotice();
this.props.closeListener();
}
submit() {
submit(): void {
// save all items
for (const ref of this.timeEditRefs) {
ref.current.saveEditTimes();
}
const sponsorTimesSubmitting = this.props.contentContainer().sponsorTimesSubmitting;
for (const sponsorTime of sponsorTimesSubmitting) {
if (sponsorTime.category === "chooseACategory") {
alert(chrome.i18n.getMessage("youMustSelectACategory"));
return;
}
}
// Check if any non music categories are being used on a music video
if (this.contentContainer().videoInfo?.microformat?.playerMicroformatRenderer?.category === "Music") {
for (const sponsorTime of sponsorTimesSubmitting) {
if (sponsorTime.category === "sponsor") {
if (!confirm(chrome.i18n.getMessage("nonMusicCategoryOnMusic"))) return;
break;
}
}
}
this.props.callback();
this.cancel();
}
}
export default SubmissionNoticeComponent;
export default SubmissionNoticeComponent;

View File

@@ -0,0 +1,37 @@
import * as React from "react";
import Config from "../config";
import { Category, SegmentUUID, SponsorTime } from "../types";
export interface TooltipProps {
text: string;
show: boolean;
}
export interface TooltipState {
}
class TooltipComponent extends React.Component<TooltipProps, TooltipState> {
constructor(props: TooltipProps) {
super(props);
}
render(): React.ReactElement {
const style: React.CSSProperties = {
display: this.props.show ? "flex" : "none",
position: "absolute",
}
return (
<span style={style}
className={"sponsorBlockTooltip"} >
<span className="sponsorBlockTooltipText">
{this.props.text}
</span>
</span>
);
}
}
export default TooltipComponent;

View File

@@ -1,222 +1,336 @@
import * as CompileConfig from "../config.json";
import { CategorySelection, CategorySkipOption } from "./types";
import * as invidiousList from "../ci/invidiouslist.json";
import { Category, CategorySelection, CategorySkipOption, NoticeVisbilityMode, PreviewBarOption, SponsorTime, StorageChangesObject, UnEncodedSegmentTimes as UnencodedSegmentTimes, Keybind, HashedValue, VideoID, SponsorHideType } from "./types";
import { keybindEquals } from "./utils/configUtils";
interface SBConfig {
userID: string,
sponsorTimes: SBMap<string, any>,
whitelistedChannels: Array<any>,
startSponsorKeybind: string,
submitKeybind: string,
isVip: boolean,
lastIsVipUpdate: number,
/* Contains unsubmitted segments that the user has created. */
unsubmittedSegments: Record<string, SponsorTime[]>,
defaultCategory: Category,
whitelistedChannels: string[],
forceChannelCheck: boolean,
minutesSaved: number,
skipCount: number,
sponsorTimesContributed: number,
submissionCountSinceCategories: number, // New count used to show the "Read The Guidelines!!" message
showTimeWithSkips: boolean,
disableSkipping: boolean,
muteSegments: boolean,
fullVideoSegments: boolean,
trackViewCount: boolean,
trackViewCountInPrivate: boolean,
trackDownvotes: boolean,
dontShowNotice: boolean,
noticeVisibilityMode: NoticeVisbilityMode,
hideVideoPlayerControls: boolean,
hideInfoButtonPlayerControls: boolean,
hideDeleteButtonPlayerControls: boolean,
hideUploadButtonPlayerControls: boolean,
hideSkipButtonPlayerControls: boolean,
hideDiscordLaunches: number,
hideDiscordLink: boolean,
invidiousInstances: string[],
autoUpvote: boolean,
supportInvidious: boolean,
serverAddress: string,
minDuration: number,
audioNotificationOnSkip,
skipNoticeDuration: number,
audioNotificationOnSkip: boolean,
checkForUnlistedVideos: boolean,
mobileUpdateShowCount: number,
testingServer: boolean,
refetchWhenNotFound: boolean,
ytInfoPermissionGranted: boolean,
allowExpirements: boolean,
showDonationLink: boolean,
showPopupDonationCount: number,
donateClicked: number,
autoHideInfoButton: boolean,
autoSkipOnMusicVideos: boolean,
colorPalette: {
red: string,
white: string,
locked: string
},
scrollToEditTimeUpdate: boolean,
categoryPillUpdate: boolean,
darkMode: boolean,
// What categories should be skipped
categorySelections: CategorySelection[]
}
interface SBObject {
configListeners: Array<Function>;
defaults: SBConfig;
localConfig: SBConfig;
config: SBConfig;
// Functions
encodeStoredItem<T>(data: T): T | Array<any>;
convertJSON(): void;
}
// Allows a SBMap to be conveted into json form
// Currently used for local storage
class SBMap<T, U> extends Map {
id: string;
constructor(id: string, entries?: [T, U][]) {
super();
this.id = id;
// Import all entries if they were given
if (entries !== undefined) {
for (const item of entries) {
super.set(item[0], item[1])
}
// Used to cache calculated text color info
categoryPillColors: {
[key in Category]: {
lastColor: string,
textColor: string
}
}
set(key, value) {
const result = super.set(key, value);
skipKeybind: Keybind,
startSponsorKeybind: Keybind,
submitKeybind: Keybind,
// Store updated SBMap locally
chrome.storage.sync.set({
[this.id]: encodeStoredItem(this)
});
// What categories should be skipped
categorySelections: CategorySelection[],
return result;
}
delete(key) {
const result = super.delete(key);
// Store updated SBMap locally
chrome.storage.sync.set({
[this.id]: encodeStoredItem(this)
});
return result;
}
clear() {
const result = super.clear();
chrome.storage.sync.set({
[this.id]: encodeStoredItem(this)
});
return result;
// Preview bar
barTypes: {
"preview-chooseACategory": PreviewBarOption,
"sponsor": PreviewBarOption,
"preview-sponsor": PreviewBarOption,
"selfpromo": PreviewBarOption,
"preview-selfpromo": PreviewBarOption,
"exclusive_access": PreviewBarOption,
"interaction": PreviewBarOption,
"preview-interaction": PreviewBarOption,
"intro": PreviewBarOption,
"preview-intro": PreviewBarOption,
"outro": PreviewBarOption,
"preview-outro": PreviewBarOption,
"preview": PreviewBarOption,
"preview-preview": PreviewBarOption,
"music_offtopic": PreviewBarOption,
"preview-music_offtopic": PreviewBarOption,
"poi_highlight": PreviewBarOption,
"preview-poi_highlight": PreviewBarOption,
"filler": PreviewBarOption,
"preview-filler": PreviewBarOption,
}
}
var Config: SBObject = {
export type VideoDownvotes = { segments: { uuid: HashedValue, hidden: SponsorHideType }[] , lastAccess: number };
interface SBStorage {
/* VideoID prefixes to UUID prefixes */
downvotedSegments: Record<VideoID & HashedValue, VideoDownvotes>,
}
export interface SBObject {
configSyncListeners: Array<(changes: StorageChangesObject) => unknown>;
syncDefaults: SBConfig;
localDefaults: SBStorage;
cachedSyncConfig: SBConfig;
cachedLocalStorage: SBStorage;
config: SBConfig;
local: SBStorage;
forceSyncUpdate(prop: string): void;
forceLocalUpdate(prop: string): void;
}
const Config: SBObject = {
/**
* Callback function when an option is updated
*/
configListeners: [],
defaults: {
configSyncListeners: [],
syncDefaults: {
userID: null,
sponsorTimes: new SBMap("sponsorTimes"),
isVip: false,
lastIsVipUpdate: 0,
unsubmittedSegments: {},
defaultCategory: "chooseACategory" as Category,
whitelistedChannels: [],
startSponsorKeybind: ";",
submitKeybind: "'",
forceChannelCheck: false,
minutesSaved: 0,
skipCount: 0,
sponsorTimesContributed: 0,
submissionCountSinceCategories: 0,
showTimeWithSkips: true,
disableSkipping: false,
muteSegments: true,
fullVideoSegments: true,
trackViewCount: true,
trackViewCountInPrivate: true,
trackDownvotes: true,
dontShowNotice: false,
noticeVisibilityMode: NoticeVisbilityMode.FadedForAutoSkip,
hideVideoPlayerControls: false,
hideInfoButtonPlayerControls: false,
hideDeleteButtonPlayerControls: false,
hideUploadButtonPlayerControls: false,
hideSkipButtonPlayerControls: false,
hideDiscordLaunches: 0,
hideDiscordLink: false,
invidiousInstances: ["invidio.us", "invidiou.sh", "invidious.snopyta.org"],
autoUpvote: true,
invidiousInstances: ["invidious.snopyta.org"], // leave as default
supportInvidious: false,
serverAddress: CompileConfig.serverAddress,
minDuration: 0,
skipNoticeDuration: 4,
audioNotificationOnSkip: false,
checkForUnlistedVideos: false,
mobileUpdateShowCount: 0,
testingServer: false,
refetchWhenNotFound: true,
ytInfoPermissionGranted: false,
allowExpirements: true,
showDonationLink: true,
showPopupDonationCount: 0,
donateClicked: 0,
autoHideInfoButton: true,
autoSkipOnMusicVideos: false,
scrollToEditTimeUpdate: false, // false means the tooltip will be shown
categoryPillUpdate: false,
darkMode: true,
categoryPillColors: {},
/**
* Default keybinds should not set "code" as that's gonna be different based on the user's locale. They should also only use EITHER ctrl OR alt modifiers (or none).
* Using ctrl+alt, or shift may produce a different character that we will not be able to recognize in different locales.
* The exception for shift is letters, where it only capitalizes. So shift+A is fine, but shift+1 isn't.
* Don't forget to add the new keybind to the checks in "KeybindDialogComponent.isKeybindAvailable()" and in "migrateOldFormats()"!
* TODO: Find a way to skip having to update these checks. Maybe storing keybinds in a Map?
*/
skipKeybind: {key: "Enter"},
startSponsorKeybind: {key: ";"},
submitKeybind: {key: "'"},
categorySelections: [{
name: "sponsor",
name: "sponsor" as Category,
option: CategorySkipOption.AutoSkip
}]
}, {
name: "interaction" as Category,
option: CategorySkipOption.AutoSkip
}, {
name: "selfpromo" as Category,
option: CategorySkipOption.AutoSkip
}],
colorPalette: {
red: "#780303",
white: "#ffffff",
locked: "#ffc83d"
},
// Preview bar
barTypes: {
"preview-chooseACategory": {
color: "#ffffff",
opacity: "0.7"
},
"sponsor": {
color: "#807EFB",
opacity: "0.7"
},
"preview-sponsor": {
color: "#007800",
opacity: "0.7"
},
"selfpromo": {
color: "#ffff00",
opacity: "0.7"
},
"preview-selfpromo": {
color: "#bfbf35",
opacity: "0.7"
},
"exclusive_access": {
color: "#008a5c",
opacity: "0.7"
},
"interaction": {
color: "#cc00ff",
opacity: "0.7"
},
"preview-interaction": {
color: "#6c0087",
opacity: "0.7"
},
"intro": {
color: "#00ffff",
opacity: "0.7"
},
"preview-intro": {
color: "#008080",
opacity: "0.7"
},
"outro": {
color: "#0202ed",
opacity: "0.7"
},
"preview-outro": {
color: "#000070",
opacity: "0.7"
},
"preview": {
color: "#008fd6",
opacity: "0.7"
},
"preview-preview": {
color: "#005799",
opacity: "0.7"
},
"music_offtopic": {
color: "#ff9900",
opacity: "0.7"
},
"preview-music_offtopic": {
color: "#a6634a",
opacity: "0.7"
},
"poi_highlight": {
color: "#ff1684",
opacity: "0.7"
},
"preview-poi_highlight": {
color: "#9b044c",
opacity: "0.7"
},
"filler": {
color: "#7300FF",
opacity: "0.9"
},
"preview-filler": {
color: "#2E0066",
opacity: "0.7"
}
}
},
localConfig: null,
localDefaults: {
downvotedSegments: {}
},
cachedSyncConfig: null,
cachedLocalStorage: null,
config: null,
// Functions
encodeStoredItem,
convertJSON
local: null,
forceSyncUpdate,
forceLocalUpdate
};
// Function setup
/**
* A SBMap cannot be stored in the chrome storage.
* This data will be encoded into an array instead
*
* @param data
*/
function encodeStoredItem<T>(data: T): T | Array<any> {
// if data is SBMap convert to json for storing
if(!(data instanceof SBMap)) return data;
return Array.from(data.entries());
}
/**
* An SBMap cannot be stored in the chrome storage.
* This data will be decoded from the array it is stored in
*
* @param {*} data
*/
function decodeStoredItem<T>(id: string, data: T): T | SBMap<string, any> {
if (!Config.defaults[id]) return data;
if (Config.defaults[id] instanceof SBMap) {
try {
let jsonData: any = data;
// Check if data is stored in the old format for SBMap (a JSON string)
if (typeof data === "string") {
try {
jsonData = JSON.parse(data);
} catch(e) {
// Continue normally (out of this if statement)
}
function configProxy(): { sync: SBConfig, local: SBStorage } {
chrome.storage.onChanged.addListener((changes: {[key: string]: chrome.storage.StorageChange}, areaName) => {
if (areaName === "sync") {
for (const key in changes) {
Config.cachedSyncConfig[key] = changes[key].newValue;
}
for (const callback of Config.configSyncListeners) {
callback(changes);
}
} else if (areaName === "local") {
for (const key in changes) {
Config.cachedLocalStorage[key] = changes[key].newValue;
}
if (!Array.isArray(jsonData)) return data;
return new SBMap(id, jsonData);
} catch(e) {
console.error("Failed to parse SBMap: " + id);
}
}
// If all else fails, return the data
return data;
}
function configProxy(): any {
chrome.storage.onChanged.addListener((changes, namespace) => {
for (const key in changes) {
Config.localConfig[key] = decodeStoredItem(key, changes[key].newValue);
}
for (const callback of Config.configListeners) {
callback(changes);
}
});
var handler: ProxyHandler<any> = {
set(obj, prop, value) {
Config.localConfig[prop] = value;
const syncHandler: ProxyHandler<SBConfig> = {
set<K extends keyof SBConfig>(obj: SBConfig, prop: K, value: SBConfig[K]) {
Config.cachedSyncConfig[prop] = value;
chrome.storage.sync.set({
[prop]: encodeStoredItem(value)
[prop]: value
});
return true;
},
get(obj, prop): any {
let data = Config.localConfig[prop];
get<K extends keyof SBConfig>(obj: SBConfig, prop: K): SBConfig[K] {
const data = Config.cachedSyncConfig[prop];
return obj[prop] || data;
},
deleteProperty(obj, prop) {
deleteProperty(obj: SBConfig, prop: keyof SBConfig) {
chrome.storage.sync.remove(<string> prop);
return true;
@@ -224,59 +338,99 @@ function configProxy(): any {
};
return new Proxy({handler}, handler);
const localHandler: ProxyHandler<SBStorage> = {
set<K extends keyof SBStorage>(obj: SBStorage, prop: K, value: SBStorage[K]) {
Config.cachedLocalStorage[prop] = value;
chrome.storage.local.set({
[prop]: value
});
return true;
},
get<K extends keyof SBStorage>(obj: SBStorage, prop: K): SBStorage[K] {
const data = Config.cachedLocalStorage[prop];
return obj[prop] || data;
},
deleteProperty(obj: SBStorage, prop: keyof SBStorage) {
chrome.storage.local.remove(<string> prop);
return true;
}
};
return {
sync: new Proxy<SBConfig>({ handler: syncHandler } as unknown as SBConfig, syncHandler),
local: new Proxy<SBStorage>({ handler: localHandler } as unknown as SBStorage, localHandler)
};
}
function fetchConfig() {
return new Promise((resolve, reject) => {
chrome.storage.sync.get(null, function(items) {
Config.localConfig = <SBConfig> <unknown> items; // Data is ready
resolve();
});
function forceSyncUpdate(prop: string): void {
chrome.storage.sync.set({
[prop]: Config.cachedSyncConfig[prop]
});
}
function migrateOldFormats() {
if (Config.config["disableAutoSkip"]) {
for (const selection of Config.config.categorySelections) {
if (selection.name === "sponsor") {
selection.option = CategorySkipOption.ManualSkip;
function forceLocalUpdate(prop: string): void {
chrome.storage.local.set({
[prop]: Config.cachedLocalStorage[prop]
});
}
chrome.storage.sync.remove("disableAutoSkip");
}
}
}
async function fetchConfig(): Promise<void> {
await Promise.all([new Promise<void>((resolve) => {
chrome.storage.sync.get(null, function(items) {
Config.cachedSyncConfig = <SBConfig> <unknown> items;
resolve();
});
}), new Promise<void>((resolve) => {
chrome.storage.local.get(null, function(items) {
Config.cachedLocalStorage = <SBStorage> <unknown> items;
resolve();
});
})]);
}
function migrateOldSyncFormats(config: SBConfig) {
//
}
async function setupConfig() {
await fetchConfig();
addDefaults();
convertJSON();
Config.config = configProxy();
migrateOldFormats();
}
const config = configProxy();
migrateOldSyncFormats(config.sync);
// Reset config
function resetConfig() {
Config.config = Config.defaults;
};
function convertJSON(): void {
Object.keys(Config.localConfig).forEach(key => {
Config.localConfig[key] = decodeStoredItem(key, Config.localConfig[key]);
});
Config.config = config.sync;
Config.local = config.local;
}
// Add defaults
function addDefaults() {
for (const key in Config.defaults) {
if(!Config.localConfig.hasOwnProperty(key)) {
Config.localConfig[key] = Config.defaults[key];
for (const key in Config.syncDefaults) {
if(!Object.prototype.hasOwnProperty.call(Config.cachedSyncConfig, key)) {
Config.cachedSyncConfig[key] = Config.syncDefaults[key];
} else if (key === "barTypes") {
for (const key2 in Config.syncDefaults[key]) {
if(!Object.prototype.hasOwnProperty.call(Config.cachedSyncConfig[key], key2)) {
Config.cachedSyncConfig[key][key2] = Config.syncDefaults[key][key2];
}
}
}
}
};
for (const key in Config.localDefaults) {
if(!Object.prototype.hasOwnProperty.call(Config.cachedLocalStorage, key)) {
Config.cachedLocalStorage[key] = Config.localDefaults[key];
}
}
}
// Sync config
setupConfig();
export default Config;
export default Config;

File diff suppressed because it is too large Load Diff

19
src/globals.d.ts vendored Normal file
View File

@@ -0,0 +1,19 @@
import { SBObject } from "./config";
declare global {
interface Window { SB: SBObject; }
// Remove this once the API becomes stable and types are shipped in @types/chrome
namespace chrome {
namespace declarativeContent {
export interface RequestContentScriptOptions {
allFrames?: boolean;
css?: string[];
instanceType?: "declarativeContent.RequestContentScript";
js?: string[];
matchAboutBlanck?: boolean;
}
export class RequestContentScript {
constructor(options: RequestContentScriptOptions);
}
}
}
}

21
src/help.ts Normal file
View File

@@ -0,0 +1,21 @@
import Config from "./config";
import { showDonationLink } from "./utils/configUtils";
import Utils from "./utils";
const utils = new Utils();
window.addEventListener('DOMContentLoaded', init);
async function init() {
utils.localizeHtmlPage();
await utils.wait(() => Config.config !== null);
if (!Config.config.darkMode) {
document.documentElement.setAttribute("data-theme", "light");
}
if (!showDonationLink()) {
document.getElementById("sbDonate").style.display = "none";
}
}

47
src/js-components/chat.ts Normal file
View File

@@ -0,0 +1,47 @@
import Config from "../config";
import Utils from "../utils";
const utils = new Utils();
export interface ChatConfig {
displayName: string,
composerInitialValue?: string,
customDescription?: string
}
export function openChat(config: ChatConfig): void {
const chat = document.createElement("div");
chat.classList.add("sbChatNotice");
chat.style.zIndex = "2000";
const iframe= document.createElement("iframe");
iframe.src = "https://chat.sponsor.ajay.app/#" + utils.objectToURI("", config, false);
chat.appendChild(iframe);
const closeButton = document.createElement("img");
closeButton.classList.add("sbChatClose");
closeButton.src = chrome.extension.getURL("icons/close.png");
closeButton.addEventListener("click", () => {
chat.remove();
closeButton.remove();
});
chat.appendChild(closeButton);
const referenceNode = utils.findReferenceNode();
referenceNode.prepend(chat);
}
export async function openWarningChat(warningMessage: string): Promise<void> {
const warningReasonMatch = warningMessage.match(/Warning reason: '(.+)'/);
alert(chrome.i18n.getMessage("warningChatInfo") + `\n\n${warningReasonMatch ? ` Warning reason: ${warningReasonMatch[1]}` : ``}`);
const userNameData = await utils.asyncRequestToServer("GET", "/api/getUsername?userID=" + Config.config.userID);
const userName = userNameData.ok ? JSON.parse(userNameData.responseText).userName : "";
const publicUserID = await utils.getHash(Config.config.userID);
openChat({
displayName: `${userName ? userName : ``}${userName !== publicUserID ? ` | ${publicUserID}` : ``}`,
composerInitialValue: `I got a warning and confirm I [REMOVE THIS CAPITAL TEXT TO CONFIRM] reread the guidelines.` +
warningReasonMatch ? ` Warning reason: ${warningReasonMatch[1]}` : ``,
customDescription: chrome.i18n.getMessage("warningChatInfo")
});
}

Some files were not shown because too many files have changed in this diff Show More