diff --git a/src/api/instance.js b/src/api/instance.js index 07f20876..7c4141de 100644 --- a/src/api/instance.js +++ b/src/api/instance.js @@ -21,6 +21,35 @@ const instanceReq = { }); }, + /** + * @param {{worldId: string, instanceId: string}} params + * @returns {Promise<{json: any, ref: any, cache?: boolean, params}>} + */ + getCachedInstance(params) { + const instanceStore = useInstanceStore(); + return new Promise((resolve, reject) => { + const ref = instanceStore.cachedInstances.get( + `${params.worldId}:${params.instanceId}` + ); + if (typeof ref === 'undefined') { + instanceReq + .getInstance(params) + .then((args) => { + args.ref = instanceStore.applyInstance(args.json); + resolve(args); + }) + .catch(reject); + } else { + resolve({ + cache: true, + json: ref, + params, + ref + }); + } + }); + }, + /** * @type {import('../types/api/instance').CreateInstance} */ diff --git a/src/api/user.js b/src/api/user.js index ad4df1a0..24a2a1e7 100644 --- a/src/api/user.js +++ b/src/api/user.js @@ -45,11 +45,11 @@ const userReq = { if (typeof ref === 'undefined') { userReq .getUser(params) - .catch(reject) .then((args) => { args.ref = userStore.applyUser(args.json); resolve(args); - }); + }) + .catch(reject); } else { resolve({ cache: true, diff --git a/src/api/world.js b/src/api/world.js index 29849780..f19bea68 100644 --- a/src/api/world.js +++ b/src/api/world.js @@ -30,11 +30,11 @@ const worldReq = { if (typeof ref === 'undefined') { worldReq .getWorld(params) - .catch(reject) .then((args) => { args.ref = worldStore.applyWorld(args.json); resolve(args); - }); + }) + .catch(reject); } else { resolve({ cache: true, diff --git a/src/components/Location.vue b/src/components/Location.vue index 919787a6..966768f4 100644 --- a/src/components/Location.vue +++ b/src/components/Location.vue @@ -25,7 +25,7 @@ const { cachedWorlds, showWorldDialog } = useWorldStore(); const { showGroupDialog } = useGroupStore(); - const { showPreviousInstancesInfoDialog } = useInstanceStore(); + const { getInstanceName, showPreviousInstancesInfoDialog } = useInstanceStore(); const { verifyShortName } = useSearchStore(); const props = defineProps({ @@ -65,45 +65,30 @@ isTraveling.value = true; } const L = parseLocation(instanceId); - if (L.isOffline) { - text.value = 'Offline'; - } else if (L.isPrivate) { - text.value = 'Private'; - } else if (L.isTraveling) { - text.value = 'Traveling'; - } else if (typeof props.hint === 'string' && props.hint !== '') { - if (L.instanceId) { - text.value = `${props.hint} #${L.instanceName} ${L.accessTypeName}`; - } else { - text.value = props.hint; - } - } else if (L.worldId) { - const ref = cachedWorlds.get(L.worldId); - if (typeof ref === 'undefined') { - getWorldName(L.worldId).then((worldName) => { - if (L.tag === instanceId) { - if (L.instanceId) { - text.value = `${worldName} #${L.instanceName} ${L.accessTypeName}`; - } else { - text.value = worldName; - } - } - }); - } else if (L.instanceId) { - text.value = `${ref.name} #${L.instanceName} ${L.accessTypeName}`; - } else { - text.value = ref.name; - } - } + setText(L, L.instanceName); + getInstanceName(instanceId) + .then((name) => { + if (name && props.location === L.tag) { + setText(L, name); + } + }) + .catch((e) => { + console.error(e); + }); + if (props.grouphint) { groupName.value = props.grouphint; } else if (L.groupId) { groupName.value = L.groupId; - getGroupName(instanceId).then((name) => { - if (L.tag === instanceId) { - groupName.value = name; - } - }); + getGroupName(instanceId) + .then((name) => { + if (name && props.location === L.tag) { + groupName.value = name; + } + }) + .catch((e) => { + console.error(e); + }); } region.value = ''; if (!L.isOffline && !L.isPrivate && !L.isTraveling) { @@ -115,6 +100,49 @@ strict.value = L.strict; } + function setText(L, instanceName) { + if (L.isOffline) { + text.value = 'Offline'; + } else if (L.isPrivate) { + text.value = 'Private'; + } else if (L.isTraveling) { + text.value = 'Traveling'; + } else if (typeof props.hint === 'string' && props.hint !== '') { + if (L.instanceId) { + text.value = `${props.hint} #${instanceName} ${L.accessTypeName}`; + } else { + text.value = props.hint; + } + } else if (L.worldId) { + const ref = cachedWorlds.get(L.worldId); + if (typeof ref === 'undefined') { + const worldName = L.worldId; + if (L.instanceId) { + text.value = `${worldName} #${instanceName} ${L.accessTypeName}`; + } else { + text.value = worldName; + } + getWorldName(L.worldId) + .then((name) => { + if (name && props.location === L.tag) { + if (L.instanceId) { + text.value = `${name} #${instanceName} ${L.accessTypeName}`; + } else { + text.value = name; + } + } + }) + .catch((e) => { + console.error(e); + }); + } else if (L.instanceId) { + text.value = `${ref.name} #${instanceName} ${L.accessTypeName}`; + } else { + text.value = ref.name; + } + } + } + function handleShowWorldDialog() { if (props.link) { let instanceId = props.location; diff --git a/src/components/LocationWorld.vue b/src/components/LocationWorld.vue index 9eaedea3..6352a58a 100644 --- a/src/components/LocationWorld.vue +++ b/src/components/LocationWorld.vue @@ -14,10 +14,11 @@ import { Lock, Unlock } from '@element-plus/icons-vue'; import { ref, watch } from 'vue'; import { getGroupName, parseLocation } from '../shared/utils'; - import { useGroupStore, useLaunchStore } from '../stores'; + import { useGroupStore, useLaunchStore, useInstanceStore } from '../stores'; const launchStore = useLaunchStore(); const groupStore = useGroupStore(); + const { getInstanceName } = useInstanceStore(); const props = defineProps({ locationobject: Object, @@ -41,7 +42,6 @@ function parse() { const locObj = props.locationobject; location.value = locObj.tag; - instanceName.value = locObj.instanceName; accessTypeName.value = locObj.accessTypeName; strict.value = locObj.strict; shortName.value = locObj.shortName; @@ -52,17 +52,29 @@ region.value = locObj.region || 'us'; + instanceName.value = locObj.instanceName; + getInstanceName(locObj.tag) + .then((name) => { + if (name && props.locationobject.tag === locObj.tag) { + instanceName.value = name; + } + }) + .catch((e) => { + console.error(e); + }); + if (props.grouphint) { groupName.value = props.grouphint; } else if (locObj.groupId) { groupName.value = locObj.groupId; getGroupName(locObj.groupId) .then((name) => { - groupName.value = name; + if (name && props.locationobject.tag === locObj.tag) { + groupName.value = name; + } }) - .catch((error) => { - console.error('Failed to get group name:', error); - groupName.value = ''; + .catch((e) => { + console.error(e); }); } else { groupName.value = ''; diff --git a/src/components/dialogs/NewInstanceDialog.vue b/src/components/dialogs/NewInstanceDialog.vue index 77c32e93..e23d22ce 100644 --- a/src/components/dialogs/NewInstanceDialog.vue +++ b/src/components/dialogs/NewInstanceDialog.vue @@ -84,14 +84,14 @@ " @change="buildInstance"> - + diff --git a/src/service/request.js b/src/service/request.js index 5b200b8c..3b61c4bb 100644 --- a/src/service/request.js +++ b/src/service/request.js @@ -290,6 +290,12 @@ export function $throw(code, error, endpoint) { ) { ignoreError = true; } + if ( + (code === 403 || code === 404 || code === -1) && + endpoint.startsWith('instances/') + ) { + ignoreError = true; + } if (endpoint.startsWith('analysis/')) { ignoreError = true; } diff --git a/src/shared/utils/instance.js b/src/shared/utils/instance.js index c599a15b..12d0ee2e 100644 --- a/src/shared/utils/instance.js +++ b/src/shared/utils/instance.js @@ -32,9 +32,11 @@ function isRealInstance(instanceId) { case 'private:private': case 'traveling': case 'traveling:traveling': - case instanceId.startsWith('local'): return false; } + if (instanceId.startsWith('local')) { + return false; + } return true; } diff --git a/src/stores/instance.js b/src/stores/instance.js index 10d2d10f..b29feacd 100644 --- a/src/stores/instance.js +++ b/src/stores/instance.js @@ -416,6 +416,21 @@ export const useInstanceStore = defineStore('Instance', () => { return ref; } + async function getInstanceName(location) { + let instanceName = ''; + + const L = parseLocation(location); + if (L.isRealInstance && L.worldId && L.instanceId) { + const args = await instanceRequest.getCachedInstance({ + worldId: L.worldId, + instanceId: L.instanceId + }); + instanceName = args.ref.displayName; + } + + return instanceName; + } + /** * * @param {string} worldId @@ -1229,6 +1244,7 @@ export const useInstanceStore = defineStore('Instance', () => { showPreviousInstancesInfoDialog, addInstanceJoinHistory, getCurrentInstanceUserList, - getInstanceJoinHistory + getInstanceJoinHistory, + getInstanceName }; }); diff --git a/src/stores/vrcx.js b/src/stores/vrcx.js index 7ca7e236..df15a8bb 100644 --- a/src/stores/vrcx.js +++ b/src/stores/vrcx.js @@ -316,6 +316,11 @@ export const useVrcxStore = defineStore('Vrcx', () => { } }); instanceStore.cachedInstances.forEach((ref, id) => { + if ( + friendStore.friends.values().some((f) => f.$location.tag === id) + ) { + return; + } // delete instances over an hour old if (Date.parse(ref.$fetchedAt) < Date.now() - 3600000) { instanceStore.cachedInstances.delete(id);