Skip to content

Commit

Permalink
perf(upload): support rapid upload on web (#237)
Browse files Browse the repository at this point in the history
* feat(upload): support rapid upload on web

* chore
  • Loading branch information
KirCute authored Jan 27, 2025
1 parent 426562c commit 656ff95
Show file tree
Hide file tree
Showing 8 changed files with 91 additions and 20 deletions.
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,10 @@
"devDependencies": {
"@crowdin/cli": "^3.7.10",
"@hrgui/libass-wasm-ts": "^1.0.3",
"@types/crypto-js": "^4.2.2",
"@types/mark.js": "^8.11.8",
"@types/node": "^20.0.0",
"@types/qrcode": "^1.5.5",
"@types/sha256": "^0.2.0",
"@types/streamsaver": "^2.0.1",
"@vitejs/plugin-legacy": "^2.0.1",
Expand All @@ -61,7 +63,6 @@
"@solid-primitives/keyboard": "^1.2.5",
"@solid-primitives/storage": "^1.3.1",
"@stitches/core": "^1.2.8",
"@types/qrcode": "^1.5.5",
"@viselect/vanilla": "^3.5.0",
"aplayer": "^1.10.1",
"artplayer": "^5.0.9",
Expand All @@ -73,6 +74,7 @@
"copy-to-clipboard": "^3.3.2",
"crypto-js": "^4.2.0",
"flv.js": "^1.6.2",
"hash-wasm": "^4.12.0",
"hls.js": "^1.2.1",
"just-once": "^2.2.0",
"libass-wasm": "^4.1.0",
Expand Down
22 changes: 19 additions & 3 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/lang/en/home.json
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@
},
"upload": {
"add_as_task": "Add as task",
"try_rapid": "Try rapid",
"upload-tips": "Drag files here to upload, or click:",
"release": "Release to upload",
"no_files_drag": "No files were dragged in.",
Expand Down
10 changes: 10 additions & 0 deletions src/pages/home/uploads/Upload.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ const Upload = () => {
const [uploading, setUploading] = createSignal(false)
const [asTask, setAsTask] = createSignal(false)
const [overwrite, setOverwrite] = createSignal(false)
const [rapid, setRapid] = createSignal(true)
const [uploadFiles, setUploadFiles] = createStore<{
uploads: UploadFileProps[]
}>({
Expand Down Expand Up @@ -119,6 +120,7 @@ const Upload = () => {
},
asTask(),
overwrite(),
rapid(),
)
if (!err) {
setUpload(path, "status", "success")
Expand Down Expand Up @@ -293,6 +295,14 @@ const Upload = () => {
>
{t("home.overwrite_existing")}
</Checkbox>
<Checkbox
checked={rapid()}
onChange={() => {
setRapid(!rapid())
}}
>
{t("home.upload.try_rapid")}
</Checkbox>
</HStack>
</Show>
</VStack>
Expand Down
25 changes: 17 additions & 8 deletions src/pages/home/uploads/form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,35 @@ import { password } from "~/store"
import { EmptyResp } from "~/types"
import { r } from "~/utils"
import { SetUpload, Upload } from "./types"
import { calculateHash } from "./util"
export const FormUpload: Upload = async (
uploadPath: string,
file: File,
setUpload: SetUpload,
asTask = false,
overwrite = false,
rapid = false,
): Promise<Error | undefined> => {
let oldTimestamp = new Date().valueOf()
let oldLoaded = 0
const form = new FormData()
form.append("file", file)
let headers: { [k: string]: any } = {
"File-Path": encodeURIComponent(uploadPath),
"As-Task": asTask,
"Content-Type": "multipart/form-data",
"Last-Modified": file.lastModified,
Password: password(),
Overwrite: overwrite.toString(),
}
if (rapid) {
const { md5, sha1, sha256 } = await calculateHash(file)
headers["X-File-Md5"] = md5
headers["X-File-Sha1"] = sha1
headers["X-File-Sha256"] = sha256
}
const resp: EmptyResp = await r.put("/fs/form", form, {
headers: {
"File-Path": encodeURIComponent(uploadPath),
"As-Task": asTask,
"Content-Type": "multipart/form-data",
"Last-Modified": file.lastModified,
Password: password(),
Overwrite: overwrite.toString(),
},
headers: headers,
onUploadProgress: (progressEvent) => {
if (progressEvent.total) {
const complete =
Expand Down
25 changes: 17 additions & 8 deletions src/pages/home/uploads/stream.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,33 @@ import { password } from "~/store"
import { EmptyResp } from "~/types"
import { r } from "~/utils"
import { SetUpload, Upload } from "./types"
import { calculateHash } from "./util"
export const StreamUpload: Upload = async (
uploadPath: string,
file: File,
setUpload: SetUpload,
asTask = false,
overwrite = false,
rapid = false,
): Promise<Error | undefined> => {
let oldTimestamp = new Date().valueOf()
let oldLoaded = 0
let headers: { [k: string]: any } = {
"File-Path": encodeURIComponent(uploadPath),
"As-Task": asTask,
"Content-Type": file.type || "application/octet-stream",
"Last-Modified": file.lastModified,
Password: password(),
Overwrite: overwrite.toString(),
}
if (rapid) {
const { md5, sha1, sha256 } = await calculateHash(file)
headers["X-File-Md5"] = md5
headers["X-File-Sha1"] = sha1
headers["X-File-Sha256"] = sha256
}
const resp: EmptyResp = await r.put("/fs/put", file, {
headers: {
"File-Path": encodeURIComponent(uploadPath),
"As-Task": asTask,
"Content-Type": file.type || "application/octet-stream",
"Last-Modified": file.lastModified,
Password: password(),
Overwrite: overwrite.toString(),
},
headers: headers,
onUploadProgress: (progressEvent) => {
if (progressEvent.total) {
const complete =
Expand Down
1 change: 1 addition & 0 deletions src/pages/home/uploads/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@ export type Upload = (
setUpload: SetUpload,
asTask: boolean,
overwrite: boolean,
rapid: boolean,
) => Promise<Error | undefined>
23 changes: 23 additions & 0 deletions src/pages/home/uploads/util.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { UploadFileProps } from "./types"
import { createMD5, createSHA1, createSHA256 } from "hash-wasm"

export const traverseFileTree = async (entry: FileSystemEntry) => {
let res: File[] = []
Expand Down Expand Up @@ -59,3 +60,25 @@ export const File2Upload = (file: File): UploadFileProps => {
status: "pending",
}
}

export const calculateHash = async (file: File) => {
const md5Digest = await createMD5()
const sha1Digest = await createSHA1()
const sha256Digest = await createSHA256()
const reader = file.stream().getReader()
const read = async () => {
const { done, value } = await reader.read()
if (done) {
return
}
md5Digest.update(value)
sha1Digest.update(value)
sha256Digest.update(value)
await read()
}
await read()
const md5 = md5Digest.digest("hex")
const sha1 = sha1Digest.digest("hex")
const sha256 = sha256Digest.digest("hex")
return { md5, sha1, sha256 }
}

0 comments on commit 656ff95

Please sign in to comment.