import React, { useState, useContext, useEffect } from "react"; import classNames from "classnames"; import path from "path-browserify"; import { useDropzone } from "react-dropzone"; import Reveal from "react-reveal/Reveal"; import { Button, UploadFile } from "../"; import { Deco3, Deco4, Deco5, Folder, DownArrow } from "../../svg"; import "./HomeUpload.scss"; import AppContext from "../../AppContext"; import axios from "axios"; export default function HomeUpload() { const [files, setFiles] = useState([]); const { apiUrl } = useContext(AppContext); const [directoryMode, setDirectoryMode] = useState(false); useEffect(() => { if (directoryMode) { inputRef.current.setAttribute("webkitdirectory", "true"); } else { inputRef.current.removeAttribute("webkitdirectory"); } }, [directoryMode]); const getFilePath = (file) => file.webkitRelativePath || file.path || file.name; const getRelativeFilePath = (file) => { const filePath = getFilePath(file); const { root, dir, base } = path.parse(filePath); const relative = path.normalize(dir).slice(root.length).split(path.sep).slice(1); return path.join(...relative, base); }; const getRootDirectory = (file) => { const filePath = getFilePath(file); const { root, dir } = path.parse(filePath); return path.normalize(dir).slice(root.length).split(path.sep)[0]; }; const handleDrop = async (acceptedFiles) => { if (directoryMode && acceptedFiles.length) { const rootDir = getRootDirectory(acceptedFiles[0]); // get the file path from the first file acceptedFiles = [{ name: rootDir, directory: true, files: acceptedFiles }]; } setFiles((previousFiles) => [...acceptedFiles.map((file) => ({ file, status: "uploading" })), ...previousFiles]); const onFileStateChange = (file, state) => { setFiles((previousFiles) => { const index = previousFiles.findIndex((f) => f.file === file); return [ ...previousFiles.slice(0, index), { ...previousFiles[index], ...state, }, ...previousFiles.slice(index + 1), ]; }); }; const upload = async (formData, directory, file) => { const uploadUrl = `${apiUrl}/skynet/skyfile/${directory ? `?filename=${encodeURIComponent(directory)}` : ""}`; const { data } = await axios.post(uploadUrl, formData, { onUploadProgress: ({ loaded, total }) => { const progress = loaded / total; const status = progress === 1 ? "processing" : "uploading"; onFileStateChange(file, { status, progress }); }, }); return data; }; acceptedFiles.forEach(async (file) => { try { const formData = new FormData(); if (file.directory) { file.files.forEach((directoryFile) => { const relativeFilePath = getRelativeFilePath(directoryFile); formData.append("files[]", directoryFile, relativeFilePath); }); } else { formData.append("file", file); } const { skylink } = await upload(formData, directoryMode && file.name, file); onFileStateChange(file, { status: "complete", url: `${apiUrl}/${skylink}` }); } catch (error) { onFileStateChange(file, { status: "error" }); } }); }; const { getRootProps, getInputProps, isDragActive, inputRef } = useDropzone({ onDrop: handleDrop }); const handleSkylink = (event) => { event.preventDefault(); const skylink = event.target.skylink.value.replace("sia://", ""); if (skylink.match(/^[a-zA-Z0-9_-]{46}$/)) { window.open(skylink, "_blank"); } }; return (

Upload your {directoryMode ? "Directory" : "Files"}

Drop your {directoryMode ? "directory" : "files"} here to pin to Skynet
{directoryMode && (

Please note that directory upload is not a standard browser feature and the browser support is limited. To check whether your browser is compatible, visit{" "} caniuse.com .

)}

Paste the link to retrieve your file

{files.length > 0 && (
{files.map((file, i) => { return ; })}
)}

Upon uploading a file, Skynet generates a 46 byte link called a Skylink. This link can then be shared with anyone to retrieve the file on any Skynet Webportal.

); }