mirror of
https://github.com/ajayyy/SponsorBlock.git
synced 2025-12-10 05:27:03 +03:00
Vip warning added when downvoting. sry that it is in the same branch, but this is the most current UI
This commit is contained in:
@@ -83,6 +83,7 @@ class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeSta
|
|||||||
|
|
||||||
selectedColor: string;
|
selectedColor: string;
|
||||||
unselectedColor: string;
|
unselectedColor: string;
|
||||||
|
lockedColor: string;
|
||||||
|
|
||||||
// Used to update on config change
|
// Used to update on config change
|
||||||
configListener: () => void;
|
configListener: () => void;
|
||||||
@@ -117,6 +118,7 @@ class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeSta
|
|||||||
|
|
||||||
this.selectedColor = Config.config.colorPalette.get("SponsorBlockRed");
|
this.selectedColor = Config.config.colorPalette.get("SponsorBlockRed");
|
||||||
this.unselectedColor = Config.config.colorPalette.get("SponsorBlockWhite");
|
this.unselectedColor = Config.config.colorPalette.get("SponsorBlockWhite");
|
||||||
|
this.lockedColor = Config.config.colorPalette.get("SponsorBlockLocked");
|
||||||
|
|
||||||
// Setup state
|
// Setup state
|
||||||
this.state = {
|
this.state = {
|
||||||
@@ -227,7 +229,7 @@ class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeSta
|
|||||||
style={{marginRight: "5px", marginLeft: "5px"}}
|
style={{marginRight: "5px", marginLeft: "5px"}}
|
||||||
title={chrome.i18n.getMessage("reportButtonInfo")}
|
title={chrome.i18n.getMessage("reportButtonInfo")}
|
||||||
onClick={() => this.prepAction(SkipNoticeAction.Downvote)}>
|
onClick={() => this.prepAction(SkipNoticeAction.Downvote)}>
|
||||||
<ThumbsDownSvg fill={(this.state.actionState === SkipNoticeAction.Downvote) ? this.selectedColor : this.unselectedColor} />
|
<ThumbsDownSvg fill={this.downvoteButtonColor(SkipNoticeAction.Downvote)} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Copy and Downvote Button */}
|
{/* Copy and Downvote Button */}
|
||||||
@@ -290,8 +292,7 @@ class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeSta
|
|||||||
{/* Copy Segment */}
|
{/* Copy Segment */}
|
||||||
<button className="sponsorSkipObject sponsorSkipNoticeButton"
|
<button className="sponsorSkipObject sponsorSkipNoticeButton"
|
||||||
title={chrome.i18n.getMessage("CopyDownvoteButtonInfo")}
|
title={chrome.i18n.getMessage("CopyDownvoteButtonInfo")}
|
||||||
//style={{color: (this.state.actionState === SkipNoticeAction.CopyDownvote && this.state.editing == true) ? this.selectedColor : this.unselectedColor}}
|
style={{color: this.downvoteButtonColor(SkipNoticeAction.Downvote)}}
|
||||||
//style={{color: (this.state.editing == true) ? this.selectedColor : this.unselectedColor}}
|
|
||||||
onClick={() => this.prepAction(SkipNoticeAction.CopyDownvote)}>
|
onClick={() => this.prepAction(SkipNoticeAction.CopyDownvote)}>
|
||||||
{chrome.i18n.getMessage("CopyAndDownvote")}
|
{chrome.i18n.getMessage("CopyAndDownvote")}
|
||||||
</button>
|
</button>
|
||||||
@@ -315,7 +316,7 @@ class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeSta
|
|||||||
{/* Category Selector */}
|
{/* Category Selector */}
|
||||||
<select id={"sponsorTimeCategories" + this.idSuffix}
|
<select id={"sponsorTimeCategories" + this.idSuffix}
|
||||||
className="sponsorTimeCategories sponsorTimeEditSelector"
|
className="sponsorTimeCategories sponsorTimeEditSelector"
|
||||||
defaultValue={this.segments[0].category} //Just default to the first segment, as we don't know which they'll choose
|
defaultValue={this.segments[0].category}
|
||||||
ref={this.categoryOptionRef}>
|
ref={this.categoryOptionRef}>
|
||||||
|
|
||||||
{this.getCategoryOptions()}
|
{this.getCategoryOptions()}
|
||||||
@@ -366,27 +367,38 @@ class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeSta
|
|||||||
|
|
||||||
getSubmissionChooser(): JSX.Element[] {
|
getSubmissionChooser(): JSX.Element[] {
|
||||||
const elements: JSX.Element[] = [];
|
const elements: JSX.Element[] = [];
|
||||||
const isUpvote = this.state.actionState === SkipNoticeAction.Upvote;
|
|
||||||
const isDownvote = this.state.actionState == SkipNoticeAction.Downvote;
|
|
||||||
const isCopyDownvote = this.state.actionState == SkipNoticeAction.CopyDownvote;
|
|
||||||
for (let i = 0; i < this.segments.length; i++) {
|
for (let i = 0; i < this.segments.length; i++) {
|
||||||
const shouldBeGray: boolean= isUpvote && this.state.voted[i] == SkipNoticeAction.Upvote ||
|
|
||||||
isDownvote && this.state.voted[i] == SkipNoticeAction.Downvote ||
|
|
||||||
isCopyDownvote && this.state.copied[i] == SkipNoticeAction.CopyDownvote;
|
|
||||||
const opacity = shouldBeGray ? 0.35 : 1;
|
|
||||||
elements.push(
|
elements.push(
|
||||||
<button className="sponsorSkipObject sponsorSkipNoticeButton"
|
<button className="sponsorSkipObject sponsorSkipNoticeButton"
|
||||||
style={{opacity: opacity}}
|
style={{opacity: this.submissionChooserOpacitySelector(i),
|
||||||
|
color: this.submissionChooserColorSelector(i)}}
|
||||||
onClick={() => this.performAction(i)}
|
onClick={() => this.performAction(i)}
|
||||||
key={"submission" + i + this.segments[i].category + this.idSuffix}>
|
key={"submission" + i + this.segments[i].category + this.idSuffix}>
|
||||||
{(i + 1) + ". " + chrome.i18n.getMessage("category_" + this.segments[i].category)}
|
{(i + 1) + ". " + chrome.i18n.getMessage("category_" + this.segments[i].category)}
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return elements;
|
return elements;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
submissionChooserOpacitySelector(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;
|
||||||
|
}
|
||||||
|
|
||||||
|
submissionChooserColorSelector(index: number): string {
|
||||||
|
const isDownvote = this.state.actionState == SkipNoticeAction.Downvote;
|
||||||
|
const isCopyDownvote = this.state.actionState == SkipNoticeAction.CopyDownvote;
|
||||||
|
const shouldWarnUser: boolean = (isDownvote || isCopyDownvote)
|
||||||
|
&& this.segments[index].locked === true;
|
||||||
|
return (shouldWarnUser) ? this.lockedColor : this.unselectedColor;
|
||||||
|
}
|
||||||
|
|
||||||
onMouseEnter(): void {
|
onMouseEnter(): void {
|
||||||
if (this.state.smaller) {
|
if (this.state.smaller) {
|
||||||
this.setState({
|
this.setState({
|
||||||
@@ -541,19 +553,22 @@ class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeSta
|
|||||||
getCategoryOptions(): React.ReactElement[] {
|
getCategoryOptions(): React.ReactElement[] {
|
||||||
const elements = [];
|
const elements = [];
|
||||||
|
|
||||||
const categories = CompileConfig.categoryList.filter((cat => getCategoryActionType(cat as Category) === CategoryActionType.Skippable));
|
const categories = (CompileConfig.categoryList.filter((cat => getCategoryActionType(cat as Category) === CategoryActionType.Skippable))) as Category[];
|
||||||
for (const category of categories) {
|
for (const category of categories) {
|
||||||
elements.push(
|
elements.push(
|
||||||
<option value={category}
|
<option value={category}
|
||||||
key={category}>
|
key={category}>
|
||||||
{chrome.i18n.getMessage("category_" + category)}
|
{this.categoryVoteButtonLockIcon(category) + chrome.i18n.getMessage("category_" + category)}
|
||||||
</option>
|
</option>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return elements;
|
return elements;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
categoryVoteButtonLockIcon(category: Category): string {
|
||||||
|
return (this.contentContainer().lockedCategories.includes(category)) ? "🔒" : " ";
|
||||||
|
}
|
||||||
|
|
||||||
unskip(index: number): void {
|
unskip(index: number): void {
|
||||||
this.contentContainer().unskipSponsorTime(this.segments[index], this.props.unskipTime);
|
this.contentContainer().unskipSponsorTime(this.segments[index], this.props.unskipTime);
|
||||||
|
|
||||||
@@ -699,6 +714,16 @@ class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeSta
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
downvoteButtonColor(downvoteType: SkipNoticeAction): string {
|
||||||
|
// Also used for "Copy and Downvote"
|
||||||
|
if (this.segments.length > 1) {
|
||||||
|
return (this.state.actionState === downvoteType) ? this.selectedColor : this.unselectedColor;
|
||||||
|
} else {
|
||||||
|
// You dont have segment selectors so the lockbutton needs to be colored and cannot be selected.
|
||||||
|
return (this.segments[0].locked === true) ? this.lockedColor : this.unselectedColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private getUnskipText(): string {
|
private getUnskipText(): string {
|
||||||
switch (this.props.segments[0].actionType) {
|
switch (this.props.segments[0].actionType) {
|
||||||
case ActionType.Mute: {
|
case ActionType.Mute: {
|
||||||
|
|||||||
@@ -3,7 +3,9 @@ import { Category, CategorySelection, CategorySkipOption, NoticeVisbilityMode, P
|
|||||||
|
|
||||||
interface SBConfig {
|
interface SBConfig {
|
||||||
userID: string,
|
userID: string,
|
||||||
/** Contains unsubmitted segments that the user has created. */
|
isVip: boolean,
|
||||||
|
lastIsVipUpdate: number,
|
||||||
|
/* Contains unsubmitted segments that the user has created. */
|
||||||
segmentTimes: SBMap<string, SponsorTime[]>,
|
segmentTimes: SBMap<string, SponsorTime[]>,
|
||||||
defaultCategory: Category,
|
defaultCategory: Category,
|
||||||
whitelistedChannels: string[],
|
whitelistedChannels: string[],
|
||||||
@@ -153,6 +155,8 @@ const Config: SBObject = {
|
|||||||
configListeners: [],
|
configListeners: [],
|
||||||
defaults: {
|
defaults: {
|
||||||
userID: null,
|
userID: null,
|
||||||
|
isVip: false,
|
||||||
|
lastIsVipUpdate: 0,
|
||||||
segmentTimes: new SBMap("segmentTimes"),
|
segmentTimes: new SBMap("segmentTimes"),
|
||||||
defaultCategory: "chooseACategory" as Category,
|
defaultCategory: "chooseACategory" as Category,
|
||||||
whitelistedChannels: [],
|
whitelistedChannels: [],
|
||||||
@@ -214,7 +218,8 @@ const Config: SBObject = {
|
|||||||
|
|
||||||
colorPalette: new SBMap("colorPalette", [
|
colorPalette: new SBMap("colorPalette", [
|
||||||
["SponsorBlockRed", "#780303"],
|
["SponsorBlockRed", "#780303"],
|
||||||
["SponsorBlockWhite", "#ffffff"]
|
["SponsorBlockWhite", "#ffffff"],
|
||||||
|
["SponsorBlockLocked", "#ffc83d"]
|
||||||
]),
|
]),
|
||||||
|
|
||||||
// Preview bar
|
// Preview bar
|
||||||
|
|||||||
@@ -34,8 +34,10 @@ let lastPOISkip = 0;
|
|||||||
|
|
||||||
// JSON video info
|
// JSON video info
|
||||||
let videoInfo: VideoInfo = null;
|
let videoInfo: VideoInfo = null;
|
||||||
//the channel this video is about
|
// The channel this video is about
|
||||||
let channelIDInfo: ChannelIDInfo;
|
let channelIDInfo: ChannelIDInfo;
|
||||||
|
// Locked Categories in this tab, like: ["sponsor","intro","outro"]
|
||||||
|
let lockedCategories: Category[] = [];
|
||||||
|
|
||||||
// Skips are scheduled to ensure precision.
|
// Skips are scheduled to ensure precision.
|
||||||
// Skips are rescheduled every seeking event.
|
// Skips are rescheduled every seeking event.
|
||||||
@@ -121,7 +123,8 @@ const skipNoticeContentContainer: ContentContainer = () => ({
|
|||||||
updateEditButtonsOnPlayer,
|
updateEditButtonsOnPlayer,
|
||||||
previewTime,
|
previewTime,
|
||||||
videoInfo,
|
videoInfo,
|
||||||
getRealCurrentTime: getRealCurrentTime
|
getRealCurrentTime: getRealCurrentTime,
|
||||||
|
lockedCategories
|
||||||
});
|
});
|
||||||
|
|
||||||
// value determining when to count segment as skipped and send telemetry to server (percent based)
|
// value determining when to count segment as skipped and send telemetry to server (percent based)
|
||||||
@@ -752,6 +755,62 @@ async function sponsorsLookup(id: string, keepOldSubmissions = true) {
|
|||||||
|
|
||||||
sponsorLookupRetries++;
|
sponsorLookupRetries++;
|
||||||
}
|
}
|
||||||
|
// Look up locked status if the user is a vip
|
||||||
|
isVipLookup();
|
||||||
|
const isVip = Config.config.isVip;
|
||||||
|
if (isVip) {
|
||||||
|
lockedCategoriesLookup(id);
|
||||||
|
lockedSegmentsLookup()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function isVipLookup() {
|
||||||
|
const currentTime = Date.now();
|
||||||
|
const lastUpdate = Config.config.lastIsVipUpdate;
|
||||||
|
if (currentTime - lastUpdate > 1000*60*60*24) { //max every 24 hours 1000*60*60*24
|
||||||
|
Config.config.lastIsVipUpdate = currentTime;
|
||||||
|
utils.sendRequestToServer("GET", "/api/isUserVIP?userID=" + Config.config.userID,
|
||||||
|
(response) => {
|
||||||
|
if (response.status === 200 && response.ok) {
|
||||||
|
console.log(JSON.parse(response.responseText).vip);
|
||||||
|
console.log(Config.config.userID);
|
||||||
|
if (JSON.parse(response.responseText).vip === true) {
|
||||||
|
Config.config.isVip = true;
|
||||||
|
}
|
||||||
|
else Config.config.isVip = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function lockedSegmentsLookup() {
|
||||||
|
let url = ""
|
||||||
|
for (let i = 0; i < sponsorTimes.length; i++) {
|
||||||
|
if (i !== 0) url += ",";
|
||||||
|
url += `"` + sponsorTimes[i].UUID + `"`;
|
||||||
|
}
|
||||||
|
utils.sendRequestToServer("GET", "/api/segmentInfo?UUIDs=[" + url + "]",
|
||||||
|
(response) => {
|
||||||
|
if (response.status === 200 && response.ok) {
|
||||||
|
for (let i = 0; i < sponsorTimes.length && i < 10; i++) { //because the api only return 10 segments maximum
|
||||||
|
sponsorTimes[i].locked = (JSON.parse(response.responseText)[i].locked === 1) ? true : false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function lockedCategoriesLookup(id: string) {
|
||||||
|
utils.sendRequestToServer("GET", "/api/lockCategories?videoID=" + id,
|
||||||
|
(response) => {
|
||||||
|
if (response.status === 200 && response.ok) {
|
||||||
|
for (const category of JSON.parse(response.responseText).categories) {
|
||||||
|
lockedCategories.push(category);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function retryFetch(): void {
|
function retryFetch(): void {
|
||||||
|
|||||||
@@ -20,7 +20,8 @@ export interface ContentContainer {
|
|||||||
updateEditButtonsOnPlayer: () => void,
|
updateEditButtonsOnPlayer: () => void,
|
||||||
previewTime: (time: number, unpause?: boolean) => void,
|
previewTime: (time: number, unpause?: boolean) => void,
|
||||||
videoInfo: VideoInfo,
|
videoInfo: VideoInfo,
|
||||||
getRealCurrentTime: () => number
|
getRealCurrentTime: () => number,
|
||||||
|
lockedCategories: string[]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,6 +75,7 @@ export enum SponsorSourceType {
|
|||||||
export interface SponsorTime {
|
export interface SponsorTime {
|
||||||
segment: [number] | [number, number];
|
segment: [number] | [number, number];
|
||||||
UUID: SegmentUUID;
|
UUID: SegmentUUID;
|
||||||
|
locked?: boolean;
|
||||||
|
|
||||||
category: Category;
|
category: Category;
|
||||||
actionType: ActionType;
|
actionType: ActionType;
|
||||||
|
|||||||
Reference in New Issue
Block a user