/* eslint-disable react/no-danger */ import "./InformingPage.less"; import { ipcRenderer } from "electron"; import React, { useCallback, useEffect } from "react"; import { useDispatch, useSelector } from "react-redux"; import { useTranslation } from "react-i18next"; import { Button } from "antd"; import _ from "lodash"; import { clearNotification, newNotification, decrementCloseTimer, } from "./informingSlice"; import useInformingWebsocket from "./useInformingWebsocket"; import { useSendInformingMutation } from "../../apis/backendWs"; const isDev = process.env.NODE_ENV === "development"; const kInformingChannel = "informing"; const kInputEventChannel = "input-event"; export default function InformingPage() { const dispatch = useDispatch(); const { t } = useTranslation(); const { data } = useInformingWebsocket(); const [sendInforming, { data: sendData }] = useSendInformingMutation(); const nId = useSelector((state) => state.informing.notificationId); const content = useSelector((state) => state.informing.content); const closeDelay = useSelector((state) => state.informing.closeDelay); const closeTimer = useSelector((state) => state.informing.closeTimer); const isOverlay = useSelector((state) => state.informing.isOverlay); const title = useSelector((state) => state.informing.title); const needConfirmation = useSelector( (state) => state.informing.needConfirmation ); useEffect(() => { if (!_.isEmpty(data)) { dispatch(newNotification(data)); } }, [dispatch, data]); const informingHandler = useCallback( (_e, { event }) => { if (event === "hidden") dispatch(clearNotification()); }, [dispatch] ); useEffect(() => { document.title = ""; ipcRenderer.on(kInformingChannel, informingHandler); return function cleanup() { ipcRenderer.removeListener(kInputEventChannel, informingHandler); }; }, [informingHandler]); const inputHandler = useCallback( (_event, userId) => { if (userId && nId) { sendInforming({ type: "notification.confirm", notification_id: nId, user_id: userId, }); } }, [sendInforming, nId] ); useEffect(() => { ipcRenderer.invoke(kInformingChannel, { event: "set-closable", data: !needConfirmation || !isOverlay, }); if (needConfirmation) ipcRenderer.on(kInputEventChannel, inputHandler); return function cleanup() { if (needConfirmation) ipcRenderer.removeListener(kInputEventChannel, inputHandler); }; }, [inputHandler, needConfirmation, isOverlay]); useEffect(() => { if (title) document.title = title; else document.title = t("informing.defaultTitle"); }, [t, title]); useEffect(() => { if (sendData) { sendInforming(null); // reset sendData state dispatch(clearNotification()); } }, [dispatch, sendData, sendInforming]); useEffect(() => { let closeTimeout; let closeInterval; if (!content) window.close(); else { // show window ipcRenderer.invoke(kInformingChannel, { event: "show", data: { isOverlay }, }); // close timeout closeTimeout = setTimeout( () => dispatch(clearNotification()), closeDelay * 60 * 1000 ); // close timeout closeInterval = setInterval( () => dispatch(decrementCloseTimer(1)), 60 * 1000 ); } return function cleanup() { clearTimeout(closeTimeout); clearInterval(closeInterval); }; }, [dispatch, content, closeDelay, isOverlay]); return ( <div className={ isOverlay ? "informing-page overflow-hidden" : "informing-page" } > {content ? ( <> <div dangerouslySetInnerHTML={{ __html: content }} /> <div className="informing-page__footer"> {(() => { if (isOverlay) return ( <div className="informing-page__close-timer"> {t("informing.closeTimer", { closeTimer })} </div> ); if (needConfirmation) return ( <Button key="informing-page-close" className="informing-page__close-button" disabled > {typeof sendData === "boolean" && !sendData ? t("informing.closeConfirmButtonError") : t("informing.closeConfirmButton")} </Button> ); return ( <Button key="informing-page-close" className="informing-page__close-button" onClick={() => dispatch(clearNotification())} > {t("informing.closeButton")} </Button> ); })()} </div> </> ) : null} {isDev && !isOverlay ? ( <Button key="informing-page-devtools" className="devtools-button" onClick={() => ipcRenderer.invoke(kInformingChannel, { event: "open-devtools", }) } > Devtools </Button> ) : null} </div> ); }