diff --git a/public/_locales/en/messages.json b/public/_locales/en/messages.json
index ab6c4e4c..ae14284a 100644
--- a/public/_locales/en/messages.json
+++ b/public/_locales/en/messages.json
@@ -1103,5 +1103,52 @@
"Import": {
"message": "Import",
"description": "Button to initiate importing segments. Appears under the textbox where they paste in the data"
+ },
+ "redeemSuccess": {
+ "message": "Reedem Successful!"
+ },
+ "redeemFailed": {
+ "message": "License key is invalid"
+ },
+ "hideUpsells": {
+ "message": "Hide options not available without extra payment"
+ },
+ "chooseACountry": {
+ "message": "Choose a country"
+ },
+ "noDiscount": {
+ "message": "You do not qualify for a discount"
+ },
+ "discountLink": {
+ "message": "Discount Link (See the pink price)"
+ },
+ "selectYourCountry": {
+ "message": "Select your country"
+ },
+ "alreadyDonated": {
+ "message": "If you've donated any amount before now, you may redeem free access by emailing:",
+ "description": "After the colon is an email address"
+ },
+ "cantAfford": {
+ "message": "If you can't afford to purchase a license, click {here} to see if you are eligible for a discount",
+ "description": "Keep the curly braces"
+ },
+ "patreonSignIn": {
+ "message": "Sign in with Patreon"
+ },
+ "redeem": {
+ "message": "Redeem"
+ },
+ "joinOnPatreon": {
+ "message": "Subscribe on Patreon"
+ },
+ "oneTimePurchase": {
+ "message": "One Time Purchase"
+ },
+ "enterLicenseKey": {
+ "message": "Enter License Key"
+ },
+ "chaptersPage1": {
+ "message": "SponsorBlock crowd-sourced chapters feature is only available to people who purchase a license, or for people who are granted access for free due their past contributions"
}
}
diff --git a/public/options/options.css b/public/options/options.css
index 36f4d5d7..2bd27161 100644
--- a/public/options/options.css
+++ b/public/options/options.css
@@ -317,6 +317,10 @@ input[type='number'] {
color: grey;
}
+tr.disabled {
+ opacity: 0.3;
+}
+
#options {
height: 100vh;
flex-basis: 80%;
@@ -678,4 +682,9 @@ svg {
#options > div {
max-width: 100%;
}
+}
+
+.upsellButton {
+ cursor: pointer;
+ vertical-align: middle;
}
\ No newline at end of file
diff --git a/public/options/options.html b/public/options/options.html
index 150212ce..765134ec 100644
--- a/public/options/options.html
+++ b/public/options/options.html
@@ -302,6 +302,18 @@
+
diff --git a/public/res/countries.json b/public/res/countries.json
new file mode 100644
index 00000000..33839f29
--- /dev/null
+++ b/public/res/countries.json
@@ -0,0 +1 @@
+{"Albania":{"allowed":true},"Algeria":{"allowed":true},"Angola":{"allowed":true},"Argentina":{"allowed":true},"Armenia":{"allowed":true},"Australia":{"allowed":false},"Austria":{"allowed":false},"Azerbaijan":{"allowed":true},"Bangladesh":{"allowed":true},"Belarus":{"allowed":true},"Belgium":{"allowed":false},"Belize":{"allowed":true},"Benin":{"allowed":true},"Bhutan":{"allowed":true},"Bolivia":{"allowed":true},"Bosnia and Herzegovina":{"allowed":true},"Botswana":{"allowed":true},"Brazil":{"allowed":true},"Bulgaria":{"allowed":true},"Burkina Faso":{"allowed":true},"Burundi":{"allowed":true},"Cameroon":{"allowed":true},"Canada":{"allowed":false},"Central African Republic":{"allowed":true},"Chad":{"allowed":true},"Chile":{"allowed":true},"China":{"allowed":true},"Colombia":{"allowed":true},"Comoros":{"allowed":true},"Costa Rica":{"allowed":true},"Croatia":{"allowed":true},"Cyprus":{"allowed":false},"Czech Republic":{"allowed":false},"Denmark":{"allowed":false},"Djibouti":{"allowed":true},"Dominican Republic":{"allowed":true},"DR Congo":{"allowed":true},"Ecuador":{"allowed":true},"Egypt":{"allowed":true},"El Salvador":{"allowed":true},"Estonia":{"allowed":false},"Eswatini":{"allowed":true},"Ethiopia":{"allowed":true},"Fiji":{"allowed":true},"Finland":{"allowed":false},"France":{"allowed":false},"Gabon":{"allowed":true},"Gambia":{"allowed":true},"Georgia":{"allowed":true},"Germany":{"allowed":false},"Ghana":{"allowed":true},"Greece":{"allowed":true},"Guatemala":{"allowed":true},"Guinea":{"allowed":true},"Guinea-Bissau":{"allowed":true},"Guyana":{"allowed":true},"Haiti":{"allowed":true},"Honduras":{"allowed":true},"Hungary":{"allowed":true},"Iceland":{"allowed":false},"India":{"allowed":true},"Iran":{"allowed":true},"Iraq":{"allowed":true},"Ireland":{"allowed":false},"Israel":{"allowed":false},"Italy":{"allowed":false},"Ivory Coast":{"allowed":true},"Jamaica":{"allowed":true},"Japan":{"allowed":false},"Jordan":{"allowed":true},"Kazakhstan":{"allowed":true},"Kenya":{"allowed":true},"Kiribati":{"allowed":true},"Kyrgyzstan":{"allowed":true},"Laos":{"allowed":true},"Latvia":{"allowed":true},"Lebanon":{"allowed":true},"Lesotho":{"allowed":true},"Liberia":{"allowed":true},"Lithuania":{"allowed":true},"Luxembourg":{"allowed":false},"Madagascar":{"allowed":true},"Malawi":{"allowed":true},"Malaysia":{"allowed":true},"Maldives":{"allowed":true},"Mali":{"allowed":true},"Malta":{"allowed":false},"Mauritania":{"allowed":true},"Mauritius":{"allowed":true},"Mexico":{"allowed":true},"Micronesia":{"allowed":true},"Moldova":{"allowed":true},"Mongolia":{"allowed":true},"Montenegro":{"allowed":true},"Morocco":{"allowed":true},"Mozambique":{"allowed":true},"Myanmar":{"allowed":true},"Namibia":{"allowed":true},"Nepal":{"allowed":true},"Netherlands":{"allowed":false},"Nicaragua":{"allowed":true},"Niger":{"allowed":true},"Nigeria":{"allowed":true},"North Macedonia":{"allowed":true},"Norway":{"allowed":false},"Pakistan":{"allowed":true},"Panama":{"allowed":true},"Papua New Guinea":{"allowed":true},"Paraguay":{"allowed":true},"Peru":{"allowed":true},"Philippines":{"allowed":true},"Poland":{"allowed":true},"Portugal":{"allowed":true},"Republic of the Congo":{"allowed":true},"Romania":{"allowed":true},"Russia":{"allowed":true},"Rwanda":{"allowed":true},"Saint Lucia":{"allowed":true},"Samoa":{"allowed":true},"Sao Tome and Principe":{"allowed":true},"Senegal":{"allowed":true},"Serbia":{"allowed":true},"Seychelles":{"allowed":true},"Sierra Leone":{"allowed":true},"Slovakia":{"allowed":true},"Slovenia":{"allowed":false},"Solomon Islands":{"allowed":true},"South Africa":{"allowed":true},"South Korea":{"allowed":false},"South Sudan":{"allowed":true},"Spain":{"allowed":false},"Sri Lanka":{"allowed":true},"Sudan":{"allowed":true},"Suriname":{"allowed":true},"Sweden":{"allowed":false},"Switzerland":{"allowed":false},"Syria":{"allowed":true},"Taiwan":{"allowed":false},"Tajikistan":{"allowed":true},"Tanzania":{"allowed":true},"Thailand":{"allowed":true},"Timor-Leste":{"allowed":true},"Togo":{"allowed":true},"Tonga":{"allowed":true},"Trinidad and Tobago":{"allowed":true},"Tunisia":{"allowed":true},"Turkey":{"allowed":true},"Turkmenistan":{"allowed":true},"Tuvalu":{"allowed":true},"Uganda":{"allowed":true},"Ukraine":{"allowed":true},"United Arab Emirates":{"allowed":false},"United Kingdom":{"allowed":false},"United States":{"allowed":false},"Uruguay":{"allowed":true},"Uzbekistan":{"allowed":true},"Vanuatu":{"allowed":true},"Venezuela":{"allowed":true},"Vietnam":{"allowed":true},"Yemen":{"allowed":true},"Zambia":{"allowed":true},"Zimbabwe":{"allowed":true}}
\ No newline at end of file
diff --git a/public/upsell/index.html b/public/upsell/index.html
new file mode 100644
index 00000000..1dbc21af
--- /dev/null
+++ b/public/upsell/index.html
@@ -0,0 +1,94 @@
+
+
+
+
Upsell - SponsorBlock
+
+
+
+
+
+
+
+
+
+
+
+
+ SponsorBlock
+
+
+
+
+
+
+ __MSG_chaptersPage1__
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ __MSG_alreadyDonated__ sponsorblock-free@ajay.app
+
+
+
+ __MSG_selectYourCountry__
+
+
+
+
+
+ __MSG_noDiscount__
+
+
+
\ No newline at end of file
diff --git a/public/upsell/styles.css b/public/upsell/styles.css
new file mode 100644
index 00000000..0c0d6b6b
--- /dev/null
+++ b/public/upsell/styles.css
@@ -0,0 +1,387 @@
+/* Based on options page CSS */
+html {
+ color-scheme: dark;
+}
+
+body {
+ font-family: sans-serif;
+}
+
+.center {
+ text-align: center;
+}
+
+.center p {
+ margin: auto;
+}
+
+.inline {
+ display: inline-block;
+}
+
+.bold {
+ font-weight: bold;
+}
+
+.hidden {
+ display: none !important;
+}
+
+.row-item {
+ margin-top: 10px;
+ margin-bottom: 10px;
+}
+
+.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-link {
+ text-decoration: none;
+}
+
+.option-link.side-by-side {
+ padding: 50px;
+}
+
+.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;
+}
+
+.optionsSelector {
+ background-color: #c00000;
+ color: white;
+
+ border: none;
+ font-size: 14px;
+ padding: 5px;
+ border-radius: 5px;
+}
+
+.categoryColorTextBox {
+ width: 60px;
+
+ background: none;
+ border: none;
+}
+
+#subsidizedPrice {
+ margin-top: 5px;
+ margin-bottom: 5px;
+}
+
+#discountButton {
+ text-decoration: underline;
+ cursor: pointer;
+}
\ No newline at end of file
diff --git a/src/components/options/CategorySkipOptionsComponent.tsx b/src/components/options/CategorySkipOptionsComponent.tsx
index b298347e..338435a8 100644
--- a/src/components/options/CategorySkipOptionsComponent.tsx
+++ b/src/components/options/CategorySkipOptionsComponent.tsx
@@ -6,6 +6,8 @@ import { Category, CategorySkipOption } from "../../types";
import { getCategorySuffix } from "../../utils/categoryUtils";
import ToggleOptionComponent, { ToggleOptionProps } from "./ToggleOptionComponent";
+import { fetchingChaptersAllowed } from "../../utils/licenseKey";
+import LockSvg from "../../svg-icons/lock_svg";
export interface CategorySkipOptionsProps {
category: Category;
@@ -16,6 +18,7 @@ export interface CategorySkipOptionsProps {
export interface CategorySkipOptionsState {
color: string;
previewColor: string;
+ hideChapter: boolean;
}
class CategorySkipOptionsComponent extends React.Component
{
@@ -28,7 +31,14 @@ class CategorySkipOptionsComponent extends React.Component {
+ this.setState({
+ hideChapter: !allowed
+ });
+ })
}
render(): React.ReactElement {
@@ -52,12 +62,25 @@ class CategorySkipOptionsComponent extends React.Component>;
+ }
+ }
+
return (
<>
+ className={`categoryTableElement${extraClasses}`} >
+ {disabled &&
+ chrome.tabs.create({url: chrome.runtime.getURL('upsell/index.html')})}/>
+ }
{chrome.i18n.getMessage("category_" + this.props.category)}
|
@@ -66,6 +89,7 @@ class CategorySkipOptionsComponent extends React.Component
{this.getCategorySkipOptions()}
@@ -77,6 +101,7 @@ class CategorySkipOptionsComponent extends React.Component this.setColorState(event, false)}
value={this.state.color} />
@@ -96,7 +121,7 @@ class CategorySkipOptionsComponent extends React.Component
+ className={`small-description categoryTableDescription${extraClasses}`}>
{chrome.i18n.getMessage("category_" + this.props.category + "_description")}
@@ -107,7 +132,7 @@ class CategorySkipOptionsComponent extends React.Component
|
- {this.getExtraOptionComponents(this.props.category)}
+ {this.getExtraOptionComponents(this.props.category, extraClasses, disabled)}
>
);
@@ -191,15 +216,16 @@ class CategorySkipOptionsComponent extends React.Component
+
|
diff --git a/src/components/options/ToggleOptionComponent.tsx b/src/components/options/ToggleOptionComponent.tsx
index b67024f4..c6ea698d 100644
--- a/src/components/options/ToggleOptionComponent.tsx
+++ b/src/components/options/ToggleOptionComponent.tsx
@@ -5,6 +5,7 @@ import Config from "../../config";
export interface ToggleOptionProps {
configKey: string;
label: string;
+ disabled?: boolean;
}
export interface ToggleOptionState {
@@ -27,7 +28,11 @@ class ToggleOptionComponent extends React.Component