mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-04-24 09:13:50 +02:00
refactor store
This commit is contained in:
@@ -16,6 +16,7 @@ import { escapeTag } from '../shared/utils';
|
||||
import { initWebsocket } from '../service/websocket';
|
||||
import { request } from '../service/request';
|
||||
import { runHandleAutoLoginFlow } from '../coordinators/authAutoLoginCoordinator';
|
||||
import { getCurrentUser } from '../coordinators/userCoordinator';
|
||||
import { useAdvancedSettingsStore } from './settings/advanced';
|
||||
import { useGeneralSettingsStore } from './settings/general';
|
||||
import { useModalStore } from './modal';
|
||||
@@ -197,8 +198,7 @@ export const useAuthStore = defineStore('Auth', () => {
|
||||
throw err;
|
||||
})
|
||||
.then(() => {
|
||||
userStore
|
||||
.getCurrentUser()
|
||||
getCurrentUser()
|
||||
.finally(() => {
|
||||
loginForm.value.loading = false;
|
||||
})
|
||||
@@ -671,7 +671,7 @@ export const useAuthStore = defineStore('Auth', () => {
|
||||
clearCookiesTryLogin();
|
||||
})
|
||||
.then(() => {
|
||||
userStore.getCurrentUser();
|
||||
getCurrentUser();
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
@@ -713,7 +713,7 @@ export const useAuthStore = defineStore('Auth', () => {
|
||||
clearCookiesTryLogin();
|
||||
})
|
||||
.then(() => {
|
||||
userStore.getCurrentUser();
|
||||
getCurrentUser();
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
@@ -756,7 +756,7 @@ export const useAuthStore = defineStore('Auth', () => {
|
||||
promptEmailOTP();
|
||||
})
|
||||
.then(() => {
|
||||
userStore.getCurrentUser();
|
||||
getCurrentUser();
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
|
||||
@@ -1,46 +1,13 @@
|
||||
import { nextTick, ref, watch } from 'vue';
|
||||
import { ref, watch } from 'vue';
|
||||
import { defineStore } from 'pinia';
|
||||
import { toast } from 'vue-sonner';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import {
|
||||
checkVRChatCache,
|
||||
createDefaultAvatarRef,
|
||||
extractFileId,
|
||||
getAvailablePlatforms,
|
||||
getBundleDateSize,
|
||||
getPlatformInfo,
|
||||
replaceBioSymbols,
|
||||
sanitizeEntityJson,
|
||||
storeAvatarImage
|
||||
checkVRChatCache
|
||||
} from '../shared/utils';
|
||||
import { avatarRequest, miscRequest, queryRequest } from '../api';
|
||||
import { AppDebug } from '../service/appConfig';
|
||||
import { database } from '../service/database';
|
||||
import { patchAvatarFromEvent } from '../queries';
|
||||
import { processBulk } from '../service/request';
|
||||
import { applyFavorite } from '../coordinators/favoriteCoordinator';
|
||||
import { useAdvancedSettingsStore } from './settings/advanced';
|
||||
import { useAvatarProviderStore } from './avatarProvider';
|
||||
import { useFavoriteStore } from './favorite';
|
||||
import { useModalStore } from './modal';
|
||||
import { useUiStore } from './ui';
|
||||
import { useUserStore } from './user';
|
||||
import { useVRCXUpdaterStore } from './vrcxUpdater';
|
||||
import { watchState } from '../service/watchState';
|
||||
|
||||
import webApiService from '../service/webapi';
|
||||
|
||||
export const useAvatarStore = defineStore('Avatar', () => {
|
||||
const favoriteStore = useFavoriteStore();
|
||||
const avatarProviderStore = useAvatarProviderStore();
|
||||
const vrcxUpdaterStore = useVRCXUpdaterStore();
|
||||
const advancedSettingsStore = useAdvancedSettingsStore();
|
||||
const userStore = useUserStore();
|
||||
const modalStore = useModalStore();
|
||||
const uiStore = useUiStore();
|
||||
const { t } = useI18n();
|
||||
|
||||
let cachedAvatarModerations = new Map();
|
||||
let cachedAvatars = new Map();
|
||||
let cachedAvatarNames = new Map();
|
||||
@@ -83,145 +50,17 @@ export const useAvatarStore = defineStore('Avatar', () => {
|
||||
cachedAvatarModerations.clear();
|
||||
avatarHistory.value = [];
|
||||
if (isLoggedIn) {
|
||||
getAvatarHistory();
|
||||
preloadOwnAvatars();
|
||||
import('../coordinators/avatarCoordinator').then(
|
||||
({ getAvatarHistory, preloadOwnAvatars }) => {
|
||||
getAvatarHistory();
|
||||
preloadOwnAvatars();
|
||||
}
|
||||
);
|
||||
}
|
||||
},
|
||||
{ flush: 'sync' }
|
||||
);
|
||||
|
||||
/**
|
||||
* @param {object} json
|
||||
* @returns {object} ref
|
||||
*/
|
||||
function applyAvatar(json) {
|
||||
sanitizeEntityJson(json, ['name', 'description']);
|
||||
let ref = cachedAvatars.get(json.id);
|
||||
if (typeof ref === 'undefined') {
|
||||
ref = createDefaultAvatarRef(json);
|
||||
cachedAvatars.set(ref.id, ref);
|
||||
} else {
|
||||
const { unityPackages } = ref;
|
||||
Object.assign(ref, json);
|
||||
if (
|
||||
json.unityPackages?.length > 0 &&
|
||||
unityPackages.length > 0 &&
|
||||
!json.unityPackages[0].assetUrl
|
||||
) {
|
||||
ref.unityPackages = unityPackages;
|
||||
}
|
||||
}
|
||||
for (const listing of ref.publishedListings) {
|
||||
listing.displayName = replaceBioSymbols(listing.displayName);
|
||||
listing.description = replaceBioSymbols(listing.description);
|
||||
}
|
||||
applyFavorite('avatar', ref.id);
|
||||
if (favoriteStore.localAvatarFavoritesList.includes(ref.id)) {
|
||||
const avatarRef = ref;
|
||||
favoriteStore.syncLocalAvatarFavoriteRef(avatarRef);
|
||||
|
||||
// update db cache
|
||||
database.addAvatarToCache(avatarRef);
|
||||
}
|
||||
patchAvatarFromEvent(ref);
|
||||
return ref;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} avatarId
|
||||
* @param options
|
||||
* @returns
|
||||
*/
|
||||
function showAvatarDialog(avatarId, options = {}) {
|
||||
const D = avatarDialog.value;
|
||||
const forceRefresh = Boolean(options?.forceRefresh);
|
||||
const isMainDialogOpen = uiStore.openDialog({
|
||||
type: 'avatar',
|
||||
id: avatarId
|
||||
});
|
||||
D.visible = true;
|
||||
if (isMainDialogOpen && D.id === avatarId && !forceRefresh) {
|
||||
uiStore.setDialogCrumbLabel('avatar', D.id, D.ref?.name || D.id);
|
||||
nextTick(() => (D.loading = false));
|
||||
return;
|
||||
}
|
||||
D.loading = true;
|
||||
D.id = avatarId;
|
||||
D.inCache = false;
|
||||
D.cacheSize = '';
|
||||
D.cacheLocked = false;
|
||||
D.cachePath = '';
|
||||
D.fileAnalysis = {};
|
||||
D.isQuestFallback = false;
|
||||
D.isPC = false;
|
||||
D.isQuest = false;
|
||||
D.isIos = false;
|
||||
D.hasImposter = false;
|
||||
D.imposterVersion = '';
|
||||
D.platformInfo = {};
|
||||
D.galleryImages = [];
|
||||
D.galleryLoading = true;
|
||||
D.isFavorite =
|
||||
favoriteStore.getCachedFavoritesByObjectId(avatarId) ||
|
||||
(userStore.isLocalUserVrcPlusSupporter &&
|
||||
favoriteStore.localAvatarFavoritesList.includes(avatarId));
|
||||
D.isBlocked = cachedAvatarModerations.has(avatarId);
|
||||
const ref2 = cachedAvatars.get(avatarId);
|
||||
if (typeof ref2 !== 'undefined') {
|
||||
D.ref = ref2;
|
||||
uiStore.setDialogCrumbLabel('avatar', D.id, D.ref?.name || D.id);
|
||||
nextTick(() => (D.loading = false));
|
||||
}
|
||||
const loadAvatarRequest = forceRefresh
|
||||
? avatarRequest.getAvatar({ avatarId })
|
||||
: queryRequest.fetch('avatar', { avatarId });
|
||||
loadAvatarRequest
|
||||
.then((args) => {
|
||||
const ref = applyAvatar(args.json);
|
||||
D.ref = ref;
|
||||
uiStore.setDialogCrumbLabel(
|
||||
'avatar',
|
||||
D.id,
|
||||
D.ref?.name || D.id
|
||||
);
|
||||
getAvatarGallery(avatarId);
|
||||
updateVRChatAvatarCache();
|
||||
if (/quest/.test(ref.tags)) {
|
||||
D.isQuestFallback = true;
|
||||
}
|
||||
const { isPC, isQuest, isIos } = getAvailablePlatforms(
|
||||
ref.unityPackages
|
||||
);
|
||||
D.isPC = isPC;
|
||||
D.isQuest = isQuest;
|
||||
D.isIos = isIos;
|
||||
D.platformInfo = getPlatformInfo(ref.unityPackages);
|
||||
for (let i = ref.unityPackages.length - 1; i > -1; i--) {
|
||||
const unityPackage = ref.unityPackages[i];
|
||||
if (unityPackage.variant === 'impostor') {
|
||||
D.hasImposter = true;
|
||||
D.imposterVersion = unityPackage.impostorizerVersion;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (Object.keys(D.fileAnalysis).length === 0) {
|
||||
getBundleDateSize(ref);
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
D.loading = false;
|
||||
D.id = null;
|
||||
D.visible = false;
|
||||
uiStore.jumpBackDialogCrumb();
|
||||
toast.error(t('message.api_handler.avatar_private_or_deleted'));
|
||||
throw err;
|
||||
})
|
||||
.finally(() => {
|
||||
nextTick(() => (D.loading = false));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {boolean} value
|
||||
*/
|
||||
@@ -249,6 +88,7 @@ export const useAvatarStore = defineStore('Avatar', () => {
|
||||
* @returns {Promise<string[]>}
|
||||
*/
|
||||
async function getAvatarGallery(avatarId) {
|
||||
const { queryRequest } = await import('../api');
|
||||
const D = avatarDialog.value;
|
||||
const args = await queryRequest
|
||||
.fetch('avatarGallery', { avatarId })
|
||||
@@ -341,54 +181,6 @@ export const useAvatarStore = defineStore('Avatar', () => {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async function getAvatarHistory() {
|
||||
const historyArray = await database.getAvatarHistory(
|
||||
userStore.currentUser.id
|
||||
);
|
||||
for (let i = 0; i < historyArray.length; i++) {
|
||||
const avatar = historyArray[i];
|
||||
if (avatar.authorId === userStore.currentUser.id) {
|
||||
continue;
|
||||
}
|
||||
applyAvatar(avatar);
|
||||
}
|
||||
avatarHistory.value = historyArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} avatarId
|
||||
*/
|
||||
function addAvatarToHistory(avatarId) {
|
||||
avatarRequest
|
||||
.getAvatar({ avatarId })
|
||||
.then((args) => {
|
||||
const ref = applyAvatar(args.json);
|
||||
|
||||
database.addAvatarToCache(ref);
|
||||
database.addAvatarToHistory(ref.id);
|
||||
|
||||
if (ref.authorId === userStore.currentUser.id) {
|
||||
return;
|
||||
}
|
||||
|
||||
const historyArray = avatarHistory.value;
|
||||
for (let i = 0; i < historyArray.length; ++i) {
|
||||
if (historyArray[i].id === ref.id) {
|
||||
historyArray.splice(i, 1);
|
||||
}
|
||||
}
|
||||
|
||||
avatarHistory.value.unshift(ref);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error('Failed to add avatar to history:', err);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@@ -397,423 +189,21 @@ export const useAvatarStore = defineStore('Avatar', () => {
|
||||
database.clearAvatarHistory();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function promptClearAvatarHistory() {
|
||||
modalStore
|
||||
.confirm({
|
||||
description: t('confirm.clear_avatar_history'),
|
||||
title: 'Confirm'
|
||||
})
|
||||
.then(({ ok }) => {
|
||||
if (!ok) return;
|
||||
clearAvatarHistory();
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} imageUrl
|
||||
* @returns {Promise<object>}
|
||||
*/
|
||||
async function getAvatarName(imageUrl) {
|
||||
const fileId = extractFileId(imageUrl);
|
||||
if (!fileId) {
|
||||
return {
|
||||
ownerId: '',
|
||||
avatarName: '-'
|
||||
};
|
||||
}
|
||||
if (cachedAvatarNames.has(fileId)) {
|
||||
return cachedAvatarNames.get(fileId);
|
||||
}
|
||||
try {
|
||||
const args = await miscRequest.getFile({ fileId });
|
||||
return storeAvatarImage(args, cachedAvatarNames);
|
||||
} catch (error) {
|
||||
console.error('Failed to get avatar images:', error);
|
||||
return {
|
||||
ownerId: '',
|
||||
avatarName: '-'
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param type
|
||||
* @param search
|
||||
*/
|
||||
async function lookupAvatars(type, search) {
|
||||
const avatars = new Map();
|
||||
if (type === 'search') {
|
||||
try {
|
||||
const url = `${
|
||||
avatarProviderStore.avatarRemoteDatabaseProvider
|
||||
}?${type}=${encodeURIComponent(search)}&n=5000`;
|
||||
const response = await webApiService.execute({
|
||||
url,
|
||||
method: 'GET',
|
||||
headers: {
|
||||
Referer: 'https://vrcx.app',
|
||||
'VRCX-ID': vrcxUpdaterStore.vrcxId
|
||||
}
|
||||
});
|
||||
const json = JSON.parse(response.data);
|
||||
if (AppDebug.debugWebRequests) {
|
||||
console.log(url, json, response);
|
||||
}
|
||||
if (response.status === 200 && typeof json === 'object') {
|
||||
json.forEach((avatar) => {
|
||||
if (!avatars.has(avatar.Id)) {
|
||||
const ref = {
|
||||
authorId: '',
|
||||
authorName: '',
|
||||
name: '',
|
||||
description: '',
|
||||
id: '',
|
||||
imageUrl: '',
|
||||
thumbnailImageUrl: '',
|
||||
created_at: '0001-01-01T00:00:00.0000000Z',
|
||||
updated_at: '0001-01-01T00:00:00.0000000Z',
|
||||
releaseStatus: 'public',
|
||||
...avatar
|
||||
};
|
||||
avatars.set(ref.id, ref);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
throw new Error(`Error: ${response.data}`);
|
||||
}
|
||||
} catch (err) {
|
||||
const msg = `Avatar search failed for ${search} with ${avatarProviderStore.avatarRemoteDatabaseProvider}\n${err}`;
|
||||
console.error(msg);
|
||||
toast.error(msg);
|
||||
}
|
||||
} else if (type === 'authorId') {
|
||||
const length =
|
||||
avatarProviderStore.avatarRemoteDatabaseProviderList.length;
|
||||
for (let i = 0; i < length; ++i) {
|
||||
const url =
|
||||
avatarProviderStore.avatarRemoteDatabaseProviderList[i];
|
||||
const avatarArray = await lookupAvatarsByAuthor(url, search);
|
||||
avatarArray.forEach((avatar) => {
|
||||
if (!avatars.has(avatar.id)) {
|
||||
avatars.set(avatar.id, avatar);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
return avatars;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param authorId
|
||||
* @param fileId
|
||||
*/
|
||||
async function lookupAvatarByImageFileId(authorId, fileId) {
|
||||
for (const providerUrl of avatarProviderStore.avatarRemoteDatabaseProviderList) {
|
||||
const avatar = await lookupAvatarByFileId(providerUrl, fileId);
|
||||
if (avatar?.id) {
|
||||
return avatar.id;
|
||||
}
|
||||
}
|
||||
|
||||
for (const providerUrl of avatarProviderStore.avatarRemoteDatabaseProviderList) {
|
||||
const avatarArray = await lookupAvatarsByAuthor(
|
||||
providerUrl,
|
||||
authorId
|
||||
);
|
||||
for (const avatar of avatarArray) {
|
||||
if (extractFileId(avatar.imageUrl) === fileId) {
|
||||
return avatar.id;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param providerUrl
|
||||
* @param fileId
|
||||
*/
|
||||
async function lookupAvatarByFileId(providerUrl, fileId) {
|
||||
try {
|
||||
const url = `${providerUrl}?fileId=${encodeURIComponent(fileId)}`;
|
||||
const response = await webApiService.execute({
|
||||
url,
|
||||
method: 'GET',
|
||||
headers: {
|
||||
Referer: 'https://vrcx.app',
|
||||
'VRCX-ID': vrcxUpdaterStore.vrcxId
|
||||
}
|
||||
});
|
||||
const json = JSON.parse(response.data);
|
||||
if (AppDebug.debugWebRequests) {
|
||||
console.log(url, json, response);
|
||||
}
|
||||
if (response.status === 200 && typeof json === 'object') {
|
||||
const ref = {
|
||||
authorId: '',
|
||||
authorName: '',
|
||||
name: '',
|
||||
description: '',
|
||||
id: '',
|
||||
imageUrl: '',
|
||||
thumbnailImageUrl: '',
|
||||
created_at: '0001-01-01T00:00:00.0000000Z',
|
||||
updated_at: '0001-01-01T00:00:00.0000000Z',
|
||||
releaseStatus: 'public',
|
||||
...json
|
||||
};
|
||||
return ref;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} catch (err) {
|
||||
// ignore errors for now, not all providers support this lookup type
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param providerUrl
|
||||
* @param authorId
|
||||
*/
|
||||
async function lookupAvatarsByAuthor(providerUrl, authorId) {
|
||||
const avatars = [];
|
||||
if (!providerUrl || !authorId) {
|
||||
return avatars;
|
||||
}
|
||||
const url = `${providerUrl}?authorId=${encodeURIComponent(authorId)}`;
|
||||
try {
|
||||
const response = await webApiService.execute({
|
||||
url,
|
||||
method: 'GET',
|
||||
headers: {
|
||||
Referer: 'https://vrcx.app',
|
||||
'VRCX-ID': vrcxUpdaterStore.vrcxId
|
||||
}
|
||||
});
|
||||
const json = JSON.parse(response.data);
|
||||
if (AppDebug.debugWebRequests) {
|
||||
console.log(url, json, response);
|
||||
}
|
||||
if (response.status === 200 && typeof json === 'object') {
|
||||
json.forEach((avatar) => {
|
||||
const ref = {
|
||||
authorId: '',
|
||||
authorName: '',
|
||||
name: '',
|
||||
description: '',
|
||||
id: '',
|
||||
imageUrl: '',
|
||||
thumbnailImageUrl: '',
|
||||
created_at: '0001-01-01T00:00:00.0000000Z',
|
||||
updated_at: '0001-01-01T00:00:00.0000000Z',
|
||||
releaseStatus: 'public',
|
||||
...avatar
|
||||
};
|
||||
avatars.push(ref);
|
||||
});
|
||||
} else {
|
||||
throw new Error(`Error: ${response.data}`);
|
||||
}
|
||||
} catch (err) {
|
||||
const msg = `Avatar lookup failed for ${authorId} with ${url}\n${err}`;
|
||||
console.error(msg);
|
||||
toast.error(msg);
|
||||
}
|
||||
return avatars;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param id
|
||||
*/
|
||||
function selectAvatarWithConfirmation(id) {
|
||||
modalStore
|
||||
.confirm({
|
||||
description: t('confirm.select_avatar'),
|
||||
title: 'Confirm'
|
||||
})
|
||||
.then(({ ok }) => {
|
||||
if (!ok) return;
|
||||
selectAvatarWithoutConfirmation(id);
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param id
|
||||
*/
|
||||
async function selectAvatarWithoutConfirmation(id) {
|
||||
if (userStore.currentUser.currentAvatar === id) {
|
||||
toast.info('Avatar already selected');
|
||||
return;
|
||||
}
|
||||
return avatarRequest
|
||||
.selectAvatar({
|
||||
avatarId: id
|
||||
})
|
||||
.then(() => {
|
||||
toast.success('Avatar changed');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param fileId
|
||||
*/
|
||||
function checkAvatarCache(fileId) {
|
||||
let avatarId = '';
|
||||
for (let ref of cachedAvatars.values()) {
|
||||
if (extractFileId(ref.imageUrl) === fileId) {
|
||||
avatarId = ref.id;
|
||||
}
|
||||
}
|
||||
return avatarId;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param fileId
|
||||
* @param ownerUserId
|
||||
*/
|
||||
async function checkAvatarCacheRemote(fileId, ownerUserId) {
|
||||
if (advancedSettingsStore.avatarRemoteDatabase) {
|
||||
try {
|
||||
toast.dismiss(loadingToastId.value);
|
||||
loadingToastId.value = toast.loading(
|
||||
t('message.avatar_lookup.loading')
|
||||
);
|
||||
const avatarId = await lookupAvatarByImageFileId(
|
||||
ownerUserId,
|
||||
fileId
|
||||
);
|
||||
return avatarId;
|
||||
} catch (err) {
|
||||
console.error('Failed to lookup avatar by image file id:', err);
|
||||
} finally {
|
||||
toast.dismiss(loadingToastId.value);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param refUserId
|
||||
* @param ownerUserId
|
||||
* @param currentAvatarImageUrl
|
||||
*/
|
||||
async function showAvatarAuthorDialog(
|
||||
refUserId,
|
||||
ownerUserId,
|
||||
currentAvatarImageUrl
|
||||
) {
|
||||
const fileId = extractFileId(currentAvatarImageUrl);
|
||||
if (!fileId) {
|
||||
toast.error(t('message.avatar_lookup.failed'));
|
||||
} else if (refUserId === userStore.currentUser.id) {
|
||||
showAvatarDialog(userStore.currentUser.currentAvatar);
|
||||
} else {
|
||||
let avatarId = checkAvatarCache(fileId);
|
||||
let avatarInfo;
|
||||
if (!avatarId) {
|
||||
avatarInfo = await getAvatarName(currentAvatarImageUrl);
|
||||
if (avatarInfo.ownerId === userStore.currentUser.id) {
|
||||
await userStore.refreshUserDialogAvatars(fileId);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!avatarId) {
|
||||
avatarId = await checkAvatarCacheRemote(fileId, ownerUserId);
|
||||
}
|
||||
if (!avatarId) {
|
||||
if (ownerUserId === refUserId) {
|
||||
toast.warning(
|
||||
t('message.avatar_lookup.private_or_not_found')
|
||||
);
|
||||
} else {
|
||||
toast.warning(t('message.avatar_lookup.not_found'));
|
||||
userStore.showUserDialog(avatarInfo.ownerId);
|
||||
}
|
||||
}
|
||||
if (avatarId) {
|
||||
showAvatarDialog(avatarId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param avatarId
|
||||
*/
|
||||
function addAvatarWearTime(avatarId) {
|
||||
if (!userStore.currentUser.$previousAvatarSwapTime || !avatarId) {
|
||||
return;
|
||||
}
|
||||
const timeSpent =
|
||||
Date.now() - userStore.currentUser.$previousAvatarSwapTime;
|
||||
database.addAvatarTimeSpent(avatarId, timeSpent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Preload all own avatars into cache at startup for global search.
|
||||
*/
|
||||
async function preloadOwnAvatars() {
|
||||
const params = {
|
||||
n: 50,
|
||||
offset: 0,
|
||||
sort: 'updated',
|
||||
order: 'descending',
|
||||
releaseStatus: 'all',
|
||||
user: 'me'
|
||||
};
|
||||
await processBulk({
|
||||
fn: avatarRequest.getAvatars,
|
||||
N: -1,
|
||||
params,
|
||||
handle: (args) => {
|
||||
for (const json of args.json) {
|
||||
applyAvatar(json);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
avatarDialog,
|
||||
avatarHistory,
|
||||
loadingToastId,
|
||||
cachedAvatarModerations,
|
||||
cachedAvatars,
|
||||
cachedAvatarNames,
|
||||
|
||||
showAvatarDialog,
|
||||
applyAvatarModeration,
|
||||
resetCachedAvatarModerations,
|
||||
getAvatarGallery,
|
||||
updateVRChatAvatarCache,
|
||||
getAvatarHistory,
|
||||
addAvatarToHistory,
|
||||
applyAvatar,
|
||||
promptClearAvatarHistory,
|
||||
getAvatarName,
|
||||
lookupAvatars,
|
||||
selectAvatarWithConfirmation,
|
||||
selectAvatarWithoutConfirmation,
|
||||
clearAvatarHistory,
|
||||
setAvatarDialogVisible,
|
||||
setAvatarDialogIsFavorite,
|
||||
setAvatarDialogLoading,
|
||||
showAvatarAuthorDialog,
|
||||
addAvatarWearTime,
|
||||
preloadOwnAvatars
|
||||
setAvatarDialogLoading
|
||||
};
|
||||
});
|
||||
|
||||
@@ -25,6 +25,7 @@ import {
|
||||
runPendingOfflineTickFlow,
|
||||
runUpdateFriendFlow
|
||||
} from '../coordinators/friendPresenceCoordinator';
|
||||
import { applyUser } from '../coordinators/userCoordinator';
|
||||
import { AppDebug } from '../service/appConfig';
|
||||
import { database } from '../service/database';
|
||||
import { useAppearanceSettingsStore } from './settings/appearance';
|
||||
@@ -981,7 +982,7 @@ export const useFriendStore = defineStore('Friend', () => {
|
||||
const sqlValues = [];
|
||||
const friends = await refreshFriends();
|
||||
for (const friend of friends) {
|
||||
const ref = userStore.applyUser(friend);
|
||||
const ref = applyUser(friend);
|
||||
const row = {
|
||||
userId: ref.id,
|
||||
displayName: ref.displayName,
|
||||
|
||||
@@ -13,6 +13,10 @@ import { useAvatarStore } from './avatar';
|
||||
import { useFavoriteStore } from './favorite';
|
||||
import { useFriendStore } from './friend';
|
||||
import { useGroupStore } from './group';
|
||||
import { showGroupDialog } from '../coordinators/groupCoordinator';
|
||||
import { showWorldDialog } from '../coordinators/worldCoordinator';
|
||||
import { showAvatarDialog } from '../coordinators/avatarCoordinator';
|
||||
import { showUserDialog } from '../coordinators/userCoordinator';
|
||||
import { useUserStore } from './user';
|
||||
import { useWorldStore } from './world';
|
||||
|
||||
@@ -166,16 +170,16 @@ export const useGlobalSearchStore = defineStore('GlobalSearch', () => {
|
||||
|
||||
switch (item.type) {
|
||||
case 'friend':
|
||||
userStore.showUserDialog(item.id);
|
||||
showUserDialog(item.id);
|
||||
break;
|
||||
case 'avatar':
|
||||
avatarStore.showAvatarDialog(item.id);
|
||||
showAvatarDialog(item.id);
|
||||
break;
|
||||
case 'world':
|
||||
worldStore.showWorldDialog(item.id);
|
||||
showWorldDialog(item.id);
|
||||
break;
|
||||
case 'group':
|
||||
groupStore.showGroupDialog(item.id);
|
||||
showGroupDialog(item.id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -44,6 +44,8 @@ import { useFriendStore } from '../friend';
|
||||
import { useGameStore } from '../game';
|
||||
import { useGeneralSettingsStore } from '../settings/general';
|
||||
import { useGroupStore } from '../group';
|
||||
import { showGroupDialog } from '../../coordinators/groupCoordinator';
|
||||
import { showUserDialog } from '../../coordinators/userCoordinator';
|
||||
import { useInstanceStore } from '../instance';
|
||||
import { useLocationStore } from '../location';
|
||||
import { useModalStore } from '../modal';
|
||||
@@ -1415,10 +1417,10 @@ export const useNotificationStore = defineStore('Notification', () => {
|
||||
}
|
||||
switch (data[0]) {
|
||||
case 'group':
|
||||
groupStore.showGroupDialog(data[1]);
|
||||
showGroupDialog(data[1]);
|
||||
break;
|
||||
case 'user':
|
||||
userStore.showUserDialog(data[1]);
|
||||
showUserDialog(data[1]);
|
||||
break;
|
||||
case 'event':
|
||||
const ids = data[1].split(',');
|
||||
@@ -1427,7 +1429,7 @@ export const useNotificationStore = defineStore('Notification', () => {
|
||||
return;
|
||||
}
|
||||
|
||||
groupStore.showGroupDialog(ids[0]);
|
||||
showGroupDialog(ids[0]);
|
||||
// ids[1] cal_ is the event id
|
||||
break;
|
||||
case 'openNotificationLink':
|
||||
|
||||
@@ -20,6 +20,8 @@ import { photonEmojis, photonEventType } from '../shared/constants/photon';
|
||||
import { AppDebug } from '../service/appConfig';
|
||||
import { database } from '../service/database';
|
||||
import { useAvatarStore } from './avatar';
|
||||
import { applyAvatar } from '../coordinators/avatarCoordinator';
|
||||
import { showUserDialog, lookupUser, applyUser } from '../coordinators/userCoordinator';
|
||||
import { useFavoriteStore } from './favorite';
|
||||
import { useFriendStore } from './friend';
|
||||
import { useGameLogStore } from './gameLog';
|
||||
@@ -424,9 +426,9 @@ export const usePhotonStore = defineStore('Photon', () => {
|
||||
const ref = photonLobby.value.get(photonId);
|
||||
if (typeof ref !== 'undefined') {
|
||||
if (typeof ref.id !== 'undefined') {
|
||||
userStore.showUserDialog(ref.id);
|
||||
showUserDialog(ref.id);
|
||||
} else if (typeof ref.displayName !== 'undefined') {
|
||||
userStore.lookupUser(ref);
|
||||
lookupUser(ref);
|
||||
}
|
||||
} else {
|
||||
toast.error('No user info available');
|
||||
@@ -1475,7 +1477,7 @@ export const usePhotonStore = defineStore('Photon', () => {
|
||||
typeof ref.id !== 'undefined' &&
|
||||
ref.currentAvatarImageUrl !== user.currentAvatarImageUrl
|
||||
) {
|
||||
userStore.applyUser({
|
||||
applyUser({
|
||||
...ref,
|
||||
currentAvatarImageUrl: user.currentAvatarImageUrl,
|
||||
currentAvatarThumbnailImageUrl:
|
||||
@@ -1803,7 +1805,7 @@ export const usePhotonStore = defineStore('Photon', () => {
|
||||
}
|
||||
}
|
||||
}
|
||||
avatarStore.applyAvatar({
|
||||
applyAvatar({
|
||||
id: avatar.id,
|
||||
authorId: avatar.authorId,
|
||||
authorName: avatar.authorName,
|
||||
|
||||
@@ -12,6 +12,10 @@ import { useAppearanceSettingsStore } from './settings/appearance';
|
||||
import { useAvatarStore } from './avatar';
|
||||
import { useFriendStore } from './friend';
|
||||
import { useGroupStore } from './group';
|
||||
import { showGroupDialog } from '../coordinators/groupCoordinator';
|
||||
import { showWorldDialog } from '../coordinators/worldCoordinator';
|
||||
import { showAvatarDialog } from '../coordinators/avatarCoordinator';
|
||||
import { applyUser, showUserDialog, lookupUser } from '../coordinators/userCoordinator';
|
||||
import { useModalStore } from './modal';
|
||||
import { useUserStore } from './user';
|
||||
import { useWorldStore } from './world';
|
||||
@@ -93,7 +97,7 @@ export const useSearchStore = defineStore('Search', () => {
|
||||
console.error('getUsers gave us garbage', json);
|
||||
continue;
|
||||
}
|
||||
userStore.applyUser(json);
|
||||
applyUser(json);
|
||||
}
|
||||
|
||||
const map = new Map();
|
||||
@@ -210,10 +214,10 @@ export const useSearchStore = defineStore('Search', () => {
|
||||
} else {
|
||||
router.push({ name: 'search' });
|
||||
searchText.value = searchTerm;
|
||||
userStore.lookupUser({ displayName: searchTerm });
|
||||
lookupUser({ displayName: searchTerm });
|
||||
}
|
||||
} else {
|
||||
userStore.showUserDialog(value);
|
||||
showUserDialog(value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -273,15 +277,15 @@ export const useSearchStore = defineStore('Search', () => {
|
||||
const type = urlPathSplit[2];
|
||||
if (type === 'user') {
|
||||
const userId = urlPathSplit[3];
|
||||
userStore.showUserDialog(userId);
|
||||
showUserDialog(userId);
|
||||
return true;
|
||||
} else if (type === 'avatar') {
|
||||
const avatarId = urlPathSplit[3];
|
||||
avatarStore.showAvatarDialog(avatarId);
|
||||
showAvatarDialog(avatarId);
|
||||
return true;
|
||||
} else if (type === 'group') {
|
||||
const groupId = urlPathSplit[3];
|
||||
groupStore.showGroupDialog(groupId);
|
||||
showGroupDialog(groupId);
|
||||
return true;
|
||||
}
|
||||
} else if (input.startsWith('https://vrc.group/')) {
|
||||
@@ -295,16 +299,16 @@ export const useSearchStore = defineStore('Search', () => {
|
||||
input.substring(0, 4) === 'usr_' ||
|
||||
/^[A-Za-z0-9]{10}$/g.test(input)
|
||||
) {
|
||||
userStore.showUserDialog(input);
|
||||
showUserDialog(input);
|
||||
return true;
|
||||
} else if (
|
||||
input.substring(0, 5) === 'avtr_' ||
|
||||
input.substring(0, 2) === 'b_'
|
||||
) {
|
||||
avatarStore.showAvatarDialog(input);
|
||||
showAvatarDialog(input);
|
||||
return true;
|
||||
} else if (input.substring(0, 4) === 'grp_') {
|
||||
groupStore.showGroupDialog(input);
|
||||
showGroupDialog(input);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -331,7 +335,7 @@ export const useSearchStore = defineStore('Search', () => {
|
||||
const urlPathSplit = urlPath.split('/');
|
||||
if (urlPathSplit.length >= 4 && urlPathSplit[2] === 'world') {
|
||||
worldId = urlPathSplit[3];
|
||||
worldStore.showWorldDialog(worldId);
|
||||
showWorldDialog(worldId);
|
||||
return true;
|
||||
} else if (urlPath.substring(5, 12) === '/launch') {
|
||||
const urlParams = new URLSearchParams(url.search);
|
||||
@@ -343,10 +347,10 @@ export const useSearchStore = defineStore('Search', () => {
|
||||
if (shortName) {
|
||||
return verifyShortName(location, shortName);
|
||||
}
|
||||
worldStore.showWorldDialog(location);
|
||||
showWorldDialog(location);
|
||||
return true;
|
||||
} else if (worldId) {
|
||||
worldStore.showWorldDialog(worldId);
|
||||
showWorldDialog(worldId);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -360,7 +364,7 @@ export const useSearchStore = defineStore('Search', () => {
|
||||
input = `https://vrchat.com/home/launch?worldId=${input}`;
|
||||
return directAccessWorld(input);
|
||||
}
|
||||
worldStore.showWorldDialog(input.trim());
|
||||
showWorldDialog(input.trim());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -399,7 +403,7 @@ export const useSearchStore = defineStore('Search', () => {
|
||||
groupRequest.groupStrictsearch({ query: shortCode }).then((args) => {
|
||||
for (const group of args.json) {
|
||||
if (`${group.shortCode}.${group.discriminator}` === shortCode) {
|
||||
groupStore.showGroupDialog(group.id);
|
||||
showGroupDialog(group.id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -414,11 +418,11 @@ export const useSearchStore = defineStore('Search', () => {
|
||||
const newLocation = args.json.location;
|
||||
const newShortName = args.json.shortName;
|
||||
if (newShortName) {
|
||||
worldStore.showWorldDialog(newLocation, newShortName);
|
||||
showWorldDialog(newLocation, newShortName);
|
||||
} else if (newLocation) {
|
||||
worldStore.showWorldDialog(newLocation);
|
||||
showWorldDialog(newLocation);
|
||||
} else {
|
||||
worldStore.showWorldDialog(location);
|
||||
showWorldDialog(location);
|
||||
}
|
||||
return args;
|
||||
});
|
||||
|
||||
@@ -10,6 +10,10 @@ import { updateLocalizedStrings } from '../plugin/i18n';
|
||||
import { useAppearanceSettingsStore } from './settings/appearance';
|
||||
import { useAvatarStore } from './avatar';
|
||||
import { useGroupStore } from './group';
|
||||
import { showGroupDialog } from '../coordinators/groupCoordinator';
|
||||
import { showWorldDialog } from '../coordinators/worldCoordinator';
|
||||
import { showAvatarDialog } from '../coordinators/avatarCoordinator';
|
||||
import { showUserDialog } from '../coordinators/userCoordinator';
|
||||
import { useInstanceStore } from './instance';
|
||||
import { useNotificationStore } from './notification';
|
||||
import { useSearchStore } from './search';
|
||||
@@ -142,19 +146,19 @@ export const useUiStore = defineStore('Ui', () => {
|
||||
}
|
||||
jumpDialogCrumb(index);
|
||||
if (item.type === 'user') {
|
||||
userStore.showUserDialog(item.id);
|
||||
showUserDialog(item.id);
|
||||
return;
|
||||
}
|
||||
if (item.type === 'world') {
|
||||
worldStore.showWorldDialog(item.tag, item.shortName);
|
||||
showWorldDialog(item.tag, item.shortName);
|
||||
return;
|
||||
}
|
||||
if (item.type === 'avatar') {
|
||||
avatarStore.showAvatarDialog(item.id);
|
||||
showAvatarDialog(item.id);
|
||||
return;
|
||||
}
|
||||
if (item.type === 'group') {
|
||||
groupStore.showGroupDialog(item.id);
|
||||
showGroupDialog(item.id);
|
||||
return;
|
||||
}
|
||||
if (item.type === 'previous-instances-user') {
|
||||
|
||||
@@ -12,6 +12,8 @@ import { useFriendStore } from './friend';
|
||||
import { useGameLogStore } from './gameLog';
|
||||
import { useGameStore } from './game';
|
||||
import { useGroupStore } from './group';
|
||||
import { handleGroupUserInstances } from '../coordinators/groupCoordinator';
|
||||
import { getCurrentUser, updateAutoStateChange } from '../coordinators/userCoordinator';
|
||||
import { useModerationStore } from './moderation';
|
||||
import { useUserStore } from './user';
|
||||
import { useVRCXUpdaterStore } from './vrcxUpdater';
|
||||
@@ -73,7 +75,7 @@ export const useUpdateLoopStore = defineStore('UpdateLoop', () => {
|
||||
if (watchState.isLoggedIn) {
|
||||
if (--state.nextCurrentUserRefresh <= 0) {
|
||||
state.nextCurrentUserRefresh = 300; // 5min
|
||||
userStore.getCurrentUser();
|
||||
getCurrentUser();
|
||||
}
|
||||
if (--state.nextFriendsRefresh <= 0) {
|
||||
state.nextFriendsRefresh = 3600; // 1hour
|
||||
@@ -92,7 +94,7 @@ export const useUpdateLoopStore = defineStore('UpdateLoop', () => {
|
||||
state.nextGroupInstanceRefresh = 300; // 5min
|
||||
const args =
|
||||
await groupRequest.getUsersGroupInstances();
|
||||
groupStore.handleGroupUserInstances(args);
|
||||
handleGroupUserInstances(args);
|
||||
}
|
||||
AppApi.CheckGameRunning();
|
||||
}
|
||||
@@ -122,7 +124,7 @@ export const useUpdateLoopStore = defineStore('UpdateLoop', () => {
|
||||
}
|
||||
if (--state.nextAutoStateChange <= 0) {
|
||||
state.nextAutoStateChange = 3;
|
||||
userStore.updateAutoStateChange();
|
||||
updateAutoStateChange();
|
||||
}
|
||||
if (LINUX && --state.nextGetLogCheck <= 0) {
|
||||
state.nextGetLogCheck = 0.5;
|
||||
|
||||
1069
src/stores/user.js
1069
src/stores/user.js
File diff suppressed because it is too large
Load Diff
@@ -32,6 +32,10 @@ import { useGalleryStore } from './gallery';
|
||||
import { useGameLogStore } from './gameLog';
|
||||
import { useGameStore } from './game';
|
||||
import { useGroupStore } from './group';
|
||||
import { showGroupDialog } from '../coordinators/groupCoordinator';
|
||||
import { showWorldDialog } from '../coordinators/worldCoordinator';
|
||||
import { showAvatarDialog, selectAvatarWithConfirmation, selectAvatarWithoutConfirmation } from '../coordinators/avatarCoordinator';
|
||||
import { showUserDialog, addCustomTag } from '../coordinators/userCoordinator';
|
||||
import { useInstanceStore } from './instance';
|
||||
import { useLocationStore } from './location';
|
||||
import { useModalStore } from './modal';
|
||||
@@ -335,7 +339,7 @@ export const useVrcxStore = defineStore('Vrcx', () => {
|
||||
let entry;
|
||||
switch (data.MsgType) {
|
||||
case 'CustomTag':
|
||||
userStore.addCustomTag(data);
|
||||
addCustomTag(data);
|
||||
break;
|
||||
case 'ClearCustomTags':
|
||||
userStore.customUserTags.forEach((value, key) => {
|
||||
@@ -669,17 +673,17 @@ export const useVrcxStore = defineStore('Vrcx', () => {
|
||||
!searchStore.directAccessWorld(input.replace('world/', ''))
|
||||
) {
|
||||
// fallback for mangled world ids
|
||||
worldStore.showWorldDialog(commandArg);
|
||||
showWorldDialog(commandArg);
|
||||
}
|
||||
break;
|
||||
case 'avatar':
|
||||
avatarStore.showAvatarDialog(commandArg);
|
||||
showAvatarDialog(commandArg);
|
||||
break;
|
||||
case 'user':
|
||||
userStore.showUserDialog(commandArg);
|
||||
showUserDialog(commandArg);
|
||||
break;
|
||||
case 'group':
|
||||
groupStore.showGroupDialog(commandArg);
|
||||
showGroupDialog(commandArg);
|
||||
break;
|
||||
case 'local-favorite-world':
|
||||
console.log('local-favorite-world', commandArg);
|
||||
@@ -701,7 +705,7 @@ export const useVrcxStore = defineStore('Vrcx', () => {
|
||||
break;
|
||||
}
|
||||
avatarRequest.getAvatar({ avatarId: avatarIdFav }).then(() => {
|
||||
avatarStore.showAvatarDialog(avatarIdFav);
|
||||
showAvatarDialog(avatarIdFav);
|
||||
addLocalAvatarFavorite(
|
||||
avatarIdFav,
|
||||
avatarGroup
|
||||
@@ -722,12 +726,11 @@ export const useVrcxStore = defineStore('Vrcx', () => {
|
||||
break;
|
||||
}
|
||||
if (advancedSettingsStore.showConfirmationOnSwitchAvatar) {
|
||||
avatarStore.selectAvatarWithConfirmation(avatarId);
|
||||
selectAvatarWithConfirmation(avatarId);
|
||||
// Makes sure the window is focused
|
||||
shouldFocusWindow = true;
|
||||
} else {
|
||||
avatarStore
|
||||
.selectAvatarWithoutConfirmation(avatarId)
|
||||
selectAvatarWithoutConfirmation(avatarId)
|
||||
.then(() => {
|
||||
toast.success('Avatar changed via launch command');
|
||||
});
|
||||
|
||||
@@ -1,39 +1,12 @@
|
||||
import { nextTick, reactive, shallowReactive, watch } from 'vue';
|
||||
import { reactive, shallowReactive, watch } from 'vue';
|
||||
import { defineStore } from 'pinia';
|
||||
import { toast } from 'vue-sonner';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import {
|
||||
checkVRChatCache,
|
||||
createDefaultWorldRef,
|
||||
evictMapCache,
|
||||
getAvailablePlatforms,
|
||||
getBundleDateSize,
|
||||
getWorldMemo,
|
||||
isRealInstance,
|
||||
parseLocation,
|
||||
sanitizeEntityJson
|
||||
checkVRChatCache
|
||||
} from '../shared/utils';
|
||||
import { instanceRequest, queryRequest, worldRequest } from '../api';
|
||||
import { database } from '../service/database';
|
||||
import { patchWorldFromEvent } from '../queries';
|
||||
import { processBulk } from '../service/request';
|
||||
import { applyFavorite } from '../coordinators/favoriteCoordinator';
|
||||
import { useFavoriteStore } from './favorite';
|
||||
import { useInstanceStore } from './instance';
|
||||
import { useLocationStore } from './location';
|
||||
import { useUiStore } from './ui';
|
||||
import { useUserStore } from './user';
|
||||
import { watchState } from '../service/watchState';
|
||||
|
||||
export const useWorldStore = defineStore('World', () => {
|
||||
const locationStore = useLocationStore();
|
||||
const favoriteStore = useFavoriteStore();
|
||||
const instanceStore = useInstanceStore();
|
||||
const userStore = useUserStore();
|
||||
const uiStore = useUiStore();
|
||||
const { t } = useI18n();
|
||||
|
||||
const worldDialog = reactive({
|
||||
visible: false,
|
||||
loading: false,
|
||||
@@ -69,145 +42,14 @@ export const useWorldStore = defineStore('World', () => {
|
||||
worldDialog.visible = false;
|
||||
cachedWorlds.clear();
|
||||
if (isLoggedIn) {
|
||||
preloadOwnWorlds();
|
||||
import('../coordinators/worldCoordinator').then(
|
||||
({ preloadOwnWorlds }) => preloadOwnWorlds()
|
||||
);
|
||||
}
|
||||
},
|
||||
{ flush: 'sync' }
|
||||
);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} tag
|
||||
* @param {string} shortName
|
||||
* @param options
|
||||
*/
|
||||
function showWorldDialog(tag, shortName = null, options = {}) {
|
||||
const D = worldDialog;
|
||||
const forceRefresh = Boolean(options?.forceRefresh);
|
||||
const L = parseLocation(tag);
|
||||
if (L.worldId === '') {
|
||||
return;
|
||||
}
|
||||
const isMainDialogOpen = uiStore.openDialog({
|
||||
type: 'world',
|
||||
id: L.worldId,
|
||||
tag,
|
||||
shortName
|
||||
});
|
||||
D.visible = true;
|
||||
if (isMainDialogOpen && D.id === L.worldId && !forceRefresh) {
|
||||
uiStore.setDialogCrumbLabel('world', D.id, D.ref?.name || D.id);
|
||||
instanceStore.applyWorldDialogInstances();
|
||||
nextTick(() => (D.loading = false));
|
||||
return;
|
||||
}
|
||||
L.shortName = shortName;
|
||||
D.id = L.worldId;
|
||||
D.$location = L;
|
||||
D.loading = true;
|
||||
D.inCache = false;
|
||||
D.cacheSize = '';
|
||||
D.cacheLocked = false;
|
||||
D.cachePath = '';
|
||||
D.fileAnalysis = {};
|
||||
D.rooms = [];
|
||||
D.lastVisit = '';
|
||||
D.visitCount = 0;
|
||||
D.timeSpent = 0;
|
||||
D.isFavorite = false;
|
||||
D.avatarScalingDisabled = false;
|
||||
D.focusViewDisabled = false;
|
||||
D.isPC = false;
|
||||
D.isQuest = false;
|
||||
D.isIos = false;
|
||||
D.hasPersistData = false;
|
||||
D.memo = '';
|
||||
const LL = parseLocation(locationStore.lastLocation.location);
|
||||
let currentWorldMatch = false;
|
||||
if (LL.worldId === D.id) {
|
||||
currentWorldMatch = true;
|
||||
}
|
||||
getWorldMemo(D.id).then((memo) => {
|
||||
if (memo.worldId === D.id) {
|
||||
D.memo = memo.memo;
|
||||
}
|
||||
});
|
||||
database.getLastVisit(D.id, currentWorldMatch).then((ref) => {
|
||||
if (ref.worldId === D.id) {
|
||||
D.lastVisit = ref.created_at;
|
||||
}
|
||||
});
|
||||
database.getVisitCount(D.id).then((ref) => {
|
||||
if (ref.worldId === D.id) {
|
||||
D.visitCount = ref.visitCount;
|
||||
}
|
||||
});
|
||||
database.getTimeSpentInWorld(D.id).then((ref) => {
|
||||
if (ref.worldId === D.id) {
|
||||
D.timeSpent = ref.timeSpent;
|
||||
}
|
||||
});
|
||||
const loadWorldRequest = worldRequest.getWorld({
|
||||
worldId: L.worldId
|
||||
});
|
||||
loadWorldRequest
|
||||
.catch((err) => {
|
||||
nextTick(() => (D.loading = false));
|
||||
D.id = null;
|
||||
D.visible = false;
|
||||
uiStore.jumpBackDialogCrumb();
|
||||
toast.error(t('message.world.load_failed'));
|
||||
throw err;
|
||||
})
|
||||
.then((args) => {
|
||||
if (D.id === args.ref.id) {
|
||||
D.ref = args.ref;
|
||||
uiStore.setDialogCrumbLabel(
|
||||
'world',
|
||||
D.id,
|
||||
D.ref?.name || D.id
|
||||
);
|
||||
D.visible = true;
|
||||
D.loading = false;
|
||||
D.isFavorite = favoriteStore.getCachedFavoritesByObjectId(
|
||||
D.id
|
||||
);
|
||||
if (!D.isFavorite) {
|
||||
D.isFavorite =
|
||||
favoriteStore.localWorldFavoritesList.includes(
|
||||
D.id
|
||||
);
|
||||
}
|
||||
let { isPC, isQuest, isIos } = getAvailablePlatforms(
|
||||
args.ref.unityPackages
|
||||
);
|
||||
D.avatarScalingDisabled = args.ref?.tags.includes(
|
||||
'feature_avatar_scaling_disabled'
|
||||
);
|
||||
D.focusViewDisabled = args.ref?.tags.includes(
|
||||
'feature_focus_view_disabled'
|
||||
);
|
||||
D.isPC = isPC;
|
||||
D.isQuest = isQuest;
|
||||
D.isIos = isIos;
|
||||
updateVRChatWorldCache();
|
||||
queryRequest
|
||||
.fetch('worldPersistData', {
|
||||
worldId: D.id
|
||||
})
|
||||
.then((args) => {
|
||||
if (
|
||||
args.params.worldId === worldDialog.id &&
|
||||
worldDialog.visible
|
||||
) {
|
||||
worldDialog.hasPersistData =
|
||||
args.json !== false;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {boolean} value
|
||||
*/
|
||||
@@ -250,99 +92,12 @@ export const useWorldStore = defineStore('World', () => {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param WorldCache
|
||||
*/
|
||||
function cleanupWorldCache(WorldCache) {
|
||||
evictMapCache(WorldCache, 10000, () => false, {
|
||||
logLabel: 'World cache cleanup'
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {object} json
|
||||
* @returns {object} ref
|
||||
*/
|
||||
function applyWorld(json) {
|
||||
sanitizeEntityJson(json, ['name', 'description']);
|
||||
let ref = cachedWorlds.get(json.id);
|
||||
if (typeof ref === 'undefined') {
|
||||
ref = createDefaultWorldRef(json);
|
||||
cleanupWorldCache(cachedWorlds);
|
||||
cachedWorlds.set(ref.id, ref);
|
||||
} else {
|
||||
Object.assign(ref, json);
|
||||
}
|
||||
ref.$isLabs = ref.tags.includes('system_labs');
|
||||
applyFavorite('world', ref.id);
|
||||
const userDialog = userStore.userDialog;
|
||||
if (userDialog.visible && userDialog.$location.worldId === ref.id) {
|
||||
userStore.applyUserDialogLocation();
|
||||
}
|
||||
if (worldDialog.visible && worldDialog.id === ref.id) {
|
||||
worldDialog.ref = ref;
|
||||
worldDialog.avatarScalingDisabled = ref.tags?.includes(
|
||||
'feature_avatar_scaling_disabled'
|
||||
);
|
||||
worldDialog.focusViewDisabled = ref.tags?.includes(
|
||||
'feature_focus_view_disabled'
|
||||
);
|
||||
instanceStore.applyWorldDialogInstances();
|
||||
for (const room of worldDialog.rooms) {
|
||||
if (isRealInstance(room.tag)) {
|
||||
instanceRequest.getInstance({
|
||||
worldId: worldDialog.id,
|
||||
instanceId: room.id
|
||||
});
|
||||
}
|
||||
}
|
||||
if (Object.keys(worldDialog.fileAnalysis).length === 0) {
|
||||
getBundleDateSize(ref);
|
||||
}
|
||||
}
|
||||
if (favoriteStore.localWorldFavoritesList.includes(ref.id)) {
|
||||
// update db cache
|
||||
database.addWorldToCache(ref);
|
||||
}
|
||||
patchWorldFromEvent(ref);
|
||||
return ref;
|
||||
}
|
||||
|
||||
/**
|
||||
* Preload all own worlds into cache at startup for global search.
|
||||
*/
|
||||
async function preloadOwnWorlds() {
|
||||
const params = {
|
||||
n: 50,
|
||||
offset: 0,
|
||||
sort: 'updated',
|
||||
order: 'descending',
|
||||
releaseStatus: 'all',
|
||||
user: 'me'
|
||||
};
|
||||
await processBulk({
|
||||
fn: (p) => worldRequest.getWorlds(p),
|
||||
N: -1,
|
||||
params,
|
||||
handle: (args) => {
|
||||
for (const json of args.json) {
|
||||
applyWorld(json);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
worldDialog,
|
||||
cachedWorlds,
|
||||
showWorldDialog,
|
||||
setWorldDialogVisible,
|
||||
setWorldDialogIsFavorite,
|
||||
setWorldDialogLoading,
|
||||
updateVRChatWorldCache,
|
||||
applyWorld,
|
||||
preloadOwnWorlds
|
||||
updateVRChatWorldCache
|
||||
};
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user