diff --git a/src/App.js b/src/App.js index 9b9ab199..f95e6737 100755 --- a/src/App.js +++ b/src/App.js @@ -22,8 +22,9 @@ import CaptchaModal from './components/modals/CaptchaModal'; import { importAll } from './components/ImageBanner'; import preloadImages from './utils/preloadImages'; import useError from "./hooks/useError"; +import useInfo from "./hooks/useInfo"; import useSuccess from "./hooks/useSuccess"; - +import packageJson from '../package.json'; export default function App() { const { @@ -41,21 +42,48 @@ export default function App() { const [, setNewErrorMessage] = useError(); const [, setNewSuccessMessage] = useSuccess(); + const [, setNewInfoMessage] = useInfo(); useEffect(() => { const successToast = localStorage.getItem("successToast"); const errorToast = localStorage.getItem("errorToast"); + const infoToast = localStorage.getItem("infoToast"); if (successToast) { setNewSuccessMessage(successToast); localStorage.removeItem("successToast"); } else if (errorToast) { setNewErrorMessage(errorToast); localStorage.removeItem("errorToast"); + } else if (infoToast) { + setNewInfoMessage(infoToast); + localStorage.removeItem("infoToast"); } else { return; } - }, [setNewErrorMessage, setNewSuccessMessage]); + }, [setNewErrorMessage, setNewSuccessMessage, setNewInfoMessage]); + + + // check for new version + useEffect(() => { + const fetchVersionInfo = async () => { + try { + const packageRes = await fetch('https://raw.githubusercontent.com/plebbit/plebchan/master/package.json', { cache: 'no-cache' }); + const packageData = await packageRes.json(); + + if (packageJson.version !== packageData.version) { + const newVersionInfo = `New version available, plebchan v${packageData.version}. Refresh the page to update.`; + localStorage.setItem('infoToast', newVersionInfo);; + } + } catch (error) { + console.error('Failed to fetch latest version info:', error); + } + }; + + fetchVersionInfo(); + }, [setNewInfoMessage]); + + // preload banners useEffect(() => { diff --git a/src/hooks/useInfo.js b/src/hooks/useInfo.js new file mode 100644 index 00000000..6d400841 --- /dev/null +++ b/src/hooks/useInfo.js @@ -0,0 +1,43 @@ +import { useEffect, useState } from "react"; +import { toast } from "react-toastify"; + +const useInfo = () => { + const [infoMessage, setInfoMessage] = useState(''); + const [renderCount, setRenderCount] = useState(0); + + useEffect(() => { + if (infoMessage && infoMessage.length > 0) { + const showInfoToast = () => { + const toastId = toast.info(infoMessage.toString(), { + position: "top-right", + autoClose: false, + hideProgressBar: false, + closeOnClick: false, + pauseOnHover: false, + draggable: false, + progress: undefined, + theme: "dark", + }); + + return () => { + toast.dismiss(toastId); + }; + }; + + const timeoutId = setTimeout(showInfoToast, 500); + + return () => { + clearTimeout(timeoutId); + }; + } + }, [infoMessage, renderCount]); + + const setNewInfoMessage = (message) => { + setInfoMessage(message); + setRenderCount(prevCount => prevCount + 1); + }; + + return [infoMessage, setNewInfoMessage]; +}; + +export default useInfo; \ No newline at end of file