mirror of
https://github.com/ragestudio/comty.git
synced 2025-06-09 10:34:17 +00:00
update deps
This commit is contained in:
parent
d50ba06a55
commit
5d4c25c413
@ -1,89 +1,90 @@
|
||||
{
|
||||
"name": "@comty/web-app",
|
||||
"version": "1.0.0-beta",
|
||||
"license": "ComtyLicense",
|
||||
"main": "electron/main",
|
||||
"author": "RageStudio",
|
||||
"description": "A prototype of a social network.",
|
||||
"scripts": {
|
||||
"build": "vite build",
|
||||
"dev": "vite",
|
||||
"docker-compose:update_run": "docker-compose down && git pull && yarn build && docker-compose up -d --build",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ant-design/icons": "^5.4.0",
|
||||
"@capacitor/android": "^5.0.5",
|
||||
"@capacitor/app": "^5.0.3",
|
||||
"@capacitor/assets": "^2.0.4",
|
||||
"@capacitor/cli": "^5.0.5",
|
||||
"@capacitor/core": "^5.0.5",
|
||||
"@capacitor/haptics": "1.1.4",
|
||||
"@capacitor/splash-screen": "^5.0.4",
|
||||
"@capacitor/status-bar": "^5.0.4",
|
||||
"@capacitor/storage": "^1.2.5",
|
||||
"@capgo/capacitor-updater": "^5.0.1",
|
||||
"@dnd-kit/core": "^6.0.8",
|
||||
"@dnd-kit/sortable": "^7.0.2",
|
||||
"@emotion/react": "^11.13.0",
|
||||
"@emotion/styled": "^11.13.0",
|
||||
"@ffmpeg/ffmpeg": "^0.12.10",
|
||||
"@ffmpeg/util": "^0.12.1",
|
||||
"@loadable/component": "5.15.2",
|
||||
"@mui/material": "^5.11.9",
|
||||
"@ragestudio/cordova-nfc": "^1.2.0",
|
||||
"@ragestudio/vessel": "^0.18.1",
|
||||
"@sentry/browser": "^7.64.0",
|
||||
"@tauri-apps/api": "^1.5.4",
|
||||
"@tsmx/human-readable": "^1.0.7",
|
||||
"antd": "^5.20.6",
|
||||
"axios": "^1.7.7",
|
||||
"bear-react-carousel": "^4.0.10-alpha.0",
|
||||
"capacitor-music-controls-plugin-v3": "^1.1.0",
|
||||
"classnames": "2.3.1",
|
||||
"dompurify": "^3.0.0",
|
||||
"fast-average-color": "^9.2.0",
|
||||
"framer-motion": "^10.12.17",
|
||||
"fuse.js": "6.5.3",
|
||||
"hls.js": "^1.5.17",
|
||||
"howler": "2.2.3",
|
||||
"i18next": "21.6.6",
|
||||
"js-cookie": "3.0.1",
|
||||
"jsmediatags": "^3.9.7",
|
||||
"less": "4.1.2",
|
||||
"lottie-react": "^2.4.0",
|
||||
"luxon": "^3.0.4",
|
||||
"million": "^2.6.4",
|
||||
"mime": "^3.0.0",
|
||||
"moment": "2.29.4",
|
||||
"mpegts.js": "^1.6.10",
|
||||
"nprogress": "^0.2.0",
|
||||
"plyr": "^3.6.12",
|
||||
"plyr-react": "^3.2.1",
|
||||
"prop-types": "^15.8.1",
|
||||
"react": "^18.2.0",
|
||||
"react-beautiful-dnd": "^13.1.1",
|
||||
"react-color": "2.19.3",
|
||||
"react-countup": "^6.4.1",
|
||||
"react-dom": "18.2.0",
|
||||
"react-fast-marquee": "^1.3.5",
|
||||
"react-helmet": "6.1.0",
|
||||
"react-i18next": "11.15.3",
|
||||
"react-icons": "^4.8.0",
|
||||
"react-lazy-load-image-component": "^1.5.4",
|
||||
"react-markdown": "^8.0.3",
|
||||
"react-modal-image": "^2.6.0",
|
||||
"react-motion": "0.5.2",
|
||||
"react-rnd": "10.3.5",
|
||||
"react-router-dom": "^6.26.2",
|
||||
"react-transition-group": "^4.4.5",
|
||||
"react-useanimations": "^2.10.0",
|
||||
"realtime-bpm-analyzer": "^3.2.1",
|
||||
"remark-gfm": "^3.0.1",
|
||||
"rxjs": "^7.5.5",
|
||||
"store": "^2.0.12",
|
||||
"ua-parser-js": "^1.0.36",
|
||||
"vaul": "^0.9.2",
|
||||
"vite": "^5.4.4"
|
||||
}
|
||||
"name": "@comty/web-app",
|
||||
"version": "1.0.0-beta",
|
||||
"license": "ComtyLicense",
|
||||
"main": "electron/main",
|
||||
"author": "RageStudio",
|
||||
"description": "A prototype of a social network.",
|
||||
"scripts": {
|
||||
"build": "vite build",
|
||||
"dev": "vite",
|
||||
"docker-compose:update_run": "docker-compose down && git pull && yarn build && docker-compose up -d --build",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ant-design/icons": "^5.4.0",
|
||||
"@capacitor/android": "^5.0.5",
|
||||
"@capacitor/app": "^5.0.3",
|
||||
"@capacitor/assets": "^2.0.4",
|
||||
"@capacitor/cli": "^5.0.5",
|
||||
"@capacitor/core": "^5.0.5",
|
||||
"@capacitor/haptics": "1.1.4",
|
||||
"@capacitor/splash-screen": "^5.0.4",
|
||||
"@capacitor/status-bar": "^5.0.4",
|
||||
"@capacitor/storage": "^1.2.5",
|
||||
"@capgo/capacitor-updater": "^5.0.1",
|
||||
"@dnd-kit/core": "^6.0.8",
|
||||
"@dnd-kit/sortable": "^7.0.2",
|
||||
"@emotion/react": "^11.13.0",
|
||||
"@emotion/styled": "^11.13.0",
|
||||
"@ffmpeg/ffmpeg": "^0.12.10",
|
||||
"@ffmpeg/util": "^0.12.1",
|
||||
"@loadable/component": "5.15.2",
|
||||
"@mui/material": "^5.11.9",
|
||||
"@ragestudio/cordova-nfc": "^1.2.0",
|
||||
"@ragestudio/vessel": "^0.18.1",
|
||||
"@sentry/browser": "^7.64.0",
|
||||
"@tauri-apps/api": "^1.5.4",
|
||||
"@tsmx/human-readable": "^1.0.7",
|
||||
"antd": "^5.20.6",
|
||||
"axios": "^1.7.7",
|
||||
"bear-react-carousel": "^4.0.10-alpha.0",
|
||||
"capacitor-music-controls-plugin-v3": "^1.1.0",
|
||||
"classnames": "2.3.1",
|
||||
"dashjs": "^4.7.4",
|
||||
"dompurify": "^3.0.0",
|
||||
"fast-average-color": "^9.2.0",
|
||||
"framer-motion": "^10.12.17",
|
||||
"fuse.js": "6.5.3",
|
||||
"hls.js": "^1.5.17",
|
||||
"howler": "2.2.3",
|
||||
"i18next": "21.6.6",
|
||||
"js-cookie": "3.0.1",
|
||||
"jsmediatags": "^3.9.7",
|
||||
"less": "4.1.2",
|
||||
"lottie-react": "^2.4.0",
|
||||
"luxon": "^3.0.4",
|
||||
"million": "^2.6.4",
|
||||
"mime": "^3.0.0",
|
||||
"moment": "2.29.4",
|
||||
"mpegts.js": "^1.6.10",
|
||||
"nprogress": "^0.2.0",
|
||||
"plyr": "^3.6.12",
|
||||
"plyr-react": "^3.2.1",
|
||||
"prop-types": "^15.8.1",
|
||||
"react": "^18.2.0",
|
||||
"react-beautiful-dnd": "^13.1.1",
|
||||
"react-color": "2.19.3",
|
||||
"react-countup": "^6.4.1",
|
||||
"react-dom": "18.2.0",
|
||||
"react-fast-marquee": "^1.3.5",
|
||||
"react-helmet": "6.1.0",
|
||||
"react-i18next": "11.15.3",
|
||||
"react-icons": "^4.8.0",
|
||||
"react-lazy-load-image-component": "^1.5.4",
|
||||
"react-markdown": "^8.0.3",
|
||||
"react-modal-image": "^2.6.0",
|
||||
"react-motion": "0.5.2",
|
||||
"react-rnd": "10.3.5",
|
||||
"react-router-dom": "^6.26.2",
|
||||
"react-transition-group": "^4.4.5",
|
||||
"react-useanimations": "^2.10.0",
|
||||
"realtime-bpm-analyzer": "^3.2.1",
|
||||
"remark-gfm": "^3.0.1",
|
||||
"rxjs": "^7.5.5",
|
||||
"store": "^2.0.12",
|
||||
"ua-parser-js": "^1.0.36",
|
||||
"vaul": "^0.9.2",
|
||||
"vite": "^5.4.4"
|
||||
}
|
||||
}
|
||||
|
@ -1,201 +1,230 @@
|
||||
import { EventBus } from "@ragestudio/vessel"
|
||||
import { events, stream } from "fetch-event-stream"
|
||||
|
||||
export default class ChunkedUpload {
|
||||
constructor(params) {
|
||||
const {
|
||||
endpoint,
|
||||
file,
|
||||
headers = {},
|
||||
splitChunkSize = 1024 * 1024 * 10,
|
||||
maxRetries = 3,
|
||||
delayBeforeRetry = 5,
|
||||
} = params
|
||||
constructor(params) {
|
||||
const {
|
||||
endpoint,
|
||||
file,
|
||||
headers = {},
|
||||
splitChunkSize = 1024 * 1024 * 10,
|
||||
maxRetries = 3,
|
||||
delayBeforeRetry = 5,
|
||||
} = params
|
||||
|
||||
if (!endpoint) {
|
||||
throw new Error("Missing endpoint")
|
||||
}
|
||||
if (!endpoint) {
|
||||
throw new Error("Missing endpoint")
|
||||
}
|
||||
|
||||
if (!file instanceof File) {
|
||||
throw new Error("Invalid or missing file")
|
||||
}
|
||||
if ((!file) instanceof File) {
|
||||
throw new Error("Invalid or missing file")
|
||||
}
|
||||
|
||||
if (typeof headers !== "object") {
|
||||
throw new Error("Invalid headers")
|
||||
}
|
||||
if (typeof headers !== "object") {
|
||||
throw new Error("Invalid headers")
|
||||
}
|
||||
|
||||
if (splitChunkSize <= 0) {
|
||||
throw new Error("Invalid splitChunkSize")
|
||||
}
|
||||
if (splitChunkSize <= 0) {
|
||||
throw new Error("Invalid splitChunkSize")
|
||||
}
|
||||
|
||||
this.chunkCount = 0
|
||||
this.retriesCount = 0
|
||||
this.chunkCount = 0
|
||||
this.retriesCount = 0
|
||||
|
||||
this.splitChunkSize = splitChunkSize
|
||||
this.totalChunks = Math.ceil(file.size / splitChunkSize)
|
||||
this.splitChunkSize = splitChunkSize
|
||||
this.totalChunks = Math.ceil(file.size / splitChunkSize)
|
||||
|
||||
this.maxRetries = maxRetries
|
||||
this.delayBeforeRetry = delayBeforeRetry
|
||||
this.offline = this.paused = false
|
||||
this.maxRetries = maxRetries
|
||||
this.delayBeforeRetry = delayBeforeRetry
|
||||
this.offline = this.paused = false
|
||||
|
||||
this.endpoint = endpoint
|
||||
this.file = file
|
||||
this.headers = {
|
||||
...headers,
|
||||
"uploader-original-name": encodeURIComponent(file.name),
|
||||
"uploader-file-id": this.getFileUID(file),
|
||||
"uploader-chunks-total": this.totalChunks,
|
||||
"chunk-size": splitChunkSize,
|
||||
"Connection": "keep-alive",
|
||||
"Cache-Control": "no-cache"
|
||||
}
|
||||
this.endpoint = endpoint
|
||||
this.file = file
|
||||
this.headers = {
|
||||
...headers,
|
||||
"uploader-original-name": encodeURIComponent(file.name),
|
||||
"uploader-file-id": this.getFileUID(file),
|
||||
"uploader-chunks-total": this.totalChunks,
|
||||
"chunk-size": splitChunkSize,
|
||||
Connection: "keep-alive",
|
||||
"Cache-Control": "no-cache",
|
||||
}
|
||||
|
||||
this.setupListeners()
|
||||
this.nextSend()
|
||||
this.setupListeners()
|
||||
this.nextSend()
|
||||
|
||||
console.debug("[Uploader] Created", {
|
||||
splitChunkSize: splitChunkSize,
|
||||
totalChunks: this.totalChunks,
|
||||
totalSize: file.size
|
||||
})
|
||||
}
|
||||
console.debug("[Uploader] Created", {
|
||||
splitChunkSize: splitChunkSize,
|
||||
totalChunks: this.totalChunks,
|
||||
totalSize: file.size,
|
||||
})
|
||||
}
|
||||
|
||||
_reader = new FileReader()
|
||||
events = new EventBus()
|
||||
_reader = new FileReader()
|
||||
events = new EventBus()
|
||||
|
||||
setupListeners() {
|
||||
window.addEventListener("online", () => !this.offline && (this.offline = false, this.events.emit("online"), this.nextSend()))
|
||||
window.addEventListener("offline", () => (this.offline = true, this.events.emit("offline")))
|
||||
}
|
||||
setupListeners() {
|
||||
window.addEventListener(
|
||||
"online",
|
||||
() =>
|
||||
!this.offline &&
|
||||
((this.offline = false),
|
||||
this.events.emit("online"),
|
||||
this.nextSend()),
|
||||
)
|
||||
window.addEventListener(
|
||||
"offline",
|
||||
() => ((this.offline = true), this.events.emit("offline")),
|
||||
)
|
||||
}
|
||||
|
||||
getFileUID(file) {
|
||||
return Math.floor(Math.random() * 100000000) + Date.now() + file.size + "_tmp"
|
||||
}
|
||||
getFileUID(file) {
|
||||
return (
|
||||
Math.floor(Math.random() * 100000000) +
|
||||
Date.now() +
|
||||
file.size +
|
||||
"_tmp"
|
||||
)
|
||||
}
|
||||
|
||||
loadChunk() {
|
||||
return new Promise((resolve) => {
|
||||
const start = this.chunkCount * this.splitChunkSize
|
||||
const end = Math.min(start + this.splitChunkSize, this.file.size)
|
||||
loadChunk() {
|
||||
return new Promise((resolve) => {
|
||||
const start = this.chunkCount * this.splitChunkSize
|
||||
const end = Math.min(start + this.splitChunkSize, this.file.size)
|
||||
|
||||
this._reader.onload = () => resolve(new Blob([this._reader.result], { type: "application/octet-stream" }))
|
||||
this._reader.readAsArrayBuffer(this.file.slice(start, end))
|
||||
})
|
||||
}
|
||||
this._reader.onload = () =>
|
||||
resolve(
|
||||
new Blob([this._reader.result], {
|
||||
type: "application/octet-stream",
|
||||
}),
|
||||
)
|
||||
this._reader.readAsArrayBuffer(this.file.slice(start, end))
|
||||
})
|
||||
}
|
||||
|
||||
async sendChunk() {
|
||||
const form = new FormData()
|
||||
async sendChunk() {
|
||||
const form = new FormData()
|
||||
|
||||
form.append("file", this.chunk)
|
||||
form.append("file", this.chunk)
|
||||
|
||||
this.headers["uploader-chunk-number"] = this.chunkCount
|
||||
this.headers["uploader-chunk-number"] = this.chunkCount
|
||||
|
||||
console.log(`[UPLOADER] Sending chunk ${this.chunkCount}`, {
|
||||
currentChunk: this.chunkCount,
|
||||
totalChunks: this.totalChunks,
|
||||
})
|
||||
console.log(`[UPLOADER] Sending chunk ${this.chunkCount}`, {
|
||||
currentChunk: this.chunkCount,
|
||||
totalChunks: this.totalChunks,
|
||||
})
|
||||
|
||||
try {
|
||||
const res = await fetch(
|
||||
this.endpoint,
|
||||
{
|
||||
method: "POST",
|
||||
headers: this.headers,
|
||||
body: form,
|
||||
},
|
||||
)
|
||||
try {
|
||||
const res = await fetch(this.endpoint, {
|
||||
method: "POST",
|
||||
headers: this.headers,
|
||||
body: form,
|
||||
})
|
||||
|
||||
return res
|
||||
} catch (error) {
|
||||
this.manageRetries()
|
||||
}
|
||||
}
|
||||
return res
|
||||
} catch (error) {
|
||||
this.manageRetries()
|
||||
}
|
||||
}
|
||||
|
||||
manageRetries() {
|
||||
if (++this.retriesCount < this.maxRetries) {
|
||||
setTimeout(() => this.nextSend(), this.delayBeforeRetry * 1000)
|
||||
manageRetries() {
|
||||
if (++this.retriesCount < this.maxRetries) {
|
||||
setTimeout(() => this.nextSend(), this.delayBeforeRetry * 1000)
|
||||
|
||||
this.events.emit("fileRetry", { message: `Retrying chunk ${this.chunkCount}`, chunk: this.chunkCount, retriesLeft: this.retries - this.retriesCount })
|
||||
} else {
|
||||
this.events.emit("error", { message: `No more retries for chunk ${this.chunkCount}` })
|
||||
}
|
||||
}
|
||||
this.events.emit("fileRetry", {
|
||||
message: `Retrying chunk ${this.chunkCount}`,
|
||||
chunk: this.chunkCount,
|
||||
retriesLeft: this.retries - this.retriesCount,
|
||||
})
|
||||
} else {
|
||||
this.events.emit("error", {
|
||||
message: `No more retries for chunk ${this.chunkCount}`,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
async nextSend() {
|
||||
if (this.paused || this.offline) {
|
||||
return null
|
||||
}
|
||||
async nextSend() {
|
||||
if (this.paused || this.offline) {
|
||||
return null
|
||||
}
|
||||
|
||||
this.chunk = await this.loadChunk()
|
||||
this.chunk = await this.loadChunk()
|
||||
|
||||
const res = await this.sendChunk()
|
||||
const res = await this.sendChunk()
|
||||
|
||||
const data = await res.json()
|
||||
const data = await res.json()
|
||||
|
||||
if ([200, 201, 204].includes(res.status)) {
|
||||
console.log(`[UPLOADER] Chunk ${this.chunkCount} sent`)
|
||||
if ([200, 201, 204].includes(res.status)) {
|
||||
console.log(`[UPLOADER] Chunk ${this.chunkCount} sent`)
|
||||
|
||||
this.chunkCount = this.chunkCount + 1
|
||||
this.chunkCount = this.chunkCount + 1
|
||||
|
||||
if (this.chunkCount < this.totalChunks) {
|
||||
this.nextSend()
|
||||
}
|
||||
if (this.chunkCount < this.totalChunks) {
|
||||
this.nextSend()
|
||||
}
|
||||
|
||||
// check if is the last chunk, if so, handle sse events
|
||||
if (this.chunkCount === this.totalChunks) {
|
||||
if (data.eventChannelURL) {
|
||||
console.log(`[UPLOADER] Connecting to SSE channel >`, data.eventChannelURL)
|
||||
// check if is the last chunk, if so, handle sse events
|
||||
if (this.chunkCount === this.totalChunks) {
|
||||
if (data.eventChannelURL) {
|
||||
console.log(
|
||||
`[UPLOADER] Connecting to SSE channel >`,
|
||||
data.eventChannelURL,
|
||||
)
|
||||
|
||||
const eventSource = new EventSource(data.eventChannelURL)
|
||||
const eventSource = new EventSource(data.eventChannelURL)
|
||||
|
||||
eventSource.onerror = (error) => {
|
||||
this.events.emit("error", error)
|
||||
}
|
||||
eventSource.onerror = (error) => {
|
||||
this.events.emit("error", error)
|
||||
}
|
||||
|
||||
eventSource.onopen = () => {
|
||||
console.log(`[UPLOADER] SSE channel opened`)
|
||||
}
|
||||
eventSource.onopen = () => {
|
||||
console.log(`[UPLOADER] SSE channel opened`)
|
||||
}
|
||||
|
||||
eventSource.onmessage = (event) => {
|
||||
// parse json
|
||||
const messageData = JSON.parse(event.data)
|
||||
eventSource.onmessage = (event) => {
|
||||
// parse json
|
||||
const messageData = JSON.parse(event.data)
|
||||
|
||||
console.log(`[UPLOADER] SSE Event >`, messageData)
|
||||
console.log(`[UPLOADER] SSE Event >`, messageData)
|
||||
|
||||
if (messageData.status === "done") {
|
||||
this.events.emit("finish", messageData.result)
|
||||
eventSource.close()
|
||||
}
|
||||
if (messageData.status === "done") {
|
||||
this.events.emit("finish", messageData.result)
|
||||
eventSource.close()
|
||||
}
|
||||
|
||||
if (messageData.status === "error") {
|
||||
this.events.emit("error", messageData.result)
|
||||
}
|
||||
if (messageData.status === "error") {
|
||||
this.events.emit("error", messageData.result)
|
||||
}
|
||||
|
||||
if (messageData.status === "progress") {
|
||||
this.events.emit("progress", {
|
||||
percentProgress: messageData.progress,
|
||||
})
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.events.emit("finish", data)
|
||||
}
|
||||
}
|
||||
if (messageData.status === "progress") {
|
||||
this.events.emit("progress", {
|
||||
percentProgress: messageData.progress,
|
||||
})
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.events.emit("finish", data)
|
||||
}
|
||||
}
|
||||
|
||||
this.events.emit("progress", {
|
||||
percentProgress: Math.round((100 / this.totalChunks) * this.chunkCount)
|
||||
})
|
||||
} else if ([408, 502, 503, 504].includes(res.status)) {
|
||||
this.manageRetries()
|
||||
} else {
|
||||
this.events.emit("error", { message: `[${res.status}] ${data.error ?? data.message}` })
|
||||
}
|
||||
}
|
||||
this.events.emit("progress", {
|
||||
percentProgress: Math.round(
|
||||
(100 / this.totalChunks) * this.chunkCount,
|
||||
),
|
||||
})
|
||||
} else if ([408, 502, 503, 504].includes(res.status)) {
|
||||
this.manageRetries()
|
||||
} else {
|
||||
this.events.emit("error", {
|
||||
message: `[${res.status}] ${data.error ?? data.message}`,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
togglePause() {
|
||||
this.paused = !this.paused
|
||||
togglePause() {
|
||||
this.paused = !this.paused
|
||||
|
||||
if (!this.paused) {
|
||||
return this.nextSend()
|
||||
}
|
||||
}
|
||||
if (!this.paused) {
|
||||
return this.nextSend()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user