DownloadLink.jsx 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. import React from "react";
  2. import { useTranslation } from "react-i18next";
  3. const generateDownloadURI = (data) => {
  4. return (
  5. "data:text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(data))
  6. );
  7. };
  8. export const DownloadLink = ({ getData = () => {} }) => {
  9. const { t } = useTranslation();
  10. const [downloadURI, setDownloadURI] = React.useState("");
  11. const [date, setDate] = React.useState(Date.now());
  12. const [genOnce, setGenOnce] = React.useState(false);
  13. const updateSaveLink = React.useCallback(async () => {
  14. const data = await getData();
  15. if (data.items.length) {
  16. setDownloadURI(generateDownloadURI(data));
  17. setDate(Date.now());
  18. setGenOnce(true);
  19. }
  20. }, [getData]);
  21. React.useEffect(() => {
  22. let mounted = true;
  23. const cancel = setInterval(() => {
  24. if (!mounted) return;
  25. updateSaveLink();
  26. }, 2000);
  27. updateSaveLink();
  28. return () => {
  29. mounted = false;
  30. setGenOnce(false);
  31. clearInterval(cancel);
  32. };
  33. }, [updateSaveLink]);
  34. return (
  35. <>
  36. {genOnce && (
  37. <a
  38. className="button success icon"
  39. href={downloadURI}
  40. download={`airboardgame_${date}.json`}
  41. >
  42. {t("Export")}
  43. <img
  44. src={"https://icongr.am/entypo/download.svg?size=20&color=f9fbfa"}
  45. alt="icon"
  46. />
  47. </a>
  48. )}
  49. {!genOnce && (
  50. <button className="button" disabled>
  51. {t("Generating export")}...
  52. </button>
  53. )}
  54. </>
  55. );
  56. };
  57. export default DownloadLink;