diff --git a/src/components/dialogs/AvatarDialog/AvatarDialog.vue b/src/components/dialogs/AvatarDialog/AvatarDialog.vue
index 97b22317..aa127861 100644
--- a/src/components/dialogs/AvatarDialog/AvatarDialog.vue
+++ b/src/components/dialogs/AvatarDialog/AvatarDialog.vue
@@ -345,17 +345,9 @@
:disabled="avatarDialog.galleryLoading"
class="ml-1"
@click="displayAvatarGalleryUpload">
-
-
+
{{ t('dialog.screenshot_metadata.upload') }}
-
@@ -543,7 +535,6 @@
import { Button } from '@/components/ui/button';
import { ElMessageBox } from 'element-plus';
import { InputGroupTextareaField } from '@/components/ui/input-group';
- import { Spinner } from '@/components/ui/spinner';
import { storeToRefs } from 'pinia';
import { toast } from 'vue-sonner';
import { useI18n } from 'vue-i18n';
@@ -1092,14 +1083,17 @@
try {
avatarDialog.value.galleryLoading = true;
const base64Body = btoa(r.result.toString());
- avatarRequest
- .uploadAvatarGalleryImage(base64Body, avatarDialog.value.id)
- .then(async (args) => {
- toast.success(t('message.avatar_gallery.uploaded'));
- console.log(args);
- avatarDialog.value.galleryImages = await getAvatarGallery(avatarDialog.value.id);
- return args;
- })
+ const uploadPromise = (async () => {
+ const args = await avatarRequest.uploadAvatarGalleryImage(base64Body, avatarDialog.value.id);
+ avatarDialog.value.galleryImages = await getAvatarGallery(avatarDialog.value.id);
+ return args;
+ })();
+ toast.promise(uploadPromise, {
+ loading: t('message.upload.loading'),
+ success: t('message.upload.success'),
+ error: t('message.upload.error')
+ });
+ uploadPromise
.catch((error) => {
console.error('Failed to upload image', error);
})
diff --git a/src/components/dialogs/AvatarDialog/ChangeAvatarImageDialog.vue b/src/components/dialogs/AvatarDialog/ChangeAvatarImageDialog.vue
index b35ed864..9ec27a78 100644
--- a/src/components/dialogs/AvatarDialog/ChangeAvatarImageDialog.vue
+++ b/src/components/dialogs/AvatarDialog/ChangeAvatarImageDialog.vue
@@ -13,13 +13,6 @@
accept="image/*"
style="display: none"
@change="onFileChangeAvatarImage" />
-
{{ t('dialog.change_content_image.description') }}
@@ -41,7 +33,6 @@
+
+
+
+
+
+
diff --git a/src/components/ui/progress/index.js b/src/components/ui/progress/index.js
new file mode 100644
index 00000000..63f2d58f
--- /dev/null
+++ b/src/components/ui/progress/index.js
@@ -0,0 +1 @@
+export { default as Progress } from './Progress.vue';
diff --git a/src/localization/en.json b/src/localization/en.json
index 998b201c..68180c31 100644
--- a/src/localization/en.json
+++ b/src/localization/en.json
@@ -1971,6 +1971,11 @@
"already_last": "Already last image",
"reordered": "Successfully reordered avatar gallery images"
},
+ "upload": {
+ "loading": "Uploading",
+ "success": "Upload completed",
+ "error": "Upload failed"
+ },
"world": {
"image_changed": "World image changed",
"image_invalid": "Current world image invalid"
diff --git a/src/views/Charts/components/MutualFriends.vue b/src/views/Charts/components/MutualFriends.vue
index d58025ba..9312dc73 100644
--- a/src/views/Charts/components/MutualFriends.vue
+++ b/src/views/Charts/components/MutualFriends.vue
@@ -35,7 +35,7 @@
{{ fetchState.processedFriends }} / {{ totalFriends }}
-
+
@@ -144,6 +144,7 @@
import { Button } from '@/components/ui/button';
import { ElMessageBox } from 'element-plus';
import { Settings } from 'lucide-vue-next';
+ import { Progress } from '@/components/ui/progress';
import { Spinner } from '@/components/ui/spinner';
import { onBeforeRouteLeave } from 'vue-router';
import { storeToRefs } from 'pinia';
@@ -213,7 +214,6 @@
const progressPercent = computed(() =>
totalFriends.value ? Math.min(100, Math.round((fetchState.processedFriends / totalFriends.value) * 100)) : 0
);
- const progressStatus = computed(() => (isFetching.value ? 'warning' : ''));
const forceDefaults = computed(() =>
computeForceOptions(graphPayload.value?.nodes ?? [], graphPayload.value?.links ?? [])
);
diff --git a/src/views/FriendList/FriendList.vue b/src/views/FriendList/FriendList.vue
index f0a5dc3c..8c1e23b2 100644
--- a/src/views/FriendList/FriendList.vue
+++ b/src/views/FriendList/FriendList.vue
@@ -241,10 +241,10 @@
:show-close="false"
align-center>
-
+
+
+
{{ friendsListLoadingPercent }}%
+
{{ friendsListLoadingCurrent }} / {{ friendsListLoadingTotal }}
@@ -262,6 +262,7 @@
import { computed, nextTick, reactive, ref, watch } from 'vue';
import { Button } from '@/components/ui/button';
import { InputGroupField } from '@/components/ui/input-group';
+ import { Progress } from '@/components/ui/progress';
import { ElMessageBox } from 'element-plus';
import { storeToRefs } from 'pinia';
import { toast } from 'vue-sonner';
diff --git a/src/views/Tools/Gallery.vue b/src/views/Tools/Gallery.vue
index 53332c15..989c4f7d 100644
--- a/src/views/Tools/Gallery.vue
+++ b/src/views/Tools/Gallery.vue
@@ -6,13 +6,6 @@
-
@@ -680,13 +673,16 @@
r.onload = function () {
try {
const base64Body = btoa(r.result.toString());
- vrcPlusImageRequest
- .uploadGalleryImage(base64Body)
- .then((args) => {
- handleGalleryImageAdd(args);
- toast.success(t('message.gallery.uploaded'));
- return args;
- })
+ const uploadPromise = vrcPlusImageRequest.uploadGalleryImage(base64Body).then((args) => {
+ handleGalleryImageAdd(args);
+ return args;
+ });
+ toast.promise(uploadPromise, {
+ loading: t('message.upload.loading'),
+ success: t('message.upload.success'),
+ error: t('message.upload.error')
+ });
+ uploadPromise
.catch((error) => {
console.error('Failed to upload', error);
})
@@ -772,15 +768,18 @@
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);
- }
- toast.success(t('message.icon.uploaded'));
- return args;
- })
+ const uploadPromise = vrcPlusIconRequest.uploadVRCPlusIcon(base64Body).then((args) => {
+ if (Object.keys(VRCPlusIconsTable.value).length !== 0) {
+ VRCPlusIconsTable.value.unshift(args.json);
+ }
+ return args;
+ });
+ toast.promise(uploadPromise, {
+ loading: t('message.upload.loading'),
+ success: t('message.upload.success'),
+ error: t('message.upload.error')
+ });
+ uploadPromise
.catch((error) => {
console.error('Failed to upload VRC+ icon', error);
})
@@ -902,15 +901,18 @@
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);
- }
- toast.success(t('message.emoji.uploaded'));
- return args;
- })
+ const uploadPromise = vrcPlusImageRequest.uploadEmoji(base64Body, params).then((args) => {
+ if (Object.keys(emojiTable.value).length !== 0) {
+ emojiTable.value.unshift(args.json);
+ }
+ return args;
+ });
+ toast.promise(uploadPromise, {
+ loading: t('message.upload.loading'),
+ success: t('message.upload.success'),
+ error: t('message.upload.error')
+ });
+ uploadPromise
.catch((error) => {
console.error('Failed to upload', error);
})
@@ -969,13 +971,16 @@
maskTag: 'square'
};
const base64Body = btoa(r.result.toString());
- vrcPlusImageRequest
- .uploadSticker(base64Body, params)
- .then((args) => {
- handleStickerAdd(args);
- toast.success(t('message.sticker.uploaded'));
- return args;
- })
+ const uploadPromise = vrcPlusImageRequest.uploadSticker(base64Body, params).then((args) => {
+ handleStickerAdd(args);
+ return args;
+ });
+ toast.promise(uploadPromise, {
+ loading: t('message.upload.loading'),
+ success: t('message.upload.success'),
+ error: t('message.upload.error')
+ });
+ uploadPromise
.catch((error) => {
console.error('Failed to upload', error);
})
@@ -1041,16 +1046,20 @@
};
const base64Body = btoa(r.result.toString());
const cropWhiteBorder = printCropBorder.value;
- vrcPlusImageRequest
+ const uploadPromise = vrcPlusImageRequest
.uploadPrint(base64Body, cropWhiteBorder, params)
.then((args) => {
- toast.success(t('message.print.uploaded'));
if (Object.keys(printTable.value).length !== 0) {
printTable.value.unshift(args.json);
}
-
return args;
- })
+ });
+ toast.promise(uploadPromise, {
+ loading: t('message.upload.loading'),
+ success: t('message.upload.success'),
+ error: t('message.upload.error')
+ });
+ uploadPromise
.catch((error) => {
console.error('Failed to upload', error);
})