mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-04-21 07:43:50 +02:00
refactor untils
This commit is contained in:
198
src/coordinators/imageUploadCoordinator.js
Normal file
198
src/coordinators/imageUploadCoordinator.js
Normal file
@@ -0,0 +1,198 @@
|
||||
import { toast } from 'vue-sonner';
|
||||
|
||||
import { $throw } from '../services/request';
|
||||
import { AppDebug } from '../services/appConfig.js';
|
||||
import { extractFileId } from '../shared/utils';
|
||||
import { imageRequest } from '../api';
|
||||
|
||||
function resolveMessage(message) {
|
||||
if (typeof message === 'function') {
|
||||
return message();
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
function getInputElement(selector) {
|
||||
if (!selector) {
|
||||
return null;
|
||||
}
|
||||
if (typeof selector === 'function') {
|
||||
return selector();
|
||||
}
|
||||
if (typeof selector === 'string') {
|
||||
return document.querySelector(selector);
|
||||
}
|
||||
return selector;
|
||||
}
|
||||
|
||||
export function handleImageUploadInput(event, options = {}) {
|
||||
const {
|
||||
inputSelector,
|
||||
// 20MB
|
||||
maxSize = 20000000,
|
||||
acceptPattern = /image.*/,
|
||||
tooLargeMessage,
|
||||
invalidTypeMessage,
|
||||
onClear
|
||||
} = options;
|
||||
|
||||
const clearInput = () => {
|
||||
onClear?.();
|
||||
const input = getInputElement(inputSelector);
|
||||
if (input) {
|
||||
input.value = '';
|
||||
}
|
||||
};
|
||||
|
||||
const files = event?.target?.files || event?.dataTransfer?.files;
|
||||
if (!files || files.length === 0) {
|
||||
clearInput();
|
||||
return { file: null, clearInput };
|
||||
}
|
||||
|
||||
const file = files[0];
|
||||
if (file.size >= maxSize) {
|
||||
if (tooLargeMessage) {
|
||||
toast.error(resolveMessage(tooLargeMessage));
|
||||
}
|
||||
clearInput();
|
||||
return { file: null, clearInput };
|
||||
}
|
||||
|
||||
let acceptRegex = null;
|
||||
if (acceptPattern) {
|
||||
acceptRegex =
|
||||
acceptPattern instanceof RegExp
|
||||
? acceptPattern
|
||||
: new RegExp(acceptPattern);
|
||||
}
|
||||
|
||||
if (acceptRegex && !acceptRegex.test(file.type)) {
|
||||
if (invalidTypeMessage) {
|
||||
toast.error(resolveMessage(invalidTypeMessage));
|
||||
}
|
||||
clearInput();
|
||||
return { file: null, clearInput };
|
||||
}
|
||||
|
||||
return { file, clearInput };
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} base64Data - base64 encoded image
|
||||
* @returns {Promise<string>} resized base64 encoded image
|
||||
*/
|
||||
export async function resizeImageToFitLimits(base64Data) {
|
||||
// frontend limit check = 20MB
|
||||
return AppApi.ResizeImageToFitLimits(base64Data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload image through AWS
|
||||
* @param {'avatar'|'world'} type
|
||||
* @param {object} opts
|
||||
* @param {string} opts.entityId - avatar or world id
|
||||
* @param {string} opts.imageUrl - current imageUrl on the entity
|
||||
* @param {string} opts.base64File - base64 encoded image data
|
||||
* @param {Blob} opts.blob - the original blob (used for file size)
|
||||
*/
|
||||
export async function uploadImageLegacy(
|
||||
type,
|
||||
{ entityId, imageUrl, base64File, blob }
|
||||
) {
|
||||
const apiMap = {
|
||||
avatar: {
|
||||
uploadImage: imageRequest.uploadAvatarImage,
|
||||
fileStart: imageRequest.uploadAvatarImageFileStart,
|
||||
fileFinish: imageRequest.uploadAvatarImageFileFinish,
|
||||
sigStart: imageRequest.uploadAvatarImageSigStart,
|
||||
sigFinish: imageRequest.uploadAvatarImageSigFinish,
|
||||
setImage: imageRequest.setAvatarImage
|
||||
},
|
||||
world: {
|
||||
uploadImage: imageRequest.uploadWorldImage,
|
||||
fileStart: imageRequest.uploadWorldImageFileStart,
|
||||
fileFinish: imageRequest.uploadWorldImageFileFinish,
|
||||
sigStart: imageRequest.uploadWorldImageSigStart,
|
||||
sigFinish: imageRequest.uploadWorldImageSigFinish,
|
||||
setImage: imageRequest.setWorldImage
|
||||
}
|
||||
};
|
||||
const api = apiMap[type];
|
||||
|
||||
const fileMd5 = await AppApi.MD5File(base64File);
|
||||
const fileSizeInBytes = parseInt(blob.size, 10);
|
||||
const base64SignatureFile = await AppApi.SignFile(base64File);
|
||||
const signatureMd5 = await AppApi.MD5File(base64SignatureFile);
|
||||
const signatureSizeInBytes = parseInt(
|
||||
await AppApi.FileLength(base64SignatureFile),
|
||||
10
|
||||
);
|
||||
const fileId = extractFileId(imageUrl);
|
||||
|
||||
// imageInit
|
||||
const uploadRes = await api.uploadImage(
|
||||
{ fileMd5, fileSizeInBytes, signatureMd5, signatureSizeInBytes },
|
||||
fileId
|
||||
);
|
||||
const uploadedFileId = uploadRes.json.id;
|
||||
const fileVersion =
|
||||
uploadRes.json.versions[uploadRes.json.versions.length - 1].version;
|
||||
|
||||
// imageFileStart
|
||||
const fileStartRes = await api.fileStart({
|
||||
fileId: uploadedFileId,
|
||||
fileVersion
|
||||
});
|
||||
|
||||
// uploadImageFileAWS
|
||||
const fileAwsRes = await webApiService.execute({
|
||||
url: fileStartRes.json.url,
|
||||
uploadFilePUT: true,
|
||||
fileData: base64File,
|
||||
fileMIME: 'image/png',
|
||||
fileMD5: fileMd5
|
||||
});
|
||||
if (fileAwsRes.status !== 200) {
|
||||
$throw(
|
||||
fileAwsRes.status,
|
||||
`${type} image upload failed`,
|
||||
fileStartRes.json.url
|
||||
);
|
||||
}
|
||||
|
||||
// imageFileFinish
|
||||
await api.fileFinish({ fileId: uploadedFileId, fileVersion });
|
||||
|
||||
// imageSigStart
|
||||
const sigStartRes = await api.sigStart({
|
||||
fileId: uploadedFileId,
|
||||
fileVersion
|
||||
});
|
||||
|
||||
// uploadImageSigAWS
|
||||
const sigAwsRes = await webApiService.execute({
|
||||
url: sigStartRes.json.url,
|
||||
uploadFilePUT: true,
|
||||
fileData: base64SignatureFile,
|
||||
fileMIME: 'application/x-rsync-signature',
|
||||
fileMD5: signatureMd5
|
||||
});
|
||||
if (sigAwsRes.status !== 200) {
|
||||
$throw(
|
||||
sigAwsRes.status,
|
||||
`${type} image upload failed`,
|
||||
sigStartRes.json.url
|
||||
);
|
||||
}
|
||||
|
||||
// imageSigFinish
|
||||
await api.sigFinish({ fileId: uploadedFileId, fileVersion });
|
||||
|
||||
// imageSet
|
||||
const newImageUrl = `${AppDebug.endpointDomain}/file/${uploadedFileId}/${fileVersion}/file`;
|
||||
const setRes = await api.setImage({ id: entityId, imageUrl: newImageUrl });
|
||||
if (setRes.json.imageUrl !== newImageUrl) {
|
||||
$throw(0, `${type} image change failed`, newImageUrl);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user