@@ -35,6 +48,7 @@
import { computed, ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { avatarRequest } from '../../../api';
+ import { handleImageUploadInput } from '../../../shared/utils/imageUpload';
import { useAvatarStore } from '../../../stores';
const { t } = useI18n();
@@ -68,39 +82,26 @@
}
function onFileChangeAvatarImage(e) {
- const clearFile = function () {
- changeAvatarImageDialogLoading.value = false;
- const fileInput = /** @type{HTMLInputElement} */ (document.querySelector('#AvatarImageUploadButton'));
- if (fileInput) {
- fileInput.value = '';
- }
- };
- const files = e.target.files || e.dataTransfer.files;
- if (!files.length || !avatarDialog.value.visible || avatarDialog.value.loading) {
- clearFile();
+ const { file, clearInput } = handleImageUploadInput(e, {
+ inputSelector: '#AvatarImageUploadButton',
+ tooLargeMessage: () => t('message.file.too_large'),
+ invalidTypeMessage: () => t('message.file.not_image')
+ });
+ if (!file) {
return;
}
-
- // validate file
- if (files[0].size >= 100000000) {
- // 100MB
- ElMessage({
- message: t('message.file.too_large'),
- type: 'error'
- });
- clearFile();
- return;
- }
- if (!files[0].type.match(/image.*/)) {
- ElMessage({
- message: t('message.file.not_image'),
- type: 'error'
- });
- clearFile();
+ if (!avatarDialog.value.visible || avatarDialog.value.loading) {
+ clearInput();
return;
}
const r = new FileReader();
+ const finalize = () => {
+ changeAvatarImageDialogLoading.value = false;
+ clearInput();
+ };
+ r.onerror = finalize;
+ r.onabort = finalize;
r.onload = async function () {
try {
const base64File = await resizeImageToFitLimits(btoa(r.result.toString()));
@@ -109,12 +110,17 @@
} catch (error) {
console.error('Avatar image upload process failed:', error);
} finally {
- clearFile();
+ finalize();
}
};
changeAvatarImageDialogLoading.value = true;
- r.readAsBinaryString(files[0]);
+ try {
+ r.readAsBinaryString(file);
+ } catch (error) {
+ console.error('Failed to read file', error);
+ finalize();
+ }
}
async function initiateUpload(base64File) {
diff --git a/src/components/dialogs/WorldDialog/ChangeWorldImageDialog.vue b/src/components/dialogs/WorldDialog/ChangeWorldImageDialog.vue
index 35a23d67..25ce239c 100644
--- a/src/components/dialogs/WorldDialog/ChangeWorldImageDialog.vue
+++ b/src/components/dialogs/WorldDialog/ChangeWorldImageDialog.vue
@@ -6,17 +6,30 @@
width="850px"
append-to-body
@close="closeDialog">
-
+
+
{{ t('dialog.change_content_image.description') }}
-
+
{{ t('dialog.change_content_image.upload') }}
@@ -35,6 +48,7 @@
import { ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { worldRequest } from '../../../api';
+ import { handleImageUploadInput } from '../../../shared/utils/imageUpload';
import { useWorldStore } from '../../../stores';
const { t } = useI18n();
@@ -42,7 +56,7 @@
const { worldDialog } = storeToRefs(useWorldStore());
const { applyWorld } = useWorldStore();
- const props = defineProps({
+ defineProps({
changeWorldImageDialogVisible: {
type: Boolean,
required: true
@@ -67,39 +81,26 @@
}
function onFileChangeWorldImage(e) {
- const clearFile = function () {
- changeWorldImageDialogLoading.value = false;
- const fileInput = /** @type{HTMLInputElement} */ (document.querySelector('#WorldImageUploadButton'));
- if (fileInput) {
- fileInput.value = '';
- }
- };
- const files = e.target.files || e.dataTransfer.files;
- if (!files.length || !worldDialog.value.visible || worldDialog.value.loading) {
- clearFile();
+ const { file, clearInput } = handleImageUploadInput(e, {
+ inputSelector: '#WorldImageUploadButton',
+ tooLargeMessage: () => t('message.file.too_large'),
+ invalidTypeMessage: () => t('message.file.not_image')
+ });
+ if (!file) {
return;
}
-
- // validate file
- if (files[0].size >= 100000000) {
- // 100MB
- ElMessage({
- message: t('message.file.too_large'),
- type: 'error'
- });
- clearFile();
- return;
- }
- if (!files[0].type.match(/image.*/)) {
- ElMessage({
- message: t('message.file.not_image'),
- type: 'error'
- });
- clearFile();
+ if (!worldDialog.value.visible || worldDialog.value.loading) {
+ clearInput();
return;
}
const r = new FileReader();
+ const finalize = () => {
+ changeWorldImageDialogLoading.value = false;
+ clearInput();
+ };
+ r.onerror = finalize;
+ r.onabort = finalize;
r.onload = async function () {
try {
const base64File = await resizeImageToFitLimits(btoa(r.result.toString()));
@@ -108,12 +109,17 @@
} catch (error) {
console.error('World image upload process failed:', error);
} finally {
- clearFile();
+ finalize();
}
};
changeWorldImageDialogLoading.value = true;
- r.readAsBinaryString(files[0]);
+ try {
+ r.readAsBinaryString(file);
+ } catch (error) {
+ console.error('Failed to read file', error);
+ finalize();
+ }
}
async function initiateUpload(base64File) {
diff --git a/src/shared/utils/imageUpload.js b/src/shared/utils/imageUpload.js
new file mode 100644
index 00000000..453faacb
--- /dev/null
+++ b/src/shared/utils/imageUpload.js
@@ -0,0 +1,70 @@
+import { ElMessage } from 'element-plus';
+
+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,
+ maxSize = 100000000,
+ 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) {
+ ElMessage({ message: resolveMessage(tooLargeMessage), type: 'error' });
+ }
+ 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) {
+ ElMessage({ message: resolveMessage(invalidTypeMessage), type: 'error' });
+ }
+ clearInput();
+ return { file: null, clearInput };
+ }
+
+ return { file, clearInput };
+}
diff --git a/src/stores/gallery.js b/src/stores/gallery.js
index 439ff2db..3dfdf348 100644
--- a/src/stores/gallery.js
+++ b/src/stores/gallery.js
@@ -1,7 +1,6 @@
import Noty from 'noty';
import { defineStore } from 'pinia';
import { computed, reactive, watch } from 'vue';
-import { ElMessage } from 'element-plus';
import * as workerTimers from 'worker-timers';
import {
inventoryRequest,
@@ -16,6 +15,7 @@ import {
getPrintFileName,
getPrintLocalDate
} from '../shared/utils';
+import { handleImageUploadInput } from '../shared/utils/imageUpload';
import { useAdvancedSettingsStore } from './settings/advanced';
import { useI18n } from 'vue-i18n';
@@ -266,32 +266,20 @@ export const useGalleryStore = defineStore('Gallery', () => {
}
function inviteImageUpload(e) {
- const files = e.target.files || e.dataTransfer.files;
- if (!files.length) {
- return;
- }
- if (files[0].size >= 100000000) {
- // 100MB
- ElMessage({
- message: t('message.file.too_large'),
- type: 'error'
- });
- clearInviteImageUpload();
- return;
- }
- if (!files[0].type.match(/image.*/)) {
- ElMessage({
- message: t('message.file.not_image'),
- type: 'error'
- });
- clearInviteImageUpload();
+ const { file } = handleImageUploadInput(e, {
+ inputSelector: null,
+ tooLargeMessage: () => t('message.file.too_large'),
+ invalidTypeMessage: () => t('message.file.not_image'),
+ onClear: clearInviteImageUpload
+ });
+ if (!file) {
return;
}
const r = new FileReader();
r.onload = function () {
state.uploadImage = btoa(r.result);
};
- r.readAsBinaryString(files[0]);
+ r.readAsBinaryString(file);
}
function clearInviteImageUpload() {
diff --git a/src/views/Tools/dialogs/GalleryDialog.vue b/src/views/Tools/dialogs/GalleryDialog.vue
index f2832c62..178d9ee1 100644
--- a/src/views/Tools/dialogs/GalleryDialog.vue
+++ b/src/views/Tools/dialogs/GalleryDialog.vue
@@ -6,6 +6,13 @@
width="97vw"
append-to-body
@close="closeGalleryDialog">
+
@@ -34,7 +41,7 @@
size="small"
@click="displayGalleryUpload"
:icon="Upload"
- :disabled="!currentUser.$isVRCPlus">
+ :disabled="!currentUser.$isVRCPlus || isUploading">
{{ t('dialog.gallery_icons.upload') }}
+ :disabled="!currentUser.$isVRCPlus || isUploading">
{{ t('dialog.gallery_icons.upload') }}
+ :disabled="!currentUser.$isVRCPlus || isUploading">
{{ t('dialog.gallery_icons.upload') }}
@@ -331,7 +338,7 @@
size="small"
@click="displayStickerUpload"
:icon="Upload"
- :disabled="!currentUser.$isVRCPlus">
+ :disabled="!currentUser.$isVRCPlus || isUploading">
{{ t('dialog.gallery_icons.upload') }}
@@ -398,7 +405,7 @@
size="small"
@click="displayPrintUpload"
:icon="Upload"
- :disabled="!currentUser.$isVRCPlus">
+ :disabled="!currentUser.$isVRCPlus || isUploading">
{{ t('dialog.gallery_icons.upload') }}
@@ -540,12 +547,13 @@
import { ElMessage, ElMessageBox } from 'element-plus';
import { Refresh, Upload, Close, Picture, Delete, Plus, Present } from '@element-plus/icons-vue';
import { storeToRefs } from 'pinia';
- import { ref } from 'vue';
+ import { computed, ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { miscRequest, userRequest, vrcPlusIconRequest, vrcPlusImageRequest, inventoryRequest } from '../../../api';
import { AppDebug } from '../../../service/appConfig';
import { emojiAnimationStyleList, emojiAnimationStyleUrl } from '../../../shared/constants';
import { extractFileId, formatDateFilter, getEmojiFileName, getPrintFileName } from '../../../shared/utils';
+ import { handleImageUploadInput } from '../../../shared/utils/imageUpload';
import { useAdvancedSettingsStore, useAuthStore, useGalleryStore, useUserStore } from '../../../stores';
const { t } = useI18n();
@@ -589,52 +597,65 @@
const emojiAnimationStyle = ref('Stop');
const emojiAnimLoopPingPong = ref(false);
+ const pendingUploads = ref(0);
+ const isUploading = computed(() => pendingUploads.value > 0);
+
+ function startUpload() {
+ pendingUploads.value += 1;
+ }
+
+ function finishUpload() {
+ pendingUploads.value = Math.max(0, pendingUploads.value - 1);
+ }
+
function closeGalleryDialog() {
galleryDialogVisible.value = false;
}
function onFileChangeGallery(e) {
- const clearFile = function () {
- const fileInput = /** @type {HTMLInputElement} */ (document.querySelector('#GalleryUploadButton'));
- if (fileInput) {
- fileInput.value = '';
+ const { file, clearInput } = handleImageUploadInput(e, {
+ inputSelector: '#GalleryUploadButton',
+ tooLargeMessage: () => t('message.file.too_large'),
+ invalidTypeMessage: () => t('message.file.not_image')
+ });
+ if (!file) {
+ return;
+ }
+ startUpload();
+ const r = new FileReader();
+ const handleReaderError = () => finishUpload();
+ r.onerror = handleReaderError;
+ r.onabort = handleReaderError;
+ r.onload = function () {
+ try {
+ const base64Body = btoa(r.result.toString());
+ vrcPlusImageRequest
+ .uploadGalleryImage(base64Body)
+ .then((args) => {
+ handleGalleryImageAdd(args);
+ ElMessage({
+ message: t('message.gallery.uploaded'),
+ type: 'success'
+ });
+ return args;
+ })
+ .catch((error) => {
+ console.error('Failed to upload', error);
+ })
+ .finally(() => finishUpload());
+ } catch (error) {
+ finishUpload();
+ console.error('Failed to process image', error);
}
};
- const files = e.target.files || e.dataTransfer.files;
- if (!files.length) {
- return;
+ try {
+ r.readAsBinaryString(file);
+ } catch (error) {
+ clearInput();
+ finishUpload();
+ console.error('Failed to read file', error);
}
- if (files[0].size >= 100000000) {
- // 100MB
- ElMessage({
- message: t('message.file.too_large'),
- type: 'error'
- });
- clearFile();
- return;
- }
- if (!files[0].type.match(/image.*/)) {
- ElMessage({
- message: t('message.file.not_image'),
- type: 'error'
- });
- clearFile();
- return;
- }
- const r = new FileReader();
- r.onload = function () {
- const base64Body = btoa(r.result.toString());
- vrcPlusImageRequest.uploadGalleryImage(base64Body).then((args) => {
- handleGalleryImageAdd(args);
- ElMessage({
- message: t('message.gallery.uploaded'),
- type: 'success'
- });
- return args;
- });
- };
- r.readAsBinaryString(files[0]);
- clearFile();
+ clearInput();
}
function displayGalleryUpload() {
@@ -693,49 +714,51 @@
}
function onFileChangeVRCPlusIcon(e) {
- const clearFile = function () {
- const fileInput = /** @type {HTMLInputElement} */ (document.querySelector('#VRCPlusIconUploadButton'));
- if (fileInput) {
- fileInput.value = '';
+ const { file, clearInput } = handleImageUploadInput(e, {
+ inputSelector: '#VRCPlusIconUploadButton',
+ tooLargeMessage: () => t('message.file.too_large'),
+ invalidTypeMessage: () => t('message.file.not_image')
+ });
+ if (!file) {
+ return;
+ }
+ startUpload();
+ const r = new FileReader();
+ const handleReaderError = () => finishUpload();
+ r.onerror = handleReaderError;
+ r.onabort = handleReaderError;
+ r.onload = function () {
+ try {
+ const base64Body = btoa(r.result.toString());
+ vrcPlusIconRequest
+ .uploadVRCPlusIcon(base64Body)
+ .then((args) => {
+ if (Object.keys(VRCPlusIconsTable.value).length !== 0) {
+ VRCPlusIconsTable.value.unshift(args.json);
+ }
+ ElMessage({
+ message: t('message.icon.uploaded'),
+ type: 'success'
+ });
+ return args;
+ })
+ .catch((error) => {
+ console.error('Failed to upload VRC+ icon', error);
+ })
+ .finally(() => finishUpload());
+ } catch (error) {
+ finishUpload();
+ console.error('Failed to process upload', error);
}
};
- const files = e.target.files || e.dataTransfer.files;
- if (!files.length) {
- return;
+ try {
+ r.readAsBinaryString(file);
+ } catch (error) {
+ clearInput();
+ finishUpload();
+ console.error('Failed to read file', error);
}
- if (files[0].size >= 100000000) {
- // 100MB
- ElMessage({
- message: t('message.file.too_large'),
- type: 'error'
- });
- clearFile();
- return;
- }
- if (!files[0].type.match(/image.*/)) {
- ElMessage({
- message: t('message.file.not_image'),
- type: 'error'
- });
- clearFile();
- return;
- }
- const r = new FileReader();
- r.onload = function () {
- const base64Body = btoa(r.result.toString());
- vrcPlusIconRequest.uploadVRCPlusIcon(base64Body).then((args) => {
- if (Object.keys(VRCPlusIconsTable.value).length !== 0) {
- VRCPlusIconsTable.value.unshift(args.json);
- }
- ElMessage({
- message: t('message.icon.uploaded'),
- type: 'success'
- });
- return args;
- });
- };
- r.readAsBinaryString(files[0]);
- clearFile();
+ clearInput();
}
function displayVRCPlusIconUpload() {
@@ -816,63 +839,65 @@
}
function onFileChangeEmoji(e) {
- const clearFile = function () {
- const fileInput = /** @type {HTMLInputElement} */ (document.querySelector('#EmojiUploadButton'));
- if (fileInput) {
- fileInput.value = '';
- }
- };
- const files = e.target.files || e.dataTransfer.files;
- if (!files.length) {
- return;
- }
- if (files[0].size >= 100000000) {
- // 100MB
- ElMessage({
- message: t('message.file.too_large'),
- type: 'error'
- });
- clearFile();
- return;
- }
- if (!files[0].type.match(/image.*/)) {
- ElMessage({
- message: t('message.file.not_image'),
- type: 'error'
- });
- clearFile();
+ const { file, clearInput } = handleImageUploadInput(e, {
+ inputSelector: '#EmojiUploadButton',
+ tooLargeMessage: () => t('message.file.too_large'),
+ invalidTypeMessage: () => t('message.file.not_image')
+ });
+ if (!file) {
return;
}
+ startUpload();
// set Emoji settings from fileName
- parseEmojiFileName(files[0].name);
+ parseEmojiFileName(file.name);
const r = new FileReader();
+ const handleReaderError = () => finishUpload();
+ r.onerror = handleReaderError;
+ r.onabort = handleReaderError;
r.onload = function () {
- const params = {
- tag: emojiAnimType.value ? 'emojianimated' : 'emoji',
- animationStyle: emojiAnimationStyle.value.toLowerCase(),
- maskTag: 'square'
- };
- if (emojiAnimType.value) {
- params.frames = emojiAnimFrameCount.value;
- params.framesOverTime = emojiAnimFps.value;
- }
- if (emojiAnimLoopPingPong.value) {
- params.loopStyle = 'pingpong';
- }
- const base64Body = btoa(r.result.toString());
- vrcPlusImageRequest.uploadEmoji(base64Body, params).then((args) => {
- if (Object.keys(emojiTable.value).length !== 0) {
- emojiTable.value.unshift(args.json);
+ try {
+ const params = {
+ tag: emojiAnimType.value ? 'emojianimated' : 'emoji',
+ animationStyle: emojiAnimationStyle.value.toLowerCase(),
+ maskTag: 'square'
+ };
+ if (emojiAnimType.value) {
+ params.frames = emojiAnimFrameCount.value;
+ params.framesOverTime = emojiAnimFps.value;
}
- ElMessage({
- message: t('message.emoji.uploaded'),
- type: 'success'
- });
- return args;
- });
+ if (emojiAnimLoopPingPong.value) {
+ params.loopStyle = 'pingpong';
+ }
+ const base64Body = btoa(r.result.toString());
+ vrcPlusImageRequest
+ .uploadEmoji(base64Body, params)
+ .then((args) => {
+ if (Object.keys(emojiTable.value).length !== 0) {
+ emojiTable.value.unshift(args.json);
+ }
+ ElMessage({
+ message: t('message.emoji.uploaded'),
+ type: 'success'
+ });
+ return args;
+ })
+ .catch((error) => {
+ console.error('Failed to upload', error);
+ })
+ .finally(() => finishUpload());
+ } catch (error) {
+ finishUpload();
+ console.error('Failed to process upload', error);
+ }
};
- r.readAsBinaryString(files[0]);
- clearFile();
+ try {
+ r.readAsBinaryString(file);
+ } catch (error) {
+ clearInput();
+ finishUpload();
+ console.error('Failed to read file', error);
+ }
+ clearInput();
}
function displayEmojiUpload() {
@@ -913,51 +938,53 @@
}
function onFileChangeSticker(e) {
- const clearFile = function () {
- const fileInput = /** @type {HTMLInputElement} */ (document.querySelector('#StickerUploadButton'));
- if (fileInput) {
- fileInput.value = '';
+ const { file, clearInput } = handleImageUploadInput(e, {
+ inputSelector: '#StickerUploadButton',
+ tooLargeMessage: () => t('message.file.too_large'),
+ invalidTypeMessage: () => t('message.file.not_image')
+ });
+ if (!file) {
+ return;
+ }
+ startUpload();
+ const r = new FileReader();
+ const handleReaderError = () => finishUpload();
+ r.onerror = handleReaderError;
+ r.onabort = handleReaderError;
+ r.onload = function () {
+ try {
+ const params = {
+ tag: 'sticker',
+ maskTag: 'square'
+ };
+ const base64Body = btoa(r.result.toString());
+ vrcPlusImageRequest
+ .uploadSticker(base64Body, params)
+ .then((args) => {
+ handleStickerAdd(args);
+ ElMessage({
+ message: t('message.sticker.uploaded'),
+ type: 'success'
+ });
+ return args;
+ })
+ .catch((error) => {
+ console.error('Failed to upload', error);
+ })
+ .finally(() => finishUpload());
+ } catch (error) {
+ finishUpload();
+ console.error('Failed to process upload', error);
}
};
- const files = e.target.files || e.dataTransfer.files;
- if (!files.length) {
- return;
+ try {
+ r.readAsBinaryString(file);
+ } catch (error) {
+ clearInput();
+ finishUpload();
+ console.error('Failed to read file', error);
}
- if (files[0].size >= 100000000) {
- // 100MB
- ElMessage({
- message: t('message.file.too_large'),
- type: 'error'
- });
- clearFile();
- return;
- }
- if (!files[0].type.match(/image.*/)) {
- ElMessage({
- message: t('message.file.not_image'),
- type: 'error'
- });
- clearFile();
- return;
- }
- const r = new FileReader();
- r.onload = function () {
- const params = {
- tag: 'sticker',
- maskTag: 'square'
- };
- const base64Body = btoa(r.result.toString());
- vrcPlusImageRequest.uploadSticker(base64Body, params).then((args) => {
- handleStickerAdd(args);
- ElMessage({
- message: t('message.sticker.uploaded'),
- type: 'success'
- });
- return args;
- });
- };
- r.readAsBinaryString(files[0]);
- clearFile();
+ clearInput();
}
function displayStickerUpload() {
@@ -980,60 +1007,62 @@
}
function onFileChangePrint(e) {
- const clearFile = function () {
- const fileInput = /** @type {HTMLInputElement} */ (document.querySelector('#PrintUploadButton'));
- if (fileInput) {
- fileInput.value = '';
+ const { file, clearInput } = handleImageUploadInput(e, {
+ inputSelector: '#PrintUploadButton',
+ tooLargeMessage: () => t('message.file.too_large'),
+ invalidTypeMessage: () => t('message.file.not_image')
+ });
+ if (!file) {
+ return;
+ }
+ startUpload();
+ const r = new FileReader();
+ const handleReaderError = () => finishUpload();
+ r.onerror = handleReaderError;
+ r.onabort = handleReaderError;
+ r.onload = function () {
+ try {
+ const date = new Date();
+ // why the fuck isn't this UTC
+ date.setMinutes(date.getMinutes() - date.getTimezoneOffset());
+ const timestamp = date.toISOString().slice(0, 19);
+ const params = {
+ note: printUploadNote.value,
+ // worldId: '',
+ timestamp
+ };
+ const base64Body = btoa(r.result.toString());
+ const cropWhiteBorder = printCropBorder.value;
+ vrcPlusImageRequest
+ .uploadPrint(base64Body, cropWhiteBorder, params)
+ .then((args) => {
+ ElMessage({
+ message: t('message.print.uploaded'),
+ type: 'success'
+ });
+ if (Object.keys(printTable.value).length !== 0) {
+ printTable.value.unshift(args.json);
+ }
+
+ return args;
+ })
+ .catch((error) => {
+ console.error('Failed to upload', error);
+ })
+ .finally(() => finishUpload());
+ } catch (error) {
+ finishUpload();
+ console.error('Failed to process upload', error);
}
};
- const files = e.target.files || e.dataTransfer.files;
- if (!files.length) {
- return;
+ try {
+ r.readAsBinaryString(file);
+ } catch (error) {
+ clearInput();
+ finishUpload();
+ console.error('Failed to read file', error);
}
- if (files[0].size >= 100000000) {
- // 100MB
- ElMessage({
- message: t('message.file.too_large'),
- type: 'error'
- });
- clearFile();
- return;
- }
- if (!files[0].type.match(/image.*/)) {
- ElMessage({
- message: t('message.file.not_image'),
- type: 'error'
- });
- clearFile();
- return;
- }
- const r = new FileReader();
- r.onload = function () {
- const date = new Date();
- // why the fuck isn't this UTC
- date.setMinutes(date.getMinutes() - date.getTimezoneOffset());
- const timestamp = date.toISOString().slice(0, 19);
- const params = {
- note: printUploadNote.value,
- // worldId: '',
- timestamp
- };
- const base64Body = btoa(r.result.toString());
- const cropWhiteBorder = printCropBorder.value;
- vrcPlusImageRequest.uploadPrint(base64Body, cropWhiteBorder, params).then((args) => {
- ElMessage({
- message: t('message.print.uploaded'),
- type: 'success'
- });
- if (Object.keys(printTable.value).length !== 0) {
- printTable.value.unshift(args.json);
- }
-
- return args;
- });
- };
- r.readAsBinaryString(files[0]);
- clearFile();
+ clearInput();
}
function displayPrintUpload() {