'use client' import React, { JSX, useState, useCallback, useEffect } from 'react' import { useDownloader } from '../hooks/useDownloader' import PasswordField from './PasswordField' import UnlockButton from './UnlockButton' import Loading from './Loading' import UploadFileList from './UploadFileList' import DownloadButton from './DownloadButton' import StopButton from './StopButton' import ProgressBar from './ProgressBar' import TitleText from './TitleText' import ReturnHome from './ReturnHome' import { pluralize } from '../utils/pluralize' import { ErrorMessage } from './ErrorMessage' interface FileInfo { fileName: string size: number type: string } export function ConnectingToUploader({ showTroubleshootingAfter = 3000, }: { showTroubleshootingAfter?: number }): JSX.Element { const [showTroubleshooting, setShowTroubleshooting] = useState(false) useEffect(() => { const timer = setTimeout(() => { setShowTroubleshooting(true) }, showTroubleshootingAfter) return () => clearTimeout(timer) }, [showTroubleshootingAfter]) if (!showTroubleshooting) { return } return ( <>

Having trouble connecting?

FilePizza uses direct peer-to-peer connections, but sometimes the connection can get stuck. Here are some possible reasons this can happen:

  • 🚪 The uploader may have closed their browser. FilePizza requires the uploader to stay online continuously because files are transferred directly between b.
  • 🔒 Your network might have strict firewalls or NAT settings, such as having UPnP disabled
  • 🌐 Some corporate or school networks block peer-to-peer connections

Note: FilePizza is designed for direct transfers between known parties and doesn't use{' '} TURN {' '} relay servers. This means it may not work on all networks.

) } export function DownloadComplete({ filesInfo, bytesDownloaded, totalSize, }: { filesInfo: FileInfo[] bytesDownloaded: number totalSize: number }): JSX.Element { return ( <> You downloaded {pluralize(filesInfo.length, 'file', 'files')}.
) } export function DownloadInProgress({ filesInfo, bytesDownloaded, totalSize, onStop, }: { filesInfo: FileInfo[] bytesDownloaded: number totalSize: number onStop: () => void }): JSX.Element { return ( <> You are downloading {pluralize(filesInfo.length, 'file', 'files')}.
) } export function ReadyToDownload({ filesInfo, onStart, }: { filesInfo: FileInfo[] onStart: () => void }): JSX.Element { return ( <> You are about to start downloading{' '} {pluralize(filesInfo.length, 'file', 'files')}.
) } export function PasswordEntry({ onSubmit, errorMessage, }: { onSubmit: (password: string) => void errorMessage: string | null }): JSX.Element { const [password, setPassword] = useState('') const handleSubmit = useCallback( (e: React.FormEvent) => { e.preventDefault() onSubmit(password) }, [onSubmit, password], ) return ( <> This download requires a password.
{errorMessage && } ) } export default function Downloader({ uploaderPeerID, }: { uploaderPeerID: string }): JSX.Element { const { filesInfo, isConnected, isPasswordRequired, isDownloading, isDone, errorMessage, submitPassword, startDownload, stopDownload, totalSize, bytesDownloaded, } = useDownloader(uploaderPeerID) if (isDone && filesInfo) { return ( ) } if (!isConnected) { return } if (isDownloading && filesInfo) { return ( ) } if (filesInfo) { return } if (isPasswordRequired) { return ( ) } return }