diff --git a/src/app/download/[...slug]/page.tsx b/src/app/download/[...slug]/page.tsx
index 40c2cc2..c294d6c 100644
--- a/src/app/download/[...slug]/page.tsx
+++ b/src/app/download/[...slug]/page.tsx
@@ -1,3 +1,4 @@
+import { notFound } from 'next/navigation'
import { channelRepo } from '../../../channel'
import Spinner from '../../../components/Spinner'
import Wordmark from '../../../components/Wordmark'
@@ -21,13 +22,7 @@ export default async function DownloadPage({
const channel = await channelRepo.fetch(slug)
if (!channel) {
- return (
-
- )
+ notFound()
}
return (
diff --git a/src/app/page.tsx b/src/app/page.tsx
index 2888f3e..0937927 100644
--- a/src/app/page.tsx
+++ b/src/app/page.tsx
@@ -13,7 +13,98 @@ import Spinner from '../components/Spinner'
import Wordmark from '../components/Wordmark'
import CancelButton from '../components/CancelButton'
-export default function IndexPage(): JSX.Element {
+function PageWrapper({
+ children,
+ isRotating = false,
+}: {
+ children: React.ReactNode
+ isRotating?: boolean
+}): JSX.Element {
+ return (
+
+
+
+ {children}
+
+ )
+}
+
+function InitialState({
+ onDrop,
+}: {
+ onDrop: (files: UploadedFile[]) => void
+}): JSX.Element {
+ return (
+
+
+
+ Peer-to-peer file transfers in your browser.
+
+
+ We never store anything. Files only served fresh.
+
+
+
+
+ )
+}
+
+function ConfirmUploadState({
+ uploadedFiles,
+ password,
+ onChangePassword,
+ onCancel,
+ onStart,
+ onFileListChange,
+}: {
+ uploadedFiles: UploadedFile[]
+ password: string
+ onChangePassword: (pw: string) => void
+ onCancel: () => void
+ onStart: () => void
+ onFileListChange: (updatedFiles: UploadedFile[]) => void
+}): JSX.Element {
+ return (
+
+
+ You are about to start uploading {uploadedFiles.length}{' '}
+ {uploadedFiles.length === 1 ? 'file' : 'files'}.
+
+
+
+
+
+
+
+
+ )
+}
+
+function UploadingState({
+ uploadedFiles,
+ password,
+ onStop,
+}: {
+ uploadedFiles: UploadedFile[]
+ password: string
+ onStop: () => void
+}): JSX.Element {
+ return (
+
+
+ You are uploading {uploadedFiles.length}{' '}
+ {uploadedFiles.length === 1 ? 'file' : 'files'}.
+
+
+
+
+
+
+
+ )
+}
+
+export default function UploadPage(): JSX.Element {
const [uploadedFiles, setUploadedFiles] = useState([])
const [password, setPassword] = useState('')
const [uploading, setUploading] = useState(false)
@@ -44,55 +135,27 @@ export default function IndexPage(): JSX.Element {
}, [])
if (!uploadedFiles.length) {
- return (
-
-
-
-
-
- Peer-to-peer file transfers in your browser.
-
-
- We never store anything. Files only served fresh.
-
-
-
-
- )
+ return
}
if (!uploading) {
return (
-
-
-
-
- You are about to start uploading {uploadedFiles.length}{' '}
- {uploadedFiles.length === 1 ? 'file' : 'files'}.
-
-
-
-
-
-
-
-
+
)
}
return (
-
-
-
-
- You are uploading {uploadedFiles.length}{' '}
- {uploadedFiles.length === 1 ? 'file' : 'files'}.
-
-
-
-
-
-
-
+
)
}
diff --git a/src/components/CancelButton.tsx b/src/components/CancelButton.tsx
index 868676b..853d85d 100644
--- a/src/components/CancelButton.tsx
+++ b/src/components/CancelButton.tsx
@@ -8,7 +8,7 @@ export default function CancelButton({
return (
diff --git a/src/components/DropZone.tsx b/src/components/DropZone.tsx
index d88fd92..bf2f008 100644
--- a/src/components/DropZone.tsx
+++ b/src/components/DropZone.tsx
@@ -97,7 +97,7 @@ export default function DropZone({
multiple
/>