diff --git a/src/components/SkipNoticeComponent.tsx b/src/components/SkipNoticeComponent.tsx index 7ede17c5..7ce28d3a 100644 --- a/src/components/SkipNoticeComponent.tsx +++ b/src/components/SkipNoticeComponent.tsx @@ -1,6 +1,8 @@ import * as React from "react"; import Config from "../config" +import TimedNoticeComponent from "./TimedNoticeComponent"; + export interface SkipNoticeProps { UUID: string; manualSkip: boolean; @@ -12,6 +14,7 @@ export interface SkipNoticeState { noticeTitle: string, countdownTime: number, + maxCountdownTime: () => number; countdownText: string, unskipText: string, @@ -26,12 +29,13 @@ class SkipNoticeComponent extends React.Component number; - countdownInterval: NodeJS.Timeout; idSuffix: any; - constructor(props: SkipNoticeComponent) { + noticeRef: React.MutableRefObject; + + constructor(props: SkipNoticeProps) { super(props); + this.noticeRef = React.createRef(); this.UUID = props.UUID; this.manualSkip = props.manualSkip; @@ -43,10 +47,6 @@ class SkipNoticeComponent extends React.Component 4; - //the id for the setInterval running the countdown - this.countdownInterval = null; - //add notice this.amountOfPreviousNotices = document.getElementsByClassName("sponsorSkipNotice").length; @@ -65,7 +65,8 @@ class SkipNoticeComponent extends React.Component 4, + countdownTime: 4, countdownText: null, unskipText: chrome.i18n.getMessage("unskip"), @@ -73,10 +74,6 @@ class SkipNoticeComponent extends React.Component - - {/* First row */} - - {/* Left column */} - - {/* Logo */} - - - - - - {this.state.noticeTitle} - - - - {/* Right column */} - - - {/* Time left */} - - - {this.state.countdownText || (this.state.countdownTime + "s")} - - - {/* Close button */} - - - - - + + {/* Spacer */} @@ -182,65 +144,11 @@ class SkipNoticeComponent extends React.Component } - + + ); } - //called every second to lower the countdown before hiding the notice - countdown() { - let countdownTime = this.state.countdownTime - 1; - - if (countdownTime <= 0) { - //remove this from setInterval - clearInterval(this.countdownInterval); - - //time to close this notice - this.close(); - - return; - } - - if (countdownTime == 3) { - //start fade out animation - let notice = document.getElementById("sponsorSkipNotice" + this.idSuffix); - notice.style.removeProperty("animation"); - notice.classList.add("sponsorSkipNoticeFadeOut"); - } - - this.setState({ - countdownTime - }) - } - - pauseCountdown() { - //remove setInterval - clearInterval(this.countdownInterval); - this.countdownInterval = null; - - //reset countdown and inform the user - this.setState({ - countdownTime: this.maxCountdownTime(), - countdownText: chrome.i18n.getMessage("paused") - }); - - //remove the fade out class if it exists - let notice = document.getElementById("sponsorSkipNotice" + this.idSuffix); - notice.classList.remove("sponsorSkipNoticeFadeOut"); - notice.style.animation = "none"; - } - - startCountdown() { - //if it has already started, don't start it again - if (this.countdownInterval !== null) return; - - this.setState({ - countdownTime: this.maxCountdownTime(), - countdownText: null - }); - - this.countdownInterval = setInterval(this.countdown.bind(this), 1000); - } - unskip() { this.contentContainer().unskipSponsorTime(this.UUID); @@ -255,40 +163,41 @@ class SkipNoticeComponent extends React.Component { + this.noticeRef.current.resetCountdown(); }); } reskip() { this.contentContainer().reskipSponsorTime(this.UUID); - //setup new callback - this.setState({ - unskipText: chrome.i18n.getMessage("unskip"), - unskipCallback: this.unskip.bind(this) - }); - - //reset duration - this.maxCountdownTime = () => 4; - //reset countdown this.setState({ - countdownTime: this.maxCountdownTime() + unskipText: chrome.i18n.getMessage("unskip"), + unskipCallback: this.unskip.bind(this), + + maxCountdownTime: () => 4, + countdownTime: 4 }); // See if the title should be changed if (this.manualSkip) { - this.changeNoticeTitle(chrome.i18n.getMessage("noticeTitle")); + this.setState({ + noticeTitle: chrome.i18n.getMessage("noticeTitle") + }); if(Config.config.autoUpvote) this.contentContainer().vote(1, this.UUID); } @@ -313,12 +222,6 @@ class SkipNoticeComponent extends React.Component number, + amountOfPreviousNotices?: number, + idSuffix: string +} + +export interface TimedNoticeState { + noticeTitle: string, + + countdownTime: number, + countdownText: string, +} + +class TimedNoticeComponent extends React.Component { + countdownInterval: NodeJS.Timeout; + idSuffix: any; + + amountOfPreviousNotices: number; + + constructor(props: TimedNoticeProps) { + super(props); + + if (props.maxCountdownTime === undefined) props.maxCountdownTime = () => 4; + + //the id for the setInterval running the countdown + this.countdownInterval = null; + + this.amountOfPreviousNotices = props.amountOfPreviousNotices || 0; + + this.idSuffix = props.idSuffix; + + // Setup state + this.state = { + noticeTitle: props.noticeTitle, + + //the countdown until this notice closes + countdownTime: props.maxCountdownTime(), + countdownText: null, + } + } + + componentDidMount() { + this.startCountdown(); + } + + // forwardRef(props, ref) { + + // } + + render() { + let noticeStyle: React.CSSProperties = { + zIndex: 50 + this.amountOfPreviousNotices + } + + return ( + + + {/* First row */} + + {/* Left column */} + + + {/* Right column */} + + + + {this.props.children} + +
+ {/* Logo */} + + + + + + {this.state.noticeTitle} + + + + {/* Time left */} + + + {this.state.countdownText || (this.state.countdownTime + "s")} + + + {/* Close button */} + + +
+ ); + } + + //called every second to lower the countdown before hiding the notice + countdown() { + let countdownTime = this.state.countdownTime - 1; + + if (countdownTime <= 0) { + //remove this from setInterval + clearInterval(this.countdownInterval); + + //time to close this notice + this.close(); + + return; + } + + if (countdownTime == 3) { + //start fade out animation + let notice = document.getElementById("sponsorSkipNotice" + this.idSuffix); + notice.style.removeProperty("animation"); + notice.classList.add("sponsorSkipNoticeFadeOut"); + } + + this.setState({ + countdownTime + }) + } + + pauseCountdown() { + //remove setInterval + clearInterval(this.countdownInterval); + this.countdownInterval = null; + + //reset countdown and inform the user + this.setState({ + countdownTime: this.props.maxCountdownTime(), + countdownText: chrome.i18n.getMessage("paused") + }); + + //remove the fade out class if it exists + let notice = document.getElementById("sponsorSkipNotice" + this.idSuffix); + notice.classList.remove("sponsorSkipNoticeFadeOut"); + notice.style.animation = "none"; + } + + startCountdown() { + //if it has already started, don't start it again + if (this.countdownInterval !== null) return; + + this.setState({ + countdownTime: this.props.maxCountdownTime(), + countdownText: null + }); + + this.countdownInterval = setInterval(this.countdown.bind(this), 1000); + } + + resetCountdown() { + this.setState({ + countdownTime: this.props.maxCountdownTime(), + countdownText: null + }); + } + + //close this notice + close() { + //TODO: Change to a listener in the renderer (not component) + let notice = document.getElementById("sponsorSkipNotice" + this.idSuffix); + if (notice != null) { + notice.remove(); + } + + //remove setInterval + if (this.countdownInterval !== null) clearInterval(this.countdownInterval); + } + + changeNoticeTitle(title) { + this.setState({ + noticeTitle: title + }); + } + + addNoticeInfoMessage(message: string, message2: string = "") { + //TODO: Replace + + let 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"); + if (previousInfoMessage2 != null) { + //remove it + document.getElementById("sponsorSkipNotice" + this.idSuffix).removeChild(previousInfoMessage2); + } + + //add info + let thanksForVotingText = document.createElement("p"); + thanksForVotingText.id = "sponsorTimesInfoMessage" + this.idSuffix; + thanksForVotingText.className = "sponsorTimesInfoMessage"; + thanksForVotingText.innerText = message; + + //add element to div + document.querySelector("#sponsorSkipNotice" + this.idSuffix + " > tbody").insertBefore(thanksForVotingText, document.getElementById("sponsorSkipNoticeSpacer" + this.idSuffix)); + + if (message2 !== undefined) { + let thanksForVotingText2 = document.createElement("p"); + thanksForVotingText2.id = "sponsorTimesInfoMessage" + this.idSuffix + "2"; + thanksForVotingText2.className = "sponsorTimesInfoMessage"; + thanksForVotingText2.innerText = message2; + + //add element to div + document.querySelector("#sponsorSkipNotice" + this.idSuffix + " > tbody").insertBefore(thanksForVotingText2, document.getElementById("sponsorSkipNoticeSpacer" + this.idSuffix)); + } + } +} + +export default TimedNoticeComponent; \ No newline at end of file