mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-04-18 14:23:51 +02:00
refactor untils
This commit is contained in:
194
src/coordinators/cacheCoordinator.js
Normal file
194
src/coordinators/cacheCoordinator.js
Normal file
@@ -0,0 +1,194 @@
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { toast } from 'vue-sonner';
|
||||
|
||||
import {
|
||||
useAuthStore,
|
||||
useAvatarStore,
|
||||
useInstanceStore,
|
||||
useWorldStore
|
||||
} from '../stores';
|
||||
import {
|
||||
extractFileId,
|
||||
extractFileVersion,
|
||||
extractVariantVersion
|
||||
} from '../shared/utils/fileUtils';
|
||||
import { compareUnityVersion } from '../shared/utils/avatar';
|
||||
import { queryRequest } from '../api';
|
||||
|
||||
async function deleteVRChatCache(ref) {
|
||||
const authStore = useAuthStore();
|
||||
const sdkUnityVersion = authStore.cachedConfig.sdkUnityVersion;
|
||||
let assetUrl = '';
|
||||
let variant = '';
|
||||
for (let i = ref.unityPackages.length - 1; i > -1; i--) {
|
||||
const unityPackage = ref.unityPackages[i];
|
||||
if (
|
||||
unityPackage.variant &&
|
||||
unityPackage.variant !== 'standard' &&
|
||||
unityPackage.variant !== 'security'
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
if (
|
||||
unityPackage.platform === 'standalonewindows' &&
|
||||
compareUnityVersion(unityPackage.unitySortNumber, sdkUnityVersion)
|
||||
) {
|
||||
assetUrl = unityPackage.assetUrl;
|
||||
if (!unityPackage.variant || unityPackage.variant === 'standard') {
|
||||
variant = 'security';
|
||||
} else {
|
||||
variant = unityPackage.variant;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
const id = extractFileId(assetUrl);
|
||||
const version = parseInt(extractFileVersion(assetUrl), 10);
|
||||
const variantVersion = parseInt(extractVariantVersion(assetUrl), 10);
|
||||
await AssetBundleManager.DeleteCache(id, version, variant, variantVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {object} ref
|
||||
* @returns
|
||||
*/
|
||||
async function checkVRChatCache(ref) {
|
||||
if (!ref.unityPackages) {
|
||||
return { Item1: -1, Item2: false, Item3: '' };
|
||||
}
|
||||
const authStore = useAuthStore();
|
||||
const sdkUnityVersion = authStore.cachedConfig.sdkUnityVersion;
|
||||
let assetUrl = '';
|
||||
let variant = '';
|
||||
for (let i = ref.unityPackages.length - 1; i > -1; i--) {
|
||||
const unityPackage = ref.unityPackages[i];
|
||||
if (unityPackage.variant && unityPackage.variant !== 'security') {
|
||||
continue;
|
||||
}
|
||||
if (
|
||||
unityPackage.platform === 'standalonewindows' &&
|
||||
compareUnityVersion(unityPackage.unitySortNumber, sdkUnityVersion)
|
||||
) {
|
||||
assetUrl = unityPackage.assetUrl;
|
||||
if (!unityPackage.variant || unityPackage.variant === 'standard') {
|
||||
variant = 'security';
|
||||
} else {
|
||||
variant = unityPackage.variant;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!assetUrl) {
|
||||
assetUrl = ref.assetUrl;
|
||||
}
|
||||
const id = extractFileId(assetUrl);
|
||||
const version = parseInt(extractFileVersion(assetUrl), 10);
|
||||
const variantVersion = parseInt(extractVariantVersion(assetUrl), 10);
|
||||
if (!id || !version) {
|
||||
return { Item1: -1, Item2: false, Item3: '' };
|
||||
}
|
||||
|
||||
try {
|
||||
return AssetBundleManager.CheckVRChatCache(
|
||||
id,
|
||||
version,
|
||||
variant,
|
||||
variantVersion
|
||||
);
|
||||
} catch (err) {
|
||||
console.error('Failed reading VRChat cache size:', err);
|
||||
toast.error(`Failed reading VRChat cache size: ${err}`);
|
||||
return { Item1: -1, Item2: false, Item3: '' };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {object} ref
|
||||
* @returns {Promise<object>}
|
||||
*/
|
||||
async function getBundleDateSize(ref) {
|
||||
const authStore = useAuthStore();
|
||||
const sdkUnityVersion = authStore.cachedConfig.sdkUnityVersion;
|
||||
const avatarStore = useAvatarStore();
|
||||
const { avatarDialog } = storeToRefs(avatarStore);
|
||||
const worldStore = useWorldStore();
|
||||
const { worldDialog } = storeToRefs(worldStore);
|
||||
const instanceStore = useInstanceStore();
|
||||
const { currentInstanceWorld, currentInstanceLocation } =
|
||||
storeToRefs(instanceStore);
|
||||
const bundleJson = {};
|
||||
for (let i = ref.unityPackages.length - 1; i > -1; i--) {
|
||||
const unityPackage = ref.unityPackages[i];
|
||||
if (!unityPackage) {
|
||||
continue;
|
||||
}
|
||||
if (
|
||||
unityPackage.variant &&
|
||||
unityPackage.variant !== 'standard' &&
|
||||
unityPackage.variant !== 'security'
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
if (
|
||||
!compareUnityVersion(unityPackage.unitySortNumber, sdkUnityVersion)
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const platform = unityPackage.platform;
|
||||
if (bundleJson[platform]) {
|
||||
continue;
|
||||
}
|
||||
const assetUrl = unityPackage.assetUrl;
|
||||
const fileId = extractFileId(assetUrl);
|
||||
const version = parseInt(extractFileVersion(assetUrl), 10);
|
||||
let variant = '';
|
||||
if (!unityPackage.variant || unityPackage.variant === 'standard') {
|
||||
variant = 'security';
|
||||
} else {
|
||||
variant = unityPackage.variant;
|
||||
}
|
||||
if (!fileId || !version) {
|
||||
continue;
|
||||
}
|
||||
const args = await queryRequest.fetch('fileAnalysis', {
|
||||
fileId,
|
||||
version,
|
||||
variant
|
||||
});
|
||||
if (!args?.json?.success) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const json = args.json;
|
||||
if (typeof json.fileSize !== 'undefined') {
|
||||
json._fileSize = `${(json.fileSize / 1048576).toFixed(2)} MB`;
|
||||
}
|
||||
if (typeof json.uncompressedSize !== 'undefined') {
|
||||
json._uncompressedSize = `${(json.uncompressedSize / 1048576).toFixed(2)} MB`;
|
||||
}
|
||||
if (typeof json.avatarStats?.totalTextureUsage !== 'undefined') {
|
||||
json._totalTextureUsage = `${(json.avatarStats.totalTextureUsage / 1048576).toFixed(2)} MB`;
|
||||
}
|
||||
bundleJson[platform] = json;
|
||||
|
||||
if (avatarDialog.value.id === ref.id) {
|
||||
// update avatar dialog
|
||||
avatarDialog.value.fileAnalysis[platform] = json;
|
||||
}
|
||||
// update world dialog
|
||||
if (worldDialog.value.id === ref.id) {
|
||||
worldDialog.value.fileAnalysis[platform] = json;
|
||||
}
|
||||
// update player list
|
||||
if (currentInstanceLocation.value.worldId === ref.id) {
|
||||
currentInstanceWorld.value.fileAnalysis[platform] = json;
|
||||
}
|
||||
}
|
||||
|
||||
return bundleJson;
|
||||
}
|
||||
|
||||
export { deleteVRChatCache, checkVRChatCache, getBundleDateSize };
|
||||
106
src/coordinators/dateCoordinator.js
Normal file
106
src/coordinators/dateCoordinator.js
Normal file
@@ -0,0 +1,106 @@
|
||||
import { useAppearanceSettingsStore } from '../stores';
|
||||
|
||||
function padZero(num) {
|
||||
return String(num).padStart(2, '0');
|
||||
}
|
||||
|
||||
function toIsoLong(date) {
|
||||
const y = date.getFullYear();
|
||||
const m = padZero(date.getMonth() + 1);
|
||||
const d = padZero(date.getDate());
|
||||
const hh = padZero(date.getHours());
|
||||
const mm = padZero(date.getMinutes());
|
||||
const ss = padZero(date.getSeconds());
|
||||
return `${y}-${m}-${d} ${hh}:${mm}:${ss}`;
|
||||
}
|
||||
|
||||
function toLocalShort(date, dateFormat, hour12) {
|
||||
return date
|
||||
.toLocaleDateString(dateFormat, {
|
||||
month: '2-digit',
|
||||
day: '2-digit',
|
||||
hour: 'numeric',
|
||||
minute: 'numeric',
|
||||
hourCycle: hour12 ? 'h12' : 'h23'
|
||||
})
|
||||
.replace(' AM', 'am')
|
||||
.replace(' PM', 'pm')
|
||||
.replace(',', '');
|
||||
}
|
||||
|
||||
function toLocalLong(date, dateFormat, hour12) {
|
||||
return date.toLocaleDateString(dateFormat, {
|
||||
month: '2-digit',
|
||||
day: '2-digit',
|
||||
year: 'numeric',
|
||||
hour: 'numeric',
|
||||
minute: 'numeric',
|
||||
second: 'numeric',
|
||||
hourCycle: hour12 ? 'h12' : 'h23'
|
||||
});
|
||||
}
|
||||
|
||||
function toLocalTime(date, dateFormat, hour12) {
|
||||
return date.toLocaleTimeString(dateFormat, {
|
||||
hour: 'numeric',
|
||||
minute: 'numeric',
|
||||
hourCycle: hour12 ? 'h12' : 'h23'
|
||||
});
|
||||
}
|
||||
|
||||
function toLocalDate(date, dateFormat) {
|
||||
return date.toLocaleDateString(dateFormat, {
|
||||
month: '2-digit',
|
||||
day: '2-digit',
|
||||
year: 'numeric'
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} dateStr
|
||||
* @param {'long'|'short'|'time'|'date'} format
|
||||
* @returns {string}
|
||||
*/
|
||||
function formatDateFilter(dateStr, format) {
|
||||
const appearance = useAppearanceSettingsStore();
|
||||
const {
|
||||
dtIsoFormat: isoFormat,
|
||||
dtHour12: hour12,
|
||||
currentCulture
|
||||
} = appearance;
|
||||
|
||||
if (!dateStr) {
|
||||
return '-';
|
||||
}
|
||||
|
||||
const dt = new Date(dateStr);
|
||||
if (isNaN(dt.getTime())) {
|
||||
return '-';
|
||||
}
|
||||
|
||||
let dateFormat = 'en-gb';
|
||||
if (!isoFormat && currentCulture) {
|
||||
dateFormat = currentCulture;
|
||||
}
|
||||
if (dateFormat.length > 4 && dateFormat[4] === '_') {
|
||||
dateFormat = dateFormat.slice(0, 4);
|
||||
}
|
||||
|
||||
if (isoFormat && format === 'long') {
|
||||
return toIsoLong(dt);
|
||||
} else if (format === 'long') {
|
||||
return toLocalLong(dt, dateFormat, hour12);
|
||||
} else if (format === 'short') {
|
||||
return toLocalShort(dt, dateFormat, hour12);
|
||||
} else if (format === 'time') {
|
||||
return toLocalTime(dt, dateFormat, hour12);
|
||||
} else if (format === 'date') {
|
||||
return toLocalDate(dt, dateFormat);
|
||||
} else {
|
||||
console.warn(`Unknown date format: ${format}`);
|
||||
}
|
||||
|
||||
return '-';
|
||||
}
|
||||
|
||||
export { formatDateFilter };
|
||||
@@ -1,7 +1,7 @@
|
||||
import { toast } from 'vue-sonner';
|
||||
|
||||
import { AppDebug } from '../services/appConfig';
|
||||
import { migrateMemos } from '../shared/utils';
|
||||
import { migrateMemos } from './memoCoordinator';
|
||||
import { reconnectWebSocket } from '../services/websocket';
|
||||
import { useAuthStore } from '../stores/auth';
|
||||
import { useFriendStore } from '../stores/friend';
|
||||
|
||||
198
src/coordinators/imageUploadCoordinator.js
Normal file
198
src/coordinators/imageUploadCoordinator.js
Normal file
@@ -0,0 +1,198 @@
|
||||
import { toast } from 'vue-sonner';
|
||||
|
||||
import { $throw } from '../services/request';
|
||||
import { AppDebug } from '../services/appConfig.js';
|
||||
import { extractFileId } from '../shared/utils';
|
||||
import { imageRequest } from '../api';
|
||||
|
||||
function resolveMessage(message) {
|
||||
if (typeof message === 'function') {
|
||||
return message();
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
function getInputElement(selector) {
|
||||
if (!selector) {
|
||||
return null;
|
||||
}
|
||||
if (typeof selector === 'function') {
|
||||
return selector();
|
||||
}
|
||||
if (typeof selector === 'string') {
|
||||
return document.querySelector(selector);
|
||||
}
|
||||
return selector;
|
||||
}
|
||||
|
||||
export function handleImageUploadInput(event, options = {}) {
|
||||
const {
|
||||
inputSelector,
|
||||
// 20MB
|
||||
maxSize = 20000000,
|
||||
acceptPattern = /image.*/,
|
||||
tooLargeMessage,
|
||||
invalidTypeMessage,
|
||||
onClear
|
||||
} = options;
|
||||
|
||||
const clearInput = () => {
|
||||
onClear?.();
|
||||
const input = getInputElement(inputSelector);
|
||||
if (input) {
|
||||
input.value = '';
|
||||
}
|
||||
};
|
||||
|
||||
const files = event?.target?.files || event?.dataTransfer?.files;
|
||||
if (!files || files.length === 0) {
|
||||
clearInput();
|
||||
return { file: null, clearInput };
|
||||
}
|
||||
|
||||
const file = files[0];
|
||||
if (file.size >= maxSize) {
|
||||
if (tooLargeMessage) {
|
||||
toast.error(resolveMessage(tooLargeMessage));
|
||||
}
|
||||
clearInput();
|
||||
return { file: null, clearInput };
|
||||
}
|
||||
|
||||
let acceptRegex = null;
|
||||
if (acceptPattern) {
|
||||
acceptRegex =
|
||||
acceptPattern instanceof RegExp
|
||||
? acceptPattern
|
||||
: new RegExp(acceptPattern);
|
||||
}
|
||||
|
||||
if (acceptRegex && !acceptRegex.test(file.type)) {
|
||||
if (invalidTypeMessage) {
|
||||
toast.error(resolveMessage(invalidTypeMessage));
|
||||
}
|
||||
clearInput();
|
||||
return { file: null, clearInput };
|
||||
}
|
||||
|
||||
return { file, clearInput };
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} base64Data - base64 encoded image
|
||||
* @returns {Promise<string>} resized base64 encoded image
|
||||
*/
|
||||
export async function resizeImageToFitLimits(base64Data) {
|
||||
// frontend limit check = 20MB
|
||||
return AppApi.ResizeImageToFitLimits(base64Data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload image through AWS
|
||||
* @param {'avatar'|'world'} type
|
||||
* @param {object} opts
|
||||
* @param {string} opts.entityId - avatar or world id
|
||||
* @param {string} opts.imageUrl - current imageUrl on the entity
|
||||
* @param {string} opts.base64File - base64 encoded image data
|
||||
* @param {Blob} opts.blob - the original blob (used for file size)
|
||||
*/
|
||||
export async function uploadImageLegacy(
|
||||
type,
|
||||
{ entityId, imageUrl, base64File, blob }
|
||||
) {
|
||||
const apiMap = {
|
||||
avatar: {
|
||||
uploadImage: imageRequest.uploadAvatarImage,
|
||||
fileStart: imageRequest.uploadAvatarImageFileStart,
|
||||
fileFinish: imageRequest.uploadAvatarImageFileFinish,
|
||||
sigStart: imageRequest.uploadAvatarImageSigStart,
|
||||
sigFinish: imageRequest.uploadAvatarImageSigFinish,
|
||||
setImage: imageRequest.setAvatarImage
|
||||
},
|
||||
world: {
|
||||
uploadImage: imageRequest.uploadWorldImage,
|
||||
fileStart: imageRequest.uploadWorldImageFileStart,
|
||||
fileFinish: imageRequest.uploadWorldImageFileFinish,
|
||||
sigStart: imageRequest.uploadWorldImageSigStart,
|
||||
sigFinish: imageRequest.uploadWorldImageSigFinish,
|
||||
setImage: imageRequest.setWorldImage
|
||||
}
|
||||
};
|
||||
const api = apiMap[type];
|
||||
|
||||
const fileMd5 = await AppApi.MD5File(base64File);
|
||||
const fileSizeInBytes = parseInt(blob.size, 10);
|
||||
const base64SignatureFile = await AppApi.SignFile(base64File);
|
||||
const signatureMd5 = await AppApi.MD5File(base64SignatureFile);
|
||||
const signatureSizeInBytes = parseInt(
|
||||
await AppApi.FileLength(base64SignatureFile),
|
||||
10
|
||||
);
|
||||
const fileId = extractFileId(imageUrl);
|
||||
|
||||
// imageInit
|
||||
const uploadRes = await api.uploadImage(
|
||||
{ fileMd5, fileSizeInBytes, signatureMd5, signatureSizeInBytes },
|
||||
fileId
|
||||
);
|
||||
const uploadedFileId = uploadRes.json.id;
|
||||
const fileVersion =
|
||||
uploadRes.json.versions[uploadRes.json.versions.length - 1].version;
|
||||
|
||||
// imageFileStart
|
||||
const fileStartRes = await api.fileStart({
|
||||
fileId: uploadedFileId,
|
||||
fileVersion
|
||||
});
|
||||
|
||||
// uploadImageFileAWS
|
||||
const fileAwsRes = await webApiService.execute({
|
||||
url: fileStartRes.json.url,
|
||||
uploadFilePUT: true,
|
||||
fileData: base64File,
|
||||
fileMIME: 'image/png',
|
||||
fileMD5: fileMd5
|
||||
});
|
||||
if (fileAwsRes.status !== 200) {
|
||||
$throw(
|
||||
fileAwsRes.status,
|
||||
`${type} image upload failed`,
|
||||
fileStartRes.json.url
|
||||
);
|
||||
}
|
||||
|
||||
// imageFileFinish
|
||||
await api.fileFinish({ fileId: uploadedFileId, fileVersion });
|
||||
|
||||
// imageSigStart
|
||||
const sigStartRes = await api.sigStart({
|
||||
fileId: uploadedFileId,
|
||||
fileVersion
|
||||
});
|
||||
|
||||
// uploadImageSigAWS
|
||||
const sigAwsRes = await webApiService.execute({
|
||||
url: sigStartRes.json.url,
|
||||
uploadFilePUT: true,
|
||||
fileData: base64SignatureFile,
|
||||
fileMIME: 'application/x-rsync-signature',
|
||||
fileMD5: signatureMd5
|
||||
});
|
||||
if (sigAwsRes.status !== 200) {
|
||||
$throw(
|
||||
sigAwsRes.status,
|
||||
`${type} image upload failed`,
|
||||
sigStartRes.json.url
|
||||
);
|
||||
}
|
||||
|
||||
// imageSigFinish
|
||||
await api.sigFinish({ fileId: uploadedFileId, fileVersion });
|
||||
|
||||
// imageSet
|
||||
const newImageUrl = `${AppDebug.endpointDomain}/file/${uploadedFileId}/${fileVersion}/file`;
|
||||
const setRes = await api.setImage({ id: entityId, imageUrl: newImageUrl });
|
||||
if (setRes.json.imageUrl !== newImageUrl) {
|
||||
$throw(0, `${type} image change failed`, newImageUrl);
|
||||
}
|
||||
}
|
||||
18
src/coordinators/instanceCoordinator.js
Normal file
18
src/coordinators/instanceCoordinator.js
Normal file
@@ -0,0 +1,18 @@
|
||||
import { instanceRequest } from '../api';
|
||||
import { parseLocation } from '../shared/utils/locationParser';
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {object} instance
|
||||
*/
|
||||
function refreshInstancePlayerCount(instance) {
|
||||
const L = parseLocation(instance);
|
||||
if (L.isRealInstance) {
|
||||
instanceRequest.getInstance({
|
||||
worldId: L.worldId,
|
||||
instanceId: L.instanceId
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export { refreshInstancePlayerCount };
|
||||
126
src/coordinators/memoCoordinator.js
Normal file
126
src/coordinators/memoCoordinator.js
Normal file
@@ -0,0 +1,126 @@
|
||||
import { useFriendStore, useUserStore } from '../stores';
|
||||
import { database } from '../services/database';
|
||||
|
||||
/**
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async function migrateMemos() {
|
||||
const json = JSON.parse(await VRCXStorage.GetAll());
|
||||
for (const line in json) {
|
||||
if (line.substring(0, 8) === 'memo_usr') {
|
||||
const userId = line.substring(5);
|
||||
const memo = json[line];
|
||||
if (memo) {
|
||||
await saveUserMemo(userId, memo);
|
||||
VRCXStorage.Remove(`memo_${userId}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} userId
|
||||
* @returns
|
||||
*/
|
||||
async function getUserMemo(userId) {
|
||||
try {
|
||||
return await database.getUserMemo(userId);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return {
|
||||
userId: '',
|
||||
editedAt: '',
|
||||
memo: ''
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} id
|
||||
* @param {string} memo
|
||||
*/
|
||||
async function saveUserMemo(id, memo) {
|
||||
const friendStore = useFriendStore();
|
||||
const userStore = useUserStore();
|
||||
if (memo) {
|
||||
await database.setUserMemo({
|
||||
userId: id,
|
||||
editedAt: new Date().toJSON(),
|
||||
memo
|
||||
});
|
||||
} else {
|
||||
await database.deleteUserMemo(id);
|
||||
}
|
||||
const ref = friendStore.friends.get(id);
|
||||
if (ref) {
|
||||
ref.memo = String(memo || '');
|
||||
if (memo) {
|
||||
const array = memo.split('\n');
|
||||
ref.$nickName = array[0];
|
||||
} else {
|
||||
ref.$nickName = '';
|
||||
}
|
||||
userStore.setUserDialogMemo(memo);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async function getAllUserMemos() {
|
||||
const friendStore = useFriendStore();
|
||||
const memos = await database.getAllUserMemos();
|
||||
memos.forEach((memo) => {
|
||||
const ref = friendStore.friends.get(memo.userId);
|
||||
if (typeof ref !== 'undefined') {
|
||||
ref.memo = memo.memo;
|
||||
ref.$nickName = '';
|
||||
if (memo.memo) {
|
||||
const array = memo.memo.split('\n');
|
||||
ref.$nickName = array[0];
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} worldId
|
||||
* @returns
|
||||
*/
|
||||
async function getWorldMemo(worldId) {
|
||||
try {
|
||||
return await database.getWorldMemo(worldId);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return {
|
||||
worldId: '',
|
||||
editedAt: '',
|
||||
memo: ''
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// async function getAvatarMemo(avatarId) {
|
||||
// try {
|
||||
// return await database.getAvatarMemoDB(avatarId);
|
||||
// } catch (err) {
|
||||
// console.error(err);
|
||||
// return {
|
||||
// avatarId: '',
|
||||
// editedAt: '',
|
||||
// memo: ''
|
||||
// };
|
||||
// }
|
||||
// }
|
||||
|
||||
export {
|
||||
migrateMemos,
|
||||
getUserMemo,
|
||||
saveUserMemo,
|
||||
getAllUserMemos,
|
||||
getWorldMemo
|
||||
// getAvatarMemo
|
||||
};
|
||||
@@ -10,12 +10,12 @@ import {
|
||||
evictMapCache,
|
||||
extractFileId,
|
||||
findUserByDisplayName,
|
||||
getUserMemo,
|
||||
getWorldName,
|
||||
isRealInstance,
|
||||
parseLocation,
|
||||
sanitizeUserJson
|
||||
} from '../shared/utils';
|
||||
import { getUserMemo } from './memoCoordinator';
|
||||
import {
|
||||
avatarRequest,
|
||||
instanceRequest,
|
||||
@@ -73,7 +73,14 @@ export function applyUser(json) {
|
||||
const moderationStore = useModerationStore();
|
||||
const photonStore = usePhotonStore();
|
||||
|
||||
const { currentUser, cachedUsers, currentTravelers, customUserTags, state, userDialog } = userStore;
|
||||
const {
|
||||
currentUser,
|
||||
cachedUsers,
|
||||
currentTravelers,
|
||||
customUserTags,
|
||||
state,
|
||||
userDialog
|
||||
} = userStore;
|
||||
|
||||
let ref = cachedUsers.get(json.id);
|
||||
let hasPropChanged = false;
|
||||
@@ -114,10 +121,8 @@ export function applyUser(json) {
|
||||
if (json.state !== 'online') {
|
||||
runUpdateFriendFlow(ref.id, json.state);
|
||||
}
|
||||
const {
|
||||
hasPropChanged: _hasPropChanged,
|
||||
changedProps: _changedProps
|
||||
} = diffObjectProps(ref, json, arraysMatch);
|
||||
const { hasPropChanged: _hasPropChanged, changedProps: _changedProps } =
|
||||
diffObjectProps(ref, json, arraysMatch);
|
||||
for (const prop in json) {
|
||||
if (typeof json[prop] !== 'undefined') {
|
||||
ref[prop] = json[prop];
|
||||
@@ -235,10 +240,7 @@ export function applyUser(json) {
|
||||
}
|
||||
}
|
||||
if (hasPropChanged) {
|
||||
if (
|
||||
changedProps.location &&
|
||||
changedProps.location[0] !== 'traveling'
|
||||
) {
|
||||
if (changedProps.location && changedProps.location[0] !== 'traveling') {
|
||||
const ts = Date.now();
|
||||
changedProps.location.push(ts - ref.$location_at);
|
||||
ref.$location_at = ts;
|
||||
@@ -286,11 +288,7 @@ export function showUserDialog(userId) {
|
||||
const D = userDialog;
|
||||
D.visible = true;
|
||||
if (isMainDialogOpen && D.id === userId) {
|
||||
uiStore.setDialogCrumbLabel(
|
||||
'user',
|
||||
D.id,
|
||||
D.ref?.displayName || D.id
|
||||
);
|
||||
uiStore.setDialogCrumbLabel('user', D.id, D.ref?.displayName || D.id);
|
||||
userStore.applyUserDialogLocation(true);
|
||||
return;
|
||||
}
|
||||
@@ -429,8 +427,7 @@ export function showUserDialog(userId) {
|
||||
D.joinCount = ref1.joinCount;
|
||||
D.timeSpent = ref1.timeSpent;
|
||||
}
|
||||
const displayNameMap =
|
||||
ref1.previousDisplayNames;
|
||||
const displayNameMap = ref1.previousDisplayNames;
|
||||
const userNotifications =
|
||||
await database.getFriendLogHistoryForUserId(
|
||||
D.id,
|
||||
@@ -457,12 +454,10 @@ export function showUserDialog(userId) {
|
||||
}
|
||||
D.dateFriendedInfo = dateFriendedInfo;
|
||||
if (dateFriendedInfo.length > 0) {
|
||||
const latestFriendedInfo =
|
||||
dateFriendedInfo[0];
|
||||
const latestFriendedInfo = dateFriendedInfo[0];
|
||||
D.unFriended =
|
||||
latestFriendedInfo.type === 'Unfriend';
|
||||
D.dateFriended =
|
||||
latestFriendedInfo.created_at;
|
||||
D.dateFriended = latestFriendedInfo.created_at;
|
||||
}
|
||||
displayNameMap.forEach(
|
||||
(updated_at, displayName) => {
|
||||
@@ -473,27 +468,24 @@ export function showUserDialog(userId) {
|
||||
}
|
||||
);
|
||||
});
|
||||
AppApi.GetVRChatUserModeration(
|
||||
currentUser.id,
|
||||
userId
|
||||
).then((result) => {
|
||||
D.avatarModeration = result;
|
||||
if (result === 4) {
|
||||
D.isHideAvatar = true;
|
||||
} else if (result === 5) {
|
||||
D.isShowAvatar = true;
|
||||
AppApi.GetVRChatUserModeration(currentUser.id, userId).then(
|
||||
(result) => {
|
||||
D.avatarModeration = result;
|
||||
if (result === 4) {
|
||||
D.isHideAvatar = true;
|
||||
} else if (result === 5) {
|
||||
D.isShowAvatar = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
);
|
||||
if (!currentUser.hasSharedConnectionsOptOut) {
|
||||
try {
|
||||
queryRequest
|
||||
.fetch('mutualCounts', { userId })
|
||||
.then((args) => {
|
||||
if (args.params.userId === D.id) {
|
||||
D.mutualFriendCount =
|
||||
args.json.friends;
|
||||
D.mutualGroupCount =
|
||||
args.json.groups;
|
||||
D.mutualFriendCount = args.json.friends;
|
||||
D.mutualGroupCount = args.json.groups;
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
@@ -501,8 +493,7 @@ export function showUserDialog(userId) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
D.previousDisplayNames =
|
||||
currentUser.pastDisplayNames;
|
||||
D.previousDisplayNames = currentUser.pastDisplayNames;
|
||||
database
|
||||
.getUserStats(D.ref, inCurrentWorld)
|
||||
.then((ref1) => {
|
||||
@@ -673,11 +664,8 @@ export function handleConfig(args) {
|
||||
if (typeof args.ref?.whiteListedAssetUrls !== 'object') {
|
||||
console.error('Invalid config whiteListedAssetUrls');
|
||||
}
|
||||
AppApi.PopulateImageHosts(
|
||||
JSON.stringify(args.ref.whiteListedAssetUrls)
|
||||
);
|
||||
const languages =
|
||||
args.ref?.constants?.LANGUAGE?.SPOKEN_LANGUAGE_OPTIONS;
|
||||
AppApi.PopulateImageHosts(JSON.stringify(args.ref.whiteListedAssetUrls));
|
||||
const languages = args.ref?.constants?.LANGUAGE?.SPOKEN_LANGUAGE_OPTIONS;
|
||||
if (!languages) {
|
||||
return;
|
||||
}
|
||||
@@ -1047,10 +1035,7 @@ export function updateAutoStateChange() {
|
||||
}
|
||||
|
||||
const params = { status: newStatus };
|
||||
if (
|
||||
withCompany &&
|
||||
generalSettingsStore.autoStateChangeCompanyDescEnabled
|
||||
) {
|
||||
if (withCompany && generalSettingsStore.autoStateChangeCompanyDescEnabled) {
|
||||
params.statusDescription =
|
||||
generalSettingsStore.autoStateChangeCompanyDesc;
|
||||
} else if (
|
||||
|
||||
@@ -8,11 +8,11 @@ import {
|
||||
evictMapCache,
|
||||
getAvailablePlatforms,
|
||||
getBundleDateSize,
|
||||
getWorldMemo,
|
||||
isRealInstance,
|
||||
parseLocation,
|
||||
sanitizeEntityJson
|
||||
} from '../shared/utils';
|
||||
import { getWorldMemo } from './memoCoordinator';
|
||||
import { instanceRequest, queryRequest, worldRequest } from '../api';
|
||||
import { database } from '../services/database';
|
||||
import { patchWorldFromEvent } from '../queries';
|
||||
@@ -118,21 +118,13 @@ export function showWorldDialog(tag, shortName = null, options = {}) {
|
||||
.then((args) => {
|
||||
if (D.id === args.ref.id) {
|
||||
D.ref = args.ref;
|
||||
uiStore.setDialogCrumbLabel(
|
||||
'world',
|
||||
D.id,
|
||||
D.ref?.name || D.id
|
||||
);
|
||||
uiStore.setDialogCrumbLabel('world', D.id, D.ref?.name || D.id);
|
||||
D.visible = true;
|
||||
D.loading = false;
|
||||
D.isFavorite = favoriteStore.getCachedFavoritesByObjectId(
|
||||
D.id
|
||||
);
|
||||
D.isFavorite = favoriteStore.getCachedFavoritesByObjectId(D.id);
|
||||
if (!D.isFavorite) {
|
||||
D.isFavorite =
|
||||
favoriteStore.localWorldFavoritesList.includes(
|
||||
D.id
|
||||
);
|
||||
favoriteStore.localWorldFavoritesList.includes(D.id);
|
||||
}
|
||||
let { isPC, isQuest, isIos } = getAvailablePlatforms(
|
||||
args.ref.unityPackages
|
||||
|
||||
Reference in New Issue
Block a user