Skip to content
This repository has been archived by the owner on Apr 23, 2024. It is now read-only.

Commit

Permalink
Temporary revert
Browse files Browse the repository at this point in the history
  • Loading branch information
birdup000 authored Apr 23, 2023
1 parent f98abb3 commit ab586b4
Showing 1 changed file with 74 additions and 107 deletions.
181 changes: 74 additions & 107 deletions web/src/pages/dashboard/components/Upload.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,14 @@ const Upload: React.FC<Props> = ({ dataFileList: [fileList, setFileList], parent
await new Promise(res => setTimeout(res, 3000 * ++retry))
await cb?.()
if (retry === RETRY_COUNT) {
notification.error({
message: 'Failed to upload file', description: <>
<Typography.Paragraph>
{error?.response?.data?.error || error.message || 'Something error'}
</Typography.Paragraph>
<Typography.Paragraph code>
{JSON.stringify(error?.response?.data || error?.data || error, null, 2)}
</Typography.Paragraph>
</>
})
notification.error({ message: 'Failed to upload file', description: <>
<Typography.Paragraph>
{error?.response?.data?.error || error.message || 'Something error'}
</Typography.Paragraph>
<Typography.Paragraph code>
{JSON.stringify(error?.response?.data || error?.data || error, null, 2)}
</Typography.Paragraph>
</> })
throw error
}
}
Expand Down Expand Up @@ -140,17 +138,14 @@ const Upload: React.FC<Props> = ({ dataFileList: [fileList, setFileList], parent
if (type === 'channel') {
peer = new Api.InputPeerChannel({
channelId: BigInt(peerId) as any,
accessHash: BigInt(accessHash as string) as any
})
accessHash: BigInt(accessHash as string) as any })
} else if (type === 'user') {
peer = new Api.InputPeerUser({
userId: BigInt(peerId.toString()) as any,
accessHash: BigInt(accessHash.toString()) as any
})
accessHash: BigInt(accessHash.toString()) as any })
} else if (type === 'chat') {
peer = new Api.InputPeerChat({
chatId: BigInt(peerId) as any
})
chatId: BigInt(peerId) as any })
}
}
return await client.sendFile(peer || 'me', {
Expand Down Expand Up @@ -208,98 +203,72 @@ const Upload: React.FC<Props> = ({ dataFileList: [fileList, setFileList], parent
}
}
} else {
const PARALLELISM = 8

interface Response {
file?: {
id: string
}
}
for (let j = 0; j < fileParts; j++) {
const fileBlob = file.slice(j * MAX_UPLOAD_SIZE, Math.min(j * MAX_UPLOAD_SIZE + MAX_UPLOAD_SIZE, file.size))
const parts = Math.ceil(fileBlob.size / CHUNK_SIZE)

const uploadFile = async (file: File, parent?: { id: string }, onProgress?: (progress: any, file: File) => void) => {
const fileParts = Math.ceil(file.size / MAX_UPLOAD_SIZE)
const totalAllParts = fileParts * Math.ceil(file.size / CHUNK_SIZE)
const totalParts = 0
let deleted = false
const responses: Response[] = []
if (!deleted) {
const uploadPart = async (i: number) => {
if (responses?.length && cancelUploading.current && file.uid === cancelUploading.current) {
await Promise.all(responses.map(async response => {
try {
await req.delete(`/files/${response?.file.id}`)
} catch (error) {
// ignore
}
}))
cancelUploading.current = null
deleted = true
window.onbeforeunload = undefined as any
} else {
const blobPart = fileBlob.slice(i * CHUNK_SIZE, Math.min(i * CHUNK_SIZE + CHUNK_SIZE, file.size))
const data = new FormData()
data.append('upload', blobPart)

const workerScript = `
const uploadPart = async (file, j, i) => {
const fileBlob = file.slice(
j * MAX_UPLOAD_SIZE,
Math.min(j * MAX_UPLOAD_SIZE + MAX_UPLOAD_SIZE, file.size)
)
const blobPart = fileBlob.slice(i * CHUNK_SIZE, Math.min(i * CHUNK_SIZE + CHUNK_SIZE, file.size))
const data = new FormData()
data.append('upload', blobPart)
const { data: response } = await axios.post(
\`/files/upload\${i > 0 && responses[j]?.file?.id ? \`/\${responses[j]?.file?.id}\` : ''}\`,
data,
{
params: {
...parent?.id ? { parent_id: parent.id } : {},
relative_path: file.webkitRelativePath || null,
name: \`\${file.name}\${fileParts > 1 ? \`.part\${String(j + 1).padStart(3, '0')}\` : ''}\`,
size: fileBlob.size,
mime_type: file.type || mime.lookup(file.name) || 'application/octet-stream',
part: i,
total_part: fileParts,
},
const beginUpload = async () => {
const { data: response } = await req.post(`/files/upload${i > 0 && responses[j]?.file?.id ? `/${responses[j]?.file.id}` : ''}`, data, {
params: {
...parent?.id ? { parent_id: parent.id } : {},
relative_path: file.webkitRelativePath || null,
name: `${file.name}${fileParts > 1 ? `.part${String(j + 1).padStart(3, '0')}` : ''}`,
size: fileBlob.size,
mime_type: file.type || mime.lookup(file.name) || 'application/octet-stream',
part: i,
total_part: parts,
},
})
return response
}
)
responses[j] = response
const percent = (++totalParts / totalAllParts * 100).toFixed(1)
self.postMessage({ percent })
}
self.onmessage = (event) => {
const { file, j, partIndex } = event.data
uploadPart(file, j, partIndex)
}
`
const workerBlob = new Blob([workerScript], { type: 'application/javascript' })
const workerUrl = URL.createObjectURL(workerBlob)

const uploadPart = async (j: number, i: number) => {
if (responses?.length && cancelUploading.current && file.name === cancelUploading.current) {
await Promise.all(
responses.map(async (response) => {
let trial = 0
while (trial < RETRY_COUNT) {
try {
await req.delete(`/files/${response?.file?.id}`)
responses[j] = await beginUpload()
trial = RETRY_COUNT
} catch (error) {
// ignore
if (trial >= RETRY_COUNT) {
throw error
}
await new Promise(res => setTimeout(res, ++trial * 3000))
}
})
)
cancelUploading.current = null
deleted = true
window.onbeforeunload = undefined as any
} else {
const worker = new Worker(workerUrl)
worker.postMessage({ file, j, partIndex: i })
worker.onmessage = (event) => {
const { percent } = event.data
onProgress?.({ percent }, file)
if (++i < fileParts) {
uploadPart(j, i)
}

const percent = (++totalParts / totalAllParts * 100).toFixed(1)
onProgress({ percent }, file)
}
}
}

const promises: Promise<void>[] = []

for (let j = 0; j < fileParts; j++) {
if (deleted) break
const groupIndex = Math.floor(j / PARALLELISM)
const partIndex = j % PARALLELISM
promises[groupIndex] = promises[groupIndex] || Promise.resolve()
promises[groupIndex] = promises[groupIndex].then(() => uploadPart(j, 0))
const group = 2
await uploadPart(0)
for (let i = 1; i < parts - 1; i += group) {
if (deleted) break
const others = Array.from(Array(i + group).keys()).slice(i, Math.min(parts - 1, i + group))
await Promise.all(others.map(async j => await uploadPart(j)))
}
if (!deleted && parts - 1 > 0) {
await uploadPart(parts - 1)
}
}

await Promise.all(promises)

URL.revokeObjectURL(workerUrl)
}
}

Expand All @@ -321,16 +290,14 @@ const Upload: React.FC<Props> = ({ dataFileList: [fileList, setFileList], parent
notification.error({
key: 'fileUploadError',
message: error?.response?.status || 'Something error',
...error?.response?.data ? {
description: <>
<Typography.Paragraph>
{error?.response?.data?.error || error.message || 'Something error'}
</Typography.Paragraph>
<Typography.Paragraph code>
{JSON.stringify(error?.response?.data || error?.data || error, null, 2)}
</Typography.Paragraph>
</>
} : {}
...error?.response?.data ? { description: <>
<Typography.Paragraph>
{error?.response?.data?.error || error.message || 'Something error'}
</Typography.Paragraph>
<Typography.Paragraph code>
{JSON.stringify(error?.response?.data || error?.data || error, null, 2)}
</Typography.Paragraph>
</> } : {}
})
// filesWantToUpload.current = filesWantToUpload.current?.map(f => f.uid === file.uid ? { ...f, status: 'done' } : f)
filesWantToUpload.current = filesWantToUpload.current?.map(f => f.uid === file.uid ? null : f).filter(Boolean)
Expand Down Expand Up @@ -375,4 +342,4 @@ const Upload: React.FC<Props> = ({ dataFileList: [fileList, setFileList], parent
</BaseUpload.Dragger>
}

export default Upload
export default Upload

0 comments on commit ab586b4

Please sign in to comment.