From 020eff858bf05673b2aa2c216744809eabf205de Mon Sep 17 00:00:00 2001 From: Supertiger Date: Fri, 11 Oct 2024 21:57:06 +0100 Subject: [PATCH] Update cdn handling --- src/chat-api/services/Request.ts | 22 ++-- src/chat-api/services/nerimityCDNService.ts | 106 +++++++++++++------- src/components/settings/AccountSettings.tsx | 12 ++- 3 files changed, 95 insertions(+), 45 deletions(-) diff --git a/src/chat-api/services/Request.ts b/src/chat-api/services/Request.ts index beddcd51..925b652a 100644 --- a/src/chat-api/services/Request.ts +++ b/src/chat-api/services/Request.ts @@ -37,7 +37,9 @@ export async function request(opts: RequestOpts): Promise { ...(!(opts.body instanceof FormData) ? { "Content-Type": "application/json" } : undefined), - Authorization: opts.useToken ? opts.token || token : "", + ...(opts.useToken || opts.token + ? { Authorization: opts.token || token } + : {}), }, }).catch((err) => { throw { message: "Could not connect to server. " + err.message }; @@ -121,8 +123,9 @@ export function xhrRequest( }); } - -export const createProgressHandler = (onProgress?: (percent: number, speed?: string) => void) => { +export const createProgressHandler = ( + onProgress?: (percent: number, speed?: string) => void +) => { let startTime = 0; let uploadedSize = 0; return (e: ProgressEvent) => { @@ -137,14 +140,17 @@ export const createProgressHandler = (onProgress?: (percent: number, speed?: str const uploadSpeedMBps = uploadSpeedKBps / 1024; // Megabytes per second // Choose the appropriate unit based on the speed - let unit = ' KB/s'; + let unit = " KB/s"; if (uploadSpeedMBps >= 1) { - unit = ' MB/s'; + unit = " MB/s"; } - let speed: string | undefined = uploadSpeedMBps >= 1 ? uploadSpeedMBps.toFixed(2) + unit : uploadSpeedKBps.toFixed(0) + unit; + let speed: string | undefined = + uploadSpeedMBps >= 1 + ? uploadSpeedMBps.toFixed(2) + unit + : uploadSpeedKBps.toFixed(0) + unit; if (uploadSpeedMBps == Infinity) { - speed = "0 KB/s" + speed = "0 KB/s"; } if (e.lengthComputable) { @@ -152,4 +158,4 @@ export const createProgressHandler = (onProgress?: (percent: number, speed?: str onProgress?.(Math.round(percentComplete), speed); } }; -} \ No newline at end of file +}; diff --git a/src/chat-api/services/nerimityCDNService.ts b/src/chat-api/services/nerimityCDNService.ts index af371907..fd7eef79 100644 --- a/src/chat-api/services/nerimityCDNService.ts +++ b/src/chat-api/services/nerimityCDNService.ts @@ -1,6 +1,5 @@ import env from "@/common/env"; -import { xhrRequest } from "./Request"; - +import { request, xhrRequest } from "./Request"; interface NerimityCDNRequestOpts { url: string; @@ -9,56 +8,93 @@ interface NerimityCDNRequestOpts { onUploadProgress?: (progress: number) => void; } - - -export function uploadBanner(groupId: string, opts: Omit) { - return nerimityCDNRequest({ - ...opts, - url: `${env.NERIMITY_CDN}banners/${groupId}`, - }) +export async function uploadBanner( + groupId: string, + opts: Omit +) { + return nerimityCDNUploadRequest({ ...opts, image: true }).then((res) => { + return nerimityCDNRequest({ + ...opts, + url: `${env.NERIMITY_CDN}banners/${groupId}/${res.fileId}`, + }); + }); } -export function uploadAvatar(groupId: string, opts: Omit & { points?: number[] }) { - return nerimityCDNRequest({ - ...opts, - query: { - points: opts.points ? JSON.stringify(opts.points) : undefined, - }, - url: `${env.NERIMITY_CDN}avatars/${groupId}`, - }) +export async function uploadAvatar( + groupId: string, + opts: Omit & { points?: number[] } +) { + return nerimityCDNUploadRequest({ ...opts, image: true }).then((res) => { + return nerimityCDNRequest({ + ...opts, + query: { + points: opts.points ? JSON.stringify(opts.points) : undefined, + }, + url: `${env.NERIMITY_CDN}avatars/${groupId}/${res.fileId}`, + }); + }); } - -export function uploadEmoji(opts: Omit) { - return nerimityCDNRequest({ - ...opts, - url: `${env.NERIMITY_CDN}emojis`, - }) +export async function uploadEmoji(opts: Omit) { + return nerimityCDNUploadRequest({ ...opts, image: true }).then((res) => { + return nerimityCDNRequest({ + ...opts, + url: `${env.NERIMITY_CDN}emojis/${res.fileId}`, + }); + }); } -export function uploadAttachment(groupId: string, opts: Omit) { - return nerimityCDNRequest({ - ...opts, - url: `${env.NERIMITY_CDN}attachments/${groupId}`, - }) +export async function uploadAttachment( + groupId: string, + opts: Omit +) { + return nerimityCDNUploadRequest({ ...opts }).then((res) => { + return nerimityCDNRequest({ + ...opts, + url: `${env.NERIMITY_CDN}attachments/${groupId}/${res.fileId}`, + }); + }); } -function nerimityCDNRequest(opts: NerimityCDNRequestOpts) { - const url = new URL(opts.url); +function nerimityCDNUploadRequest(opts: { + image?: boolean; + file: File; + onUploadProgress?: (percent: number, speed?: string) => void; +}) { + const url = new URL(`${env.NERIMITY_CDN}upload`); - if (opts.query) { - url.search = new URLSearchParams(JSON.parse(JSON.stringify(opts.query))).toString(); + if (opts.image) { + url.search = new URLSearchParams({ image: "true" }).toString(); } const formData = new FormData(); - formData.append("attachment", opts.file); + formData.append("f", opts.file); return xhrRequest<{ fileId: string }>( { method: "POST", url: url.href, body: formData, - useToken: false + useToken: false, }, opts.onUploadProgress ); -} \ No newline at end of file +} + +function nerimityCDNRequest(opts: NerimityCDNRequestOpts) { + const url = new URL(opts.url); + + if (opts.query) { + url.search = new URLSearchParams( + JSON.parse(JSON.stringify(opts.query)) + ).toString(); + } + + const formData = new FormData(); + formData.append("attachment", opts.file); + + return request<{ fileId: string }>({ + method: "POST", + url: url.href, + useToken: false, + }); +} diff --git a/src/components/settings/AccountSettings.tsx b/src/components/settings/AccountSettings.tsx index ca39e38d..2a7df160 100644 --- a/src/components/settings/AccountSettings.tsx +++ b/src/components/settings/AccountSettings.tsx @@ -171,15 +171,23 @@ export function EditAccountPage(props: { const res = await uploadAvatar(props.bot?.id || account.user()?.id!, { file: avatar, points: avatarPoints!, + }).catch((err) => { + setError(err.message); }); - avatarId = res.fileId; + if (res) { + avatarId = res.fileId; + } } if (banner) { const res = await uploadBanner(props.bot?.id || account.user()?.id!, { file: banner, + }).catch((err) => { + setError(err.message); }); - bannerId = res.fileId; + if (res) { + bannerId = res.fileId; + } } await updateUser({ ...values, bannerId, avatarId }, props.botToken)