diff --git a/frontend/src/components/reader/BurnModal.tsx b/frontend/src/components/reader/BurnModal.tsx new file mode 100644 index 0000000..4fdb372 --- /dev/null +++ b/frontend/src/components/reader/BurnModal.tsx @@ -0,0 +1,99 @@ +import { CampfireIcon, FlameIcon, XCircleIcon } from "@phosphor-icons/react"; +import { useEffect, useState } from "react"; + +export function BurnModal({ + burnLetter, + isBurning, + setShowBurnModal, + setRevealState, +}) { + const [flameOn, setFlameOn] = useState(0); + const [rotate, setRotate] = useState(0); + const [burnClicked, setBurnClicked] = useState(false); + useEffect(() => { + if (!burnClicked) return; + if (flameOn === 100) { + setRevealState("sealed"); + burnLetter(); + } + const interval = setInterval(() => { + setFlameOn((prev) => prev + 1); + setRotate(Math.random() * 4 - 2); + }, 100); + return () => clearInterval(interval); + }, [burnClicked, flameOn, setRevealState, burnLetter]); + + const burnStyle = flameOn < 30 ? "" : `contrast(${flameOn / 30})`; + + return ( +
+
+ + +

+ Are you ready to burn this letter? +

+

+ Some words are meant to be unsaid, but they don't have to linger + forever. +
+ Let the echoes of your unsaid be finally released. +

+
+ Press and{" "} + hold the{" "} + flame to proceed. +
+
+
+ +
+
+
+ ); +} diff --git a/frontend/src/components/reader/PostActionOverlay.tsx b/frontend/src/components/reader/PostActionOverlay.tsx new file mode 100644 index 0000000..4959fed --- /dev/null +++ b/frontend/src/components/reader/PostActionOverlay.tsx @@ -0,0 +1,36 @@ +import { useNavigate } from "react-router-dom"; +import { ROUTES } from "../../config/routes"; + +export function PostActionOverlay({ revealState }) { + const navigate = useNavigate(); + return ( +
+

+ It is done +

+
+

+ May your soul find + solace, +
+ just like your unsaid{" "} + words did. +

+
+ +
+
+ ); +} diff --git a/frontend/src/components/reader/ShareModal.tsx b/frontend/src/components/reader/ShareModal.tsx new file mode 100644 index 0000000..20bfc2e --- /dev/null +++ b/frontend/src/components/reader/ShareModal.tsx @@ -0,0 +1,70 @@ +import { + EyeSlashIcon, + PaperPlaneTiltIcon, + XCircleIcon, +} from "@phosphor-icons/react"; + +export function ShareModal({ shareLink, setShareLink }) { + const copyToClipboard = async () => { + if (!shareLink) return; + await navigator.clipboard.writeText(shareLink); + }; + return ( +
+
+ +
+
+ +

Send this letter

+

+ You've carried these words long enough. Send your letter now, and + let the unsaid{" "} + finally find its home. +

+
+
+ The recipient will have the same viewing experience like you do + now. +
+
+
+ + +
+
+

+ {" "} + Zero-Knowledge Share: +

+

+ The key never leaves your or the recipient's browser. +

+
+
+
+
+ ); +} diff --git a/frontend/src/pages/Reader.tsx b/frontend/src/pages/Reader.tsx index acfc5b7..4cd861a 100644 --- a/frontend/src/pages/Reader.tsx +++ b/frontend/src/pages/Reader.tsx @@ -1,10 +1,4 @@ -import { - CampfireIcon, - EyeSlashIcon, - FlameIcon, - PaperPlaneTiltIcon, - XCircleIcon, -} from "@phosphor-icons/react"; +import { FlameIcon, PaperPlaneTiltIcon } from "@phosphor-icons/react"; import { useEffect, useRef, useState } from "react"; import { type NavigateFunction, @@ -19,10 +13,13 @@ import { ComposeCanvas, } from "../components/editor/ComposeCanvas"; import Logo from "../components/Logo"; +import { BurnModal } from "../components/reader/BurnModal"; import { EnvelopeReveal } from "../components/reader/EnvelopeReveal"; +import { PostActionOverlay } from "../components/reader/PostActionOverlay"; +import { ShareModal } from "../components/reader/ShareModal"; import { LogModal } from "../components/ui/LogModal"; import { endpoints } from "../config/endpoints"; -import { PATHS, ROUTES } from "../config/routes"; +import { PATHS } from "../config/routes"; import { useKeyStore } from "../store/useKeyStore"; import { CryptoUtils } from "../utils/crypto"; import { formatDate } from "../utils/dateFormat"; @@ -82,73 +79,6 @@ export default function Reader() { } }; - const copyToClipboard = async () => { - if (!shareLink) return; - await navigator.clipboard.writeText(shareLink); - }; - - function ShareModal() { - return ( -
-
- -
-
- -

Send this letter

-

- You've carried these words long enough. Send your letter now, - and let the{" "} - unsaid finally - find its home. -

-
-
- The recipient will have the same viewing experience like you do - now. -
-
-
- - -
-
-

- {" "} - Zero-Knowledge Share: -

-

- The key never leaves your or the recipient's browser. -

-
-
-
-
- ); - } - const burnLetter = async () => { if (!public_id || isBurning) return; setIsBurning(true); @@ -167,99 +97,6 @@ export default function Reader() { } }; - function BurnModal() { - const [flameOn, setFlameOn] = useState(0); - const [rotate, setRotate] = useState(0); - const [burnClicked, setBurnClicked] = useState(false); - useEffect(() => { - if (!burnClicked) return; - if (flameOn === 100) { - setRevealState("sealed"); - burnLetter(); - } - const interval = setInterval(() => { - setFlameOn((prev) => prev + 1); - setRotate(Math.random() * 4 - 2); - }, 100); - return () => clearInterval(interval); - }, [burnClicked, flameOn]); - - const burnStyle = flameOn < 30 ? "" : `contrast(${flameOn / 30})`; - - return ( -
-
- - -

- Are you ready to burn this letter? -

-

- Some words are meant to be unsaid, but they don't have to linger - forever. -
- Let the echoes of your unsaid be finally released. -

-
- Press and{" "} - hold the{" "} - flame to proceed. -
-
-
- -
-
-
- ); - } - useEffect(() => { if (!(sharingKey || masterKey)) { navigateRef.current("/login", { @@ -427,36 +264,7 @@ export default function Reader() { )}
- {ignite && ( -
-

- It is done -

-
-

- May your soul find - solace, -
- just like your unsaid{" "} - words did. -

-
- -
-
- )} + {ignite && } )} - {shareLink && } - {showBurnModal && } + {shareLink && ( + + )} + {showBurnModal && ( + + )} {isAuthor && revealState !== "burned" && (