diff --git a/components/walrus/FileStorage.tsx b/components/walrus/FileStorage.tsx new file mode 100644 index 0000000..eb62caf --- /dev/null +++ b/components/walrus/FileStorage.tsx @@ -0,0 +1,125 @@ +import React, { useState, useRef } from 'react'; +import axios from 'axios'; +import { FiUploadCloud, FiDownload, FiShare2 } from 'react-icons/fi'; + +const PUBLISHER = 'https://publisher-devnet.walrus.space'; +const AGGREGATOR = 'https://aggregator-devnet.walrus.space'; + +interface FileInfo { + name: string; + blobId: string; +} + +const FileStorage: React.FC = () => { + const [files, setFiles] = useState([]); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(null); + const fileInputRef = useRef(null); + + const handleFileChange = (e: React.ChangeEvent) => { + if (e.target.files) { + setLoading(true); + setError(null); + Array.from(e.target.files).forEach(uploadFile); + } + }; + + const uploadFile = async (file: File) => { + try { + const formData = new FormData(); + formData.append('file', file); + + const response = await axios.put(`${PUBLISHER}/v1/store`, formData, { + headers: { 'Content-Type': 'multipart/form-data' }, + }); + + let blobId = ''; + if (response.data.newlyCreated) { + blobId = response.data.newlyCreated.blobObject.blobId; + } else if (response.data.alreadyCertified) { + blobId = response.data.alreadyCertified.blobId; + } + + setFiles(prev => [...prev, { name: file.name, blobId }]); + } catch (err) { + setError(`Failed to upload ${file.name}. Please try again.`); + console.error(err); + } finally { + setLoading(false); + } + }; + + const handleDownload = async (fileInfo: FileInfo) => { + try { + const response = await axios.get(`${AGGREGATOR}/v1/${fileInfo.blobId}`, { + responseType: 'blob', + }); + + const url = window.URL.createObjectURL(new Blob([response.data])); + const link = document.createElement('a'); + link.href = url; + link.setAttribute('download', fileInfo.name); + document.body.appendChild(link); + link.click(); + link.remove(); + } catch (err) { + setError(`Failed to download ${fileInfo.name}. Please try again.`); + console.error(err); + } + }; + + const handleShare = (fileInfo: FileInfo) => { + const shareUrl = `${AGGREGATOR}/v1/${fileInfo.blobId}`; + navigator.clipboard.writeText(shareUrl); + alert(`Share link copied to clipboard: ${shareUrl}`); + }; + + return ( +
+

File Storage

+ +
fileInputRef.current?.click()} + > + +

Click or drag files to upload

+

Supports any file type

+ +
+ + {loading &&

Uploading...

} + +
+ {files.length > 0 && ( +
+

Uploaded Files

+ {files.map((fileInfo, index) => ( +
+ {fileInfo.name} +
+ + +
+
+ ))} +
+ )} +
+ + {error &&

{error}

} +
+ ); +}; + +export default FileStorage; \ No newline at end of file diff --git a/pages/subscription.tsx b/pages/subscription.tsx index 5596ff3..33f0f54 100644 --- a/pages/subscription.tsx +++ b/pages/subscription.tsx @@ -16,6 +16,7 @@ import Image from "next/image"; import SingleSignerTransaction from "../components/transactionFlow/SingleSigner"; import SaveToWalrusButton from "../components/walrus/SaveToWalrusButton"; import DownloadFromWalrusButton from "../components/walrus/DownloadFromWalrusButton"; +import FileStorage from "../components/walrus/FileStorage"; const REACT_APP_GATEWAY_URL = process.env.NEXT_PUBLIC_GATEWAY_URL; const EREBRUS_GATEWAY_URL = process.env.NEXT_PUBLIC_EREBRUS_BASE_URL; const mynetwork = process.env.NEXT_PUBLIC_NETWORK; @@ -843,7 +844,8 @@ const Subscription = () => { )} -
+
+
{nftdata && (
{
)} +
+ +
+ +
)}