mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-05-05 06:16:05 +02:00
refactor store
This commit is contained in:
+6
-33
@@ -5,17 +5,19 @@ import { useI18n } from 'vue-i18n';
|
||||
|
||||
import {
|
||||
checkVRChatCache,
|
||||
createDefaultAvatarRef,
|
||||
extractFileId,
|
||||
getAvailablePlatforms,
|
||||
getBundleDateSize,
|
||||
getPlatformInfo,
|
||||
replaceBioSymbols,
|
||||
sanitizeEntityJson,
|
||||
storeAvatarImage
|
||||
} from '../shared/utils';
|
||||
import { avatarRequest, miscRequest } from '../api';
|
||||
import { patchAvatarFromEvent } from '../query';
|
||||
import { AppDebug } from '../service/appConfig';
|
||||
import { database } from '../service/database';
|
||||
import { patchAvatarFromEvent } from '../query';
|
||||
import { processBulk } from '../service/request';
|
||||
import { useAdvancedSettingsStore } from './settings/advanced';
|
||||
import { useAvatarProviderStore } from './avatarProvider';
|
||||
@@ -92,40 +94,10 @@ export const useAvatarStore = defineStore('Avatar', () => {
|
||||
* @returns {object} ref
|
||||
*/
|
||||
function applyAvatar(json) {
|
||||
json.name = replaceBioSymbols(json.name);
|
||||
json.description = replaceBioSymbols(json.description);
|
||||
sanitizeEntityJson(json, ['name', 'description']);
|
||||
let ref = cachedAvatars.get(json.id);
|
||||
if (typeof ref === 'undefined') {
|
||||
ref = {
|
||||
acknowledgements: '',
|
||||
authorId: '',
|
||||
authorName: '',
|
||||
created_at: '',
|
||||
description: '',
|
||||
featured: false,
|
||||
highestPrice: null,
|
||||
id: '',
|
||||
imageUrl: '',
|
||||
listingDate: null,
|
||||
lock: false,
|
||||
lowestPrice: null,
|
||||
name: '',
|
||||
pendingUpload: false,
|
||||
performance: {},
|
||||
productId: null,
|
||||
publishedListings: [],
|
||||
releaseStatus: '',
|
||||
searchable: false,
|
||||
styles: [],
|
||||
tags: [],
|
||||
thumbnailImageUrl: '',
|
||||
unityPackageUrl: '',
|
||||
unityPackageUrlObject: {},
|
||||
unityPackages: [],
|
||||
updated_at: '',
|
||||
version: 0,
|
||||
...json
|
||||
};
|
||||
ref = createDefaultAvatarRef(json);
|
||||
cachedAvatars.set(ref.id, ref);
|
||||
} else {
|
||||
const { unityPackages } = ref;
|
||||
@@ -178,6 +150,7 @@ export const useAvatarStore = defineStore('Avatar', () => {
|
||||
/**
|
||||
*
|
||||
* @param {string} avatarId
|
||||
* @param options
|
||||
* @returns
|
||||
*/
|
||||
function showAvatarDialog(avatarId, options = {}) {
|
||||
|
||||
+92
-22
@@ -5,6 +5,8 @@ import { useI18n } from 'vue-i18n';
|
||||
|
||||
import {
|
||||
compareByName,
|
||||
createDefaultFavoriteCachedRef,
|
||||
createDefaultFavoriteGroupRef,
|
||||
removeFromArray,
|
||||
replaceReactiveObject
|
||||
} from '../shared/utils';
|
||||
@@ -209,6 +211,11 @@ export const useFavoriteStore = defineStore('Favorite', () => {
|
||||
return favoriteGroup.length;
|
||||
});
|
||||
|
||||
/**
|
||||
*
|
||||
* @param list
|
||||
* @param selectionRef
|
||||
*/
|
||||
function syncFavoriteSelection(list, selectionRef) {
|
||||
if (!Array.isArray(list)) {
|
||||
selectionRef.value = [];
|
||||
@@ -255,6 +262,9 @@ export const useFavoriteStore = defineStore('Favorite', () => {
|
||||
{ flush: 'sync' }
|
||||
);
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function getCachedFavoriteGroupsByTypeName() {
|
||||
const group = {};
|
||||
|
||||
@@ -274,10 +284,18 @@ export const useFavoriteStore = defineStore('Favorite', () => {
|
||||
return group;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param objectId
|
||||
*/
|
||||
function getCachedFavoritesByObjectId(objectId) {
|
||||
return cachedFavoritesByObjectId.get(objectId);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param args
|
||||
*/
|
||||
function handleFavoriteAdd(args) {
|
||||
handleFavorite({
|
||||
json: args.json,
|
||||
@@ -310,6 +328,10 @@ export const useFavoriteStore = defineStore('Favorite', () => {
|
||||
updateFavoriteDialog(args.params.objectId);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param args
|
||||
*/
|
||||
function handleFavorite(args) {
|
||||
args.ref = applyFavoriteCached(args.json);
|
||||
applyFavorite(args.ref.type, args.ref.favoriteId);
|
||||
@@ -329,6 +351,10 @@ export const useFavoriteStore = defineStore('Favorite', () => {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param objectId
|
||||
*/
|
||||
function handleFavoriteDelete(objectId) {
|
||||
const ref = getCachedFavoritesByObjectId(objectId);
|
||||
if (typeof ref === 'undefined') {
|
||||
@@ -337,10 +363,18 @@ export const useFavoriteStore = defineStore('Favorite', () => {
|
||||
handleFavoriteAtDelete(ref);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param args
|
||||
*/
|
||||
function handleFavoriteGroup(args) {
|
||||
args.ref = applyFavoriteGroup(args.json);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param args
|
||||
*/
|
||||
function handleFavoriteGroupClear(args) {
|
||||
const key = `${args.params.type}:${args.params.group}`;
|
||||
for (const ref of cachedFavorites.values()) {
|
||||
@@ -351,6 +385,10 @@ export const useFavoriteStore = defineStore('Favorite', () => {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param args
|
||||
*/
|
||||
function handleFavoriteWorldList(args) {
|
||||
for (const json of args.json) {
|
||||
if (json.id === '???') {
|
||||
@@ -360,6 +398,10 @@ export const useFavoriteStore = defineStore('Favorite', () => {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param args
|
||||
*/
|
||||
function handleFavoriteAvatarList(args) {
|
||||
for (const json of args.json) {
|
||||
if (json.releaseStatus === 'hidden') {
|
||||
@@ -369,6 +411,10 @@ export const useFavoriteStore = defineStore('Favorite', () => {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param ref
|
||||
*/
|
||||
function handleFavoriteAtDelete(ref) {
|
||||
const favorite = state.favoriteObjects.get(ref.favoriteId);
|
||||
removeFromArray(state.favoriteFriends_, favorite);
|
||||
@@ -536,6 +582,9 @@ export const useFavoriteStore = defineStore('Favorite', () => {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function refreshFavoriteGroups() {
|
||||
if (isFavoriteGroupLoading.value) {
|
||||
return;
|
||||
@@ -567,6 +616,9 @@ export const useFavoriteStore = defineStore('Favorite', () => {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function buildFavoriteGroups() {
|
||||
let group;
|
||||
let groups;
|
||||
@@ -683,6 +735,9 @@ export const useFavoriteStore = defineStore('Favorite', () => {
|
||||
countFavoriteGroups();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function countFavoriteGroups() {
|
||||
const cachedFavoriteGroups = getCachedFavoriteGroupsByTypeName();
|
||||
for (const key in cachedFavoriteGroups) {
|
||||
@@ -764,17 +819,7 @@ export const useFavoriteStore = defineStore('Favorite', () => {
|
||||
function applyFavoriteGroup(json) {
|
||||
let ref = cachedFavoriteGroups.value[json.id];
|
||||
if (typeof ref === 'undefined') {
|
||||
ref = {
|
||||
id: '',
|
||||
ownerId: '',
|
||||
ownerDisplayName: '',
|
||||
name: '',
|
||||
displayName: '',
|
||||
type: '',
|
||||
visibility: '',
|
||||
tags: [],
|
||||
...json
|
||||
};
|
||||
ref = createDefaultFavoriteGroupRef(json);
|
||||
cachedFavoriteGroups.value[ref.id] = ref;
|
||||
} else {
|
||||
Object.assign(ref, json);
|
||||
@@ -790,19 +835,9 @@ export const useFavoriteStore = defineStore('Favorite', () => {
|
||||
function applyFavoriteCached(json) {
|
||||
let ref = cachedFavorites.get(json.id);
|
||||
if (typeof ref === 'undefined') {
|
||||
ref = {
|
||||
id: '',
|
||||
type: '',
|
||||
favoriteId: '',
|
||||
tags: [],
|
||||
// VRCX
|
||||
$groupKey: '',
|
||||
//
|
||||
...json
|
||||
};
|
||||
ref = createDefaultFavoriteCachedRef(json);
|
||||
cachedFavorites.set(ref.id, ref);
|
||||
cachedFavoritesByObjectId.set(ref.favoriteId, ref);
|
||||
ref.$groupKey = `${ref.type}:${String(ref.tags[0])}`;
|
||||
if (
|
||||
ref.type === 'friend' &&
|
||||
(!generalSettingsStore.localFavoriteFriendsGroups.some(
|
||||
@@ -893,14 +928,23 @@ export const useFavoriteStore = defineStore('Favorite', () => {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function showWorldImportDialog() {
|
||||
worldImportDialogVisible.value = true;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function showAvatarImportDialog() {
|
||||
avatarImportDialogVisible.value = true;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function showFriendImportDialog() {
|
||||
friendImportDialogVisible.value = true;
|
||||
}
|
||||
@@ -1016,6 +1060,10 @@ export const useFavoriteStore = defineStore('Favorite', () => {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param objectId
|
||||
*/
|
||||
function updateFavoriteDialog(objectId) {
|
||||
const D = favoriteDialog.value;
|
||||
if (!D.visible || D.objectId !== objectId) {
|
||||
@@ -1108,6 +1156,9 @@ export const useFavoriteStore = defineStore('Favorite', () => {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function sortLocalAvatarFavorites() {
|
||||
if (!appearanceSettingsStore.sortFavorites) {
|
||||
for (let i = 0; i < localAvatarFavoriteGroups.value.length; ++i) {
|
||||
@@ -1294,6 +1345,9 @@ export const useFavoriteStore = defineStore('Favorite', () => {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function sortLocalWorldFavorites() {
|
||||
if (!appearanceSettingsStore.sortFavorites) {
|
||||
for (let i = 0; i < localWorldFavoriteGroups.value.length; ++i) {
|
||||
@@ -1718,6 +1772,11 @@ export const useFavoriteStore = defineStore('Favorite', () => {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param type
|
||||
* @param objectId
|
||||
*/
|
||||
function showFavoriteDialog(type, objectId) {
|
||||
const D = favoriteDialog.value;
|
||||
D.type = type;
|
||||
@@ -1726,12 +1785,18 @@ export const useFavoriteStore = defineStore('Favorite', () => {
|
||||
updateFavoriteDialog(objectId);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
async function saveSortFavoritesOption() {
|
||||
getLocalWorldFavorites();
|
||||
getLocalFriendFavorites();
|
||||
appearanceSettingsStore.setSortFavorites();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
async function initFavorites() {
|
||||
refreshFavorites();
|
||||
getLocalWorldFavorites();
|
||||
@@ -1739,6 +1804,11 @@ export const useFavoriteStore = defineStore('Favorite', () => {
|
||||
getLocalFriendFavorites();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param a
|
||||
* @param b
|
||||
*/
|
||||
function compareByFavoriteSortOrder(a, b) {
|
||||
const indexA = favoritesSortOrder.value.indexOf(a.id);
|
||||
const indexB = favoritesSortOrder.value.indexOf(b.id);
|
||||
|
||||
+106
-71
@@ -8,11 +8,17 @@ import dayjs from 'dayjs';
|
||||
|
||||
import {
|
||||
compareGameLogRows,
|
||||
createJoinLeaveEntry,
|
||||
createLocationEntry,
|
||||
createPortalSpawnEntry,
|
||||
createResourceLoadEntry,
|
||||
findUserByDisplayName,
|
||||
formatSeconds,
|
||||
gameLogSearchFilter,
|
||||
getGroupName,
|
||||
parseInventoryFromUrl,
|
||||
parseLocation,
|
||||
parsePrintFromUrl,
|
||||
replaceBioSymbols
|
||||
} from '../../shared/utils';
|
||||
import { AppDebug } from '../../service/appConfig';
|
||||
@@ -131,6 +137,9 @@ export const useGameLogStore = defineStore('GameLog', () => {
|
||||
{ flush: 'sync' }
|
||||
);
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
async function init() {
|
||||
gameLogTable.value.filter = JSON.parse(
|
||||
await configRepository.getString('VRCX_gameLogTableFilters', '[]')
|
||||
@@ -143,6 +152,10 @@ export const useGameLogStore = defineStore('GameLog', () => {
|
||||
|
||||
init();
|
||||
|
||||
/**
|
||||
*
|
||||
* @param entry
|
||||
*/
|
||||
function insertGameLogSorted(entry) {
|
||||
const arr = gameLogTableData.value;
|
||||
if (arr.length === 0) {
|
||||
@@ -170,6 +183,9 @@ export const useGameLogStore = defineStore('GameLog', () => {
|
||||
gameLogTableData.value = [...arr, entry];
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function clearNowPlaying() {
|
||||
nowPlaying.value = {
|
||||
url: '',
|
||||
@@ -186,6 +202,10 @@ export const useGameLogStore = defineStore('GameLog', () => {
|
||||
vrStore.updateVrNowPlaying();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param data
|
||||
*/
|
||||
function setNowPlaying(data) {
|
||||
const ctx = structuredClone(data);
|
||||
if (nowPlaying.value.url !== ctx.videoUrl) {
|
||||
@@ -257,6 +277,9 @@ export const useGameLogStore = defineStore('GameLog', () => {
|
||||
advancedSettingsStore
|
||||
});
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function updateNowPlaying() {
|
||||
const np = nowPlaying.value;
|
||||
if (!nowPlaying.value.playing) {
|
||||
@@ -275,6 +298,9 @@ export const useGameLogStore = defineStore('GameLog', () => {
|
||||
workerTimers.setTimeout(() => updateNowPlaying(), 1000);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
async function tryLoadPlayerList() {
|
||||
// TODO: make this work again
|
||||
if (!gameStore.isGameRunning) {
|
||||
@@ -355,6 +381,10 @@ export const useGameLogStore = defineStore('GameLog', () => {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param row
|
||||
*/
|
||||
function gameLogIsFriend(row) {
|
||||
if (typeof row.isFriend !== 'undefined') {
|
||||
return row.isFriend;
|
||||
@@ -365,6 +395,10 @@ export const useGameLogStore = defineStore('GameLog', () => {
|
||||
return friendStore.friends.has(row.userId);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param row
|
||||
*/
|
||||
function gameLogIsFavorite(row) {
|
||||
if (typeof row.isFavorite !== 'undefined') {
|
||||
return row.isFavorite;
|
||||
@@ -375,6 +409,9 @@ export const useGameLogStore = defineStore('GameLog', () => {
|
||||
return friendStore.localFavoriteFriends.has(row.userId);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
async function gameLogTableLookup() {
|
||||
await configRepository.setString(
|
||||
'VRCX_gameLogTableFilters',
|
||||
@@ -416,6 +453,10 @@ export const useGameLogStore = defineStore('GameLog', () => {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param entry
|
||||
*/
|
||||
function addGameLog(entry) {
|
||||
entry.isFriend = gameLogIsFriend(entry);
|
||||
entry.isFavorite = gameLogIsFavorite(entry);
|
||||
@@ -456,6 +497,10 @@ export const useGameLogStore = defineStore('GameLog', () => {
|
||||
uiStore.notifyMenu('game-log');
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param input
|
||||
*/
|
||||
async function addGamelogLocationToDatabase(input) {
|
||||
const groupName = await getGroupName(input.location);
|
||||
const entry = {
|
||||
@@ -465,10 +510,17 @@ export const useGameLogStore = defineStore('GameLog', () => {
|
||||
database.addGamelogLocationToDatabase(entry);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param row
|
||||
*/
|
||||
function gameLogSearch(row) {
|
||||
return gameLogSearchFilter(row, gameLogTable.value.search);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function sweepGameLog() {
|
||||
const j = gameLogTableData.value.length;
|
||||
if (j > vrcxStore.maxTableSize + 50) {
|
||||
@@ -476,6 +528,11 @@ export const useGameLogStore = defineStore('GameLog', () => {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param gameLog
|
||||
* @param location
|
||||
*/
|
||||
function addGameLogEntry(gameLog, location) {
|
||||
let entry = undefined;
|
||||
if (advancedSettingsStore.gameLogDisabled) {
|
||||
@@ -543,15 +600,12 @@ export const useGameLogStore = defineStore('GameLog', () => {
|
||||
gameLog.dt
|
||||
);
|
||||
const L = parseLocation(gameLog.location);
|
||||
entry = {
|
||||
created_at: gameLog.dt,
|
||||
type: 'Location',
|
||||
location: gameLog.location,
|
||||
worldId: L.worldId,
|
||||
worldName,
|
||||
groupName: '',
|
||||
time: 0
|
||||
};
|
||||
entry = createLocationEntry(
|
||||
gameLog.dt,
|
||||
gameLog.location,
|
||||
L.worldId,
|
||||
worldName
|
||||
);
|
||||
getGroupName(gameLog.location).then((groupName) => {
|
||||
entry.groupName = groupName;
|
||||
});
|
||||
@@ -595,14 +649,13 @@ export const useGameLogStore = defineStore('GameLog', () => {
|
||||
}
|
||||
vrStore.updateVRLastLocation();
|
||||
instanceStore.getCurrentInstanceUserList();
|
||||
entry = {
|
||||
created_at: gameLog.dt,
|
||||
type: 'OnPlayerJoined',
|
||||
displayName: gameLog.displayName,
|
||||
entry = createJoinLeaveEntry(
|
||||
'OnPlayerJoined',
|
||||
gameLog.dt,
|
||||
gameLog.displayName,
|
||||
location,
|
||||
userId,
|
||||
time: 0
|
||||
};
|
||||
userId
|
||||
);
|
||||
database.addGamelogJoinLeaveToDatabase(entry);
|
||||
break;
|
||||
case 'player-left':
|
||||
@@ -617,29 +670,21 @@ export const useGameLogStore = defineStore('GameLog', () => {
|
||||
photonStore.photonLobbyAvatars.delete(userId);
|
||||
vrStore.updateVRLastLocation();
|
||||
instanceStore.getCurrentInstanceUserList();
|
||||
entry = {
|
||||
created_at: gameLog.dt,
|
||||
type: 'OnPlayerLeft',
|
||||
displayName: gameLog.displayName,
|
||||
entry = createJoinLeaveEntry(
|
||||
'OnPlayerLeft',
|
||||
gameLog.dt,
|
||||
gameLog.displayName,
|
||||
location,
|
||||
userId,
|
||||
time
|
||||
};
|
||||
);
|
||||
database.addGamelogJoinLeaveToDatabase(entry);
|
||||
break;
|
||||
case 'portal-spawn':
|
||||
if (vrcxStore.ipcEnabled && gameStore.isGameRunning) {
|
||||
break;
|
||||
}
|
||||
entry = {
|
||||
created_at: gameLog.dt,
|
||||
type: 'PortalSpawn',
|
||||
location,
|
||||
displayName: '',
|
||||
userId: '',
|
||||
instanceId: '',
|
||||
worldName: ''
|
||||
};
|
||||
entry = createPortalSpawnEntry(gameLog.dt, location);
|
||||
database.addGamelogPortalSpawnToDatabase(entry);
|
||||
break;
|
||||
case 'video-play':
|
||||
@@ -665,15 +710,12 @@ export const useGameLogStore = defineStore('GameLog', () => {
|
||||
break;
|
||||
}
|
||||
lastResourceloadUrl.value = gameLog.resourceUrl;
|
||||
entry = {
|
||||
created_at: gameLog.dt,
|
||||
type:
|
||||
gameLog.type === 'resource-load-string'
|
||||
? 'StringLoad'
|
||||
: 'ImageLoad',
|
||||
resourceUrl: gameLog.resourceUrl,
|
||||
entry = createResourceLoadEntry(
|
||||
gameLog.type,
|
||||
gameLog.dt,
|
||||
gameLog.resourceUrl,
|
||||
location
|
||||
};
|
||||
);
|
||||
database.addGamelogResourceLoadToDatabase(entry);
|
||||
break;
|
||||
case 'screenshot':
|
||||
@@ -711,42 +753,18 @@ export const useGameLogStore = defineStore('GameLog', () => {
|
||||
// }
|
||||
|
||||
if (advancedSettingsStore.saveInstanceEmoji) {
|
||||
try {
|
||||
// https://api.vrchat.cloud/api/1/user/usr_032383a7-748c-4fb2-94e4-bcb928e5de6b/inventory/inv_75781d65-92fe-4a80-a1ff-27ee6e843b08
|
||||
const url = new URL(gameLog.url);
|
||||
if (
|
||||
url.pathname.substring(0, 12) === '/api/1/user/' &&
|
||||
url.pathname.includes('/inventory/inv_')
|
||||
) {
|
||||
const pathArray = url.pathname.split('/');
|
||||
const userId = pathArray[4];
|
||||
const inventoryId = pathArray[6];
|
||||
if (userId && inventoryId.length === 40) {
|
||||
galleryStore.queueCheckInstanceInventory(
|
||||
inventoryId,
|
||||
userId
|
||||
);
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
const inv = parseInventoryFromUrl(gameLog.url);
|
||||
if (inv) {
|
||||
galleryStore.queueCheckInstanceInventory(
|
||||
inv.inventoryId,
|
||||
inv.userId
|
||||
);
|
||||
}
|
||||
}
|
||||
if (advancedSettingsStore.saveInstancePrints) {
|
||||
try {
|
||||
let printId = '';
|
||||
const url1 = new URL(gameLog.url);
|
||||
if (
|
||||
url1.pathname.substring(0, 14) === '/api/1/prints/'
|
||||
) {
|
||||
const pathArray = url1.pathname.split('/');
|
||||
printId = pathArray[4];
|
||||
}
|
||||
if (printId && printId.length === 41) {
|
||||
galleryStore.queueSavePrintToFile(printId);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
const printId = parsePrintFromUrl(gameLog.url);
|
||||
if (printId) {
|
||||
galleryStore.queueSavePrintToFile(printId);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -902,12 +920,19 @@ export const useGameLogStore = defineStore('GameLog', () => {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
async function getGameLogTable() {
|
||||
await database.initTables();
|
||||
const dateTill = await database.getLastDateGameLogDatabase();
|
||||
updateGameLog(dateTill);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param dateTill
|
||||
*/
|
||||
async function updateGameLog(dateTill) {
|
||||
await gameLogService.setDateTill(dateTill);
|
||||
await new Promise((resolve) => {
|
||||
@@ -923,6 +948,10 @@ export const useGameLogStore = defineStore('GameLog', () => {
|
||||
}
|
||||
|
||||
// use in C#
|
||||
/**
|
||||
*
|
||||
* @param json
|
||||
*/
|
||||
function addGameLogEvent(json) {
|
||||
const rawLogs = JSON.parse(json);
|
||||
const gameLog = gameLogService.parseRawGameLog(
|
||||
@@ -941,6 +970,9 @@ export const useGameLogStore = defineStore('GameLog', () => {
|
||||
addGameLogEntry(gameLog, locationStore.lastLocation.location);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
async function disableGameLogDialog() {
|
||||
if (gameStore.isGameRunning) {
|
||||
toast.error(t('message.gamelog.vrchat_must_be_closed'));
|
||||
@@ -962,6 +994,9 @@ export const useGameLogStore = defineStore('GameLog', () => {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
async function initGameLogTable() {
|
||||
gameLogTable.value.loading = true;
|
||||
const rows = await database.lookupGameLogDatabase(
|
||||
|
||||
+137
-96
@@ -3,20 +3,22 @@ import { defineStore } from 'pinia';
|
||||
import { toast } from 'vue-sonner';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import {
|
||||
convertFileUrlToImageUrl,
|
||||
createDefaultGroupRef,
|
||||
hasGroupPermission,
|
||||
replaceBioSymbols,
|
||||
sanitizeEntityJson
|
||||
} from '../shared/utils';
|
||||
import {
|
||||
groupRequest,
|
||||
instanceRequest,
|
||||
userRequest,
|
||||
worldRequest
|
||||
} from '../api';
|
||||
import { patchGroupFromEvent } from '../query';
|
||||
import {
|
||||
convertFileUrlToImageUrl,
|
||||
hasGroupPermission,
|
||||
replaceBioSymbols
|
||||
} from '../shared/utils';
|
||||
import { database } from '../service/database';
|
||||
import { groupDialogFilterOptions } from '../shared/constants/';
|
||||
import { patchGroupFromEvent } from '../query';
|
||||
import { useGameStore } from './game';
|
||||
import { useInstanceStore } from './instance';
|
||||
import { useModalStore } from './modal';
|
||||
@@ -128,6 +130,11 @@ export const useGroupStore = defineStore('Group', () => {
|
||||
{ flush: 'sync' }
|
||||
);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param groupId
|
||||
* @param options
|
||||
*/
|
||||
function showGroupDialog(groupId, options = {}) {
|
||||
if (!groupId) {
|
||||
return;
|
||||
@@ -232,6 +239,11 @@ export const useGroupStore = defineStore('Group', () => {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param ref
|
||||
* @param message
|
||||
*/
|
||||
function groupChange(ref, message) {
|
||||
if (!currentUserGroupsInit.value) {
|
||||
return;
|
||||
@@ -260,6 +272,9 @@ export const useGroupStore = defineStore('Group', () => {
|
||||
workerTimers.setTimeout(saveCurrentUserGroups, 100);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function saveCurrentUserGroups() {
|
||||
if (!currentUserGroupsInit.value) {
|
||||
return;
|
||||
@@ -284,10 +299,10 @@ export const useGroupStore = defineStore('Group', () => {
|
||||
/**
|
||||
*
|
||||
* @param {object} ref
|
||||
* @param {array} oldRoles
|
||||
* @param {array} newRoles
|
||||
* @param {array} oldRoleIds
|
||||
* @param {array} newRoleIds
|
||||
* @param {Array} oldRoles
|
||||
* @param {Array} newRoles
|
||||
* @param {Array} oldRoleIds
|
||||
* @param {Array} newRoleIds
|
||||
*/
|
||||
function groupRoleChange(ref, oldRoles, newRoles, oldRoleIds, newRoleIds) {
|
||||
// check for removed/added roleIds
|
||||
@@ -401,7 +416,7 @@ export const useGroupStore = defineStore('Group', () => {
|
||||
/**
|
||||
*
|
||||
* @param {{ groupId: string }} params
|
||||
* @return { Promise<{posts: any, params}> }
|
||||
* @returns { Promise<{posts: any, params}> }
|
||||
*/
|
||||
async function getAllGroupPosts(params) {
|
||||
const n = 100;
|
||||
@@ -442,6 +457,10 @@ export const useGroupStore = defineStore('Group', () => {
|
||||
return returnArgs;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param groupId
|
||||
*/
|
||||
function getGroupDialogGroup(groupId) {
|
||||
const D = groupDialog.value;
|
||||
D.isGetGroupDialogGroupLoading = false;
|
||||
@@ -497,32 +516,38 @@ export const useGroupStore = defineStore('Group', () => {
|
||||
});
|
||||
}
|
||||
});
|
||||
groupRequest.getCachedGroupCalendar(groupId).then((args) => {
|
||||
if (groupDialog.value.id === args.params.groupId) {
|
||||
D.calendar = args.json.results;
|
||||
for (const event of D.calendar) {
|
||||
applyGroupEvent(event);
|
||||
// fetch again for isFollowing
|
||||
groupRequest
|
||||
.getCachedGroupCalendarEvent({
|
||||
groupId,
|
||||
eventId: event.id
|
||||
})
|
||||
.then((args) => {
|
||||
Object.assign(
|
||||
event,
|
||||
applyGroupEvent(args.json)
|
||||
);
|
||||
});
|
||||
groupRequest
|
||||
.getCachedGroupCalendar(groupId)
|
||||
.then((args) => {
|
||||
if (groupDialog.value.id === args.params.groupId) {
|
||||
D.calendar = args.json.results;
|
||||
for (const event of D.calendar) {
|
||||
applyGroupEvent(event);
|
||||
// fetch again for isFollowing
|
||||
groupRequest
|
||||
.getCachedGroupCalendarEvent({
|
||||
groupId,
|
||||
eventId: event.id
|
||||
})
|
||||
.then((args) => {
|
||||
Object.assign(
|
||||
event,
|
||||
applyGroupEvent(args.json)
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
nextTick(() => (D.isGetGroupDialogGroupLoading = false));
|
||||
return args;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param event
|
||||
*/
|
||||
function applyGroupEvent(event) {
|
||||
return {
|
||||
userInterest: {
|
||||
@@ -536,6 +561,9 @@ export const useGroupStore = defineStore('Group', () => {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
async function updateInGameGroupOrder() {
|
||||
inGameGroupOrder.value = [];
|
||||
try {
|
||||
@@ -551,6 +579,11 @@ export const useGroupStore = defineStore('Group', () => {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param a
|
||||
* @param b
|
||||
*/
|
||||
function sortGroupInstancesByInGame(a, b) {
|
||||
const aIndex = inGameGroupOrder.value.indexOf(a?.group?.id);
|
||||
const bIndex = inGameGroupOrder.value.indexOf(b?.group?.id);
|
||||
@@ -566,6 +599,10 @@ export const useGroupStore = defineStore('Group', () => {
|
||||
return aIndex - bIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param groupId
|
||||
*/
|
||||
function leaveGroup(groupId) {
|
||||
groupRequest
|
||||
.leaveGroup({
|
||||
@@ -590,6 +627,10 @@ export const useGroupStore = defineStore('Group', () => {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param groupId
|
||||
*/
|
||||
function leaveGroupPrompt(groupId) {
|
||||
modalStore
|
||||
.confirm({
|
||||
@@ -603,6 +644,9 @@ export const useGroupStore = defineStore('Group', () => {
|
||||
.catch(() => {});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function updateGroupPostSearch() {
|
||||
const D = groupDialog.value;
|
||||
const search = D.postsSearch.toLowerCase();
|
||||
@@ -620,6 +664,11 @@ export const useGroupStore = defineStore('Group', () => {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param groupId
|
||||
* @param visibility
|
||||
*/
|
||||
function setGroupVisibility(groupId, visibility) {
|
||||
return groupRequest
|
||||
.setGroupMemberProps(userStore.currentUser.id, groupId, {
|
||||
@@ -632,6 +681,11 @@ export const useGroupStore = defineStore('Group', () => {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param groupId
|
||||
* @param subscribe
|
||||
*/
|
||||
function setGroupSubscription(groupId, subscribe) {
|
||||
return groupRequest
|
||||
.setGroupMemberProps(userStore.currentUser.id, groupId, {
|
||||
@@ -651,73 +705,9 @@ export const useGroupStore = defineStore('Group', () => {
|
||||
*/
|
||||
function applyGroup(json) {
|
||||
let ref = cachedGroups.get(json.id);
|
||||
if (json.rules) {
|
||||
json.rules = replaceBioSymbols(json.rules);
|
||||
}
|
||||
if (json.name) {
|
||||
json.name = replaceBioSymbols(json.name);
|
||||
}
|
||||
if (json.description) {
|
||||
json.description = replaceBioSymbols(json.description);
|
||||
}
|
||||
sanitizeEntityJson(json, ['rules', 'name', 'description']);
|
||||
if (typeof ref === 'undefined') {
|
||||
ref = {
|
||||
id: '',
|
||||
name: '',
|
||||
shortCode: '',
|
||||
description: '',
|
||||
bannerId: '',
|
||||
bannerUrl: '',
|
||||
createdAt: '',
|
||||
discriminator: '',
|
||||
galleries: [],
|
||||
iconId: '',
|
||||
iconUrl: '',
|
||||
isVerified: false,
|
||||
joinState: '',
|
||||
languages: [],
|
||||
links: [],
|
||||
memberCount: 0,
|
||||
memberCountSyncedAt: '',
|
||||
membershipStatus: '',
|
||||
onlineMemberCount: 0,
|
||||
ownerId: '',
|
||||
privacy: '',
|
||||
rules: null,
|
||||
tags: [],
|
||||
// in group
|
||||
initialRoleIds: [],
|
||||
myMember: {
|
||||
bannedAt: null,
|
||||
groupId: '',
|
||||
has2FA: false,
|
||||
id: '',
|
||||
isRepresenting: false,
|
||||
isSubscribedToAnnouncements: false,
|
||||
joinedAt: '',
|
||||
managerNotes: '',
|
||||
membershipStatus: '',
|
||||
permissions: [],
|
||||
roleIds: [],
|
||||
userId: '',
|
||||
visibility: '',
|
||||
_created_at: '',
|
||||
_id: '',
|
||||
_updated_at: ''
|
||||
},
|
||||
updatedAt: '',
|
||||
// includeRoles: true
|
||||
roles: [],
|
||||
// group list
|
||||
$memberId: '',
|
||||
groupId: '',
|
||||
isRepresenting: false,
|
||||
memberVisibility: false,
|
||||
mutualGroup: false,
|
||||
// VRCX
|
||||
$languages: [],
|
||||
...json
|
||||
};
|
||||
ref = createDefaultGroupRef(json);
|
||||
cachedGroups.set(ref.id, ref);
|
||||
} else {
|
||||
if (currentUserGroups.has(ref.id)) {
|
||||
@@ -796,6 +786,10 @@ export const useGroupStore = defineStore('Group', () => {
|
||||
return ref;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param args
|
||||
*/
|
||||
function handleGroupRepresented(args) {
|
||||
const D = userStore.userDialog;
|
||||
const json = args.json;
|
||||
@@ -819,6 +813,10 @@ export const useGroupStore = defineStore('Group', () => {
|
||||
applyGroup(json);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param args
|
||||
*/
|
||||
function handleGroupList(args) {
|
||||
for (const json of args.json) {
|
||||
json.$memberId = json.id;
|
||||
@@ -827,6 +825,10 @@ export const useGroupStore = defineStore('Group', () => {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param args
|
||||
*/
|
||||
function handleGroupMemberProps(args) {
|
||||
if (args.userId === userStore.currentUser.id) {
|
||||
const json = args.json;
|
||||
@@ -873,6 +875,10 @@ export const useGroupStore = defineStore('Group', () => {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param args
|
||||
*/
|
||||
function handleGroupPermissions(args) {
|
||||
if (args.params.userId !== userStore.currentUser.id) {
|
||||
return;
|
||||
@@ -919,10 +925,18 @@ export const useGroupStore = defineStore('Group', () => {
|
||||
updateGroupPostSearch();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param args
|
||||
*/
|
||||
function handleGroupMember(args) {
|
||||
args.ref = applyGroupMember(args.json);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param args
|
||||
*/
|
||||
async function handleGroupUserInstances(args) {
|
||||
groupInstances.value = [];
|
||||
for (const json of args.json.instances) {
|
||||
@@ -990,6 +1004,10 @@ export const useGroupStore = defineStore('Group', () => {
|
||||
return json;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param ref
|
||||
*/
|
||||
function applyGroupLanguage(ref) {
|
||||
ref.$languages = [];
|
||||
const { languages } = ref;
|
||||
@@ -1008,6 +1026,11 @@ export const useGroupStore = defineStore('Group', () => {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param userId
|
||||
* @param groups
|
||||
*/
|
||||
async function loadCurrentUserGroups(userId, groups) {
|
||||
const savedGroups = JSON.parse(
|
||||
await configRepository.getString(
|
||||
@@ -1063,6 +1086,9 @@ export const useGroupStore = defineStore('Group', () => {
|
||||
getCurrentUserGroups();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
async function getCurrentUserGroups() {
|
||||
const args = await groupRequest.getGroups({
|
||||
userId: userStore.currentUser.id
|
||||
@@ -1082,6 +1108,9 @@ export const useGroupStore = defineStore('Group', () => {
|
||||
saveCurrentUserGroups();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function getCurrentUserRepresentedGroup() {
|
||||
return groupRequest
|
||||
.getRepresentedGroup({
|
||||
@@ -1093,6 +1122,9 @@ export const useGroupStore = defineStore('Group', () => {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
async function initUserGroups() {
|
||||
updateInGameGroupOrder();
|
||||
loadCurrentUserGroups(
|
||||
@@ -1101,6 +1133,10 @@ export const useGroupStore = defineStore('Group', () => {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param userId
|
||||
*/
|
||||
function showModerateGroupDialog(userId) {
|
||||
const D = moderateGroupDialog.value;
|
||||
D.userId = userId;
|
||||
@@ -1108,6 +1144,11 @@ export const useGroupStore = defineStore('Group', () => {
|
||||
D.visible = true;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param groupId
|
||||
* @param userId
|
||||
*/
|
||||
function showGroupMemberModerationDialog(groupId, userId = '') {
|
||||
const D = groupMemberModeration.value;
|
||||
D.id = groupId;
|
||||
|
||||
+93
-82
@@ -8,8 +8,11 @@ import {
|
||||
compareByDisplayName,
|
||||
compareById,
|
||||
compareByLocationAt,
|
||||
computeDisabledContentSettings,
|
||||
createDefaultInstanceRef,
|
||||
debounce,
|
||||
displayLocation,
|
||||
evictMapCache,
|
||||
getAvailablePlatforms,
|
||||
getBundleDateSize,
|
||||
getGroupName,
|
||||
@@ -25,12 +28,12 @@ import {
|
||||
userRequest,
|
||||
worldRequest
|
||||
} from '../api';
|
||||
import { patchInstanceFromEvent } from '../query';
|
||||
import {
|
||||
accessTypeLocaleKeyMap,
|
||||
instanceContentSettings
|
||||
} from '../shared/constants';
|
||||
import { database } from '../service/database';
|
||||
import { patchInstanceFromEvent } from '../query';
|
||||
import { resolveRef } from '../shared/utils/resolveRef';
|
||||
import { useAppearanceSettingsStore } from './settings/appearance';
|
||||
import { useFriendStore } from './friend';
|
||||
@@ -66,30 +69,26 @@ export const useInstanceStore = defineStore('Instance', () => {
|
||||
|
||||
let cachedInstances = new Map();
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function cleanInstanceCache() {
|
||||
const maxSize = 200;
|
||||
if (cachedInstances.size <= maxSize) {
|
||||
return;
|
||||
}
|
||||
const removable = [];
|
||||
cachedInstances.forEach((ref, id) => {
|
||||
if (
|
||||
[...friendStore.friends.values()].some(
|
||||
(f) => f.$location?.tag === id
|
||||
)
|
||||
) {
|
||||
return;
|
||||
const friendLocationTags = new Set(
|
||||
[...friendStore.friends.values()]
|
||||
.map((f) => f.$location?.tag)
|
||||
.filter(Boolean)
|
||||
);
|
||||
evictMapCache(
|
||||
cachedInstances,
|
||||
200,
|
||||
(_value, key) => friendLocationTags.has(key),
|
||||
{
|
||||
sortFn: (a, b) =>
|
||||
(Date.parse(a.value.$fetchedAt) || 0) -
|
||||
(Date.parse(b.value.$fetchedAt) || 0),
|
||||
logLabel: 'Instance cache cleanup'
|
||||
}
|
||||
removable.push({
|
||||
id,
|
||||
fetchedAt: Date.parse(ref.$fetchedAt) || 0
|
||||
});
|
||||
});
|
||||
removable.sort((a, b) => a.fetchedAt - b.fetchedAt);
|
||||
const overBy = cachedInstances.size - maxSize;
|
||||
for (let i = 0; i < overBy && i < removable.length; i++) {
|
||||
cachedInstances.delete(removable[i].id);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
const lastInstanceApplied = ref('');
|
||||
@@ -183,6 +182,9 @@ export const useInstanceStore = defineStore('Instance', () => {
|
||||
{ flush: 'sync' }
|
||||
);
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
async function getInstanceJoinHistory() {
|
||||
try {
|
||||
const data = await database.getInstanceJoinHistory();
|
||||
@@ -195,6 +197,11 @@ export const useInstanceStore = defineStore('Instance', () => {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param location
|
||||
* @param dateTime
|
||||
*/
|
||||
function addInstanceJoinHistory(location, dateTime) {
|
||||
if (!location || !dateTime) {
|
||||
return;
|
||||
@@ -208,11 +215,18 @@ export const useInstanceStore = defineStore('Instance', () => {
|
||||
instanceJoinHistory.set(location, epoch);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function hidePreviousInstancesDialogs() {
|
||||
previousInstancesInfoDialog.value.visible = false;
|
||||
previousInstancesListDialog.value.visible = false;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param input
|
||||
*/
|
||||
function resolveUserRef(input) {
|
||||
return resolveRef(input, {
|
||||
emptyDefault: { id: '', displayName: '' },
|
||||
@@ -222,6 +236,10 @@ export const useInstanceStore = defineStore('Instance', () => {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param input
|
||||
*/
|
||||
function resolveWorldRef(input) {
|
||||
return resolveRef(input, {
|
||||
emptyDefault: { id: '', name: '' },
|
||||
@@ -231,6 +249,10 @@ export const useInstanceStore = defineStore('Instance', () => {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param input
|
||||
*/
|
||||
function resolveGroupRef(input) {
|
||||
return resolveRef(input, {
|
||||
emptyDefault: { id: '', name: '' },
|
||||
@@ -240,6 +262,10 @@ export const useInstanceStore = defineStore('Instance', () => {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param accessTypeNameRaw
|
||||
*/
|
||||
function translateAccessType(accessTypeNameRaw) {
|
||||
const key = accessTypeLocaleKeyMap[accessTypeNameRaw];
|
||||
if (!key) {
|
||||
@@ -255,6 +281,11 @@ export const useInstanceStore = defineStore('Instance', () => {
|
||||
return t(key);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param instanceId
|
||||
* @param worldNameOverride
|
||||
*/
|
||||
function formatPreviousInstancesInfoLabel(
|
||||
instanceId,
|
||||
worldNameOverride = ''
|
||||
@@ -275,6 +306,10 @@ export const useInstanceStore = defineStore('Instance', () => {
|
||||
return `${baseLabel} · ${accessTypeLabel}`;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param instanceId
|
||||
*/
|
||||
function showPreviousInstancesInfoDialog(instanceId) {
|
||||
previousInstancesInfoDialog.value.visible = true;
|
||||
previousInstancesInfoDialog.value.instanceId = instanceId;
|
||||
@@ -308,6 +343,11 @@ export const useInstanceStore = defineStore('Instance', () => {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param variant
|
||||
* @param targetRef
|
||||
*/
|
||||
async function showPreviousInstancesListDialog(variant, targetRef) {
|
||||
previousInstancesListDialog.value.variant = variant;
|
||||
let resolved = null;
|
||||
@@ -335,6 +375,9 @@ export const useInstanceStore = defineStore('Instance', () => {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function updateCurrentInstanceWorld() {
|
||||
let L;
|
||||
let instanceId = locationStore.lastLocation.location;
|
||||
@@ -472,53 +515,7 @@ export const useInstanceStore = defineStore('Instance', () => {
|
||||
}
|
||||
let ref = cachedInstances.get(json.id);
|
||||
if (typeof ref === 'undefined') {
|
||||
ref = {
|
||||
id: '',
|
||||
location: '',
|
||||
instanceId: '',
|
||||
name: '',
|
||||
worldId: '',
|
||||
type: '',
|
||||
ownerId: '',
|
||||
tags: [],
|
||||
active: false,
|
||||
full: false,
|
||||
n_users: 0,
|
||||
hasCapacityForYou: true, // not present depending on endpoint
|
||||
capacity: 0,
|
||||
recommendedCapacity: 0,
|
||||
userCount: 0,
|
||||
queueEnabled: false, // only present with group instance type
|
||||
queueSize: 0, // only present when queuing is enabled
|
||||
platforms: {},
|
||||
gameServerVersion: 0,
|
||||
hardClose: null, // boolean or null
|
||||
closedAt: null, // string or null
|
||||
secureName: '',
|
||||
shortName: '',
|
||||
world: {},
|
||||
users: [], // only present when you're the owner
|
||||
clientNumber: '',
|
||||
contentSettings: {},
|
||||
photonRegion: '',
|
||||
region: '',
|
||||
canRequestInvite: false,
|
||||
permanent: false,
|
||||
private: '', // part of instance tag
|
||||
hidden: '', // part of instance tag
|
||||
nonce: '', // only present when you're the owner
|
||||
strict: false, // deprecated
|
||||
displayName: null,
|
||||
groupAccessType: null, // only present with group instance type
|
||||
roleRestricted: false, // only present with group instance type
|
||||
instancePersistenceEnabled: null,
|
||||
playerPersistenceEnabled: null,
|
||||
ageGate: null,
|
||||
// VRCX
|
||||
$fetchedAt: '',
|
||||
$disabledContentSettings: [],
|
||||
...json
|
||||
};
|
||||
ref = createDefaultInstanceRef(json);
|
||||
cachedInstances.set(ref.id, ref);
|
||||
cleanInstanceCache();
|
||||
} else {
|
||||
@@ -535,18 +532,10 @@ export const useInstanceStore = defineStore('Instance', () => {
|
||||
return args;
|
||||
});
|
||||
}
|
||||
ref.$disabledContentSettings = [];
|
||||
if (json.contentSettings && Object.keys(json.contentSettings).length) {
|
||||
for (const setting of instanceContentSettings) {
|
||||
if (
|
||||
typeof json.contentSettings[setting] === 'undefined' ||
|
||||
json.contentSettings[setting] === true
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
ref.$disabledContentSettings.push(setting);
|
||||
}
|
||||
}
|
||||
ref.$disabledContentSettings = computeDisabledContentSettings(
|
||||
json.contentSettings,
|
||||
instanceContentSettings
|
||||
);
|
||||
if (ref.displayName) {
|
||||
ref.displayName = replaceBioSymbols(ref.displayName);
|
||||
}
|
||||
@@ -578,6 +567,10 @@ export const useInstanceStore = defineStore('Instance', () => {
|
||||
return ref;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param location
|
||||
*/
|
||||
async function getInstanceName(location) {
|
||||
let instanceName = '';
|
||||
|
||||
@@ -701,10 +694,16 @@ export const useInstanceStore = defineStore('Instance', () => {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function applyWorldDialogInstances() {
|
||||
debounce(applyWorldDialogInstancesDebounced, 100)();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function applyWorldDialogInstancesDebounced() {
|
||||
let ref;
|
||||
let instance;
|
||||
@@ -1079,6 +1078,9 @@ export const useInstanceStore = defineStore('Instance', () => {
|
||||
D.instances = rooms;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function removeAllQueuedInstances() {
|
||||
queuedInstances.forEach((ref) => {
|
||||
toast.info(`Removed instance ${ref.$worldName} from queue`);
|
||||
@@ -1233,6 +1235,9 @@ export const useInstanceStore = defineStore('Instance', () => {
|
||||
// workerTimers.setTimeout(this.instanceQueueTimeout, 3600000);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function getCurrentInstanceUserList() {
|
||||
if (!watchState.isFriendsLoaded) {
|
||||
return;
|
||||
@@ -1250,6 +1255,9 @@ export const useInstanceStore = defineStore('Instance', () => {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function updatePlayerListExecute() {
|
||||
try {
|
||||
updatePlayerListDebounce();
|
||||
@@ -1260,6 +1268,9 @@ export const useInstanceStore = defineStore('Instance', () => {
|
||||
state.updatePlayerListPending = false;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function updatePlayerListDebounce() {
|
||||
const users = [];
|
||||
const pushUser = function (ref) {
|
||||
|
||||
@@ -7,14 +7,18 @@ import Noty from 'noty';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
import {
|
||||
applyBoopLegacyHandling,
|
||||
checkCanInvite,
|
||||
createDefaultNotificationRef,
|
||||
createDefaultNotificationV2Ref,
|
||||
escapeTag,
|
||||
executeWithBackoff,
|
||||
findUserByDisplayName,
|
||||
getUserMemo,
|
||||
parseLocation,
|
||||
parseNotificationDetails,
|
||||
removeFromArray,
|
||||
replaceBioSymbols
|
||||
sanitizeNotificationJson
|
||||
} from '../../shared/utils';
|
||||
import {
|
||||
friendRequest,
|
||||
@@ -163,6 +167,9 @@ export const useNotificationStore = defineStore('Notification', () => {
|
||||
{ flush: 'sync' }
|
||||
);
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
async function init() {
|
||||
notificationTable.value.filters[0].value = JSON.parse(
|
||||
await configRepository.getString(
|
||||
@@ -174,6 +181,10 @@ export const useNotificationStore = defineStore('Notification', () => {
|
||||
|
||||
init();
|
||||
|
||||
/**
|
||||
*
|
||||
* @param args
|
||||
*/
|
||||
function handleNotification(args) {
|
||||
args.ref = applyNotification(args.json);
|
||||
const { ref } = args;
|
||||
@@ -234,6 +245,10 @@ export const useNotificationStore = defineStore('Notification', () => {
|
||||
D.incomingRequest = true;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param notificationId
|
||||
*/
|
||||
function handleNotificationHide(notificationId) {
|
||||
const ref = notificationTable.value.data.find(
|
||||
(n) => n.id === notificationId
|
||||
@@ -259,6 +274,10 @@ export const useNotificationStore = defineStore('Notification', () => {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param args
|
||||
*/
|
||||
function handlePipelineNotification(args) {
|
||||
const ref = args.json;
|
||||
if (
|
||||
@@ -373,6 +392,10 @@ export const useNotificationStore = defineStore('Notification', () => {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param notificationId
|
||||
*/
|
||||
function handleNotificationSee(notificationId) {
|
||||
removeFromArray(unseenNotifications.value, notificationId);
|
||||
if (unseenNotifications.value.length === 0) {
|
||||
@@ -392,6 +415,9 @@ export const useNotificationStore = defineStore('Notification', () => {
|
||||
let seeProcessing = false;
|
||||
const SEE_CONCURRENCY = 2;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
async function processSeeQueue() {
|
||||
if (seeProcessing) return;
|
||||
seeProcessing = true;
|
||||
@@ -443,7 +469,7 @@ export const useNotificationStore = defineStore('Notification', () => {
|
||||
/**
|
||||
* Queue a notification to be marked as seen.
|
||||
* @param {string} notificationId
|
||||
* @param {number} [version=1]
|
||||
* @param {number} [version]
|
||||
*/
|
||||
function queueMarkAsSeen(notificationId, version = 1) {
|
||||
if (seenIds.has(notificationId)) return;
|
||||
@@ -452,6 +478,10 @@ export const useNotificationStore = defineStore('Notification', () => {
|
||||
processSeeQueue();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param args
|
||||
*/
|
||||
function handleNotificationAccept(args) {
|
||||
let ref;
|
||||
const array = notificationTable.value.data;
|
||||
@@ -490,6 +520,10 @@ export const useNotificationStore = defineStore('Notification', () => {
|
||||
D.isFriend = true;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param args
|
||||
*/
|
||||
function handleNotificationExpire(args) {
|
||||
const { ref } = args;
|
||||
const D = userStore.userDialog;
|
||||
@@ -509,10 +543,7 @@ export const useNotificationStore = defineStore('Notification', () => {
|
||||
* @returns {object}
|
||||
*/
|
||||
function applyNotification(data) {
|
||||
const json = { ...data };
|
||||
if (json.message) {
|
||||
json.message = replaceBioSymbols(json.message);
|
||||
}
|
||||
const json = sanitizeNotificationJson({ ...data });
|
||||
let ref;
|
||||
const array = notificationTable.value.data;
|
||||
for (let i = array.length - 1; i >= 0; i--) {
|
||||
@@ -521,102 +552,37 @@ export const useNotificationStore = defineStore('Notification', () => {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// delete any null in json
|
||||
for (const key in json) {
|
||||
if (json[key] === null) {
|
||||
delete json[key];
|
||||
}
|
||||
}
|
||||
if (typeof ref === 'undefined') {
|
||||
ref = {
|
||||
id: '',
|
||||
senderUserId: '',
|
||||
senderUsername: '',
|
||||
type: '',
|
||||
message: '',
|
||||
details: {},
|
||||
seen: false,
|
||||
created_at: '',
|
||||
// VRCX
|
||||
$isExpired: false,
|
||||
//
|
||||
...json
|
||||
};
|
||||
ref = createDefaultNotificationRef(json);
|
||||
} else {
|
||||
Object.assign(ref, json);
|
||||
ref.$isExpired = false;
|
||||
}
|
||||
if (ref.details !== Object(ref.details)) {
|
||||
let details = {};
|
||||
if (ref.details !== '{}') {
|
||||
try {
|
||||
const object = JSON.parse(ref.details);
|
||||
if (object === Object(object)) {
|
||||
details = object;
|
||||
}
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
}
|
||||
ref.details = details;
|
||||
}
|
||||
ref.details = parseNotificationDetails(ref.details);
|
||||
return ref;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param data
|
||||
*/
|
||||
function applyNotificationV2(data) {
|
||||
const json = { ...data };
|
||||
// delete any null in json
|
||||
for (const key in json) {
|
||||
if (json[key] === null || typeof json[key] === 'undefined') {
|
||||
delete json[key];
|
||||
}
|
||||
}
|
||||
if (json.message) {
|
||||
json.message = replaceBioSymbols(json.message);
|
||||
}
|
||||
if (json.title) {
|
||||
json.title = replaceBioSymbols(json.title);
|
||||
}
|
||||
const json = sanitizeNotificationJson({ ...data });
|
||||
let ref = notificationTable.value.data.find((n) => n.id === json.id);
|
||||
if (typeof ref === 'undefined') {
|
||||
ref = {
|
||||
id: '',
|
||||
createdAt: '',
|
||||
updatedAt: '',
|
||||
expiresAt: '',
|
||||
type: '',
|
||||
link: '',
|
||||
linkText: '',
|
||||
message: '',
|
||||
title: '',
|
||||
imageUrl: '',
|
||||
seen: false,
|
||||
senderUserId: '',
|
||||
senderUsername: '',
|
||||
data: {},
|
||||
responses: [],
|
||||
details: {},
|
||||
version: 2,
|
||||
...json
|
||||
};
|
||||
ref = createDefaultNotificationV2Ref(json);
|
||||
} else {
|
||||
Object.assign(ref, json);
|
||||
}
|
||||
ref.created_at = ref.createdAt; // for table
|
||||
// legacy handling of boops
|
||||
if (ref.type === 'boop' && ref.title) {
|
||||
ref.message = ref.title;
|
||||
ref.title = '';
|
||||
if (ref.details?.emojiId?.startsWith('default_')) {
|
||||
ref.imageUrl = ref.details.emojiId;
|
||||
ref.message += ` ${ref.details.emojiId.replace('default_', '')}`;
|
||||
} else {
|
||||
ref.imageUrl = `${AppDebug.endpointDomain}/file/${ref.details.emojiId}/${ref.details.emojiVersion}`;
|
||||
}
|
||||
}
|
||||
applyBoopLegacyHandling(ref, AppDebug.endpointDomain);
|
||||
return ref;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param args
|
||||
*/
|
||||
function handleNotificationV2(args) {
|
||||
const ref = applyNotificationV2(args.json);
|
||||
if (ref.seen) {
|
||||
@@ -645,6 +611,10 @@ export const useNotificationStore = defineStore('Notification', () => {
|
||||
sharedFeedStore.addEntry(ref);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param args
|
||||
*/
|
||||
function handleNotificationV2Update(args) {
|
||||
const notificationId = args.params.notificationId;
|
||||
const json = { ...args.json };
|
||||
@@ -663,6 +633,10 @@ export const useNotificationStore = defineStore('Notification', () => {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param notificationId
|
||||
*/
|
||||
function handleNotificationV2Hide(notificationId) {
|
||||
database.expireNotificationV2(notificationId);
|
||||
const ref = notificationTable.value.data.find(
|
||||
@@ -674,6 +648,9 @@ export const useNotificationStore = defineStore('Notification', () => {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function expireFriendRequestNotifications() {
|
||||
const array = notificationTable.value.data;
|
||||
for (let i = array.length - 1; i >= 0; i--) {
|
||||
@@ -813,6 +790,10 @@ export const useNotificationStore = defineStore('Notification', () => {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param noty
|
||||
*/
|
||||
function playNoty(noty) {
|
||||
if (
|
||||
userStore.currentUser.status === 'busy' ||
|
||||
@@ -1014,6 +995,10 @@ export const useNotificationStore = defineStore('Notification', () => {
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param gamelog
|
||||
*/
|
||||
function queueGameLogNoty(gamelog) {
|
||||
const noty = structuredClone(gamelog);
|
||||
let bias;
|
||||
@@ -1090,6 +1075,10 @@ export const useNotificationStore = defineStore('Notification', () => {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param feed
|
||||
*/
|
||||
function queueFeedNoty(feed) {
|
||||
const noty = { ...feed };
|
||||
if (noty.type === 'Avatar') {
|
||||
@@ -1116,6 +1105,10 @@ export const useNotificationStore = defineStore('Notification', () => {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param noty
|
||||
*/
|
||||
function queueFriendLogNoty(noty) {
|
||||
if (noty.type === 'FriendRequest') {
|
||||
return;
|
||||
@@ -1133,6 +1126,10 @@ export const useNotificationStore = defineStore('Notification', () => {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param noty
|
||||
*/
|
||||
function queueModerationNoty(noty) {
|
||||
noty.isFriend = false;
|
||||
noty.isFavorite = false;
|
||||
@@ -1146,6 +1143,9 @@ export const useNotificationStore = defineStore('Notification', () => {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
async function initNotifications() {
|
||||
notificationInitStatus.value = false;
|
||||
let tableData = await database.getNotificationsV2();
|
||||
@@ -1161,6 +1161,9 @@ export const useNotificationStore = defineStore('Notification', () => {
|
||||
refreshNotifications();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function testNotification() {
|
||||
playNoty({
|
||||
type: 'Event',
|
||||
@@ -1169,6 +1172,10 @@ export const useNotificationStore = defineStore('Notification', () => {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param row
|
||||
*/
|
||||
function acceptFriendRequestNotification(row) {
|
||||
modalStore
|
||||
.confirm({
|
||||
@@ -1193,6 +1200,10 @@ export const useNotificationStore = defineStore('Notification', () => {
|
||||
.catch(() => {});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param row
|
||||
*/
|
||||
async function hideNotification(row) {
|
||||
if (row.type === 'ignoredFriendRequest') {
|
||||
await friendRequest.deleteHiddenFriendRequest(
|
||||
@@ -1211,6 +1222,10 @@ export const useNotificationStore = defineStore('Notification', () => {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param row
|
||||
*/
|
||||
function hideNotificationPrompt(row) {
|
||||
modalStore
|
||||
.confirm({
|
||||
@@ -1223,6 +1238,10 @@ export const useNotificationStore = defineStore('Notification', () => {
|
||||
.catch(() => {});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param row
|
||||
*/
|
||||
function acceptRequestInvite(row) {
|
||||
modalStore
|
||||
.confirm({
|
||||
@@ -1268,6 +1287,12 @@ export const useNotificationStore = defineStore('Notification', () => {
|
||||
.catch(() => {});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param notificationId
|
||||
* @param responses
|
||||
* @param responseType
|
||||
*/
|
||||
function sendNotificationResponse(notificationId, responses, responseType) {
|
||||
if (!Array.isArray(responses) || responses.length === 0) return;
|
||||
let responseData = '';
|
||||
@@ -1295,6 +1320,10 @@ export const useNotificationStore = defineStore('Notification', () => {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param row
|
||||
*/
|
||||
function deleteNotificationLog(row) {
|
||||
const idx = notificationTable.value.data.findIndex(
|
||||
(e) => e.id === row.id
|
||||
@@ -1314,6 +1343,10 @@ export const useNotificationStore = defineStore('Notification', () => {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param row
|
||||
*/
|
||||
function deleteNotificationLogPrompt(row) {
|
||||
modalStore
|
||||
.confirm({
|
||||
@@ -1327,6 +1360,10 @@ export const useNotificationStore = defineStore('Notification', () => {
|
||||
.catch(() => {});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param notification
|
||||
*/
|
||||
function isNotificationExpired(notification) {
|
||||
if (notification.$isExpired !== undefined) {
|
||||
return notification.$isExpired;
|
||||
@@ -1338,6 +1375,10 @@ export const useNotificationStore = defineStore('Notification', () => {
|
||||
return expiresAt.isValid() && dayjs().isSameOrAfter(expiresAt);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param link
|
||||
*/
|
||||
function openNotificationLink(link) {
|
||||
if (!link) {
|
||||
return;
|
||||
|
||||
@@ -20,8 +20,8 @@ import {
|
||||
getThemeMode,
|
||||
updateTrustColorClasses
|
||||
} from '../../shared/utils/base/ui';
|
||||
import { computeTrustLevel, getNameColour } from '../../shared/utils';
|
||||
import { database } from '../../service/database';
|
||||
import { getNameColour } from '../../shared/utils';
|
||||
import { languageCodes } from '../../localization';
|
||||
import { loadLocalizedStrings } from '../../plugin';
|
||||
import { useFeedStore } from '../feed';
|
||||
@@ -127,6 +127,9 @@ export const useAppearanceSettingsStore = defineStore(
|
||||
: fallback;
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
async function initAppearanceSettings() {
|
||||
const { initThemeMode, isDarkMode: initDarkMode } =
|
||||
await getThemeMode(configRepository);
|
||||
@@ -410,6 +413,10 @@ export const useAppearanceSettingsStore = defineStore(
|
||||
updateTrustColorClasses(trustColor.value);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param customFunc
|
||||
*/
|
||||
async function userColourInit(customFunc) {
|
||||
let dictObject = null;
|
||||
if (typeof customFunc === 'function') {
|
||||
@@ -440,55 +447,13 @@ export const useAppearanceSettingsStore = defineStore(
|
||||
* @param {object} ref
|
||||
*/
|
||||
function applyUserTrustLevel(ref) {
|
||||
ref.$isModerator =
|
||||
ref.developerType && ref.developerType !== 'none';
|
||||
ref.$isTroll = false;
|
||||
ref.$isProbableTroll = false;
|
||||
let trustColorTemp = '';
|
||||
const { tags } = ref;
|
||||
if (tags.includes('admin_moderator')) {
|
||||
ref.$isModerator = true;
|
||||
}
|
||||
if (tags.includes('system_troll')) {
|
||||
ref.$isTroll = true;
|
||||
}
|
||||
if (tags.includes('system_probable_troll') && !ref.$isTroll) {
|
||||
ref.$isProbableTroll = true;
|
||||
}
|
||||
if (tags.includes('system_trust_veteran')) {
|
||||
ref.$trustLevel = 'Trusted User';
|
||||
ref.$trustClass = 'x-tag-veteran';
|
||||
trustColorTemp = 'veteran';
|
||||
ref.$trustSortNum = 5;
|
||||
} else if (tags.includes('system_trust_trusted')) {
|
||||
ref.$trustLevel = 'Known User';
|
||||
ref.$trustClass = 'x-tag-trusted';
|
||||
trustColorTemp = 'trusted';
|
||||
ref.$trustSortNum = 4;
|
||||
} else if (tags.includes('system_trust_known')) {
|
||||
ref.$trustLevel = 'User';
|
||||
ref.$trustClass = 'x-tag-known';
|
||||
trustColorTemp = 'known';
|
||||
ref.$trustSortNum = 3;
|
||||
} else if (tags.includes('system_trust_basic')) {
|
||||
ref.$trustLevel = 'New User';
|
||||
ref.$trustClass = 'x-tag-basic';
|
||||
trustColorTemp = 'basic';
|
||||
ref.$trustSortNum = 2;
|
||||
} else {
|
||||
ref.$trustLevel = 'Visitor';
|
||||
ref.$trustClass = 'x-tag-untrusted';
|
||||
trustColorTemp = 'untrusted';
|
||||
ref.$trustSortNum = 1;
|
||||
}
|
||||
if (ref.$isTroll || ref.$isProbableTroll) {
|
||||
trustColorTemp = 'troll';
|
||||
ref.$trustSortNum += 0.1;
|
||||
}
|
||||
if (ref.$isModerator) {
|
||||
trustColorTemp = 'vip';
|
||||
ref.$trustSortNum += 0.3;
|
||||
}
|
||||
const trust = computeTrustLevel(ref.tags, ref.developerType);
|
||||
ref.$isModerator = trust.isModerator;
|
||||
ref.$isTroll = trust.isTroll;
|
||||
ref.$isProbableTroll = trust.isProbableTroll;
|
||||
ref.$trustLevel = trust.trustLevel;
|
||||
ref.$trustClass = trust.trustClass;
|
||||
ref.$trustSortNum = trust.trustSortNum;
|
||||
if (randomUserColours.value && watchState.isFriendsLoaded) {
|
||||
if (!ref.$userColour) {
|
||||
getNameColour(ref.id).then((colour) => {
|
||||
@@ -496,7 +461,7 @@ export const useAppearanceSettingsStore = defineStore(
|
||||
});
|
||||
}
|
||||
} else {
|
||||
ref.$userColour = trustColor.value[trustColorTemp];
|
||||
ref.$userColour = trustColor.value[trust.trustColorKey];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -525,6 +490,9 @@ export const useAppearanceSettingsStore = defineStore(
|
||||
updateTrustColor(undefined, undefined);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function toggleThemeMode() {
|
||||
const nextMode = isDarkMode.value
|
||||
? 'light'
|
||||
@@ -532,12 +500,20 @@ export const useAppearanceSettingsStore = defineStore(
|
||||
setThemeMode(nextMode);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param value
|
||||
*/
|
||||
function normalizeAppFontFamily(value) {
|
||||
return APP_FONT_FAMILIES.includes(value)
|
||||
? value
|
||||
: APP_FONT_DEFAULT_KEY;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param value
|
||||
*/
|
||||
function setAppFontFamily(value) {
|
||||
const normalized = normalizeAppFontFamily(value);
|
||||
appFontFamily.value = normalized;
|
||||
@@ -545,6 +521,9 @@ export const useAppearanceSettingsStore = defineStore(
|
||||
applyAppFontFamily(normalized);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function setDisplayVRCPlusIconsAsAvatar() {
|
||||
displayVRCPlusIconsAsAvatar.value =
|
||||
!displayVRCPlusIconsAsAvatar.value;
|
||||
@@ -553,6 +532,9 @@ export const useAppearanceSettingsStore = defineStore(
|
||||
displayVRCPlusIconsAsAvatar.value
|
||||
);
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function setNotificationIconDot() {
|
||||
notificationIconDot.value = !notificationIconDot.value;
|
||||
configRepository.setBool(
|
||||
@@ -561,10 +543,16 @@ export const useAppearanceSettingsStore = defineStore(
|
||||
);
|
||||
uiStore.updateTrayIconNotify();
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function setHideNicknames() {
|
||||
hideNicknames.value = !hideNicknames.value;
|
||||
configRepository.setBool('VRCX_hideNicknames', hideNicknames.value);
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function setShowInstanceIdInLocation() {
|
||||
showInstanceIdInLocation.value = !showInstanceIdInLocation.value;
|
||||
configRepository.setBool(
|
||||
@@ -572,6 +560,9 @@ export const useAppearanceSettingsStore = defineStore(
|
||||
showInstanceIdInLocation.value
|
||||
);
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function setIsAgeGatedInstancesVisible() {
|
||||
isAgeGatedInstancesVisible.value =
|
||||
!isAgeGatedInstancesVisible.value;
|
||||
@@ -580,10 +571,16 @@ export const useAppearanceSettingsStore = defineStore(
|
||||
isAgeGatedInstancesVisible.value
|
||||
);
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function setSortFavorites() {
|
||||
sortFavorites.value = !sortFavorites.value;
|
||||
configRepository.setBool('VRCX_sortFavorites', sortFavorites.value);
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function setInstanceUsersSortAlphabetical() {
|
||||
instanceUsersSortAlphabetical.value =
|
||||
!instanceUsersSortAlphabetical.value;
|
||||
@@ -593,6 +590,10 @@ export const useAppearanceSettingsStore = defineStore(
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param size
|
||||
*/
|
||||
function setTablePageSize(size) {
|
||||
const processedSize = clampInt(size, 1, MAX_TABLE_PAGE_SIZE);
|
||||
tablePageSize.value = processedSize;
|
||||
@@ -601,6 +602,10 @@ export const useAppearanceSettingsStore = defineStore(
|
||||
return processedSize;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param input
|
||||
*/
|
||||
function normalizeTablePageSizes(input) {
|
||||
const values = (
|
||||
Array.isArray(input) ? input : DEFAULT_TABLE_PAGE_SIZES
|
||||
@@ -629,10 +634,16 @@ export const useAppearanceSettingsStore = defineStore(
|
||||
setTablePageSize(tablePageSizes.value[0]);
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function setDtHour12() {
|
||||
dtHour12.value = !dtHour12.value;
|
||||
configRepository.setBool('VRCX_dtHour12', dtHour12.value);
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function setDtIsoFormat() {
|
||||
dtIsoFormat.value = !dtIsoFormat.value;
|
||||
configRepository.setBool('VRCX_dtIsoFormat', dtIsoFormat.value);
|
||||
@@ -668,13 +679,24 @@ export const useAppearanceSettingsStore = defineStore(
|
||||
JSON.stringify(methods)
|
||||
);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param collapsed
|
||||
*/
|
||||
function setNavCollapsed(collapsed) {
|
||||
isNavCollapsed.value = collapsed;
|
||||
configRepository.setBool('VRCX_navIsCollapsed', collapsed);
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function toggleNavCollapsed() {
|
||||
setNavCollapsed(!isNavCollapsed.value);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param widthOrArray
|
||||
*/
|
||||
function setNavWidth(widthOrArray) {
|
||||
let width = null;
|
||||
if (Array.isArray(widthOrArray) && widthOrArray.length) {
|
||||
@@ -692,6 +714,9 @@ export const useAppearanceSettingsStore = defineStore(
|
||||
});
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function setIsSidebarGroupByInstance() {
|
||||
isSidebarGroupByInstance.value = !isSidebarGroupByInstance.value;
|
||||
configRepository.setBool(
|
||||
@@ -699,6 +724,9 @@ export const useAppearanceSettingsStore = defineStore(
|
||||
isSidebarGroupByInstance.value
|
||||
);
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function setIsHideFriendsInSameInstance() {
|
||||
isHideFriendsInSameInstance.value =
|
||||
!isHideFriendsInSameInstance.value;
|
||||
@@ -707,6 +735,9 @@ export const useAppearanceSettingsStore = defineStore(
|
||||
isHideFriendsInSameInstance.value
|
||||
);
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function setIsSidebarDivideByFriendGroup() {
|
||||
isSidebarDivideByFriendGroup.value =
|
||||
!isSidebarDivideByFriendGroup.value;
|
||||
@@ -735,18 +766,30 @@ export const useAppearanceSettingsStore = defineStore(
|
||||
JSON.stringify(value)
|
||||
);
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function setHideUserNotes() {
|
||||
hideUserNotes.value = !hideUserNotes.value;
|
||||
configRepository.setBool('VRCX_hideUserNotes', hideUserNotes.value);
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function setHideUserMemos() {
|
||||
hideUserMemos.value = !hideUserMemos.value;
|
||||
configRepository.setBool('VRCX_hideUserMemos', hideUserMemos.value);
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function setHideUnfriends() {
|
||||
hideUnfriends.value = !hideUnfriends.value;
|
||||
configRepository.setBool('VRCX_hideUnfriends', hideUnfriends.value);
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function setRandomUserColours() {
|
||||
randomUserColours.value = !randomUserColours.value;
|
||||
configRepository.setBool(
|
||||
@@ -754,6 +797,10 @@ export const useAppearanceSettingsStore = defineStore(
|
||||
randomUserColours.value
|
||||
);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param value
|
||||
*/
|
||||
function normalizeTableDensity(value) {
|
||||
if (
|
||||
value === 'compact' ||
|
||||
@@ -765,6 +812,10 @@ export const useAppearanceSettingsStore = defineStore(
|
||||
return 'standard';
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param density
|
||||
*/
|
||||
function setTableDensity(density) {
|
||||
const normalized = normalizeTableDensity(density);
|
||||
tableDensity.value = normalized;
|
||||
@@ -772,6 +823,9 @@ export const useAppearanceSettingsStore = defineStore(
|
||||
configRepository.setString('VRCX_tableDensity', tableDensity.value);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function toggleStripedDataTable() {
|
||||
isDataTableStriped.value = !isDataTableStriped.value;
|
||||
configRepository.setBool(
|
||||
@@ -781,6 +835,9 @@ export const useAppearanceSettingsStore = defineStore(
|
||||
}
|
||||
|
||||
// FIXME: this is nasty, there should be a better way of doing this
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function applyPointerHoverClass() {
|
||||
const classList = document.documentElement.classList;
|
||||
classList.remove('force-pointer-on-hover');
|
||||
@@ -790,6 +847,9 @@ export const useAppearanceSettingsStore = defineStore(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function togglePointerOnHover() {
|
||||
showPointerOnHover.value = !showPointerOnHover.value;
|
||||
configRepository.setBool(
|
||||
@@ -811,6 +871,9 @@ export const useAppearanceSettingsStore = defineStore(
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function handleSaveSidebarSortOrder() {
|
||||
if (sidebarSortMethod1.value === sidebarSortMethod2.value) {
|
||||
sidebarSortMethod2.value = '';
|
||||
@@ -835,6 +898,9 @@ export const useAppearanceSettingsStore = defineStore(
|
||||
setSidebarSortMethods(sidebarSortMethods);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
async function mergeOldSortMethodsSettings() {
|
||||
const orderFriendsGroupPrivate = await configRepository.getBool(
|
||||
'orderFriendGroupPrivate'
|
||||
@@ -897,6 +963,9 @@ export const useAppearanceSettingsStore = defineStore(
|
||||
return n;
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function showTableLimitsDialog() {
|
||||
tableLimitsDialog.value.maxTableSize = Number(
|
||||
vrcxStore.maxTableSize ?? 500
|
||||
@@ -907,10 +976,16 @@ export const useAppearanceSettingsStore = defineStore(
|
||||
tableLimitsDialog.value.visible = true;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function closeTableLimitsDialog() {
|
||||
tableLimitsDialog.value.visible = false;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
async function saveTableLimitsDialog() {
|
||||
const nextMaxTableSize = clampLimit(
|
||||
tableLimitsDialog.value.maxTableSize,
|
||||
@@ -949,6 +1024,9 @@ export const useAppearanceSettingsStore = defineStore(
|
||||
tableLimitsDialog.value.visible = false;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
async function tryInitUserColours() {
|
||||
if (!randomUserColours.value) {
|
||||
return;
|
||||
@@ -958,6 +1036,10 @@ export const useAppearanceSettingsStore = defineStore(
|
||||
await userColourInit();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param density
|
||||
*/
|
||||
function applyTableDensity(density) {
|
||||
const classList = document.documentElement.classList;
|
||||
classList.remove('is-compact-table', 'is-comfortable-table');
|
||||
|
||||
@@ -9,6 +9,12 @@ import {
|
||||
isRpcWorld,
|
||||
parseLocation
|
||||
} from '../../shared/utils';
|
||||
import {
|
||||
getPlatformLabel,
|
||||
getRpcWorldConfig,
|
||||
getStatusInfo,
|
||||
isPopcornPalaceWorld
|
||||
} from '../../shared/utils/discordPresence';
|
||||
import {
|
||||
ActivityType,
|
||||
StatusDisplayType
|
||||
@@ -59,14 +65,23 @@ export const useDiscordPresenceSettingsStore = defineStore(
|
||||
const discordWorldIntegration = ref(true);
|
||||
const discordWorldNameAsDiscordStatus = ref(false);
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function setDiscordActive() {
|
||||
discordActive.value = !discordActive.value;
|
||||
configRepository.setBool('discordActive', discordActive.value);
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function setDiscordInstance() {
|
||||
discordInstance.value = !discordInstance.value;
|
||||
configRepository.setBool('discordInstance', discordInstance.value);
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function setDiscordHideInvite() {
|
||||
discordHideInvite.value = !discordHideInvite.value;
|
||||
configRepository.setBool(
|
||||
@@ -74,6 +89,9 @@ export const useDiscordPresenceSettingsStore = defineStore(
|
||||
discordHideInvite.value
|
||||
);
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function setDiscordJoinButton() {
|
||||
discordJoinButton.value = !discordJoinButton.value;
|
||||
configRepository.setBool(
|
||||
@@ -81,6 +99,9 @@ export const useDiscordPresenceSettingsStore = defineStore(
|
||||
discordJoinButton.value
|
||||
);
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function setDiscordHideImage() {
|
||||
discordHideImage.value = !discordHideImage.value;
|
||||
configRepository.setBool(
|
||||
@@ -88,6 +109,9 @@ export const useDiscordPresenceSettingsStore = defineStore(
|
||||
discordHideImage.value
|
||||
);
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function setDiscordShowPlatform() {
|
||||
discordShowPlatform.value = !discordShowPlatform.value;
|
||||
configRepository.setBool(
|
||||
@@ -95,6 +119,9 @@ export const useDiscordPresenceSettingsStore = defineStore(
|
||||
discordShowPlatform.value
|
||||
);
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function setDiscordWorldIntegration() {
|
||||
discordWorldIntegration.value = !discordWorldIntegration.value;
|
||||
configRepository.setBool(
|
||||
@@ -102,6 +129,9 @@ export const useDiscordPresenceSettingsStore = defineStore(
|
||||
discordWorldIntegration.value
|
||||
);
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function setDiscordWorldNameAsDiscordStatus() {
|
||||
discordWorldNameAsDiscordStatus.value =
|
||||
!discordWorldNameAsDiscordStatus.value;
|
||||
@@ -111,6 +141,9 @@ export const useDiscordPresenceSettingsStore = defineStore(
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
async function initDiscordPresenceSettings() {
|
||||
const [
|
||||
discordActiveConfig,
|
||||
@@ -148,6 +181,9 @@ export const useDiscordPresenceSettingsStore = defineStore(
|
||||
|
||||
initDiscordPresenceSettings();
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
async function updateDiscord() {
|
||||
let currentLocation = locationStore.lastLocation.location;
|
||||
let startTime = locationStore.lastLocation.date;
|
||||
@@ -204,27 +240,12 @@ export const useDiscordPresenceSettingsStore = defineStore(
|
||||
|
||||
let platform = '';
|
||||
if (discordShowPlatform.value) {
|
||||
if (gameStore.isGameRunning) {
|
||||
platform = gameStore.isGameNoVR
|
||||
? ` (${t('view.settings.discord_presence.rpc.desktop')})`
|
||||
: ` (${t('view.settings.discord_presence.rpc.vr')})`;
|
||||
} else {
|
||||
switch (userStore.currentUser.presence.platform) {
|
||||
case 'web':
|
||||
break;
|
||||
case 'standalonewindows':
|
||||
platform = ` (PC)`;
|
||||
break;
|
||||
case 'android':
|
||||
platform = ` (Android)`;
|
||||
break;
|
||||
case 'ios':
|
||||
platform = ` (iOS)`;
|
||||
break;
|
||||
default:
|
||||
platform = ` (${userStore.currentUser.presence.platform})`;
|
||||
}
|
||||
}
|
||||
platform = getPlatformLabel(
|
||||
userStore.currentUser.presence.platform,
|
||||
gameStore.isGameRunning,
|
||||
gameStore.isGameNoVR,
|
||||
t
|
||||
);
|
||||
}
|
||||
state.lastLocationDetails.groupAccessType = L.groupAccessType;
|
||||
if (L.groupAccessType) {
|
||||
@@ -281,34 +302,14 @@ export const useDiscordPresenceSettingsStore = defineStore(
|
||||
) {
|
||||
hidePrivate = true;
|
||||
}
|
||||
let statusName = '';
|
||||
let statusImage = '';
|
||||
switch (userStore.currentUser.status) {
|
||||
case 'active':
|
||||
statusName = t('dialog.user.status.active');
|
||||
statusImage = 'active';
|
||||
break;
|
||||
case 'join me':
|
||||
statusName = t('dialog.user.status.join_me');
|
||||
statusImage = 'joinme';
|
||||
break;
|
||||
case 'ask me':
|
||||
statusName = t('dialog.user.status.ask_me');
|
||||
statusImage = 'askme';
|
||||
if (discordHideInvite.value) {
|
||||
hidePrivate = true;
|
||||
}
|
||||
break;
|
||||
case 'busy':
|
||||
statusName = t('dialog.user.status.busy');
|
||||
statusImage = 'busy';
|
||||
hidePrivate = true;
|
||||
break;
|
||||
default:
|
||||
statusName = t('dialog.user.status.offline');
|
||||
statusImage = 'offline';
|
||||
hidePrivate = true;
|
||||
break;
|
||||
const statusInfo = getStatusInfo(
|
||||
userStore.currentUser.status,
|
||||
discordHideInvite.value,
|
||||
t
|
||||
);
|
||||
const { statusName, statusImage } = statusInfo;
|
||||
if (statusInfo.hidePrivate) {
|
||||
hidePrivate = true;
|
||||
}
|
||||
let details = state.lastLocationDetails.worldName;
|
||||
let stateText = state.lastLocationDetails.accessName;
|
||||
@@ -345,74 +346,23 @@ export const useDiscordPresenceSettingsStore = defineStore(
|
||||
buttonUrl = '';
|
||||
}
|
||||
|
||||
if (
|
||||
const rpcConfig =
|
||||
isRpcWorld(state.lastLocationDetails.tag) &&
|
||||
discordWorldIntegration.value
|
||||
) {
|
||||
// custom world rpc
|
||||
? getRpcWorldConfig(state.lastLocationDetails.worldId)
|
||||
: null;
|
||||
|
||||
if (rpcConfig) {
|
||||
activityType = rpcConfig.activityType;
|
||||
statusDisplayType = rpcConfig.statusDisplayType;
|
||||
appId = rpcConfig.appId;
|
||||
bigIcon = rpcConfig.bigIcon;
|
||||
if (
|
||||
state.lastLocationDetails.worldId ===
|
||||
'wrld_f20326da-f1ac-45fc-a062-609723b097b1' ||
|
||||
state.lastLocationDetails.worldId ===
|
||||
'wrld_10e5e467-fc65-42ed-8957-f02cace1398c' ||
|
||||
state.lastLocationDetails.worldId ===
|
||||
'wrld_04899f23-e182-4a8d-b2c7-2c74c7c15534'
|
||||
isPopcornPalaceWorld(state.lastLocationDetails.worldId) &&
|
||||
!discordHideImage.value &&
|
||||
gameLogStore.nowPlaying.thumbnailUrl
|
||||
) {
|
||||
activityType = ActivityType.Listening;
|
||||
statusDisplayType = StatusDisplayType.Details;
|
||||
appId = '784094509008551956';
|
||||
bigIcon = 'pypy';
|
||||
} else if (
|
||||
state.lastLocationDetails.worldId ===
|
||||
'wrld_42377cf1-c54f-45ed-8996-5875b0573a83' ||
|
||||
state.lastLocationDetails.worldId ===
|
||||
'wrld_dd6d2888-dbdc-47c2-bc98-3d631b2acd7c'
|
||||
) {
|
||||
activityType = ActivityType.Listening;
|
||||
statusDisplayType = StatusDisplayType.Details;
|
||||
appId = '846232616054030376';
|
||||
bigIcon = 'vr_dancing';
|
||||
} else if (
|
||||
state.lastLocationDetails.worldId ===
|
||||
'wrld_52bdcdab-11cd-4325-9655-0fb120846945' ||
|
||||
state.lastLocationDetails.worldId ===
|
||||
'wrld_2d40da63-8f1f-4011-8a9e-414eb8530acd'
|
||||
) {
|
||||
activityType = ActivityType.Listening;
|
||||
statusDisplayType = StatusDisplayType.Details;
|
||||
appId = '939473404808007731';
|
||||
bigIcon = 'zuwa_zuwa_dance';
|
||||
} else if (
|
||||
state.lastLocationDetails.worldId ===
|
||||
'wrld_74970324-58e8-4239-a17b-2c59dfdf00db' ||
|
||||
state.lastLocationDetails.worldId ===
|
||||
'wrld_db9d878f-6e76-4776-8bf2-15bcdd7fc445' ||
|
||||
state.lastLocationDetails.worldId ===
|
||||
'wrld_435bbf25-f34f-4b8b-82c6-cd809057eb8e' ||
|
||||
state.lastLocationDetails.worldId ===
|
||||
'wrld_f767d1c8-b249-4ecc-a56f-614e433682c8'
|
||||
) {
|
||||
activityType = ActivityType.Watching;
|
||||
statusDisplayType = StatusDisplayType.Details;
|
||||
appId = '968292722391785512';
|
||||
bigIcon = 'ls_media';
|
||||
} else if (
|
||||
state.lastLocationDetails.worldId ===
|
||||
'wrld_266523e8-9161-40da-acd0-6bd82e075833' ||
|
||||
state.lastLocationDetails.worldId ===
|
||||
'wrld_27c7e6b2-d938-447e-a270-3d1a873e2cf3'
|
||||
) {
|
||||
activityType = ActivityType.Watching;
|
||||
statusDisplayType = StatusDisplayType.Details;
|
||||
appId = '1095440531821170820';
|
||||
if (
|
||||
!discordHideImage.value &&
|
||||
gameLogStore.nowPlaying.thumbnailUrl
|
||||
) {
|
||||
bigIcon = gameLogStore.nowPlaying.thumbnailUrl;
|
||||
} else {
|
||||
bigIcon = 'popcorn_palace';
|
||||
}
|
||||
bigIcon = gameLogStore.nowPlaying.thumbnailUrl;
|
||||
}
|
||||
if (gameLogStore.nowPlaying.name) {
|
||||
details = gameLogStore.nowPlaying.name;
|
||||
@@ -476,12 +426,20 @@ export const useDiscordPresenceSettingsStore = defineStore(
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param active
|
||||
*/
|
||||
async function setIsDiscordActive(active) {
|
||||
if (active !== state.isDiscordActive) {
|
||||
state.isDiscordActive = await Discord.SetActive(active);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param configLabel
|
||||
*/
|
||||
async function saveDiscordOption(configLabel = '') {
|
||||
state.lastLocationDetails.tag = '';
|
||||
updateLoopStore.nextDiscordUpdate = 3;
|
||||
|
||||
+71
-176
@@ -12,6 +12,10 @@ import {
|
||||
compareByLocationAt,
|
||||
compareByName,
|
||||
compareByUpdatedAt,
|
||||
computeUserPlatform,
|
||||
createDefaultUserRef,
|
||||
diffObjectProps,
|
||||
evictMapCache,
|
||||
extractFileId,
|
||||
findUserByDisplayName,
|
||||
getAllUserMemos,
|
||||
@@ -20,8 +24,8 @@ import {
|
||||
getWorldName,
|
||||
isRealInstance,
|
||||
parseLocation,
|
||||
removeEmojis,
|
||||
replaceBioSymbols
|
||||
replaceBioSymbols,
|
||||
sanitizeUserJson
|
||||
} from '../shared/utils';
|
||||
import {
|
||||
avatarRequest,
|
||||
@@ -29,10 +33,10 @@ import {
|
||||
instanceRequest,
|
||||
userRequest
|
||||
} from '../api';
|
||||
import { patchUserFromEvent } from '../query';
|
||||
import { processBulk, request } from '../service/request';
|
||||
import { AppDebug } from '../service/appConfig';
|
||||
import { database } from '../service/database';
|
||||
import { patchUserFromEvent } from '../query';
|
||||
import { useAppearanceSettingsStore } from './settings/appearance';
|
||||
import { useAuthStore } from './auth';
|
||||
import { useAvatarStore } from './avatar';
|
||||
@@ -344,6 +348,10 @@ export const useUserStore = defineStore('User', () => {
|
||||
{ flush: 'sync' }
|
||||
);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param args
|
||||
*/
|
||||
function handleConfig(args) {
|
||||
const authStore = useAuthStore();
|
||||
const ref = {
|
||||
@@ -419,143 +427,18 @@ export const useUserStore = defineStore('User', () => {
|
||||
}
|
||||
|
||||
const robotUrl = `${AppDebug.endpointDomain}/file/file_0e8c4e32-7444-44ea-ade4-313c010d4bae/1/file`;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Map<string, any>} userCache
|
||||
* @param {Map<string, any>} friendMap
|
||||
*/
|
||||
function cleanupUserCache(userCache, friendMap) {
|
||||
const bufferSize = 300;
|
||||
|
||||
const currentFriendCount = friendMap.size;
|
||||
const currentTotalSize = userCache.size;
|
||||
|
||||
const effectiveMaxSize = currentFriendCount + bufferSize;
|
||||
|
||||
if (currentTotalSize <= effectiveMaxSize) {
|
||||
return;
|
||||
}
|
||||
|
||||
const targetDeleteCount = currentTotalSize - effectiveMaxSize;
|
||||
let deletedCount = 0;
|
||||
const keysToDelete = [];
|
||||
|
||||
for (const userId of userCache.keys()) {
|
||||
if (friendMap.has(userId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (deletedCount >= targetDeleteCount) {
|
||||
break;
|
||||
}
|
||||
|
||||
keysToDelete.push(userId);
|
||||
deletedCount++;
|
||||
}
|
||||
|
||||
for (const id of keysToDelete) {
|
||||
userCache.delete(id);
|
||||
}
|
||||
|
||||
console.log(
|
||||
`User cache cleanup: Deleted ${deletedCount}. Current cache size: ${userCache.size}`
|
||||
);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param {import('../types/api/user').GetUserResponse} json
|
||||
* @returns {import('../types/api/user').VrcxUser}
|
||||
*/
|
||||
function applyUser(json) {
|
||||
let hasPropChanged = false;
|
||||
const changedProps = {};
|
||||
let ref = cachedUsers.get(json.id);
|
||||
if (json.statusDescription) {
|
||||
json.statusDescription = replaceBioSymbols(json.statusDescription);
|
||||
json.statusDescription = removeEmojis(json.statusDescription);
|
||||
}
|
||||
if (json.bio) {
|
||||
json.bio = replaceBioSymbols(json.bio);
|
||||
}
|
||||
if (json.note) {
|
||||
json.note = replaceBioSymbols(json.note);
|
||||
}
|
||||
if (json.currentAvatarImageUrl === robotUrl) {
|
||||
delete json.currentAvatarImageUrl;
|
||||
delete json.currentAvatarThumbnailImageUrl;
|
||||
}
|
||||
let hasPropChanged = false;
|
||||
let changedProps = {};
|
||||
sanitizeUserJson(json, robotUrl);
|
||||
if (typeof ref === 'undefined') {
|
||||
ref = reactive({
|
||||
ageVerificationStatus: '',
|
||||
ageVerified: false,
|
||||
allowAvatarCopying: false,
|
||||
badges: [],
|
||||
bio: '',
|
||||
bioLinks: [],
|
||||
currentAvatarImageUrl: '',
|
||||
currentAvatarTags: [],
|
||||
currentAvatarThumbnailImageUrl: '',
|
||||
date_joined: '',
|
||||
developerType: '',
|
||||
discordId: '',
|
||||
displayName: '',
|
||||
friendKey: '',
|
||||
friendRequestStatus: '',
|
||||
id: '',
|
||||
instanceId: '',
|
||||
isFriend: false,
|
||||
last_activity: '',
|
||||
last_login: '',
|
||||
last_mobile: null,
|
||||
last_platform: '',
|
||||
location: '',
|
||||
platform: '',
|
||||
note: null,
|
||||
profilePicOverride: '',
|
||||
profilePicOverrideThumbnail: '',
|
||||
pronouns: '',
|
||||
state: '',
|
||||
status: '',
|
||||
statusDescription: '',
|
||||
tags: [],
|
||||
travelingToInstance: '',
|
||||
travelingToLocation: '',
|
||||
travelingToWorld: '',
|
||||
userIcon: '',
|
||||
worldId: '',
|
||||
// only in bulk request
|
||||
fallbackAvatar: '',
|
||||
// VRCX
|
||||
$location: {},
|
||||
$location_at: Date.now(),
|
||||
$online_for: Date.now(),
|
||||
$travelingToTime: Date.now(),
|
||||
$offline_for: null,
|
||||
$active_for: Date.now(),
|
||||
$isVRCPlus: false,
|
||||
$isModerator: false,
|
||||
$isTroll: false,
|
||||
$isProbableTroll: false,
|
||||
$trustLevel: 'Visitor',
|
||||
$trustClass: 'x-tag-untrusted',
|
||||
$userColour: '',
|
||||
$trustSortNum: 1,
|
||||
$languages: [],
|
||||
$joinCount: 0,
|
||||
$timeSpent: 0,
|
||||
$lastSeen: '',
|
||||
$mutualCount: 0,
|
||||
$nickName: '',
|
||||
$previousLocation: '',
|
||||
$customTag: '',
|
||||
$customTagColour: '',
|
||||
$friendNumber: 0,
|
||||
$platform: '',
|
||||
$moderations: {},
|
||||
//
|
||||
...json
|
||||
});
|
||||
ref = reactive(createDefaultUserRef(json));
|
||||
if (locationStore.lastLocation.playerList.has(json.id)) {
|
||||
// update $location_at from instance join time
|
||||
const player = locationStore.lastLocation.playerList.get(
|
||||
@@ -581,7 +464,12 @@ export const useUserStore = defineStore('User', () => {
|
||||
ref.$customTag = '';
|
||||
ref.$customTagColour = '';
|
||||
}
|
||||
cleanupUserCache(cachedUsers, friendStore.friends);
|
||||
evictMapCache(
|
||||
cachedUsers,
|
||||
friendStore.friends.size + 300,
|
||||
(_value, key) => friendStore.friends.has(key),
|
||||
{ logLabel: 'User cache cleanup' }
|
||||
);
|
||||
cachedUsers.set(ref.id, ref);
|
||||
friendStore.updateFriend(ref.id);
|
||||
} else {
|
||||
@@ -589,59 +477,23 @@ export const useUserStore = defineStore('User', () => {
|
||||
// offline event before GPS to offline location
|
||||
friendStore.updateFriend(ref.id, json.state);
|
||||
}
|
||||
for (const prop in ref) {
|
||||
if (typeof json[prop] === 'undefined') {
|
||||
continue;
|
||||
}
|
||||
// Only compare primitive values
|
||||
if (ref[prop] === null || typeof ref[prop] !== 'object') {
|
||||
changedProps[prop] = true;
|
||||
}
|
||||
}
|
||||
for (const prop in json) {
|
||||
if (typeof ref[prop] === 'undefined') {
|
||||
continue;
|
||||
}
|
||||
if (Array.isArray(json[prop]) && Array.isArray(ref[prop])) {
|
||||
if (!arraysMatch(json[prop], ref[prop])) {
|
||||
changedProps[prop] = true;
|
||||
}
|
||||
} else if (
|
||||
json[prop] === null ||
|
||||
typeof json[prop] !== 'object'
|
||||
) {
|
||||
changedProps[prop] = true;
|
||||
}
|
||||
}
|
||||
for (const prop in changedProps) {
|
||||
const asIs = ref[prop];
|
||||
const toBe = json[prop];
|
||||
if (asIs === toBe) {
|
||||
delete changedProps[prop];
|
||||
} else {
|
||||
hasPropChanged = true;
|
||||
changedProps[prop] = [toBe, asIs];
|
||||
}
|
||||
}
|
||||
const {
|
||||
hasPropChanged: _hasPropChanged,
|
||||
changedProps: _changedProps
|
||||
} = diffObjectProps(ref, json, arraysMatch);
|
||||
for (const prop in json) {
|
||||
if (typeof json[prop] !== 'undefined') {
|
||||
ref[prop] = json[prop];
|
||||
}
|
||||
}
|
||||
hasPropChanged = _hasPropChanged;
|
||||
changedProps = _changedProps;
|
||||
}
|
||||
ref.$moderations = moderationStore.getUserModerations(ref.id);
|
||||
ref.$isVRCPlus = ref.tags.includes('system_supporter');
|
||||
appearanceSettingsStore.applyUserTrustLevel(ref);
|
||||
applyUserLanguage(ref);
|
||||
if (
|
||||
ref.platform &&
|
||||
ref.platform !== 'offline' &&
|
||||
ref.platform !== 'web'
|
||||
) {
|
||||
ref.$platform = ref.platform;
|
||||
} else {
|
||||
ref.$platform = ref.last_platform;
|
||||
}
|
||||
ref.$platform = computeUserPlatform(ref.platform, ref.last_platform);
|
||||
// traveling
|
||||
if (ref.location === 'traveling') {
|
||||
ref.$location = parseLocation(ref.travelingToLocation);
|
||||
@@ -1180,6 +1032,10 @@ export const useUserStore = defineStore('User', () => {
|
||||
D.instance.friendCount = friendCount;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param array
|
||||
*/
|
||||
function sortUserDialogAvatars(array) {
|
||||
const D = userDialog.value;
|
||||
if (D.avatarSorting === 'update') {
|
||||
@@ -1192,6 +1048,10 @@ export const useUserStore = defineStore('User', () => {
|
||||
D.avatars = array;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param fileId
|
||||
*/
|
||||
async function refreshUserDialogAvatars(fileId) {
|
||||
const D = userDialog.value;
|
||||
const userId = D.id;
|
||||
@@ -1248,6 +1108,10 @@ export const useUserStore = defineStore('User', () => {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param ref
|
||||
*/
|
||||
async function lookupUser(ref) {
|
||||
let ctx;
|
||||
if (ref.userId) {
|
||||
@@ -1577,6 +1441,9 @@ export const useUserStore = defineStore('User', () => {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function updateAutoStateChange() {
|
||||
if (
|
||||
!generalSettingsStore.autoStateChangeEnabled ||
|
||||
@@ -1683,6 +1550,10 @@ export const useUserStore = defineStore('User', () => {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param data
|
||||
*/
|
||||
function addCustomTag(data) {
|
||||
if (data.Tag) {
|
||||
customUserTags.set(data.UserId, {
|
||||
@@ -1708,6 +1579,9 @@ export const useUserStore = defineStore('User', () => {
|
||||
sharedFeedStore.addTag(data.UserId, data.TagColour);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
async function initUserNotes() {
|
||||
state.lastNoteCheck = new Date();
|
||||
state.lastDbNoteDate = null;
|
||||
@@ -1735,6 +1609,9 @@ export const useUserStore = defineStore('User', () => {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
async function getLatestUserNotes() {
|
||||
state.lastNoteCheck = new Date();
|
||||
const params = {
|
||||
@@ -1793,6 +1670,11 @@ export const useUserStore = defineStore('User', () => {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param userId
|
||||
* @param newNote
|
||||
*/
|
||||
async function checkNote(userId, newNote) {
|
||||
// last check was more than than 5 minutes ago
|
||||
if (
|
||||
@@ -1814,6 +1696,9 @@ export const useUserStore = defineStore('User', () => {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function getCurrentUser() {
|
||||
return request('auth/user', {
|
||||
method: 'GET'
|
||||
@@ -2079,11 +1964,18 @@ export const useUserStore = defineStore('User', () => {
|
||||
return ref;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param userId
|
||||
*/
|
||||
function showSendBoopDialog(userId) {
|
||||
sendBoopDialog.value.userId = userId;
|
||||
sendBoopDialog.value.visible = true;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function toggleSharedConnectionsOptOut() {
|
||||
userRequest.saveCurrentUser({
|
||||
hasSharedConnectionsOptOut:
|
||||
@@ -2091,6 +1983,9 @@ export const useUserStore = defineStore('User', () => {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function toggleDiscordFriendsOptOut() {
|
||||
userRequest.saveCurrentUser({
|
||||
hasDiscordFriendsOptOut: !currentUser.value.hasDiscordFriendsOptOut
|
||||
|
||||
+10
-64
@@ -5,16 +5,18 @@ import { useI18n } from 'vue-i18n';
|
||||
|
||||
import {
|
||||
checkVRChatCache,
|
||||
createDefaultWorldRef,
|
||||
evictMapCache,
|
||||
getAvailablePlatforms,
|
||||
getBundleDateSize,
|
||||
getWorldMemo,
|
||||
isRealInstance,
|
||||
parseLocation,
|
||||
replaceBioSymbols
|
||||
sanitizeEntityJson
|
||||
} from '../shared/utils';
|
||||
import { instanceRequest, miscRequest, worldRequest } from '../api';
|
||||
import { patchWorldFromEvent } from '../query';
|
||||
import { database } from '../service/database';
|
||||
import { patchWorldFromEvent } from '../query';
|
||||
import { processBulk } from '../service/request';
|
||||
import { useFavoriteStore } from './favorite';
|
||||
import { useInstanceStore } from './instance';
|
||||
@@ -76,6 +78,7 @@ export const useWorldStore = defineStore('World', () => {
|
||||
*
|
||||
* @param {string} tag
|
||||
* @param {string} shortName
|
||||
* @param options
|
||||
*/
|
||||
function showWorldDialog(tag, shortName = null, options = {}) {
|
||||
const D = worldDialog;
|
||||
@@ -204,7 +207,6 @@ export const useWorldStore = defineStore('World', () => {
|
||||
args.json !== false;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -235,20 +237,9 @@ export const useWorldStore = defineStore('World', () => {
|
||||
* @param WorldCache
|
||||
*/
|
||||
function cleanupWorldCache(WorldCache) {
|
||||
const maxCacheSize = 10000;
|
||||
|
||||
if (WorldCache.size <= maxCacheSize) {
|
||||
return;
|
||||
}
|
||||
|
||||
const deletedCount = WorldCache.size - maxCacheSize;
|
||||
while (WorldCache.size > maxCacheSize) {
|
||||
const deletedKey = WorldCache.keys().next().value;
|
||||
WorldCache.delete(deletedKey);
|
||||
}
|
||||
console.log(
|
||||
`World cache cleanup: Deleted ${deletedCount}. Current cache size: ${WorldCache.size}`
|
||||
);
|
||||
evictMapCache(WorldCache, 10000, () => false, {
|
||||
logLabel: 'World cache cleanup'
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -257,55 +248,10 @@ export const useWorldStore = defineStore('World', () => {
|
||||
* @returns {object} ref
|
||||
*/
|
||||
function applyWorld(json) {
|
||||
if (json.name) {
|
||||
json.name = replaceBioSymbols(json.name);
|
||||
}
|
||||
if (json.description) {
|
||||
json.description = replaceBioSymbols(json.description);
|
||||
}
|
||||
sanitizeEntityJson(json, ['name', 'description']);
|
||||
let ref = cachedWorlds.get(json.id);
|
||||
if (typeof ref === 'undefined') {
|
||||
ref = {
|
||||
id: '',
|
||||
name: '',
|
||||
description: '',
|
||||
defaultContentSettings: {},
|
||||
authorId: '',
|
||||
authorName: '',
|
||||
capacity: 0,
|
||||
recommendedCapacity: 0,
|
||||
tags: [],
|
||||
releaseStatus: '',
|
||||
imageUrl: '',
|
||||
thumbnailImageUrl: '',
|
||||
assetUrl: '',
|
||||
assetUrlObject: {},
|
||||
pluginUrl: '',
|
||||
pluginUrlObject: {},
|
||||
unityPackageUrl: '',
|
||||
unityPackageUrlObject: {},
|
||||
unityPackages: [],
|
||||
version: 0,
|
||||
favorites: 0,
|
||||
created_at: '',
|
||||
updated_at: '',
|
||||
publicationDate: '',
|
||||
labsPublicationDate: '',
|
||||
visits: 0,
|
||||
popularity: 0,
|
||||
heat: 0,
|
||||
publicOccupants: 0,
|
||||
privateOccupants: 0,
|
||||
occupants: 0,
|
||||
instances: [],
|
||||
featured: false,
|
||||
organization: '',
|
||||
previewYoutubeId: '',
|
||||
// VRCX
|
||||
$isLabs: false,
|
||||
//
|
||||
...json
|
||||
};
|
||||
ref = createDefaultWorldRef(json);
|
||||
cleanupWorldCache(cachedWorlds);
|
||||
cachedWorlds.set(ref.id, ref);
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user