import * as React from "react"; import Config from "../config" import { ContentContainer } from "../types"; import NoticeComponent from "./NoticeComponent"; import NoticeTextSelectionComponent from "./NoticeTextSectionComponent"; import SponsorTimeEditComponent from "./SponsorTimeEditComponent"; export interface SubmissionNoticeProps { // Contains functions and variables from the content script needed by the skip notice contentContainer: ContentContainer; callback: () => unknown; closeListener: () => void } export interface SubmissionNoticeeState { noticeTitle: string, messages: string[], idSuffix: string; } class SubmissionNoticeComponent extends React.Component { // Contains functions and variables from the content script needed by the skip notice contentContainer: ContentContainer; callback: () => unknown; noticeRef: React.MutableRefObject; timeEditRefs: React.RefObject[]; videoObserver: MutationObserver; constructor(props: SubmissionNoticeProps) { super(props); this.noticeRef = React.createRef(); this.contentContainer = props.contentContainer; this.callback = props.callback; const noticeTitle = chrome.i18n.getMessage("confirmNoticeTitle"); // Setup state this.state = { noticeTitle, messages: [], idSuffix: "SubmissionNotice" } } 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 ( {/* Text Boxes */} {this.getMessageBoxes()} {/* Sponsor Time List */} {this.getSponsorTimeMessages()} {/* Last Row */} {/* Guidelines button */} {/* Submit Button */} ); } getSponsorTimeMessages(): JSX.Element[] | JSX.Element { const elements: JSX.Element[] = []; this.timeEditRefs = []; const sponsorTimes = this.props.contentContainer().sponsorTimesSubmitting; for (let i = 0; i < sponsorTimes.length; i++) { const timeRef = React.createRef(); elements.push( ); this.timeEditRefs.push(timeRef); } return elements; } getMessageBoxes(): JSX.Element[] | JSX.Element { const elements: JSX.Element[] = []; for (let i = 0; i < this.state.messages.length; i++) { elements.push( ); } return elements; } cancel(): void { this.noticeRef.current.close(true); this.contentContainer().resetSponsorSubmissionNotice(); this.props.closeListener(); } 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;