Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | import { Alert as MuiAlert } from "@mui/material"; import { usePersistedState } from "platform/usePersistedState"; import React, { useEffect } from "react"; interface GlobalMessageData { // the unix timestamp (as a string with milliseconds) when the message was issued epoch: string; severity: "success" | "info" | "warning" | "error"; message: string; } const TIME_BETWEEN_CHECKS_MS = 300_000; // 5 min export function GlobalMessage() { // data from the global message file const [data, setData] = usePersistedState<GlobalMessageData | null>( "globalmessage.data", null ); // last time we queried it const [lastCheck, setLastCheck] = usePersistedState<number | null>( "globalmessage.lastcheck", null ); // the epoch value of the last message we dismissed const [dismissedEpoch, setDismissedEpoch] = usePersistedState<string | null>( "globalmessage.dismissed", null ); useEffect(() => { const fetchData = async () => { try { const response = await fetch( process.env.NEXT_PUBLIC_GLOBAL_MESSAGE_URL ); Iif (!response.ok) { throw new Error(`HTTP error! Status: ${response.status}`); } setData(await response.json()); setLastCheck(new Date().getTime()); } catch (error) { console.error("Error fetching global message:", error); } }; Iif ( !lastCheck || new Date().getTime() - lastCheck > TIME_BETWEEN_CHECKS_MS ) { fetchData(); } }, [setData, setLastCheck, lastCheck]); const dismiss = () => { Iif (!data) return; setDismissedEpoch(data!.epoch); }; return data && data.epoch && data.epoch != dismissedEpoch ? ( <MuiAlert severity={data.severity} onClose={dismiss}> <span dangerouslySetInnerHTML={{ __html: data.message }} /> </MuiAlert> ) : null; } |