mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-04-25 09:43:49 +02:00
refactor: app.js (#1291)
* refactor: frontend * Fix avatar gallery sort * Update .NET dependencies * Update npm dependencies electron v37.1.0 * bulkRefreshFriends * fix dark theme * Remove crowdin * Fix config.json dialog not updating * VRCX log file fixes & add Cef log * Remove SharedVariable, fix startup * Revert init theme change * Logging date not working? Fix WinformThemer designer error * Add Cef request hander, no more escaping main page * clean * fix * fix * clean * uh * Apply thememode at startup, fixes random user colours * Split database into files * Instance info remove empty lines * Open external VRC links with VRCX * Electron fixes * fix userdialog style * ohhhh * fix store * fix store * fix: load all group members after kicking a user * fix: world dialog favorite button style * fix: Clear VRCX Cache Timer input value * clean * Fix VR overlay * Fix VR overlay 2 * Fix Discord discord rich presence for RPC worlds * Clean up age verified user tags * Fix playerList being occupied after program reload * no `this` * Fix login stuck loading * writable: false * Hide dialogs on logout * add flush sync option * rm LOGIN event * rm LOGOUT event * remove duplicate event listeners * remove duplicate event listeners * clean * remove duplicate event listeners * clean * fix theme style * fix t * clearable * clean * fix ipcEvent * Small changes * Popcorn Palace support * Remove checkActiveFriends * Clean up * Fix dragEnterCef * Block API requests when not logged in * Clear state on login & logout * Fix worldDialog instances not updating * use <script setup> * Fix avatar change event, CheckGameRunning at startup * Fix image dragging * fix * Remove PWI * fix updateLoop * add webpack-dev-server to dev environment * rm unnecessary chunks * use <script setup> * webpack-dev-server changes * use <script setup> * use <script setup> * Fix UGC text size * Split login event * t * use <script setup> * fix * Update .gitignore and enable checkJs in jsconfig * fix i18n t * use <script setup> * use <script setup> * clean * global types * fix * use checkJs for debugging * Add watchState for login watchers * fix .vue template * type fixes * rm Vue.filter * Cef v138.0.170, VC++ 2022 * Settings fixes * Remove 'USER:CURRENT' * clean up 2FA callbacks * remove userApply * rm i18n import * notification handling to use notification store methods * refactor favorite handling to use favorite store methods and clean up event emissions * refactor moderation handling to use dedicated functions for player moderation events * refactor friend handling to use dedicated functions for friend events * Fix program startup, move lang init * Fix friend state * Fix status change error * Fix user notes diff * fix * rm group event * rm auth event * rm avatar event * clean * clean * getUser * getFriends * getFavoriteWorlds, getFavoriteAvatars * AvatarGalleryUpload btn style & package.json update * Fix friend requests * Apply user * Apply world * Fix note diff * Fix VR overlay * Fixes * Update build scripts * Apply avatar * Apply instance * Apply group * update hidden VRC+ badge * Fix sameInstance "private" * fix 502/504 API errors * fix 502/504 API errors * clean * Fix friend in same instance on orange showing twice in friends list * Add back in broken friend state repair methods * add types --------- Co-authored-by: Natsumi <cmcooper123@hotmail.com>
This commit is contained in:
@@ -261,7 +261,7 @@
|
||||
type="default"
|
||||
icon="el-icon-check"
|
||||
circle
|
||||
:disabled="API.currentUser.currentAvatar === avatarDialog.id"
|
||||
:disabled="currentUser.currentAvatar === avatarDialog.id"
|
||||
style="margin-left: 5px"
|
||||
@click="selectAvatar(avatarDialog.id)"></el-button>
|
||||
</el-tooltip>
|
||||
@@ -299,12 +299,12 @@
|
||||
>{{ t('dialog.avatar.actions.select_fallback') }}</el-dropdown-item
|
||||
>
|
||||
<el-dropdown-item
|
||||
v-if="avatarDialog.ref.authorId !== API.currentUser.id"
|
||||
v-if="avatarDialog.ref.authorId !== currentUser.id"
|
||||
icon="el-icon-picture-outline"
|
||||
command="Previous Images"
|
||||
>{{ t('dialog.avatar.actions.show_previous_images') }}</el-dropdown-item
|
||||
>
|
||||
<template v-if="avatarDialog.ref.authorId === API.currentUser.id">
|
||||
<template v-if="avatarDialog.ref.authorId === currentUser.id">
|
||||
<el-dropdown-item
|
||||
v-if="avatarDialog.ref.releaseStatus === 'public'"
|
||||
icon="el-icon-user-solid"
|
||||
@@ -367,7 +367,7 @@
|
||||
<el-tab-pane :label="t('dialog.avatar.info.header')">
|
||||
<div class="x-friend-list" style="max-height: unset">
|
||||
<div
|
||||
v-if="avatarDialog.galleryImages.length || avatarDialog.ref.authorId === API.currentUser.id"
|
||||
v-if="avatarDialog.galleryImages.length || avatarDialog.ref.authorId === currentUser.id"
|
||||
style="width: 100%">
|
||||
<span class="name">{{ t('dialog.avatar.info.gallery') }}</span>
|
||||
<input
|
||||
@@ -377,8 +377,8 @@
|
||||
style="display: none"
|
||||
@change="onFileChangeAvatarGallery" />
|
||||
<el-button
|
||||
v-if="avatarDialog.ref.authorId === API.currentUser.id"
|
||||
v-loading="avatarDialog.galleryLoading"
|
||||
v-if="avatarDialog.ref.authorId === currentUser.id"
|
||||
:disabled="!!avatarDialog.galleryLoading"
|
||||
size="small"
|
||||
icon="el-icon-upload2"
|
||||
style="margin-left: 5px"
|
||||
@@ -396,7 +396,7 @@
|
||||
style="width: 100%; height: 100%; object-fit: contain"
|
||||
@click="showFullscreenImageDialog(imageUrl)" />
|
||||
<div
|
||||
v-if="avatarDialog.ref.authorId === API.currentUser.id"
|
||||
v-if="avatarDialog.ref.authorId === currentUser.id"
|
||||
style="position: absolute; bottom: 5px; left: 33.3%">
|
||||
<el-button
|
||||
size="mini"
|
||||
@@ -497,16 +497,18 @@
|
||||
<div class="x-friend-item" style="cursor: default">
|
||||
<div class="detail">
|
||||
<span class="name">{{ t('dialog.avatar.info.created_at') }}</span>
|
||||
<span class="extra">{{ avatarDialog.ref.created_at | formatDate('long') }}</span>
|
||||
<span class="extra">{{ formatDateFilter(avatarDialog.ref.created_at, 'long') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="x-friend-item" style="cursor: default">
|
||||
<div class="detail">
|
||||
<span class="name">{{ t('dialog.avatar.info.last_updated') }}</span>
|
||||
<span v-if="avatarDialog.lastUpdated" class="extra">{{
|
||||
avatarDialog.lastUpdated | formatDate('long')
|
||||
formatDateFilter(avatarDialog.lastUpdated, 'long')
|
||||
}}</span>
|
||||
<span v-else class="extra">{{
|
||||
formatDateFilter(avatarDialog.ref.updated_at, 'long')
|
||||
}}</span>
|
||||
<span v-else class="extra">{{ avatarDialog.ref.updated_at | formatDate('long') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="x-friend-item" style="cursor: default">
|
||||
@@ -596,71 +598,68 @@
|
||||
<SetAvatarStylesDialog :set-avatar-styles-dialog="setAvatarStylesDialog" />
|
||||
<ChangeAvatarImageDialog
|
||||
:change-avatar-image-dialog-visible.sync="changeAvatarImageDialogVisible"
|
||||
:previous-images-table="previousImagesTable"
|
||||
:avatar-dialog="avatarDialog"
|
||||
:previous-images-file-id="previousImagesFileId"
|
||||
@refresh="displayPreviousImages" />
|
||||
<PreviousImagesDialog
|
||||
:previous-images-dialog-visible.sync="previousImagesDialogVisible"
|
||||
:previous-images-table="previousImagesTable" />
|
||||
<PreviousImagesDialog />
|
||||
</safe-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, getCurrentInstance, inject, nextTick, reactive, ref, watch } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { computed, getCurrentInstance, nextTick, reactive, ref, watch } from 'vue';
|
||||
import { useI18n } from 'vue-i18n-bridge';
|
||||
import { avatarModerationRequest, avatarRequest, favoriteRequest, imageRequest, miscRequest } from '../../../api';
|
||||
import utils from '../../../classes/utils';
|
||||
import { compareUnityVersion, storeAvatarImage } from '../../../composables/avatar/utils';
|
||||
import { database } from '../../../service/database';
|
||||
import {
|
||||
adjustDialogZ,
|
||||
buildTreeData,
|
||||
commaNumber,
|
||||
compareUnityVersion,
|
||||
copyToClipboard,
|
||||
downloadAndSaveJson,
|
||||
extractFileId,
|
||||
extractFileVersion,
|
||||
replaceVrcPackageUrl
|
||||
} from '../../../composables/shared/utils';
|
||||
import database from '../../../service/database';
|
||||
openExternalLink,
|
||||
openFolderGeneric,
|
||||
replaceVrcPackageUrl,
|
||||
storeAvatarImage,
|
||||
timeToText,
|
||||
moveArrayItem,
|
||||
formatDateFilter
|
||||
} from '../../../shared/utils';
|
||||
import {
|
||||
useAppearanceSettingsStore,
|
||||
useAvatarStore,
|
||||
useFavoriteStore,
|
||||
useGalleryStore,
|
||||
useGameStore,
|
||||
useUserStore
|
||||
} from '../../../stores';
|
||||
import PreviousImagesDialog from '../PreviousImagesDialog.vue';
|
||||
import ChangeAvatarImageDialog from './ChangeAvatarImageDialog.vue';
|
||||
import SetAvatarStylesDialog from './SetAvatarStylesDialog.vue';
|
||||
import SetAvatarTagsDialog from './SetAvatarTagsDialog.vue';
|
||||
|
||||
const API = inject('API');
|
||||
const showFullscreenImageDialog = inject('showFullscreenImageDialog');
|
||||
const showUserDialog = inject('showUserDialog');
|
||||
const showAvatarDialog = inject('showAvatarDialog');
|
||||
const showFavoriteDialog = inject('showFavoriteDialog');
|
||||
const openExternalLink = inject('openExternalLink');
|
||||
const adjustDialogZ = inject('adjustDialogZ');
|
||||
const getImageUrlFromImageId = inject('getImageUrlFromImageId');
|
||||
const getAvatarGallery = inject('getAvatarGallery');
|
||||
const { hideTooltips } = storeToRefs(useAppearanceSettingsStore());
|
||||
const { showUserDialog, sortUserDialogAvatars } = useUserStore();
|
||||
const { userDialog, currentUser } = storeToRefs(useUserStore());
|
||||
const { avatarDialog, cachedAvatarModerations, cachedAvatars, cachedAvatarNames } = storeToRefs(useAvatarStore());
|
||||
const { showAvatarDialog, getAvatarGallery, applyAvatarModeration, applyAvatar } = useAvatarStore();
|
||||
const { showFavoriteDialog } = useFavoriteStore();
|
||||
const { isGameRunning } = storeToRefs(useGameStore());
|
||||
const { deleteVRChatCache } = useGameStore();
|
||||
const { previousImagesDialogVisible, previousImagesTable } = storeToRefs(useGalleryStore());
|
||||
const { showFullscreenImageDialog, checkPreviousImageAvailable } = useGalleryStore();
|
||||
|
||||
const { t } = useI18n();
|
||||
const instance = getCurrentInstance();
|
||||
const { $message, $confirm, $prompt } = instance.proxy;
|
||||
|
||||
const emit = defineEmits(['openFolderGeneric', 'deleteVRChatCache', 'openPreviousImagesDialog']);
|
||||
|
||||
const props = defineProps({
|
||||
avatarDialog: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
hideTooltips: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
isGameRunning: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
});
|
||||
defineEmits(['openPreviousImagesDialog']);
|
||||
|
||||
const avatarDialogRef = ref(null);
|
||||
const changeAvatarImageDialogVisible = ref(false);
|
||||
const previousImagesFileId = ref('');
|
||||
const previousImagesDialogVisible = ref(false);
|
||||
const previousImagesTable = ref([]);
|
||||
|
||||
const treeData = ref([]);
|
||||
const timeSpent = ref(0);
|
||||
@@ -695,7 +694,7 @@
|
||||
});
|
||||
|
||||
const avatarDialogPlatform = computed(() => {
|
||||
const { ref } = props.avatarDialog;
|
||||
const { ref } = avatarDialog.value;
|
||||
const platforms = [];
|
||||
if (ref.unityPackages) {
|
||||
for (const unityPackage of ref.unityPackages) {
|
||||
@@ -721,11 +720,11 @@
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.avatarDialog.loading,
|
||||
() => avatarDialog.value.loading,
|
||||
(newVal) => {
|
||||
if (newVal) {
|
||||
nextTick(() => {
|
||||
const D = props.avatarDialog;
|
||||
const D = avatarDialog.value;
|
||||
if (D.visible) {
|
||||
adjustDialogZ(avatarDialogRef.value.$el);
|
||||
}
|
||||
@@ -735,6 +734,10 @@
|
||||
}
|
||||
);
|
||||
|
||||
function getImageUrlFromImageId(imageId) {
|
||||
return `https://api.vrchat.cloud/api/1/file/${imageId}/1/`;
|
||||
}
|
||||
|
||||
function handleDialogOpen() {
|
||||
fileAnalysis.value = {};
|
||||
memo.value = '';
|
||||
@@ -744,19 +747,19 @@
|
||||
}
|
||||
|
||||
function getAvatarTimeSpent() {
|
||||
const D = props.avatarDialog;
|
||||
const D = avatarDialog.value;
|
||||
database.getAvatarTimeSpent(D.id).then((aviTime) => {
|
||||
if (D.id === aviTime.avatarId) {
|
||||
timeSpent.value = aviTime.timeSpent;
|
||||
if (D.id === API.currentUser.currentAvatar && API.currentUser.$previousAvatarSwapTime) {
|
||||
timeSpent.value += Date.now() - API.currentUser.$previousAvatarSwapTime;
|
||||
if (D.id === currentUser.value.currentAvatar && currentUser.value.$previousAvatarSwapTime) {
|
||||
timeSpent.value += Date.now() - currentUser.value.$previousAvatarSwapTime;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getAvatarMemo() {
|
||||
const D = props.avatarDialog;
|
||||
const D = avatarDialog.value;
|
||||
database.getAvatarMemoDB(D.id).then((res) => {
|
||||
if (D.id === res.avatarId) {
|
||||
memo.value = res.memo;
|
||||
@@ -764,20 +767,8 @@
|
||||
});
|
||||
}
|
||||
|
||||
function openFolderGeneric(path) {
|
||||
emit('openFolderGeneric', path);
|
||||
}
|
||||
|
||||
function deleteVRChatCache(ref) {
|
||||
emit('deleteVRChatCache', ref);
|
||||
}
|
||||
|
||||
function commaNumber(num) {
|
||||
return utils.commaNumber(num);
|
||||
}
|
||||
|
||||
function avatarDialogCommand(command) {
|
||||
const D = props.avatarDialog;
|
||||
const D = avatarDialog.value;
|
||||
switch (command) {
|
||||
case 'Refresh':
|
||||
showAvatarDialog(D.id);
|
||||
@@ -804,7 +795,7 @@
|
||||
showSetAvatarStylesDialog(D.id);
|
||||
break;
|
||||
case 'Download Unity Package':
|
||||
openExternalLink(replaceVrcPackageUrl(props.avatarDialog.ref.unityPackageUrl));
|
||||
openExternalLink(replaceVrcPackageUrl(avatarDialog.value.ref.unityPackageUrl));
|
||||
break;
|
||||
case 'Add Favorite':
|
||||
showFavoriteDialog('avatar', D.id);
|
||||
@@ -845,7 +836,7 @@
|
||||
})
|
||||
.then((args) => {
|
||||
// 'AVATAR-MODERATION';
|
||||
args.ref = API.applyAvatarModeration(args.json);
|
||||
applyAvatarModeration(args.json);
|
||||
$message({
|
||||
message: 'Avatar blocked',
|
||||
type: 'success'
|
||||
@@ -860,9 +851,8 @@
|
||||
targetAvatarId: D.id
|
||||
})
|
||||
.then((args) => {
|
||||
// 'AVATAR-MODERATION:DELETE';
|
||||
API.cachedAvatarModerations.delete(args.params.targetAvatarId);
|
||||
const D = props.avatarDialog;
|
||||
cachedAvatarModerations.value.delete(args.params.targetAvatarId);
|
||||
const D = avatarDialog.value;
|
||||
if (
|
||||
args.params.avatarModerationType === 'block' &&
|
||||
D.id === args.params.targetAvatarId
|
||||
@@ -878,6 +868,7 @@
|
||||
releaseStatus: 'public'
|
||||
})
|
||||
.then((args) => {
|
||||
applyAvatar(args.json);
|
||||
$message({
|
||||
message: 'Avatar updated to public',
|
||||
type: 'success'
|
||||
@@ -892,6 +883,7 @@
|
||||
releaseStatus: 'private'
|
||||
})
|
||||
.then((args) => {
|
||||
applyAvatar(args.json);
|
||||
$message({
|
||||
message: 'Avatar updated to private',
|
||||
type: 'success'
|
||||
@@ -905,6 +897,19 @@
|
||||
avatarId: D.id
|
||||
})
|
||||
.then((args) => {
|
||||
const { json } = args;
|
||||
cachedAvatars.value.delete(json._id);
|
||||
if (userDialog.value.id === json.authorId) {
|
||||
const map = new Map();
|
||||
for (const ref of cachedAvatars.value.values()) {
|
||||
if (ref.authorId === json.authorId) {
|
||||
map.set(ref.id, ref);
|
||||
}
|
||||
}
|
||||
const array = Array.from(map.values());
|
||||
sortUserDialogAvatars(array);
|
||||
}
|
||||
|
||||
$message({
|
||||
message: 'Avatar deleted',
|
||||
type: 'success'
|
||||
@@ -973,7 +978,7 @@
|
||||
function displayPreviousImages(command) {
|
||||
previousImagesTable.value = [];
|
||||
previousImagesFileId.value = '';
|
||||
const { imageUrl } = props.avatarDialog.ref;
|
||||
const { imageUrl } = avatarDialog.value.ref;
|
||||
const fileId = extractFileId(imageUrl);
|
||||
if (!fileId) {
|
||||
return;
|
||||
@@ -988,7 +993,7 @@
|
||||
changeAvatarImageDialogVisible.value = true;
|
||||
}
|
||||
imageRequest.getAvatarImages(params).then((args) => {
|
||||
storeAvatarImage(args);
|
||||
storeAvatarImage(args, cachedAvatarNames.value);
|
||||
previousImagesFileId.value = args.json.id;
|
||||
|
||||
const images = [];
|
||||
@@ -1001,23 +1006,6 @@
|
||||
});
|
||||
}
|
||||
|
||||
async function checkPreviousImageAvailable(images) {
|
||||
previousImagesTable.value = [];
|
||||
for (const image of images) {
|
||||
if (image.file && image.file.url) {
|
||||
const response = await fetch(image.file.url, {
|
||||
method: 'HEAD',
|
||||
redirect: 'follow'
|
||||
}).catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
if (response.status === 200) {
|
||||
previousImagesTable.value.push(image);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function selectAvatar(id) {
|
||||
avatarRequest
|
||||
.selectAvatar({
|
||||
@@ -1047,6 +1035,7 @@
|
||||
description: instance.inputValue
|
||||
})
|
||||
.then((args) => {
|
||||
applyAvatar(args.json);
|
||||
$message({
|
||||
message: t('prompt.change_avatar_description.message.success'),
|
||||
type: 'success'
|
||||
@@ -1073,6 +1062,7 @@
|
||||
name: instance.inputValue
|
||||
})
|
||||
.then((args) => {
|
||||
applyAvatar(args.json);
|
||||
$message({
|
||||
message: t('prompt.rename_avatar.message.success'),
|
||||
type: 'success'
|
||||
@@ -1087,12 +1077,12 @@
|
||||
function onAvatarMemoChange() {
|
||||
if (memo.value) {
|
||||
database.setAvatarMemo({
|
||||
avatarId: props.avatarDialog.id,
|
||||
avatarId: avatarDialog.value.id,
|
||||
editedAt: new Date().toJSON(),
|
||||
memo: memo.value
|
||||
});
|
||||
} else {
|
||||
database.deleteAvatarMemo(props.avatarDialog.id);
|
||||
database.deleteAvatarMemo(avatarDialog.value.id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1104,17 +1094,13 @@
|
||||
copyToClipboard(`https://vrchat.com/home/avatar/${id}`);
|
||||
}
|
||||
|
||||
function timeToText(time) {
|
||||
return utils.timeToText(time);
|
||||
}
|
||||
|
||||
function refreshAvatarDialogTreeData() {
|
||||
treeData.value = utils.buildTreeData(props.avatarDialog.ref);
|
||||
treeData.value = buildTreeData(avatarDialog.value.ref);
|
||||
}
|
||||
|
||||
function getAvatarFileAnalysis() {
|
||||
let unityPackage;
|
||||
const D = props.avatarDialog;
|
||||
const D = avatarDialog.value;
|
||||
const avatarId = D.ref.id;
|
||||
let assetUrl = '';
|
||||
let variant = 'security';
|
||||
@@ -1154,8 +1140,7 @@
|
||||
return;
|
||||
}
|
||||
miscRequest.getFileAnalysis({ fileId, version, variant, avatarId }).then((args) => {
|
||||
// API.$on('FILE:ANALYSIS', function (args) {
|
||||
if (!props.avatarDialog.visible || props.avatarDialog.id !== args.params.avatarId) {
|
||||
if (!avatarDialog.value.visible || avatarDialog.value.id !== args.params.avatarId) {
|
||||
return;
|
||||
}
|
||||
const ref = args.json;
|
||||
@@ -1169,9 +1154,8 @@
|
||||
ref._totalTextureUsage = `${(ref.avatarStats.totalTextureUsage / 1048576).toFixed(2)} MB`;
|
||||
}
|
||||
|
||||
fileAnalysis.value = utils.buildTreeData(args.json);
|
||||
fileAnalysis.value = buildTreeData(args.json);
|
||||
});
|
||||
// });
|
||||
}
|
||||
|
||||
function showSetAvatarTagsDialog(avatarId) {
|
||||
@@ -1187,7 +1171,7 @@
|
||||
D.contentViolence = false;
|
||||
D.contentAdult = false;
|
||||
D.contentSex = false;
|
||||
const oldTags = props.avatarDialog.ref.tags;
|
||||
const oldTags = avatarDialog.value.ref.tags;
|
||||
oldTags.forEach((tag) => {
|
||||
switch (tag) {
|
||||
case 'content_horror':
|
||||
@@ -1212,8 +1196,8 @@
|
||||
break;
|
||||
}
|
||||
});
|
||||
for (const ref of API.cachedAvatars.values()) {
|
||||
if (ref.authorId === API.currentUser.id) {
|
||||
for (const ref of cachedAvatars.value.values()) {
|
||||
if (ref.authorId === currentUser.value.id) {
|
||||
ref.$selected = false;
|
||||
ref.$tagString = '';
|
||||
if (avatarId === ref.id) {
|
||||
@@ -1245,12 +1229,12 @@
|
||||
const D = setAvatarStylesDialog;
|
||||
D.visible = true;
|
||||
D.loading = true;
|
||||
D.avatarId = props.avatarDialog.id;
|
||||
D.primaryStyle = props.avatarDialog.ref.styles?.primary || '';
|
||||
D.secondaryStyle = props.avatarDialog.ref.styles?.secondary || '';
|
||||
D.avatarId = avatarDialog.value.id;
|
||||
D.primaryStyle = avatarDialog.value.ref.styles?.primary || '';
|
||||
D.secondaryStyle = avatarDialog.value.ref.styles?.secondary || '';
|
||||
D.initialPrimaryStyle = D.primaryStyle;
|
||||
D.initialSecondaryStyle = D.secondaryStyle;
|
||||
D.initialTags = props.avatarDialog.ref.tags;
|
||||
D.initialTags = avatarDialog.value.ref.tags;
|
||||
D.authorTags = '';
|
||||
for (const tag of D.initialTags) {
|
||||
if (tag.startsWith('author_tag_')) {
|
||||
@@ -1298,43 +1282,31 @@
|
||||
}
|
||||
const r = new FileReader();
|
||||
r.onload = function () {
|
||||
props.avatarDialog.galleryLoading = true;
|
||||
avatarDialog.value.galleryLoading = true;
|
||||
const base64Body = btoa(r.result);
|
||||
avatarRequest
|
||||
.uploadAvatarGalleryImage(base64Body, props.avatarDialog.id)
|
||||
.uploadAvatarGalleryImage(base64Body, avatarDialog.value.id)
|
||||
.then((args) => {
|
||||
$message({
|
||||
message: t('message.avatar_gallery.uploaded'),
|
||||
type: 'success'
|
||||
});
|
||||
console.log(args);
|
||||
props.avatarDialog.galleryImages = getAvatarGallery(props.avatarDialog.id);
|
||||
avatarDialog.value.galleryImages = getAvatarGallery(avatarDialog.value.id);
|
||||
return args;
|
||||
})
|
||||
.finally(() => {
|
||||
props.avatarDialog.galleryLoading = false;
|
||||
avatarDialog.value.galleryLoading = false;
|
||||
});
|
||||
};
|
||||
r.readAsBinaryString(files[0]);
|
||||
clearFile();
|
||||
}
|
||||
|
||||
function deleteAvatarGalleryImage(imageUrl) {
|
||||
const fileId = extractFileId(imageUrl);
|
||||
miscRequest.deleteFile(fileId).then((args) => {
|
||||
$message({
|
||||
message: t('message.avatar_gallery.deleted'),
|
||||
type: 'success'
|
||||
});
|
||||
props.avatarDialog.galleryImages = getAvatarGallery(props.avatarDialog.id);
|
||||
return args;
|
||||
});
|
||||
}
|
||||
|
||||
function reorderAvatarGalleryImage(imageUrl, direction) {
|
||||
const fileId = extractFileId(imageUrl);
|
||||
let fileIds = [];
|
||||
props.avatarDialog.ref.gallery.forEach((item) => {
|
||||
avatarDialog.value.ref.gallery.forEach((item) => {
|
||||
fileIds.push(extractFileId(item.id));
|
||||
});
|
||||
const index = fileIds.indexOf(fileId);
|
||||
@@ -1360,16 +1332,28 @@
|
||||
return;
|
||||
}
|
||||
if (direction === -1) {
|
||||
utils.moveArrayItem(fileIds, index, index - 1);
|
||||
moveArrayItem(fileIds, index, index - 1);
|
||||
} else {
|
||||
utils.moveArrayItem(fileIds, index, index + 1);
|
||||
moveArrayItem(fileIds, index, index + 1);
|
||||
}
|
||||
avatarRequest.setAvatarGalleryOrder(fileIds).then((args) => {
|
||||
$message({
|
||||
message: t('message.avatar_gallery.reordered'),
|
||||
type: 'success'
|
||||
});
|
||||
props.avatarDialog.galleryImages = getAvatarGallery(props.avatarDialog.id);
|
||||
avatarDialog.value.galleryImages = getAvatarGallery(avatarDialog.value.id);
|
||||
return args;
|
||||
});
|
||||
}
|
||||
|
||||
function deleteAvatarGalleryImage(imageUrl) {
|
||||
const fileId = extractFileId(imageUrl);
|
||||
miscRequest.deleteFile(fileId).then((args) => {
|
||||
$message({
|
||||
message: t('message.avatar_gallery.deleted'),
|
||||
type: 'success'
|
||||
});
|
||||
getAvatarGallery(avatarDialog.value.id);
|
||||
return args;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -42,32 +42,29 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { getCurrentInstance, inject, ref } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { getCurrentInstance, ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n-bridge';
|
||||
import { imageRequest } from '../../../api';
|
||||
import { extractFileId } from '../../../composables/shared/utils';
|
||||
import webApiService from '../../../service/webapi';
|
||||
import { AppGlobal } from '../../../service/appConfig';
|
||||
import { $throw } from '../../../service/request';
|
||||
import { extractFileId } from '../../../shared/utils';
|
||||
import { useAvatarStore, useGalleryStore } from '../../../stores';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const instance = getCurrentInstance();
|
||||
const $message = instance.proxy.$message;
|
||||
|
||||
const API = inject('API');
|
||||
const { avatarDialog } = storeToRefs(useAvatarStore());
|
||||
const { previousImagesTable } = storeToRefs(useGalleryStore());
|
||||
const { applyAvatar } = useAvatarStore();
|
||||
|
||||
const props = defineProps({
|
||||
changeAvatarImageDialogVisible: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
previousImagesTable: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
avatarDialog: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
previousImagesFileId: {
|
||||
type: String,
|
||||
default: ''
|
||||
@@ -121,7 +118,7 @@
|
||||
}
|
||||
};
|
||||
const files = e.target.files || e.dataTransfer.files;
|
||||
if (!files.length || !props.avatarDialog.visible || props.avatarDialog.loading) {
|
||||
if (!files.length || !avatarDialog.value.visible || avatarDialog.value.loading) {
|
||||
clearFile();
|
||||
return;
|
||||
}
|
||||
@@ -156,8 +153,8 @@
|
||||
const signatureMd5 = await genMd5(base64SignatureFile);
|
||||
const signatureSizeInBytes = parseInt(await genLength(base64SignatureFile), 10);
|
||||
|
||||
const avatarId = props.avatarDialog.id;
|
||||
const { imageUrl } = props.avatarDialog.ref;
|
||||
const avatarId = avatarDialog.value.id;
|
||||
const { imageUrl } = avatarDialog.value.ref;
|
||||
|
||||
const fileId = extractFileId(imageUrl);
|
||||
if (!fileId) {
|
||||
@@ -206,7 +203,6 @@
|
||||
}
|
||||
|
||||
async function avatarImageInit(args) {
|
||||
// API.$on('AVATARIMAGE:INIT')
|
||||
const fileId = args.json.id;
|
||||
const fileVersion = args.json.versions[args.json.versions.length - 1].version;
|
||||
const params = {
|
||||
@@ -218,7 +214,6 @@
|
||||
}
|
||||
|
||||
async function avatarImageFileStart(args) {
|
||||
// API.$on('AVATARIMAGE:FILESTART')
|
||||
const { url } = args.json;
|
||||
const { fileId, fileVersion } = args.params;
|
||||
const params = {
|
||||
@@ -242,7 +237,7 @@
|
||||
|
||||
if (json.status !== 200) {
|
||||
changeAvatarImageDialogLoading.value = false;
|
||||
API.$throw('Avatar image upload failed', json, params.url);
|
||||
$throw('Avatar image upload failed', json, params.url);
|
||||
}
|
||||
const args = {
|
||||
json,
|
||||
@@ -252,7 +247,6 @@
|
||||
}
|
||||
|
||||
async function avatarImageFileAWS(args) {
|
||||
// API.$on('AVATARIMAGE:FILEAWS')
|
||||
const { fileId, fileVersion } = args.params;
|
||||
const params = {
|
||||
fileId,
|
||||
@@ -263,7 +257,6 @@
|
||||
}
|
||||
|
||||
async function avatarImageFileFinish(args) {
|
||||
// API.$on('AVATARIMAGE:FILEFINISH')
|
||||
const { fileId, fileVersion } = args.params;
|
||||
const params = {
|
||||
fileId,
|
||||
@@ -274,7 +267,6 @@
|
||||
}
|
||||
|
||||
async function avatarImageSigStart(args) {
|
||||
// API.$on('AVATARIMAGE:SIGSTART')
|
||||
const { url } = args.json;
|
||||
const { fileId, fileVersion } = args.params;
|
||||
const params = {
|
||||
@@ -298,7 +290,7 @@
|
||||
|
||||
if (json.status !== 200) {
|
||||
changeAvatarImageDialogLoading.value = false;
|
||||
API.$throw('Avatar image upload failed', json, params.url);
|
||||
$throw('Avatar image upload failed', json, params.url);
|
||||
}
|
||||
const args = {
|
||||
json,
|
||||
@@ -308,7 +300,6 @@
|
||||
}
|
||||
|
||||
async function avatarImageSigAWS(args) {
|
||||
// API.$on('AVATARIMAGE:SIGAWS')
|
||||
const { fileId, fileVersion } = args.params;
|
||||
const params = {
|
||||
fileId,
|
||||
@@ -319,18 +310,17 @@
|
||||
}
|
||||
|
||||
async function avatarImageSigFinish(args) {
|
||||
// API.$on('AVATARIMAGE:SIGFINISH')
|
||||
const { fileId, fileVersion } = args.params;
|
||||
const parmas = {
|
||||
id: avatarImage.value.avatarId,
|
||||
imageUrl: `${API.endpointDomain}/file/${fileId}/${fileVersion}/file`
|
||||
imageUrl: `${AppGlobal.endpointDomain}/file/${fileId}/${fileVersion}/file`
|
||||
};
|
||||
const res = await imageRequest.setAvatarImage(parmas);
|
||||
return avatarImageSet(res);
|
||||
}
|
||||
|
||||
async function avatarImageSet(args) {
|
||||
// API.$on('AVATARIMAGE:SET')
|
||||
applyAvatar(args.json);
|
||||
changeAvatarImageDialogLoading.value = false;
|
||||
if (args.json.imageUrl === args.params.imageUrl) {
|
||||
$message({
|
||||
@@ -339,7 +329,7 @@
|
||||
});
|
||||
refresh();
|
||||
} else {
|
||||
API.$throw(0, 'Avatar image change failed', args.params.imageUrl);
|
||||
$throw(0, 'Avatar image change failed', args.params.imageUrl);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -352,42 +342,22 @@
|
||||
function setAvatarImage(image) {
|
||||
changeAvatarImageDialogLoading.value = true;
|
||||
const parmas = {
|
||||
id: props.avatarDialog.id,
|
||||
imageUrl: `${API.endpointDomain}/file/${props.previousImagesFileId}/${image.version}/file`
|
||||
id: avatarDialog.value.id,
|
||||
imageUrl: `${AppGlobal.endpointDomain}/file/${props.previousImagesFileId}/${image.version}/file`
|
||||
};
|
||||
imageRequest.setAvatarImage(parmas).finally(() => {
|
||||
changeAvatarImageDialogLoading.value = false;
|
||||
closeDialog();
|
||||
});
|
||||
imageRequest
|
||||
.setAvatarImage(parmas)
|
||||
.then((args) => applyAvatar(args.json))
|
||||
.finally(() => {
|
||||
changeAvatarImageDialogLoading.value = false;
|
||||
closeDialog();
|
||||
});
|
||||
}
|
||||
|
||||
function compareCurrentImage(image) {
|
||||
return (
|
||||
`${API.endpointDomain}/file/${props.previousImagesFileId}/${image.version}/file` ===
|
||||
props.avatarDialog.ref.imageUrl
|
||||
`${AppGlobal.endpointDomain}/file/${props.previousImagesFileId}/${image.version}/file` ===
|
||||
avatarDialog.value.ref.imageUrl
|
||||
);
|
||||
}
|
||||
|
||||
// $app.methods.deleteAvatarImage = function () {
|
||||
// this.changeAvatarImageDialogLoading = true;
|
||||
// var parmas = {
|
||||
// fileId: this.previousImagesFileId,
|
||||
// version: this.previousImagesTable[0].version
|
||||
// };
|
||||
// vrcPlusIconRequest
|
||||
// .deleteFileVersion(parmas)
|
||||
// .then((args) => {
|
||||
// this.previousImagesFileId = args.json.id;
|
||||
// var images = [];
|
||||
// args.json.versions.forEach((item) => {
|
||||
// if (!item.deleted) {
|
||||
// images.unshift(item);
|
||||
// }
|
||||
// });
|
||||
// this.checkPreviousImageAvailable(images);
|
||||
// })
|
||||
// .finally(() => {
|
||||
// this.changeAvatarImageDialogLoading = false;
|
||||
// });
|
||||
// };
|
||||
</script>
|
||||
|
||||
@@ -64,13 +64,16 @@
|
||||
import { watch, getCurrentInstance } from 'vue';
|
||||
|
||||
import { useI18n } from 'vue-i18n-bridge';
|
||||
import utils from '../../../classes/utils';
|
||||
import { arraysMatch } from '../../../shared/utils';
|
||||
import { avatarRequest } from '../../../api';
|
||||
import { useAvatarStore } from '../../../stores';
|
||||
|
||||
const { t } = useI18n();
|
||||
const instance = getCurrentInstance();
|
||||
const $message = instance.proxy.$message;
|
||||
|
||||
const { applyAvatar } = useAvatarStore();
|
||||
|
||||
const props = defineProps({
|
||||
setAvatarStylesDialog: {
|
||||
type: Object,
|
||||
@@ -125,7 +128,7 @@
|
||||
if (
|
||||
props.setAvatarStylesDialog.initialPrimaryStyle === props.setAvatarStylesDialog.primaryStyle &&
|
||||
props.setAvatarStylesDialog.initialSecondaryStyle === props.setAvatarStylesDialog.secondaryStyle &&
|
||||
utils.arraysMatch(props.setAvatarStylesDialog.initialTags, tags)
|
||||
arraysMatch(props.setAvatarStylesDialog.initialTags, tags)
|
||||
) {
|
||||
props.setAvatarStylesDialog.visible = false;
|
||||
return;
|
||||
@@ -139,7 +142,8 @@
|
||||
};
|
||||
avatarRequest
|
||||
.saveAvatar(params)
|
||||
.then(() => {
|
||||
.then((args) => {
|
||||
applyAvatar(args.json);
|
||||
$message.success(t('dialog.set_avatar_styles.save_success'));
|
||||
props.setAvatarStylesDialog.visible = false;
|
||||
})
|
||||
|
||||
@@ -94,12 +94,12 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { inject, watch, getCurrentInstance } from 'vue';
|
||||
|
||||
import { getCurrentInstance, watch } from 'vue';
|
||||
import { useI18n } from 'vue-i18n-bridge';
|
||||
import { avatarRequest } from '../../../api';
|
||||
import { useAvatarStore } from '../../../stores';
|
||||
|
||||
const showAvatarDialog = inject('showAvatarDialog');
|
||||
const { showAvatarDialog, applyAvatar } = useAvatarStore();
|
||||
|
||||
const { t } = useI18n();
|
||||
const instance = getCurrentInstance();
|
||||
@@ -220,10 +220,11 @@
|
||||
tags.push(tag);
|
||||
}
|
||||
}
|
||||
await avatarRequest.saveAvatar({
|
||||
const args = await avatarRequest.saveAvatar({
|
||||
id: ref.id,
|
||||
tags
|
||||
});
|
||||
applyAvatar(args.json);
|
||||
D.selectedCount--;
|
||||
}
|
||||
} catch (err) {
|
||||
@@ -270,15 +271,6 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// useless
|
||||
// $app.data.avatarContentTags = [
|
||||
// 'content_horror',
|
||||
// 'content_gore',
|
||||
// 'content_violence',
|
||||
// 'content_adult',
|
||||
// 'content_sex'
|
||||
// ];
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
|
||||
Reference in New Issue
Block a user