From cdf34ee9a1d0b78814252a19df7f22a297f47e74 Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Sat, 11 Jan 2025 15:28:23 +0800 Subject: [PATCH] :sparkles: Attachment uploading --- bun.lockb | Bin 303668 -> 306076 bytes package.json | 8 +- packages/sn/package.json | 2 +- packages/sn/src/attachment.ts | 52 +++++----- src/pages/_app.tsx | 6 +- src/pages/attachments/new.tsx | 190 ++++++++++++++++++++++++++++++++++ 6 files changed, 228 insertions(+), 30 deletions(-) create mode 100644 src/pages/attachments/new.tsx diff --git a/bun.lockb b/bun.lockb index 9e6de21de48376528e3fa359e7b549aa956dd521..2b906a4c2c1c4275ff65087466d15c19ec030858 100755 GIT binary patch delta 49452 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 MrekGGx?$UY0Iib#iU0rr delta 47960 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%0DN2IPlU&U-@q^6 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 - isUploaded: boolean } export class UploadAttachmentTask { @@ -66,9 +65,9 @@ export class UploadAttachmentTask { private multipartInfo: MultipartInfo | null = null private multipartProgress: MultipartProgress = { value: null, current: 0, total: 0 } - loading: boolean = false - success: boolean = false - error: string | null = null + onProgress?: (progress: MultipartProgress) => void + onSuccess?: (success: boolean) => void + onError?: (error: string) => void constructor(content: File, pool: string) { if (!content || !pool) { @@ -78,8 +77,7 @@ export class UploadAttachmentTask { this.pool = pool } - public async submit(): Promise { - this.loading = true + public async submit(): Promise { const limit = 3 try { @@ -92,14 +90,20 @@ export class UploadAttachmentTask { const chunks = Object.keys(this.multipartInfo?.fileChunks || {}) this.multipartProgress.total = chunks.length + let result: SnAttachment | null = null + const uploadChunks = async (chunk: string): Promise => { try { - await this.uploadSingleMultipart(chunk) + const resp = await this.uploadOneChunk(chunk) this.multipartProgress.current++ console.log( `[Paperclip] Uploaded multipart ${this.multipartProgress.current}/${this.multipartProgress.total}`, ) this.multipartProgress.value = this.multipartProgress.current / this.multipartProgress.total + + if (this.onProgress) this.onProgress(this.multipartProgress) + + result = resp } catch (err) { console.log(`[Paperclip] Upload multipart ${chunk} failed, retrying in 3 seconds...`) await this.delay(3000) @@ -112,15 +116,13 @@ export class UploadAttachmentTask { await Promise.all(chunkSlice.map(uploadChunks)) } - if (this.multipartInfo?.isUploaded) { - console.log(`[Paperclip] Entire file has been uploaded in ${this.multipartProgress.total} chunk(s)`) - this.success = true - } - } catch (e) { - console.error(e) - this.error = e instanceof Error ? e.message : String(e) - } finally { - this.loading = false + console.log(`[Paperclip] Entire file has been uploaded in ${this.multipartProgress.total} chunk(s)`) + if (this.onSuccess) this.onSuccess(true) + + return result! + } catch (err: any) { + if (this.onError) this.onError(err.toString()) + throw err } } @@ -139,7 +141,7 @@ export class UploadAttachmentTask { const nameArray = this.content.name.split('.') nameArray.pop() - const resp = await sni.post('/cgi/uc/attachments/fragments', { + const resp = await sni.post('/cgi/uc/fragments', { pool: this.pool, size: this.content.size, name: this.content.name, @@ -153,20 +155,22 @@ export class UploadAttachmentTask { this.multipartInfo = data.meta } - private async uploadSingleMultipart(chunkId: string): Promise { - if (!this.multipartInfo) return + private async uploadOneChunk(chunkId: string): Promise { + if (!this.multipartInfo) return null const chunkIdx = this.multipartInfo.fileChunks[chunkId] const chunk = this.content.slice(chunkIdx * this.multipartSize, (chunkIdx + 1) * this.multipartSize) - const data = new FormData() - data.set('file', chunk) - - const resp = await sni.post(`/cgi/uc/attachments/fragments/${this.multipartInfo.rid}/${chunkId}`, data, { + const resp = await sni.post(`/cgi/uc/fragments/${this.multipartInfo.rid}/${chunkId}`, chunk, { + headers: { 'Content-Type': 'application/octet-stream' }, timeout: 3 * 60 * 1000, }) - this.multipartInfo = resp.data + if (resp.data['attachment']) { + return resp.data['attachment'] as SnAttachment + } + this.multipartInfo = resp.data['fragment'] + return null } private delay(ms: number): Promise { diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index 5cb3168..4f71f28 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -38,7 +38,11 @@ export default function App({ Component, pageProps }: AppProps) { userStore.fetchUser() }, []) - const title = pageProps.title ? `${pageProps.title} | Solsynth LLC` : 'Solsynth LLC' + const title = pageProps.title + ? pageProps.startsWith('Solar Network Console') + ? pageProps.title + : `${pageProps.title} | Solsynth LLC` + : 'Solsynth LLC' return ( <> diff --git a/src/pages/attachments/new.tsx b/src/pages/attachments/new.tsx new file mode 100644 index 0000000..ce8410a --- /dev/null +++ b/src/pages/attachments/new.tsx @@ -0,0 +1,190 @@ +import { + styled, + Button, + Container, + Card, + Box, + List, + ListItem, + ListItemText, + IconButton, + FormControl, + InputLabel, + MenuItem, + Select, + LinearProgress, + Typography, + Alert, + Collapse, +} from '@mui/material' +import { MultipartProgress, SnAttachment, UploadAttachmentTask } from 'solar-js-sdk' +import { useState } from 'react' + +import ErrorIcon from '@mui/icons-material/Error' +import CloseIcon from '@mui/icons-material/Close' +import CloudUploadIcon from '@mui/icons-material/CloudUpload' +import PlayIcon from '@mui/icons-material/PlayArrow' + +const VisuallyHiddenInput = styled('input')({ + clip: 'rect(0 0 0 0)', + clipPath: 'inset(50%)', + height: 1, + overflow: 'hidden', + position: 'absolute', + bottom: 0, + left: 0, + whiteSpace: 'nowrap', + width: 1, +}) + +interface FileUploadTask { + file: File + attachment?: SnAttachment +} + +export default function AttachmentNew() { + const [files, setFiles] = useState([]) + + const [busy, setBusy] = useState(false) + const [error, setError] = useState(null) + + const [task, setTask] = useState() + const [taskProgress, setTaskProgress] = useState() + + const [pool, setPool] = useState('interactive') + + async function upload() { + if (files.length == 0) return + + setBusy(true) + + for (let idx = 0; idx < files.length; idx++) { + if (files[idx].attachment) continue + + try { + const task = new UploadAttachmentTask(files[idx].file, pool) + setTask(files[idx]) + task.onProgress = (progress) => setTaskProgress(progress) + task.onError = (err) => setError(err) + const attachment = await task.submit() + setFiles((files) => files.map((f, i) => (i == idx ? { ...f, attachment } : f))) + } catch (err: any) { + setError(err.toString()) + setBusy(false) + return + } + } + + setBusy(false) + } + + return ( + + + + + {files.length > 0 && ( + + )} + + + + } severity="error"> + {error} + + + + {taskProgress && ( + + + {task?.file.name ?? 'Waiting...'} + + + + )} + + {files.length > 0 && ( + + + + {files?.map((f, idx) => ( + setFiles((files) => files.filter((_, i) => i != idx))} + > + + + } + > + + + ))} + + + + )} + + + Attachment Pool + + + + + ) +}