diff options
-rw-r--r-- | manifest/manifest.json | 2 | ||||
-rw-r--r-- | public/_locales/en/messages.json | 5 | ||||
-rw-r--r-- | public/content.css | 7 | ||||
-rw-r--r-- | src/components/NoticeComponent.tsx | 10 | ||||
-rw-r--r-- | src/components/SkipNoticeComponent.tsx | 5 | ||||
-rw-r--r-- | src/components/SponsorTimeEditComponent.tsx | 38 | ||||
-rw-r--r-- | src/components/SubmissionNoticeComponent.tsx | 30 | ||||
-rw-r--r-- | src/content.ts | 413 | ||||
-rw-r--r-- | src/render/SkipNotice.tsx | 21 | ||||
-rw-r--r-- | src/render/SubmissionNotice.tsx | 19 |
10 files changed, 231 insertions, 319 deletions
diff --git a/manifest/manifest.json b/manifest/manifest.json index a72a4819..8830c74a 100644 --- a/manifest/manifest.json +++ b/manifest/manifest.json @@ -1,7 +1,7 @@ { "name": "__MSG_fullName__", "short_name": "__MSG_Name__", - "version": "1.2.25", + "version": "1.2.26", "default_locale": "en", "description": "__MSG_Description__", "content_scripts": [{ diff --git a/public/_locales/en/messages.json b/public/_locales/en/messages.json index 63d35ae4..fa721e16 100644 --- a/public/_locales/en/messages.json +++ b/public/_locales/en/messages.json @@ -515,7 +515,7 @@ "message": "Manual Skip" }, "showOverlay": { - "message": "Show Overlay On Player" + "message": "Show In Seek Bar" }, "enableTestingServer": { "message": "Enable Beta Testing Server" @@ -528,5 +528,8 @@ }, "bracketNow": { "message": "(Now)" + }, + "moreCategories": { + "message": "More Categories" } } diff --git a/public/content.css b/public/content.css index 5d65f788..24d8b9ac 100644 --- a/public/content.css +++ b/public/content.css @@ -338,6 +338,13 @@ input::-webkit-inner-spin-button { margin: 0; } +.sponsorTimeMessagesRow { + max-height: 300px; + display: flex; + + overflow: auto; +} + .sponsorTimeEdit { font-size: 14px; diff --git a/src/components/NoticeComponent.tsx b/src/components/NoticeComponent.tsx index d554f85d..b7ff8adf 100644 --- a/src/components/NoticeComponent.tsx +++ b/src/components/NoticeComponent.tsx @@ -11,7 +11,7 @@ export interface NoticeProps { fadeIn?: boolean, // Callback for when this is closed - closeListener?: () => void, + closeListener: () => void, zIndex?: number } @@ -195,16 +195,10 @@ class NoticeComponent extends React.Component<NoticeProps, NoticeState> { * @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(); - } - //remove setInterval if (this.countdownInterval !== null) clearInterval(this.countdownInterval); - if (this.props.closeListener && !silent) this.props.closeListener(); + if (!silent) this.props.closeListener(); } changeNoticeTitle(title) { diff --git a/src/components/SkipNoticeComponent.tsx b/src/components/SkipNoticeComponent.tsx index 07572de6..08d817e6 100644 --- a/src/components/SkipNoticeComponent.tsx +++ b/src/components/SkipNoticeComponent.tsx @@ -14,6 +14,8 @@ export interface SkipNoticeProps { autoSkip: boolean; // Contains functions and variables from the content script needed by the skip notice contentContainer: ContentContainer; + + closeListener: () => void } export interface SkipNoticeState { @@ -112,7 +114,8 @@ class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeSta fadeIn={true} timed={true} maxCountdownTime={this.state.maxCountdownTime} - ref={this.noticeRef}> + ref={this.noticeRef} + closeListener={this.props.closeListener}> {(Config.config.audioNotificationOnSkip) && <audio ref={(source) => { this.audio = source; }}> <source src={chrome.extension.getURL("icons/beep.ogg")} type="audio/ogg"></source> diff --git a/src/components/SponsorTimeEditComponent.tsx b/src/components/SponsorTimeEditComponent.tsx index 0235179f..42840405 100644 --- a/src/components/SponsorTimeEditComponent.tsx +++ b/src/components/SponsorTimeEditComponent.tsx @@ -154,7 +154,7 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo className="sponsorTimeCategories" defaultValue={sponsorTime.category} ref={this.categoryOptionRef} - onChange={this.saveEditTimes.bind(this)}> + onChange={this.categorySelectionChange.bind(this)}> {this.getCategoryOptions()} </select> @@ -190,13 +190,21 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo getCategoryOptions() { let elements = []; - //TODO: Remove this when testing server is not needed - let categoryList = Config.config.testingServer ? CompileConfig.categoryList : ["sponsor"]; - for (const category of categoryList) { + for (const category of Config.config.categorySelections) { elements.push( - <option value={category} - key={category}> - {chrome.i18n.getMessage("category_" + category)} + <option value={category.name} + key={category.name}> + {chrome.i18n.getMessage("category_" + category.name)} + </option> + ); + } + + if (elements.length < CompileConfig.categoryList.length) { + // Add show more button + elements.push( + <option value={"moreCategories"} + key={"moreCategories"}> + {chrome.i18n.getMessage("moreCategories")} </option> ); } @@ -204,6 +212,20 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo return elements; } + categorySelectionChange(event: React.ChangeEvent<HTMLSelectElement>) { + // See if show more categories was pressed + if (event.target.value === "moreCategories") { + // Open options page + chrome.runtime.sendMessage({"message": "openConfig"}); + + // Reset option to previous + event.target.value = this.props.contentContainer().sponsorTimesSubmitting[this.props.index].category; + return; + } + + this.saveEditTimes(); + } + setTimeToNow(index: number) { let sponsorTime = this.props.contentContainer().sponsorTimesSubmitting[this.props.index]; @@ -259,7 +281,7 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo let sponsorTimes = this.props.contentContainer().sponsorTimesSubmitting; let index = this.props.index; - let skipTime = sponsorTimes[index][0]; + let skipTime = sponsorTimes[index].segment[0]; if (this.state.editing) { // Save edits before previewing diff --git a/src/components/SubmissionNoticeComponent.tsx b/src/components/SubmissionNoticeComponent.tsx index f35a458b..a9943479 100644 --- a/src/components/SubmissionNoticeComponent.tsx +++ b/src/components/SubmissionNoticeComponent.tsx @@ -11,6 +11,8 @@ export interface SubmissionNoticeProps { contentContainer: ContentContainer; callback: () => any; + + closeListener: () => void } export interface SubmissionNoticeeState { @@ -28,6 +30,8 @@ class SubmissionNoticeComponent extends React.Component<SubmissionNoticeProps, S noticeRef: React.MutableRefObject<NoticeComponent>; timeEditRefs: React.RefObject<SponsorTimeEditComponent>[]; + videoObserver: MutationObserver; + constructor(props: SubmissionNoticeProps) { super(props); this.noticeRef = React.createRef(); @@ -45,6 +49,24 @@ class SubmissionNoticeComponent extends React.Component<SubmissionNoticeProps, S } } + componentDidMount() { + // 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() { + if (this.videoObserver) { + this.videoObserver.disconnect(); + } + } + render() { return ( <NoticeComponent noticeTitle={this.state.noticeTitle} @@ -57,8 +79,10 @@ class SubmissionNoticeComponent extends React.Component<SubmissionNoticeProps, S {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> @@ -133,6 +157,8 @@ class SubmissionNoticeComponent extends React.Component<SubmissionNoticeProps, S this.noticeRef.current.close(true); this.contentContainer().resetSponsorSubmissionNotice(); + + this.props.closeListener(); } submit() { diff --git a/src/content.ts b/src/content.ts index 573dc071..09fca172 100644 --- a/src/content.ts +++ b/src/content.ts @@ -593,239 +593,122 @@ function sponsorsLookup(id: string, channelIDPromise?) { //check database for sponsor times //made true once a setTimeout has been created to try again after a server error let recheckStarted = false; - if (Config.config.testingServer) { - // Create categories list - let categories: string[] = []; - for (const categorySelection of Config.config.categorySelections) { - categories.push(categorySelection.name); - } + // Create categories list + let categories: string[] = []; + for (const categorySelection of Config.config.categorySelections) { + categories.push(categorySelection.name); + } - utils.asyncRequestToServer('GET', "/api/skipSegments", { - videoID: id, - categories - }).then(async (response: Response) => { - if (response.status === 200) { - let recievedSegments: SponsorTime[] = await response.json(); - if (!recievedSegments.length) { - console.error("[SponsorBlock] Server returned malformed response: " + JSON.stringify(recievedSegments)); - return; + utils.asyncRequestToServer('GET', "/api/skipSegments", { + videoID: id, + categories + }).then(async (response: Response) => { + if (response.status === 200) { + let recievedSegments: SponsorTime[] = await response.json(); + if (!recievedSegments.length) { + console.error("[SponsorBlock] Server returned malformed response: " + JSON.stringify(recievedSegments)); + return; + } + + sponsorDataFound = true; + + // Check if any old submissions should be kept + if (sponsorTimes !== null) { + for (let i = 0; i < sponsorTimes.length; i++) { + if (sponsorTimes[i].UUID === null) { + // This is a user submission, keep it + recievedSegments.push(sponsorTimes[i]); + } } + } - sponsorDataFound = true; - - // Check if any old submissions should be kept - if (sponsorTimes !== null) { - for (let i = 0; i < sponsorTimes.length; i++) { - if (sponsorTimes[i].UUID === null) { - // This is a user submission, keep it - recievedSegments.push(sponsorTimes[i]); - } + sponsorTimes = recievedSegments; + + // Remove all submissions smaller than the minimum duration + if (Config.config.minDuration !== 0) { + let smallSegments: SponsorTime[] = []; + + for (let i = 0; i < sponsorTimes.length; i++) { + if (sponsorTimes[i].segment[1] - sponsorTimes[i].segment[0] >= Config.config.minDuration) { + smallSegments.push(sponsorTimes[i]); } } - sponsorTimes = recievedSegments; - - // Remove all submissions smaller than the minimum duration - if (Config.config.minDuration !== 0) { - let smallSegments: SponsorTime[] = []; - - for (let i = 0; i < sponsorTimes.length; i++) { - if (sponsorTimes[i].segment[1] - sponsorTimes[i].segment[0] >= Config.config.minDuration) { - smallSegments.push(sponsorTimes[i]); - } + sponsorTimes = smallSegments; + } + + if (!switchingVideos) { + // See if there are any starting sponsors + let startingSponsor: number = -1; + for (const time of sponsorTimes) { + if (time[0] <= video.currentTime && time.segment[0] > startingSponsor && time.segment[1] > video.currentTime) { + startingSponsor = time.segment[0]; + break; } - - sponsorTimes = smallSegments; } - - if (!switchingVideos) { - // See if there are any starting sponsors - let startingSponsor: number = -1; - for (const time of sponsorTimes) { - if (time[0] <= video.currentTime && time.segment[0] > startingSponsor && time.segment[1] > video.currentTime) { + if (!startingSponsor) { + for (const time of sponsorTimesSubmitting) { + if (time.segment[0] <= video.currentTime && time.segment[0] > startingSponsor && time.segment[1] > video.currentTime) { startingSponsor = time.segment[0]; break; } } - if (!startingSponsor) { - for (const time of sponsorTimesSubmitting) { - if (time.segment[0] <= video.currentTime && time.segment[0] > startingSponsor && time.segment[1] > video.currentTime) { - startingSponsor = time.segment[0]; - break; - } - } - } - - if (startingSponsor !== -1) { - startSponsorSchedule(false, startingSponsor); - } else { - startSponsorSchedule(); - } } - - // Reset skip save - sponsorSkipped = []; - - //update the preview bar - //leave the type blank for now until categories are added - if (lastPreviewBarUpdate == id || (lastPreviewBarUpdate == null && !isNaN(video.duration))) { - //set it now - //otherwise the listener can handle it - updatePreviewBar(); + + if (startingSponsor !== -1) { + startSponsorSchedule(false, startingSponsor); + } else { + startSponsorSchedule(); } - - sponsorLookupRetries = 0; - } else if (response.status === 404) { - sponsorDataFound = false; - - //check if this video was uploaded recently - //use the invidious api to get the time published - sendRequestToCustomServer('GET', "https://www.youtube.com/get_video_info?video_id=" + id, function(xmlhttp, error) { - if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { - let decodedData = decodeURIComponent(xmlhttp.responseText).match(/player_response=([^&]*)/)[1]; - - if (decodedData === undefined) { - console.error("[SB] Failed at getting video upload date info from YouTube."); - return; - } + } - let dateUploaded = JSON.parse(decodedData).microformat.playerMicroformatRenderer.uploadDate; + // Reset skip save + sponsorSkipped = []; - //if less than 3 days old - if (Date.now() - new Date(dateUploaded).getTime() < 259200000) { - //TODO lower when server becomes better - setTimeout(() => sponsorsLookup(id, channelIDPromise), 180000); - } - } - }); + //update the preview bar + //leave the type blank for now until categories are added + if (lastPreviewBarUpdate == id || (lastPreviewBarUpdate == null && !isNaN(video.duration))) { + //set it now + //otherwise the listener can handle it + updatePreviewBar(); + } - sponsorLookupRetries = 0; - } else if (sponsorLookupRetries < 90 && !recheckStarted) { - recheckStarted = true; + sponsorLookupRetries = 0; + } else if (response.status === 404) { + sponsorDataFound = false; - //TODO lower when server becomes better (back to 1 second) - //some error occurred, try again in a second - setTimeout(() => sponsorsLookup(id, channelIDPromise), 10000); + //check if this video was uploaded recently + //use the invidious api to get the time published + sendRequestToCustomServer('GET', "https://www.youtube.com/get_video_info?video_id=" + id, function(xmlhttp, error) { + if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { + let decodedData = decodeURIComponent(xmlhttp.responseText).match(/player_response=([^&]*)/)[1]; - sponsorLookupRetries++; - } - }); - } else { - utils.sendRequestToServer('GET', "/api/getVideoSponsorTimes?videoID=" + id, function(xmlhttp) { - if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { - sponsorDataFound = true; - - let recievedSegments: number[][] = JSON.parse(xmlhttp.responseText).sponsorTimes; - let recievedUUIDs: string[] = JSON.parse(xmlhttp.responseText).UUIDs; - - // Check if any old submissions should be kept - if (sponsorTimes !== null) { - for (let i = 0; i < sponsorTimes.length; i++) { - if (sponsorTimes[i].UUID === null) { - // This is a user submission, keep it - recievedSegments.push(sponsorTimes[i].segment); - } - } - } - - // Create formatted array - sponsorTimes = []; - for (let i = 0; i < recievedSegments.length; i++) { - sponsorTimes.push({ - segment: recievedSegments[i], - UUID: recievedUUIDs[i], - // Force sponsor category for now - //TODO: Remove this - category: "sponsor" - }); - } - - // Remove all submissions smaller than the minimum duration - if (Config.config.minDuration !== 0) { - let smallSegments: SponsorTime[] = []; - - for (let i = 0; i < sponsorTimes.length; i++) { - if (sponsorTimes[i].segment[1] - sponsorTimes[i].segment[0] >= Config.config.minDuration) { - smallSegments.push(sponsorTimes[i]); - } - } - - sponsorTimes = smallSegments; - } - - if (!switchingVideos) { - // See if there are any starting sponsors - let startingSponsor: number = -1; - for (const time of sponsorTimes) { - if (time[0] <= video.currentTime && time.segment[0] > startingSponsor && time.segment[1] > video.currentTime) { - startingSponsor = time.segment[0]; - break; - } - } - if (!startingSponsor) { - for (const time of sponsorTimesSubmitting) { - if (time.segment[0] <= video.currentTime && time.segment[0] > startingSponsor && time.segment[1] > video.currentTime) { - startingSponsor = time.segment[0]; - break; - } - } + if (decodedData === undefined) { + console.error("[SB] Failed at getting video upload date info from YouTube."); + return; } - - if (startingSponsor !== -1) { - startSponsorSchedule(false, startingSponsor); - } else { - startSponsorSchedule(); + + let dateUploaded = JSON.parse(decodedData).microformat.playerMicroformatRenderer.uploadDate; + + //if less than 3 days old + if (Date.now() - new Date(dateUploaded).getTime() < 259200000) { + //TODO lower when server becomes better + setTimeout(() => sponsorsLookup(id, channelIDPromise), 180000); } } - - // Reset skip save - sponsorSkipped = []; - - //update the preview bar - //leave the type blank for now until categories are added - if (lastPreviewBarUpdate == id || (lastPreviewBarUpdate == null && !isNaN(video.duration))) { - //set it now - //otherwise the listener can handle it - updatePreviewBar(); - } - - sponsorLookupRetries = 0; - } else if (xmlhttp.readyState == 4 && xmlhttp.status == 404) { - sponsorDataFound = false; - - //check if this video was uploaded recently - //use the invidious api to get the time published - sendRequestToCustomServer('GET', "https://www.youtube.com/get_video_info?video_id=" + id, function(xmlhttp, error) { - if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { - let decodedData = decodeURIComponent(xmlhttp.responseText).match(/player_response=([^&]*)/)[1]; - - if (decodedData === undefined) { - console.error("[SB] Failed at getting video upload date info from YouTube."); - return; - } - - let dateUploaded = JSON.parse(decodedData).microformat.playerMicroformatRenderer.uploadDate; - - //if less than 3 days old - if (Date.now() - new Date(dateUploaded).getTime() < 259200000) { - //TODO lower when server becomes better - setTimeout(() => sponsorsLookup(id, channelIDPromise), 180000); - } - } - }); - - sponsorLookupRetries = 0; - } else if (xmlhttp.readyState == 4 && sponsorLookupRetries < 90 && !recheckStarted) { - recheckStarted = true; - - //TODO lower when server becomes better (back to 1 second) - //some error occurred, try again in a second - setTimeout(() => sponsorsLookup(id, channelIDPromise), 10000); - - sponsorLookupRetries++; - } - }); - } + }); + + sponsorLookupRetries = 0; + } else if (sponsorLookupRetries < 90 && !recheckStarted) { + recheckStarted = true; + + //TODO lower when server becomes better (back to 1 second) + //some error occurred, try again in a second + setTimeout(() => sponsorsLookup(id, channelIDPromise), 10000); + + sponsorLookupRetries++; + } + }); } function getYouTubeVideoID(url: string) { @@ -1577,92 +1460,46 @@ async function sendSubmitMessage(){ } } - if (Config.config.testingServer) { - let response = await utils.asyncRequestToServer("POST", "/api/skipSegments", { - videoID: sponsorVideoID, - userID: Config.config.userID, - segments: sponsorTimesSubmitting - }); - - if (response.status === 200) { - //hide loading message - let submitButton = document.getElementById("submitButton"); - submitButton.style.animation = "rotate 1s"; - //finish this animation - //when the animation is over, hide the button - let animationEndListener = function() { - changeStartSponsorButton(true, false); - - submitButton.style.animation = "none"; + let response = await utils.asyncRequestToServer("POST", "/api/skipSegments", { + videoID: sponsorVideoID, + userID: Config.config.userID, + segments: sponsorTimesSubmitting + }); - submitButton.removeEventListener("animationend", animationEndListener); - }; + if (response.status === 200) { + //hide loading message + let submitButton = document.getElementById("submitButton"); + submitButton.style.animation = "rotate 1s"; + //finish this animation + //when the animation is over, hide the button + let animationEndListener = function() { + changeStartSponsorButton(true, false); - submitButton.addEventListener("animationend", animationEndListener); + submitButton.style.animation = "none"; - //clear the sponsor times - Config.config.sponsorTimes.delete(sponsorVideoID); + submitButton.removeEventListener("animationend", animationEndListener); + }; - //add submissions to current sponsors list - if (sponsorTimes === null) sponsorTimes = []; - - sponsorTimes = sponsorTimes.concat(sponsorTimesSubmitting); + submitButton.addEventListener("animationend", animationEndListener); - // Empty the submitting times - sponsorTimesSubmitting = []; + //clear the sponsor times + Config.config.sponsorTimes.delete(sponsorVideoID); - updatePreviewBar(); - } else { - //show that the upload failed - document.getElementById("submitButton").style.animation = "unset"; - (<HTMLImageElement> document.getElementById("submitImage")).src = chrome.extension.getURL("icons/PlayerUploadFailedIconSponsorBlocker256px.png"); + //add submissions to current sponsors list + if (sponsorTimes === null) sponsorTimes = []; + + sponsorTimes = sponsorTimes.concat(sponsorTimesSubmitting); - alert(utils.getErrorMessage(response.status) + "\n\n" + (await response.text())); - } + // Empty the submitting times + sponsorTimesSubmitting = []; + updatePreviewBar(); } else { - chrome.runtime.sendMessage({ - message: "submitTimes", - videoID: sponsorVideoID - }, function(response) { - if (response != undefined) { - if (response.statusCode == 200) { - //hide loading message - let submitButton = document.getElementById("submitButton"); - submitButton.style.animation = "rotate 1s"; - //finish this animation - //when the animation is over, hide the button - let animationEndListener = function() { - changeStartSponsorButton(true, false); - - submitButton.style.animation = "none"; - - submitButton.removeEventListener("animationend", animationEndListener); - }; - - submitButton.addEventListener("animationend", animationEndListener); - - //clear the sponsor times - Config.config.sponsorTimes.delete(sponsorVideoID); - - //add submissions to current sponsors list - if (sponsorTimes === null) sponsorTimes = []; - - sponsorTimes = sponsorTimes.concat(sponsorTimesSubmitting); - - // Empty the submitting times - sponsorTimesSubmitting = []; - - updatePreviewBar(); - } else { - //show that the upload failed - document.getElementById("submitButton").style.animation = "unset"; - (<HTMLImageElement> document.getElementById("submitImage")).src = chrome.extension.getURL("icons/PlayerUploadFailedIconSponsorBlocker256px.png"); - - alert(utils.getErrorMessage(response.statusCode) + "\n\n" + response.responseText); - } - } - }); + //show that the upload failed + document.getElementById("submitButton").style.animation = "unset"; + (<HTMLImageElement> document.getElementById("submitImage")).src = chrome.extension.getURL("icons/PlayerUploadFailedIconSponsorBlocker256px.png"); + + alert(utils.getErrorMessage(response.status) + "\n\n" + (await response.text())); } } diff --git a/src/render/SkipNotice.tsx b/src/render/SkipNotice.tsx index 2322cadf..49265fb8 100644 --- a/src/render/SkipNotice.tsx +++ b/src/render/SkipNotice.tsx @@ -9,6 +9,8 @@ class SkipNotice { // Contains functions and variables from the content script needed by the skip notice contentContainer: () => any; + noticeElement: HTMLDivElement; + constructor(UUID: string, autoSkip: boolean = false, contentContainer) { this.UUID = UUID; this.autoSkip = autoSkip; @@ -35,16 +37,25 @@ class SkipNotice { //this is the suffix added at the end of every id let idSuffix = this.UUID + amountOfPreviousNotices; - let noticeElement = document.createElement("div"); - noticeElement.id = "sponsorSkipNoticeContainer" + idSuffix; + this.noticeElement = document.createElement("div"); + this.noticeElement.id = "sponsorSkipNoticeContainer" + idSuffix; - referenceNode.prepend(noticeElement); + referenceNode.prepend(this.noticeElement); ReactDOM.render( - <SkipNoticeComponent UUID={UUID} autoSkip={autoSkip} contentContainer={contentContainer} />, - noticeElement + <SkipNoticeComponent UUID={UUID} + autoSkip={autoSkip} + contentContainer={contentContainer} + closeListener={() => this.close()} />, + this.noticeElement ); } + + close() { + ReactDOM.unmountComponentAtNode(this.noticeElement); + + this.noticeElement.remove(); + } } export default SkipNotice;
\ No newline at end of file diff --git a/src/render/SubmissionNotice.tsx b/src/render/SubmissionNotice.tsx index bebed3e2..71f4c1e7 100644 --- a/src/render/SubmissionNotice.tsx +++ b/src/render/SubmissionNotice.tsx @@ -11,6 +11,8 @@ class SubmissionNotice { noticeRef: React.MutableRefObject<SubmissionNoticeComponent>; + noticeElement: HTMLDivElement; + constructor(contentContainer: () => any, callback: () => any) { this.noticeRef = React.createRef(); @@ -34,23 +36,30 @@ class SubmissionNotice { } } - let noticeElement = document.createElement("div"); - noticeElement.id = "submissionNoticeContainer"; + this.noticeElement = document.createElement("div"); + this.noticeElement.id = "submissionNoticeContainer"; - referenceNode.prepend(noticeElement); + referenceNode.prepend(this.noticeElement); ReactDOM.render( <SubmissionNoticeComponent contentContainer={contentContainer} callback={callback} - ref={this.noticeRef} />, - noticeElement + ref={this.noticeRef} + closeListener={() => this.close()} />, + this.noticeElement ); } update() { this.noticeRef.current.forceUpdate(); } + + close() { + ReactDOM.unmountComponentAtNode(this.noticeElement); + + this.noticeElement.remove(); + } } export default SubmissionNotice;
\ No newline at end of file |