mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-04-26 10:13:48 +02:00
refactor: dialogs (#1224)
* refactor: dialogs * fix: storeAvatarImage * FriendLog.vue * FriendLog.vue * FriendLog.vue * GameLog.vue * fix: next day button jumping to the wrong date * sync master * fix: launchGame * Notification.vue * Feed.vue * Search.vue * Profile.vue * PlayerList.vue * Login.vue * utils * update dialog * del gameLog.pug * fix * fix: group role cannot be displayed currently * fix: "Hide Friends in Same Instance" hides players in unrelated private instances (#1210) * fix * fix: "Hide Friends in Same Instance" does not work when "Split Favorite Friends" is enabled * fix Notification.vue message * fix: deleteFavoriteNoConfirm * fix: feed status style * fix: infinite loading when deleting note * fix: private players will not be hidden when 'Hide Friends in Same Instance', and 'Hide Friends in Same Instance' will not work when 'Split Favorite Friends'
This commit is contained in:
@@ -239,13 +239,12 @@ export default class extends baseClass {
|
||||
API.websocketDomain = API.websocketDomainVrchat;
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
this.loginForm.loading = true;
|
||||
if (this.enablePrimaryPassword) {
|
||||
this.checkPrimaryPassword(loginParmas)
|
||||
.then((pwd) => {
|
||||
this.loginForm.loading = true;
|
||||
return API.getConfig()
|
||||
.catch((err) => {
|
||||
this.loginForm.loading = false;
|
||||
reject(err);
|
||||
})
|
||||
.then(() => {
|
||||
@@ -257,12 +256,10 @@ export default class extends baseClass {
|
||||
websocket: loginParmas.websocket
|
||||
})
|
||||
.catch((err2) => {
|
||||
this.loginForm.loading = false;
|
||||
// API.logout();
|
||||
reject(err2);
|
||||
})
|
||||
.then(() => {
|
||||
this.loginForm.loading = false;
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
@@ -277,7 +274,6 @@ export default class extends baseClass {
|
||||
} else {
|
||||
API.getConfig()
|
||||
.catch((err) => {
|
||||
this.loginForm.loading = false;
|
||||
reject(err);
|
||||
})
|
||||
.then(() => {
|
||||
@@ -288,17 +284,15 @@ export default class extends baseClass {
|
||||
websocket: loginParmas.websocket
|
||||
})
|
||||
.catch((err2) => {
|
||||
this.loginForm.loading = false;
|
||||
API.logout();
|
||||
reject(err2);
|
||||
})
|
||||
.then(() => {
|
||||
this.loginForm.loading = false;
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}).finally(() => (this.loginForm.loading = false));
|
||||
},
|
||||
|
||||
async deleteSavedLogin(userId) {
|
||||
@@ -325,100 +319,90 @@ export default class extends baseClass {
|
||||
|
||||
async login() {
|
||||
await webApiService.clearCookies();
|
||||
this.$refs.loginForm.validate((valid) => {
|
||||
if (valid && !this.loginForm.loading) {
|
||||
this.loginForm.loading = true;
|
||||
if (this.loginForm.endpoint) {
|
||||
API.endpointDomain = this.loginForm.endpoint;
|
||||
API.websocketDomain = this.loginForm.websocket;
|
||||
} else {
|
||||
API.endpointDomain = API.endpointDomainVrchat;
|
||||
API.websocketDomain = API.websocketDomainVrchat;
|
||||
}
|
||||
API.getConfig()
|
||||
.catch((err) => {
|
||||
this.loginForm.loading = false;
|
||||
throw err;
|
||||
})
|
||||
.then((args) => {
|
||||
if (
|
||||
this.loginForm.saveCredentials &&
|
||||
this.enablePrimaryPassword
|
||||
) {
|
||||
$app.$prompt(
|
||||
$t('prompt.primary_password.description'),
|
||||
$t('prompt.primary_password.header'),
|
||||
{
|
||||
inputType: 'password',
|
||||
inputPattern: /[\s\S]{1,32}/
|
||||
}
|
||||
)
|
||||
.then(({ value }) => {
|
||||
let saveCredential =
|
||||
this.loginForm.savedCredentials[
|
||||
Object.keys(
|
||||
this.loginForm
|
||||
.savedCredentials
|
||||
)[0]
|
||||
];
|
||||
security
|
||||
.decrypt(
|
||||
saveCredential.loginParmas
|
||||
.password,
|
||||
value
|
||||
)
|
||||
.then(() => {
|
||||
security
|
||||
.encrypt(
|
||||
this.loginForm.password,
|
||||
value
|
||||
)
|
||||
.then((pwd) => {
|
||||
API.login({
|
||||
username:
|
||||
this.loginForm
|
||||
.username,
|
||||
password:
|
||||
this.loginForm
|
||||
.password,
|
||||
endpoint:
|
||||
this.loginForm
|
||||
.endpoint,
|
||||
websocket:
|
||||
this.loginForm
|
||||
.websocket,
|
||||
saveCredentials:
|
||||
this.loginForm
|
||||
.saveCredentials,
|
||||
cipher: pwd
|
||||
}).then(() => {
|
||||
this.$refs.loginForm.resetFields();
|
||||
});
|
||||
if (!this.loginForm.loading) {
|
||||
this.loginForm.loading = true;
|
||||
if (this.loginForm.endpoint) {
|
||||
API.endpointDomain = this.loginForm.endpoint;
|
||||
API.websocketDomain = this.loginForm.websocket;
|
||||
} else {
|
||||
API.endpointDomain = API.endpointDomainVrchat;
|
||||
API.websocketDomain = API.websocketDomainVrchat;
|
||||
}
|
||||
API.getConfig()
|
||||
.catch((err) => {
|
||||
this.loginForm.loading = false;
|
||||
throw err;
|
||||
})
|
||||
.then((args) => {
|
||||
if (
|
||||
this.loginForm.saveCredentials &&
|
||||
this.enablePrimaryPassword
|
||||
) {
|
||||
$app.$prompt(
|
||||
$t('prompt.primary_password.description'),
|
||||
$t('prompt.primary_password.header'),
|
||||
{
|
||||
inputType: 'password',
|
||||
inputPattern: /[\s\S]{1,32}/
|
||||
}
|
||||
)
|
||||
.then(({ value }) => {
|
||||
let saveCredential =
|
||||
this.loginForm.savedCredentials[
|
||||
Object.keys(
|
||||
this.loginForm.savedCredentials
|
||||
)[0]
|
||||
];
|
||||
security
|
||||
.decrypt(
|
||||
saveCredential.loginParmas.password,
|
||||
value
|
||||
)
|
||||
.then(() => {
|
||||
security
|
||||
.encrypt(
|
||||
this.loginForm.password,
|
||||
value
|
||||
)
|
||||
.then((pwd) => {
|
||||
API.login({
|
||||
username:
|
||||
this.loginForm
|
||||
.username,
|
||||
password:
|
||||
this.loginForm
|
||||
.password,
|
||||
endpoint:
|
||||
this.loginForm
|
||||
.endpoint,
|
||||
websocket:
|
||||
this.loginForm
|
||||
.websocket,
|
||||
saveCredentials:
|
||||
this.loginForm
|
||||
.saveCredentials,
|
||||
cipher: pwd
|
||||
});
|
||||
});
|
||||
})
|
||||
.finally(() => {
|
||||
this.loginForm.loading = false;
|
||||
});
|
||||
return args;
|
||||
}
|
||||
API.login({
|
||||
username: this.loginForm.username,
|
||||
password: this.loginForm.password,
|
||||
endpoint: this.loginForm.endpoint,
|
||||
websocket: this.loginForm.websocket,
|
||||
saveCredentials: this.loginForm.saveCredentials
|
||||
})
|
||||
.then(() => {
|
||||
this.$refs.loginForm.resetFields();
|
||||
});
|
||||
});
|
||||
})
|
||||
.finally(() => {
|
||||
this.loginForm.loading = false;
|
||||
});
|
||||
return args;
|
||||
}
|
||||
API.login({
|
||||
username: this.loginForm.username,
|
||||
password: this.loginForm.password,
|
||||
endpoint: this.loginForm.endpoint,
|
||||
websocket: this.loginForm.websocket,
|
||||
saveCredentials: this.loginForm.saveCredentials
|
||||
}).finally(() => {
|
||||
this.loginForm.loading = false;
|
||||
});
|
||||
}
|
||||
});
|
||||
return args;
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
logout() {
|
||||
|
||||
@@ -1,104 +0,0 @@
|
||||
import { baseClass, $app, API, $t, $utils } from './baseClass.js';
|
||||
import { notificationRequest } from '../api';
|
||||
|
||||
export default class extends baseClass {
|
||||
constructor(_app, _API, _t) {
|
||||
super(_app, _API, _t);
|
||||
}
|
||||
|
||||
init() {
|
||||
/**
|
||||
* @params {{
|
||||
userId: string,
|
||||
emojiId: string
|
||||
}} params
|
||||
* @returns {Promise<{json: any, params}>}
|
||||
*/
|
||||
API.sendBoop = function (params) {
|
||||
return this.call(`users/${params.userId}/boop`, {
|
||||
method: 'POST',
|
||||
params
|
||||
}).then((json) => {
|
||||
var args = {
|
||||
json,
|
||||
params
|
||||
};
|
||||
this.$emit('BOOP:SEND', args);
|
||||
return args;
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
_data = {
|
||||
sendBoopDialog: {
|
||||
visible: false,
|
||||
userId: '',
|
||||
fileId: ''
|
||||
}
|
||||
};
|
||||
|
||||
_methods = {
|
||||
sendBoop() {
|
||||
var D = this.sendBoopDialog;
|
||||
this.dismissBoop(D.userId);
|
||||
var params = {
|
||||
userId: D.userId
|
||||
};
|
||||
if (D.fileId) {
|
||||
params.emojiId = D.fileId;
|
||||
}
|
||||
API.sendBoop(params);
|
||||
D.visible = false;
|
||||
},
|
||||
|
||||
dismissBoop(userId) {
|
||||
// JANK: This is a hack to remove boop notifications when responding
|
||||
var array = this.notificationTable.data;
|
||||
for (var i = array.length - 1; i >= 0; i--) {
|
||||
var ref = array[i];
|
||||
if (
|
||||
ref.type !== 'boop' ||
|
||||
ref.$isExpired ||
|
||||
ref.senderUserId !== userId
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
notificationRequest.sendNotificationResponse({
|
||||
notificationId: ref.id,
|
||||
responseType: 'delete',
|
||||
responseData: ''
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
showSendBoopDialog(userId) {
|
||||
this.$nextTick(() =>
|
||||
$app.adjustDialogZ(this.$refs.sendBoopDialog.$el)
|
||||
);
|
||||
var D = this.sendBoopDialog;
|
||||
D.userId = userId;
|
||||
D.visible = true;
|
||||
if (this.emojiTable.length === 0 && API.currentUser.$isVRCPlus) {
|
||||
this.refreshEmojiTable();
|
||||
}
|
||||
},
|
||||
|
||||
getEmojiValue(emojiName) {
|
||||
if (!emojiName) {
|
||||
return '';
|
||||
}
|
||||
return `vrchat_${emojiName.replace(/ /g, '_').toLowerCase()}`;
|
||||
},
|
||||
|
||||
getEmojiName(emojiValue) {
|
||||
// uppercase first letter of each word
|
||||
if (!emojiValue) {
|
||||
return '';
|
||||
}
|
||||
return emojiValue
|
||||
.replace('vrchat_', '')
|
||||
.replace(/_/g, ' ')
|
||||
.replace(/\b\w/g, (l) => l.toUpperCase());
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
import { baseClass, $app, API, $t, $utils } from './baseClass.js';
|
||||
import { isRealInstance, parseLocation } from '../composables/instance/utils';
|
||||
import { $app, API, baseClass } from './baseClass.js';
|
||||
|
||||
export default class extends baseClass {
|
||||
constructor(_app, _API, _t) {
|
||||
@@ -83,8 +84,8 @@ export default class extends baseClass {
|
||||
args.ref = this.applyCurrentUser(json);
|
||||
|
||||
// when isGameRunning use gameLog instead of API
|
||||
var $location = $app.parseLocation($app.lastLocation.location);
|
||||
var $travelingLocation = $app.parseLocation(
|
||||
var $location = parseLocation($app.lastLocation.location);
|
||||
var $travelingLocation = parseLocation(
|
||||
$app.lastLocationDestination
|
||||
);
|
||||
var location = $app.lastLocation.location;
|
||||
@@ -94,12 +95,12 @@ export default class extends baseClass {
|
||||
var travelingToWorld = $travelingLocation.worldId;
|
||||
var travelingToInstance = $travelingLocation.instanceId;
|
||||
if (!$app.isGameRunning && json.presence) {
|
||||
if ($utils.isRealInstance(json.presence.world)) {
|
||||
if (isRealInstance(json.presence.world)) {
|
||||
location = `${json.presence.world}:${json.presence.instance}`;
|
||||
} else {
|
||||
location = json.presence.world;
|
||||
}
|
||||
if ($utils.isRealInstance(json.presence.travelingToWorld)) {
|
||||
if (isRealInstance(json.presence.travelingToWorld)) {
|
||||
travelingToLocation = `${json.presence.travelingToWorld}:${json.presence.travelingToInstance}`;
|
||||
} else {
|
||||
travelingToLocation = json.presence.travelingToWorld;
|
||||
@@ -175,7 +176,7 @@ export default class extends baseClass {
|
||||
}
|
||||
Object.assign(ref, json);
|
||||
if (ref.homeLocation !== ref.$homeLocation.tag) {
|
||||
ref.$homeLocation = $app.parseLocation(ref.homeLocation);
|
||||
ref.$homeLocation = parseLocation(ref.homeLocation);
|
||||
// apply home location name to user dialog
|
||||
if (
|
||||
$app.userDialog.visible &&
|
||||
@@ -295,13 +296,12 @@ export default class extends baseClass {
|
||||
$languages: [],
|
||||
$locationTag: '',
|
||||
$travelingToLocation: '',
|
||||
$vrchatcredits: null,
|
||||
...json
|
||||
};
|
||||
if ($app.isGameRunning) {
|
||||
ref.$previousAvatarSwapTime = Date.now();
|
||||
}
|
||||
ref.$homeLocation = $app.parseLocation(ref.homeLocation);
|
||||
ref.$homeLocation = parseLocation(ref.homeLocation);
|
||||
ref.$isVRCPlus = ref.tags.includes('system_supporter');
|
||||
this.applyUserTrustLevel(ref);
|
||||
this.applyUserLanguage(ref);
|
||||
@@ -316,32 +316,6 @@ export default class extends baseClass {
|
||||
}
|
||||
return ref;
|
||||
};
|
||||
|
||||
/**
|
||||
* @typedef {{
|
||||
* status: 'active' | 'offline' | 'busy' | 'ask me' | 'join me',
|
||||
* statusDescription: string
|
||||
* }} SaveCurrentUserParameters
|
||||
*/
|
||||
|
||||
/**
|
||||
* Updates current user's status.
|
||||
* @param params {SaveCurrentUserParameters} new status to be set
|
||||
* @returns {Promise<{json: any, params}>}
|
||||
*/
|
||||
API.saveCurrentUser = function (params) {
|
||||
return this.call(`users/${this.currentUser.id}`, {
|
||||
method: 'PUT',
|
||||
params
|
||||
}).then((json) => {
|
||||
var args = {
|
||||
json,
|
||||
params
|
||||
};
|
||||
this.$emit('USER:CURRENT:SAVE', args);
|
||||
return args;
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
_data = {};
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import configRepository from '../service/config.js';
|
||||
import { baseClass, $app, API, $t, $utils } from './baseClass.js';
|
||||
import { worldRequest } from '../api';
|
||||
import { parseLocation } from '../composables/instance/utils';
|
||||
import { getLaunchURL } from '../composables/shared/utils';
|
||||
import configRepository from '../service/config.js';
|
||||
import { API, baseClass } from './baseClass.js';
|
||||
|
||||
export default class extends baseClass {
|
||||
constructor(_app, _API, _t) {
|
||||
@@ -36,7 +38,7 @@ export default class extends baseClass {
|
||||
var L = this.lastLocation$;
|
||||
if (currentLocation !== this.lastLocation$.tag) {
|
||||
Discord.SetTimestamps(timeStamp, 0);
|
||||
L = $app.parseLocation(currentLocation);
|
||||
L = parseLocation(currentLocation);
|
||||
L.worldName = '';
|
||||
L.thumbnailImageUrl = '';
|
||||
L.worldCapacity = 0;
|
||||
@@ -76,7 +78,7 @@ export default class extends baseClass {
|
||||
}
|
||||
switch (L.accessType) {
|
||||
case 'public':
|
||||
L.joinUrl = $utils.getLaunchURL(L);
|
||||
L.joinUrl = getLaunchURL(L);
|
||||
L.accessName = `Public #${L.instanceName} (${platform})`;
|
||||
break;
|
||||
case 'invite+':
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import * as workerTimers from 'worker-timers';
|
||||
import { parseLocation } from '../composables/instance/utils';
|
||||
import gameLogService from '../service/gamelog.js';
|
||||
import configRepository from '../service/config.js';
|
||||
import database from '../service/database.js';
|
||||
import { baseClass, $app, API, $t, $utils } from './baseClass.js';
|
||||
import { baseClass, $app, API, $utils } from './baseClass.js';
|
||||
import { userRequest } from '../api';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
@@ -80,7 +81,7 @@ export default class extends baseClass {
|
||||
this.lastLocation.location,
|
||||
gameLog.dt
|
||||
);
|
||||
var worldName = this.replaceBioSymbols(gameLog.worldName);
|
||||
var worldName = $utils.replaceBioSymbols(gameLog.worldName);
|
||||
if (this.isGameRunning) {
|
||||
this.lastLocationReset(gameLog.dt);
|
||||
this.clearNowPlaying();
|
||||
@@ -100,7 +101,7 @@ export default class extends baseClass {
|
||||
this.applyGroupDialogInstances();
|
||||
}
|
||||
this.addInstanceJoinHistory(gameLog.location, gameLog.dt);
|
||||
var L = $utils.parseLocation(gameLog.location);
|
||||
var L = parseLocation(gameLog.location);
|
||||
var entry = {
|
||||
created_at: gameLog.dt,
|
||||
type: 'Location',
|
||||
@@ -789,7 +790,7 @@ export default class extends baseClass {
|
||||
var videoPos = Number(data[1]);
|
||||
var videoLength = Number(data[2]);
|
||||
var displayName = data[3];
|
||||
var videoName = this.replaceBioSymbols(data[4]);
|
||||
var videoName = $utils.replaceBioSymbols(data[4]);
|
||||
var videoUrl = videoName;
|
||||
var videoId = 'LSMedia';
|
||||
if (videoUrl === this.nowPlaying.url) {
|
||||
@@ -981,29 +982,6 @@ export default class extends baseClass {
|
||||
this.addGameLogEntry(gameLog, this.lastLocation.location);
|
||||
},
|
||||
|
||||
deleteGameLogEntryPrompt(row) {
|
||||
this.$confirm('Continue? Delete Log', 'Confirm', {
|
||||
confirmButtonText: 'Confirm',
|
||||
cancelButtonText: 'Cancel',
|
||||
type: 'info',
|
||||
callback: (action) => {
|
||||
if (action === 'confirm') {
|
||||
this.deleteGameLogEntry(row);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
deleteGameLogEntry(row) {
|
||||
$app.removeFromArray(this.gameLogTable.data, row);
|
||||
database.deleteGameLogEntry(row);
|
||||
console.log(row);
|
||||
database.getGamelogDatabase().then((data) => {
|
||||
this.gameLogSessionTable = data;
|
||||
this.updateSharedFeed(true);
|
||||
});
|
||||
},
|
||||
|
||||
gameLogSearch(row) {
|
||||
var value = this.gameLogTable.search.toUpperCase();
|
||||
if (!value) {
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
import * as workerTimers from 'worker-timers';
|
||||
import { displayLocation, parseLocation } from '../composables/instance/utils';
|
||||
import { checkVRChatCache } from '../composables/shared/utils';
|
||||
import configRepository from '../service/config.js';
|
||||
import database from '../service/database.js';
|
||||
import { baseClass, $app, API, $t, $utils } from './baseClass.js';
|
||||
import { baseClass, $app, API, $utils } from './baseClass.js';
|
||||
import { instanceRequest, userRequest } from '../api';
|
||||
import {
|
||||
photonEmojis,
|
||||
photonEventType
|
||||
} from '../composables/shared/constants/photon.js';
|
||||
|
||||
export default class extends baseClass {
|
||||
constructor(_app, _API, _t) {
|
||||
@@ -80,111 +86,6 @@ export default class extends baseClass {
|
||||
}
|
||||
},
|
||||
|
||||
photonEventType: [
|
||||
'MeshVisibility',
|
||||
'AnimationFloat',
|
||||
'AnimationBool',
|
||||
'AnimationTrigger',
|
||||
'AudioTrigger',
|
||||
'PlayAnimation',
|
||||
'SendMessage',
|
||||
'SetParticlePlaying',
|
||||
'TeleportPlayer',
|
||||
'RunConsoleCommand',
|
||||
'SetGameObjectActive',
|
||||
'SetWebPanelURI',
|
||||
'SetWebPanelVolume',
|
||||
'SpawnObject',
|
||||
'SendRPC',
|
||||
'ActivateCustomTrigger',
|
||||
'DestroyObject',
|
||||
'SetLayer',
|
||||
'SetMaterial',
|
||||
'AddHealth',
|
||||
'AddDamage',
|
||||
'SetComponentActive',
|
||||
'AnimationInt',
|
||||
'AnimationIntAdd',
|
||||
'AnimationIntSubtract',
|
||||
'AnimationIntMultiply',
|
||||
'AnimationIntDivide',
|
||||
'AddVelocity',
|
||||
'SetVelocity',
|
||||
'AddAngularVelocity',
|
||||
'SetAngularVelocity',
|
||||
'AddForce',
|
||||
'SetUIText',
|
||||
'CallUdonMethod'
|
||||
],
|
||||
|
||||
photonEmojis: [
|
||||
'Angry',
|
||||
'Blushing',
|
||||
'Crying',
|
||||
'Frown',
|
||||
'Hand Wave',
|
||||
'Hang Ten',
|
||||
'In Love',
|
||||
'Jack O Lantern',
|
||||
'Kiss',
|
||||
'Laugh',
|
||||
'Skull',
|
||||
'Smile',
|
||||
'Spooky Ghost',
|
||||
'Stoic',
|
||||
'Sunglasses',
|
||||
'Thinking',
|
||||
'Thumbs Down',
|
||||
'Thumbs Up',
|
||||
'Tongue Out',
|
||||
'Wow',
|
||||
'Arrow Point',
|
||||
"Can't see",
|
||||
'Hourglass',
|
||||
'Keyboard',
|
||||
'No Headphones',
|
||||
'No Mic',
|
||||
'Portal',
|
||||
'Shush',
|
||||
'Bats',
|
||||
'Cloud',
|
||||
'Fire',
|
||||
'Snow Fall',
|
||||
'Snowball',
|
||||
'Splash',
|
||||
'Web',
|
||||
'Beer',
|
||||
'Candy',
|
||||
'Candy Cane',
|
||||
'Candy Corn',
|
||||
'Champagne',
|
||||
'Drink',
|
||||
'Gingerbread',
|
||||
'Ice Cream',
|
||||
'Pineapple',
|
||||
'Pizza',
|
||||
'Tomato',
|
||||
'Beachball',
|
||||
'Coal',
|
||||
'Confetti',
|
||||
'Gift',
|
||||
'Gifts',
|
||||
'Life Ring',
|
||||
'Mistletoe',
|
||||
'Money',
|
||||
'Neon Shades',
|
||||
'Sun Lotion',
|
||||
'Boo',
|
||||
'Broken Heart',
|
||||
'Exclamation',
|
||||
'Go',
|
||||
'Heart',
|
||||
'Music Note',
|
||||
'Question',
|
||||
'Stop',
|
||||
'Zzz'
|
||||
],
|
||||
|
||||
photonEventTableFilter: '',
|
||||
photonEventTableTypeFilter: [],
|
||||
photonEventTableTypeOverlayFilter: [],
|
||||
@@ -894,7 +795,7 @@ export default class extends baseClass {
|
||||
var imageUrl = '';
|
||||
if (type === 0) {
|
||||
var emojiId = data.Parameters[245][2];
|
||||
emojiName = this.photonEmojis[emojiId];
|
||||
emojiName = photonEmojis[emojiId];
|
||||
} else if (type === 1) {
|
||||
emojiName = 'Custom';
|
||||
var fileId = data.Parameters[245][1];
|
||||
@@ -982,7 +883,7 @@ export default class extends baseClass {
|
||||
if (this.debugPhotonLogging) {
|
||||
var displayName = this.getDisplayNameFromPhotonId(senderId);
|
||||
var feed = `RPC ${displayName} ${
|
||||
this.photonEventType[eventData.EventType]
|
||||
photonEventType[eventData.EventType]
|
||||
}${eventName}`;
|
||||
console.log('VrcRpc:', feed);
|
||||
}
|
||||
@@ -1026,7 +927,7 @@ export default class extends baseClass {
|
||||
shortName
|
||||
});
|
||||
var location = instance.json.location;
|
||||
var L = $utils.parseLocation(location);
|
||||
var L = parseLocation(location);
|
||||
var groupName = '';
|
||||
if (L.groupId) {
|
||||
groupName = await this.getGroupName(L.groupId);
|
||||
@@ -1040,14 +941,14 @@ export default class extends baseClass {
|
||||
// if (shortName === newShortName) {
|
||||
// portalType = 'Unlocked';
|
||||
// }
|
||||
var displayLocation = this.displayLocation(
|
||||
var _displayLocation = displayLocation(
|
||||
location,
|
||||
worldName,
|
||||
groupName
|
||||
);
|
||||
this.addEntryPhotonEvent({
|
||||
photonId: this.getPhotonIdFromUserId(userId),
|
||||
text: `PortalSpawn to ${displayLocation}`,
|
||||
text: `PortalSpawn to ${_displayLocation}`,
|
||||
type: 'PortalSpawn',
|
||||
shortName,
|
||||
location,
|
||||
@@ -1210,10 +1111,10 @@ export default class extends baseClass {
|
||||
type: 'ChangeStatus',
|
||||
status: photonUser.status,
|
||||
previousStatus: ref.status,
|
||||
statusDescription: this.replaceBioSymbols(
|
||||
statusDescription: $utils.replaceBioSymbols(
|
||||
photonUser.statusDescription
|
||||
),
|
||||
previousStatusDescription: this.replaceBioSymbols(
|
||||
previousStatusDescription: $utils.replaceBioSymbols(
|
||||
ref.statusDescription
|
||||
),
|
||||
created_at: Date.parse(gameLogDate)
|
||||
@@ -1227,8 +1128,8 @@ export default class extends baseClass {
|
||||
return;
|
||||
}
|
||||
var avatar = user.avatarDict;
|
||||
avatar.name = this.replaceBioSymbols(avatar.name);
|
||||
avatar.description = this.replaceBioSymbols(avatar.description);
|
||||
avatar.name = $utils.replaceBioSymbols(avatar.name);
|
||||
avatar.description = $utils.replaceBioSymbols(avatar.description);
|
||||
var platform = '';
|
||||
if (user.last_platform === 'android') {
|
||||
platform = 'Android';
|
||||
@@ -1240,7 +1141,7 @@ export default class extends baseClass {
|
||||
platform = 'Desktop';
|
||||
}
|
||||
this.photonUserSusieCheck(photonId, user, gameLogDate);
|
||||
$utils.checkVRChatCache(avatar).then((cacheInfo) => {
|
||||
checkVRChatCache(avatar).then((cacheInfo) => {
|
||||
var inCache = false;
|
||||
if (cacheInfo.Item1 > 0) {
|
||||
inCache = true;
|
||||
@@ -1410,9 +1311,11 @@ export default class extends baseClass {
|
||||
oldAvatarId !== avatar.id &&
|
||||
photonId !== this.photonLobbyCurrentUser
|
||||
) {
|
||||
avatar.name = this.replaceBioSymbols(avatar.name);
|
||||
avatar.description = this.replaceBioSymbols(avatar.description);
|
||||
$utils.checkVRChatCache(avatar).then((cacheInfo) => {
|
||||
avatar.name = $utils.replaceBioSymbols(avatar.name);
|
||||
avatar.description = $utils.replaceBioSymbols(
|
||||
avatar.description
|
||||
);
|
||||
checkVRChatCache(avatar).then((cacheInfo) => {
|
||||
var inCache = false;
|
||||
if (cacheInfo.Item1 > 0) {
|
||||
inCache = true;
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
instanceRequest,
|
||||
groupRequest
|
||||
} from '../api';
|
||||
import $utils from './utils';
|
||||
|
||||
export default class extends baseClass {
|
||||
constructor(_app, _API, _t) {
|
||||
@@ -171,8 +172,8 @@ export default class extends baseClass {
|
||||
var D = $app.groupDialog;
|
||||
if (D.id === args.params.groupId) {
|
||||
for (var post of args.posts) {
|
||||
post.title = $app.replaceBioSymbols(post.title);
|
||||
post.text = $app.replaceBioSymbols(post.text);
|
||||
post.title = $utils.replaceBioSymbols(post.title);
|
||||
post.text = $utils.replaceBioSymbols(post.text);
|
||||
}
|
||||
if (args.posts.length > 0) {
|
||||
D.announcement = args.posts[0];
|
||||
@@ -189,8 +190,8 @@ export default class extends baseClass {
|
||||
}
|
||||
|
||||
var newPost = args.json;
|
||||
newPost.title = $app.replaceBioSymbols(newPost.title);
|
||||
newPost.text = $app.replaceBioSymbols(newPost.text);
|
||||
newPost.title = $utils.replaceBioSymbols(newPost.title);
|
||||
newPost.text = $utils.replaceBioSymbols(newPost.text);
|
||||
var hasPost = false;
|
||||
// update existing post
|
||||
for (var post of D.posts) {
|
||||
@@ -275,9 +276,9 @@ export default class extends baseClass {
|
||||
|
||||
API.applyGroup = function (json) {
|
||||
var ref = this.cachedGroups.get(json.id);
|
||||
json.rules = $app.replaceBioSymbols(json.rules);
|
||||
json.name = $app.replaceBioSymbols(json.name);
|
||||
json.description = $app.replaceBioSymbols(json.description);
|
||||
json.rules = $utils.replaceBioSymbols(json.rules);
|
||||
json.name = $utils.replaceBioSymbols(json.name);
|
||||
json.description = $utils.replaceBioSymbols(json.description);
|
||||
if (typeof ref === 'undefined') {
|
||||
ref = {
|
||||
id: '',
|
||||
@@ -912,9 +913,6 @@ export default class extends baseClass {
|
||||
case 'Unsubscribe To Announcements':
|
||||
this.setGroupSubscription(D.id, false);
|
||||
break;
|
||||
case 'Invite To Group':
|
||||
this.showInviteGroupDialog(D.id, '');
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1050,17 +1048,6 @@ export default class extends baseClass {
|
||||
this.userDialog.representedGroup = args.json;
|
||||
return args;
|
||||
});
|
||||
},
|
||||
|
||||
showInviteGroupDialog(groupId, userId) {
|
||||
const D = this.inviteGroupDialog;
|
||||
D.userIds = '';
|
||||
D.groups = [];
|
||||
D.groupId = groupId;
|
||||
D.groupName = groupId;
|
||||
D.userId = userId;
|
||||
D.userObject = {};
|
||||
D.visible = true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -24,85 +24,9 @@ export default class extends baseClass {
|
||||
}
|
||||
$app.languageDialog.languages = data;
|
||||
});
|
||||
|
||||
API.$on('LOGOUT', function () {
|
||||
$app.languageDialog.visible = false;
|
||||
});
|
||||
}
|
||||
|
||||
_data = {
|
||||
// vrchat to famfamfam language mappings
|
||||
languageMappings: {
|
||||
eng: 'us',
|
||||
kor: 'kr',
|
||||
rus: 'ru',
|
||||
spa: 'es',
|
||||
por: 'pt',
|
||||
zho: 'cn',
|
||||
deu: 'de',
|
||||
jpn: 'jp',
|
||||
fra: 'fr',
|
||||
swe: 'se',
|
||||
nld: 'nl',
|
||||
pol: 'pl',
|
||||
dan: 'dk',
|
||||
nor: 'no',
|
||||
ita: 'it',
|
||||
tha: 'th',
|
||||
fin: 'fi',
|
||||
hun: 'hu',
|
||||
ces: 'cz',
|
||||
tur: 'tr',
|
||||
ara: 'ae',
|
||||
ron: 'ro',
|
||||
vie: 'vn',
|
||||
ukr: 'ua',
|
||||
ase: 'us',
|
||||
bfi: 'gb',
|
||||
dse: 'nl',
|
||||
fsl: 'fr',
|
||||
jsl: 'jp',
|
||||
kvk: 'kr',
|
||||
|
||||
mlt: 'mt',
|
||||
ind: 'id',
|
||||
hrv: 'hr',
|
||||
heb: 'he',
|
||||
afr: 'af',
|
||||
ben: 'be',
|
||||
bul: 'bg',
|
||||
cmn: 'cn',
|
||||
cym: 'cy',
|
||||
ell: 'el',
|
||||
est: 'et',
|
||||
fil: 'ph',
|
||||
gla: 'gd',
|
||||
gle: 'ga',
|
||||
hin: 'hi',
|
||||
hmn: 'cn',
|
||||
hye: 'hy',
|
||||
isl: 'is',
|
||||
lav: 'lv',
|
||||
lit: 'lt',
|
||||
ltz: 'lb',
|
||||
mar: 'hi',
|
||||
mkd: 'mk',
|
||||
msa: 'my',
|
||||
sco: 'gd',
|
||||
slk: 'sk',
|
||||
slv: 'sl',
|
||||
tel: 'hi',
|
||||
mri: 'nz',
|
||||
wuu: 'cn',
|
||||
yue: 'cn',
|
||||
tws: 'cn',
|
||||
asf: 'au',
|
||||
nzs: 'nz',
|
||||
gsg: 'de',
|
||||
epo: 'eo',
|
||||
tok: 'tok'
|
||||
},
|
||||
|
||||
subsetOfLanguages: [],
|
||||
|
||||
languageDialog: {
|
||||
@@ -113,54 +37,5 @@ export default class extends baseClass {
|
||||
}
|
||||
};
|
||||
|
||||
_methods = {
|
||||
languageClass(language) {
|
||||
var style = {};
|
||||
var mapping = this.languageMappings[language];
|
||||
if (typeof mapping !== 'undefined') {
|
||||
style[mapping] = true;
|
||||
} else {
|
||||
style.unknown = true;
|
||||
}
|
||||
return style;
|
||||
},
|
||||
|
||||
addUserLanguage(language) {
|
||||
if (language !== String(language)) {
|
||||
return;
|
||||
}
|
||||
const D = this.languageDialog;
|
||||
D.loading = true;
|
||||
userRequest
|
||||
.addUserTags({
|
||||
tags: [`language_${language}`]
|
||||
})
|
||||
.finally(function () {
|
||||
D.loading = false;
|
||||
});
|
||||
},
|
||||
|
||||
removeUserLanguage(language) {
|
||||
if (language !== String(language)) {
|
||||
return;
|
||||
}
|
||||
const D = this.languageDialog;
|
||||
D.loading = true;
|
||||
userRequest
|
||||
.removeUserTags({
|
||||
tags: [`language_${language}`]
|
||||
})
|
||||
.finally(function () {
|
||||
D.loading = false;
|
||||
});
|
||||
},
|
||||
|
||||
showLanguageDialog() {
|
||||
this.$nextTick(() =>
|
||||
$app.adjustDialogZ(this.$refs.languageDialog.$el)
|
||||
);
|
||||
var D = this.languageDialog;
|
||||
D.visible = true;
|
||||
}
|
||||
};
|
||||
_methods = {};
|
||||
}
|
||||
|
||||
@@ -27,11 +27,6 @@ export default class extends baseClass {
|
||||
}
|
||||
},
|
||||
|
||||
onUserMemoChange() {
|
||||
var D = this.userDialog;
|
||||
this.saveUserMemo(D.id, D.memo);
|
||||
},
|
||||
|
||||
async getUserMemo(userId) {
|
||||
try {
|
||||
return await database.getUserMemo(userId);
|
||||
|
||||
@@ -132,139 +132,6 @@ export default class extends baseClass {
|
||||
);
|
||||
},
|
||||
|
||||
promptUserIdDialog() {
|
||||
this.$prompt(
|
||||
$t('prompt.direct_access_user_id.description'),
|
||||
$t('prompt.direct_access_user_id.header'),
|
||||
{
|
||||
distinguishCancelAndClose: true,
|
||||
confirmButtonText: $t('prompt.direct_access_user_id.ok'),
|
||||
cancelButtonText: $t('prompt.direct_access_user_id.cancel'),
|
||||
inputPattern: /\S+/,
|
||||
inputErrorMessage: $t(
|
||||
'prompt.direct_access_user_id.input_error'
|
||||
),
|
||||
callback: (action, instance) => {
|
||||
if (action === 'confirm' && instance.inputValue) {
|
||||
var testUrl = instance.inputValue.substring(0, 15);
|
||||
if (testUrl === 'https://vrchat.') {
|
||||
var userId = this.parseUserUrl(
|
||||
instance.inputValue
|
||||
);
|
||||
if (userId) {
|
||||
this.showUserDialog(userId);
|
||||
} else {
|
||||
this.$message({
|
||||
message: $t(
|
||||
'prompt.direct_access_user_id.message.error'
|
||||
),
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
} else {
|
||||
this.showUserDialog(instance.inputValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
promptUsernameDialog() {
|
||||
this.$prompt(
|
||||
$t('prompt.direct_access_username.description'),
|
||||
$t('prompt.direct_access_username.header'),
|
||||
{
|
||||
distinguishCancelAndClose: true,
|
||||
confirmButtonText: $t('prompt.direct_access_username.ok'),
|
||||
cancelButtonText: $t(
|
||||
'prompt.direct_access_username.cancel'
|
||||
),
|
||||
inputPattern: /\S+/,
|
||||
inputErrorMessage: $t(
|
||||
'prompt.direct_access_username.input_error'
|
||||
),
|
||||
callback: (action, instance) => {
|
||||
if (action === 'confirm' && instance.inputValue) {
|
||||
this.lookupUser({
|
||||
displayName: instance.inputValue
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
promptWorldDialog() {
|
||||
this.$prompt(
|
||||
$t('prompt.direct_access_world_id.description'),
|
||||
$t('prompt.direct_access_world_id.header'),
|
||||
{
|
||||
distinguishCancelAndClose: true,
|
||||
confirmButtonText: $t('prompt.direct_access_world_id.ok'),
|
||||
cancelButtonText: $t(
|
||||
'prompt.direct_access_world_id.cancel'
|
||||
),
|
||||
inputPattern: /\S+/,
|
||||
inputErrorMessage: $t(
|
||||
'prompt.direct_access_world_id.input_error'
|
||||
),
|
||||
callback: (action, instance) => {
|
||||
if (action === 'confirm' && instance.inputValue) {
|
||||
if (!this.directAccessWorld(instance.inputValue)) {
|
||||
this.$message({
|
||||
message: $t(
|
||||
'prompt.direct_access_world_id.message.error'
|
||||
),
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
promptAvatarDialog() {
|
||||
this.$prompt(
|
||||
$t('prompt.direct_access_avatar_id.description'),
|
||||
$t('prompt.direct_access_avatar_id.header'),
|
||||
{
|
||||
distinguishCancelAndClose: true,
|
||||
confirmButtonText: $t('prompt.direct_access_avatar_id.ok'),
|
||||
cancelButtonText: $t(
|
||||
'prompt.direct_access_avatar_id.cancel'
|
||||
),
|
||||
inputPattern: /\S+/,
|
||||
inputErrorMessage: $t(
|
||||
'prompt.direct_access_avatar_id.input_error'
|
||||
),
|
||||
callback: (action, instance) => {
|
||||
if (action === 'confirm' && instance.inputValue) {
|
||||
var testUrl = instance.inputValue.substring(0, 15);
|
||||
if (testUrl === 'https://vrchat.') {
|
||||
var avatarId = this.parseAvatarUrl(
|
||||
instance.inputValue
|
||||
);
|
||||
if (avatarId) {
|
||||
this.showAvatarDialog(avatarId);
|
||||
} else {
|
||||
this.$message({
|
||||
message: $t(
|
||||
'prompt.direct_access_avatar_id.message.error'
|
||||
),
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
} else {
|
||||
this.showAvatarDialog(instance.inputValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
promptOmniDirectDialog() {
|
||||
this.$prompt(
|
||||
$t('prompt.direct_access_omni.description'),
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import Vue from 'vue';
|
||||
import VueMarkdown from 'vue-markdown';
|
||||
import { baseClass, $app, API, $t, $utils } from './baseClass.js';
|
||||
import { instanceRequest, userRequest } from '../api';
|
||||
import utils from './utils';
|
||||
import { hasGroupPermission } from '../composables/group/utils';
|
||||
import { parseLocation } from '../composables/instance/utils';
|
||||
import { $app, $t, API, baseClass } from './baseClass.js';
|
||||
|
||||
export default class extends baseClass {
|
||||
constructor(_app, _API, _t) {
|
||||
@@ -60,7 +61,7 @@ export default class extends baseClass {
|
||||
this.selfInvite(this.location, this.shortname);
|
||||
},
|
||||
selfInvite(location, shortName) {
|
||||
const L = utils.parseLocation(location);
|
||||
const L = parseLocation(location);
|
||||
if (!L.isRealInstance) {
|
||||
return;
|
||||
}
|
||||
@@ -165,7 +166,7 @@ export default class extends baseClass {
|
||||
if (!this.location) {
|
||||
return;
|
||||
}
|
||||
var L = $utils.parseLocation(this.location);
|
||||
var L = parseLocation(this.location);
|
||||
if (!L.groupId) {
|
||||
return;
|
||||
}
|
||||
@@ -320,7 +321,7 @@ export default class extends baseClass {
|
||||
// check group perms
|
||||
var groupId = this.instance.ownerId;
|
||||
var group = API.cachedGroups.get(groupId);
|
||||
this.canCloseInstance = utils.hasGroupPermission(
|
||||
this.canCloseInstance = hasGroupPermission(
|
||||
group,
|
||||
'group-instance-moderate'
|
||||
);
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
import Noty from 'noty';
|
||||
|
||||
let echarts = null;
|
||||
|
||||
// messy here, organize later
|
||||
const _utils = {
|
||||
removeFromArray(array, item) {
|
||||
var { length } = array;
|
||||
@@ -14,7 +11,6 @@ const _utils = {
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
arraysMatch(a, b) {
|
||||
if (!Array.isArray(a) || !Array.isArray(b)) {
|
||||
return false;
|
||||
@@ -27,12 +23,10 @@ const _utils = {
|
||||
)
|
||||
);
|
||||
},
|
||||
|
||||
escapeTag(tag) {
|
||||
var s = String(tag);
|
||||
return s.replace(/["&'<>]/g, (c) => `&#${c.charCodeAt(0)};`);
|
||||
},
|
||||
|
||||
escapeTagRecursive(obj) {
|
||||
if (typeof obj === 'string') {
|
||||
return this.escapeTag(obj);
|
||||
@@ -44,7 +38,6 @@ const _utils = {
|
||||
}
|
||||
return obj;
|
||||
},
|
||||
|
||||
timeToText(sec, isNeedSeconds = false) {
|
||||
let n = Number(sec);
|
||||
if (isNaN(n)) {
|
||||
@@ -72,7 +65,6 @@ const _utils = {
|
||||
}
|
||||
return arr.join(' ');
|
||||
},
|
||||
|
||||
textToHex(text) {
|
||||
var s = String(text);
|
||||
return s
|
||||
@@ -80,7 +72,6 @@ const _utils = {
|
||||
.map((c) => c.charCodeAt(0).toString(16))
|
||||
.join(' ');
|
||||
},
|
||||
|
||||
commaNumber(num) {
|
||||
if (!num) {
|
||||
return '0';
|
||||
@@ -88,182 +79,6 @@ const _utils = {
|
||||
var s = String(Number(num));
|
||||
return s.replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,');
|
||||
},
|
||||
|
||||
isRealInstance(instanceId) {
|
||||
if (!instanceId) {
|
||||
return false;
|
||||
}
|
||||
switch (instanceId) {
|
||||
case ':':
|
||||
case 'offline':
|
||||
case 'offline:offline':
|
||||
case 'private':
|
||||
case 'private:private':
|
||||
case 'traveling':
|
||||
case 'traveling:traveling':
|
||||
case instanceId.startsWith('local'):
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
parseLocation(tag) {
|
||||
var _tag = String(tag || '');
|
||||
var ctx = {
|
||||
tag: _tag,
|
||||
isOffline: false,
|
||||
isPrivate: false,
|
||||
isTraveling: false,
|
||||
isRealInstance: false,
|
||||
worldId: '',
|
||||
instanceId: '',
|
||||
instanceName: '',
|
||||
accessType: '',
|
||||
accessTypeName: '',
|
||||
region: '',
|
||||
shortName: '',
|
||||
userId: null,
|
||||
hiddenId: null,
|
||||
privateId: null,
|
||||
friendsId: null,
|
||||
groupId: null,
|
||||
groupAccessType: null,
|
||||
canRequestInvite: false,
|
||||
strict: false,
|
||||
ageGate: false
|
||||
};
|
||||
if (_tag === 'offline' || _tag === 'offline:offline') {
|
||||
ctx.isOffline = true;
|
||||
} else if (_tag === 'private' || _tag === 'private:private') {
|
||||
ctx.isPrivate = true;
|
||||
} else if (_tag === 'traveling' || _tag === 'traveling:traveling') {
|
||||
ctx.isTraveling = true;
|
||||
} else if (!_tag.startsWith('local')) {
|
||||
ctx.isRealInstance = true;
|
||||
var sep = _tag.indexOf(':');
|
||||
// technically not part of instance id, but might be there when coping id from url so why not support it
|
||||
var shortNameQualifier = '&shortName=';
|
||||
var shortNameIndex = _tag.indexOf(shortNameQualifier);
|
||||
if (shortNameIndex >= 0) {
|
||||
ctx.shortName = _tag.substr(
|
||||
shortNameIndex + shortNameQualifier.length
|
||||
);
|
||||
_tag = _tag.substr(0, shortNameIndex);
|
||||
}
|
||||
if (sep >= 0) {
|
||||
ctx.worldId = _tag.substr(0, sep);
|
||||
ctx.instanceId = _tag.substr(sep + 1);
|
||||
ctx.instanceId.split('~').forEach((s, i) => {
|
||||
if (i) {
|
||||
var A = s.indexOf('(');
|
||||
var Z = A >= 0 ? s.lastIndexOf(')') : -1;
|
||||
var key = Z >= 0 ? s.substr(0, A) : s;
|
||||
var value = A < Z ? s.substr(A + 1, Z - A - 1) : '';
|
||||
if (key === 'hidden') {
|
||||
ctx.hiddenId = value;
|
||||
} else if (key === 'private') {
|
||||
ctx.privateId = value;
|
||||
} else if (key === 'friends') {
|
||||
ctx.friendsId = value;
|
||||
} else if (key === 'canRequestInvite') {
|
||||
ctx.canRequestInvite = true;
|
||||
} else if (key === 'region') {
|
||||
ctx.region = value;
|
||||
} else if (key === 'group') {
|
||||
ctx.groupId = value;
|
||||
} else if (key === 'groupAccessType') {
|
||||
ctx.groupAccessType = value;
|
||||
} else if (key === 'strict') {
|
||||
ctx.strict = true;
|
||||
} else if (key === 'ageGate') {
|
||||
ctx.ageGate = true;
|
||||
}
|
||||
} else {
|
||||
ctx.instanceName = s;
|
||||
}
|
||||
});
|
||||
ctx.accessType = 'public';
|
||||
if (ctx.privateId !== null) {
|
||||
if (ctx.canRequestInvite) {
|
||||
// InvitePlus
|
||||
ctx.accessType = 'invite+';
|
||||
} else {
|
||||
// InviteOnly
|
||||
ctx.accessType = 'invite';
|
||||
}
|
||||
ctx.userId = ctx.privateId;
|
||||
} else if (ctx.friendsId !== null) {
|
||||
// FriendsOnly
|
||||
ctx.accessType = 'friends';
|
||||
ctx.userId = ctx.friendsId;
|
||||
} else if (ctx.hiddenId !== null) {
|
||||
// FriendsOfGuests
|
||||
ctx.accessType = 'friends+';
|
||||
ctx.userId = ctx.hiddenId;
|
||||
} else if (ctx.groupId !== null) {
|
||||
// Group
|
||||
ctx.accessType = 'group';
|
||||
}
|
||||
ctx.accessTypeName = ctx.accessType;
|
||||
if (ctx.groupAccessType !== null) {
|
||||
if (ctx.groupAccessType === 'public') {
|
||||
ctx.accessTypeName = 'groupPublic';
|
||||
} else if (ctx.groupAccessType === 'plus') {
|
||||
ctx.accessTypeName = 'groupPlus';
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ctx.worldId = _tag;
|
||||
}
|
||||
}
|
||||
return ctx;
|
||||
},
|
||||
|
||||
displayLocation(location, worldName, groupName) {
|
||||
var text = worldName;
|
||||
var L = this.parseLocation(location);
|
||||
if (L.isOffline) {
|
||||
text = 'Offline';
|
||||
} else if (L.isPrivate) {
|
||||
text = 'Private';
|
||||
} else if (L.isTraveling) {
|
||||
text = 'Traveling';
|
||||
} else if (L.worldId) {
|
||||
if (groupName) {
|
||||
text = `${worldName} ${L.accessTypeName}(${groupName})`;
|
||||
} else if (L.instanceId) {
|
||||
text = `${worldName} ${L.accessTypeName}`;
|
||||
}
|
||||
}
|
||||
return text;
|
||||
},
|
||||
|
||||
extractFileId(s) {
|
||||
var match = String(s).match(/file_[0-9A-Za-z-]+/);
|
||||
return match ? match[0] : '';
|
||||
},
|
||||
|
||||
extractFileVersion(s) {
|
||||
var match = /(?:\/file_[0-9A-Za-z-]+\/)([0-9]+)/gi.exec(s);
|
||||
return match ? match[1] : '';
|
||||
},
|
||||
|
||||
extractVariantVersion(url) {
|
||||
if (!url) {
|
||||
return '0';
|
||||
}
|
||||
try {
|
||||
const params = new URLSearchParams(new URL(url).search);
|
||||
const version = params.get('v');
|
||||
if (version) {
|
||||
return version;
|
||||
}
|
||||
return '0';
|
||||
} catch {
|
||||
return '0';
|
||||
}
|
||||
},
|
||||
|
||||
buildTreeData(json) {
|
||||
var node = [];
|
||||
for (var key in json) {
|
||||
@@ -325,8 +140,6 @@ const _utils = {
|
||||
});
|
||||
return node;
|
||||
},
|
||||
|
||||
// app.js 4900ln
|
||||
// descending
|
||||
compareByCreatedAt(a, b) {
|
||||
if (
|
||||
@@ -406,298 +219,69 @@ const _utils = {
|
||||
}
|
||||
return false;
|
||||
},
|
||||
convertFileUrlToImageUrl(url, resolution = 128) {
|
||||
if (!url) {
|
||||
compareByName(a, b) {
|
||||
if (typeof a.name !== 'string' || typeof b.name !== 'string') {
|
||||
return 0;
|
||||
}
|
||||
return a.name.localeCompare(b.name);
|
||||
},
|
||||
replaceBioSymbols(text) {
|
||||
if (!text) {
|
||||
return '';
|
||||
}
|
||||
/**
|
||||
* possible patterns?
|
||||
* /file/file_fileId/version
|
||||
* /file/file_fileId/version/
|
||||
* /file/file_fileId/version/file
|
||||
* /file/file_fileId/version/file/
|
||||
*/
|
||||
const pattern = /file\/file_([a-f0-9-]+)\/(\d+)(\/file)?\/?$/;
|
||||
const match = url.match(pattern);
|
||||
|
||||
if (match) {
|
||||
const fileId = match[1];
|
||||
const version = match[2];
|
||||
return `https://api.vrchat.cloud/api/1/image/file_${fileId}/${version}/${resolution}`;
|
||||
var symbolList = {
|
||||
'@': '@',
|
||||
'#': '#',
|
||||
$: '$',
|
||||
'%': '%',
|
||||
'&': '&',
|
||||
'=': '=',
|
||||
'+': '+',
|
||||
'/': '⁄',
|
||||
'\\': '\',
|
||||
';': ';',
|
||||
':': '˸',
|
||||
',': '‚',
|
||||
'?': '?',
|
||||
'!': 'ǃ',
|
||||
'"': '"',
|
||||
'<': '≺',
|
||||
'>': '≻',
|
||||
'.': '․',
|
||||
'^': '^',
|
||||
'{': '{',
|
||||
'}': '}',
|
||||
'[': '[',
|
||||
']': ']',
|
||||
'(': '(',
|
||||
')': ')',
|
||||
'|': '|',
|
||||
'*': '∗'
|
||||
};
|
||||
var newText = text;
|
||||
for (var key in symbolList) {
|
||||
var regex = new RegExp(symbolList[key], 'g');
|
||||
newText = newText.replace(regex, key);
|
||||
}
|
||||
// no match return origin url
|
||||
return url;
|
||||
return newText.replace(/ {1,}/g, ' ').trimRight();
|
||||
},
|
||||
replaceVrcPackageUrl(url) {
|
||||
if (!url) {
|
||||
return '';
|
||||
}
|
||||
return url.replace('https://api.vrchat.cloud/', 'https://vrchat.com/');
|
||||
},
|
||||
getLaunchURL(instance) {
|
||||
var L = instance;
|
||||
if (L.instanceId) {
|
||||
if (L.shortName) {
|
||||
return `https://vrchat.com/home/launch?worldId=${encodeURIComponent(
|
||||
L.worldId
|
||||
)}&instanceId=${encodeURIComponent(
|
||||
L.instanceId
|
||||
)}&shortName=${encodeURIComponent(L.shortName)}`;
|
||||
}
|
||||
return `https://vrchat.com/home/launch?worldId=${encodeURIComponent(
|
||||
L.worldId
|
||||
)}&instanceId=${encodeURIComponent(L.instanceId)}`;
|
||||
}
|
||||
return `https://vrchat.com/home/launch?worldId=${encodeURIComponent(
|
||||
L.worldId
|
||||
)}`;
|
||||
},
|
||||
getFaviconUrl(resource) {
|
||||
try {
|
||||
const url = new URL(resource);
|
||||
return `https://icons.duckduckgo.com/ip2/${url.host}.ico`;
|
||||
} catch (err) {
|
||||
return '';
|
||||
}
|
||||
},
|
||||
copyToClipboard(text) {
|
||||
navigator.clipboard
|
||||
.writeText(text)
|
||||
.then(() => {
|
||||
window.$app.$message({
|
||||
message: 'Copied successfully!',
|
||||
type: 'success'
|
||||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error('Copy failed:', err);
|
||||
this.$message.error('Copy failed!');
|
||||
});
|
||||
},
|
||||
hasGroupPermission(ref, permission) {
|
||||
// descending
|
||||
compareByUpdatedAt(a, b) {
|
||||
if (
|
||||
ref &&
|
||||
ref.myMember &&
|
||||
ref.myMember.permissions &&
|
||||
(ref.myMember.permissions.includes('*') ||
|
||||
ref.myMember.permissions.includes(permission))
|
||||
typeof a.updated_at !== 'string' ||
|
||||
typeof b.updated_at !== 'string'
|
||||
) {
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
compareUnityVersion(unitySortNumber) {
|
||||
if (!window.API.cachedConfig.sdkUnityVersion) {
|
||||
console.error('No cachedConfig.sdkUnityVersion');
|
||||
return false;
|
||||
var A = a.updated_at.toUpperCase();
|
||||
var B = b.updated_at.toUpperCase();
|
||||
if (A < B) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// 2022.3.6f1 2022 03 06 000
|
||||
// 2019.4.31f1 2019 04 31 000
|
||||
// 5.3.4p1 5 03 04 010
|
||||
// 2019.4.31f1c1 is a thing
|
||||
var array = API.cachedConfig.sdkUnityVersion.split('.');
|
||||
if (array.length < 3) {
|
||||
console.error('Invalid cachedConfig.sdkUnityVersion');
|
||||
return false;
|
||||
if (A > B) {
|
||||
return -1;
|
||||
}
|
||||
var currentUnityVersion = array[0];
|
||||
currentUnityVersion += array[1].padStart(2, '0');
|
||||
var indexFirstLetter = array[2].search(/[a-zA-Z]/);
|
||||
if (indexFirstLetter > -1) {
|
||||
currentUnityVersion += array[2]
|
||||
.substr(0, indexFirstLetter)
|
||||
.padStart(2, '0');
|
||||
currentUnityVersion += '0';
|
||||
var letter = array[2].substr(indexFirstLetter, 1);
|
||||
if (letter === 'p') {
|
||||
currentUnityVersion += '1';
|
||||
} else {
|
||||
// f
|
||||
currentUnityVersion += '0';
|
||||
}
|
||||
currentUnityVersion += '0';
|
||||
} else {
|
||||
// just in case
|
||||
currentUnityVersion += '000';
|
||||
}
|
||||
// just in case
|
||||
currentUnityVersion = currentUnityVersion.replace(/\D/g, '');
|
||||
|
||||
if (
|
||||
parseInt(unitySortNumber, 10) <= parseInt(currentUnityVersion, 10)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
async checkVRChatCache(ref) {
|
||||
if (!ref.unityPackages) {
|
||||
return { Item1: -1, Item2: false, Item3: '' };
|
||||
}
|
||||
var assetUrl = '';
|
||||
var variant = '';
|
||||
for (var i = ref.unityPackages.length - 1; i > -1; i--) {
|
||||
var unityPackage = ref.unityPackages[i];
|
||||
if (unityPackage.variant && unityPackage.variant !== 'security') {
|
||||
continue;
|
||||
}
|
||||
if (
|
||||
unityPackage.platform === 'standalonewindows' &&
|
||||
_utils.compareUnityVersion(unityPackage.unitySortNumber)
|
||||
) {
|
||||
assetUrl = unityPackage.assetUrl;
|
||||
if (unityPackage.variant !== 'standard') {
|
||||
variant = unityPackage.variant;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!assetUrl) {
|
||||
assetUrl = ref.assetUrl;
|
||||
}
|
||||
var id = _utils.extractFileId(assetUrl);
|
||||
var version = parseInt(_utils.extractFileVersion(assetUrl), 10);
|
||||
var variantVersion = parseInt(
|
||||
_utils.extractVariantVersion(assetUrl),
|
||||
10
|
||||
);
|
||||
if (!id || !version) {
|
||||
return { Item1: -1, Item2: false, Item3: '' };
|
||||
}
|
||||
|
||||
return AssetBundleManager.CheckVRChatCache(
|
||||
id,
|
||||
version,
|
||||
variant,
|
||||
variantVersion
|
||||
);
|
||||
},
|
||||
async deleteVRChatCache(ref) {
|
||||
var assetUrl = '';
|
||||
var variant = '';
|
||||
for (var i = ref.unityPackages.length - 1; i > -1; i--) {
|
||||
var unityPackage = ref.unityPackages[i];
|
||||
if (
|
||||
unityPackage.variant &&
|
||||
unityPackage.variant !== 'standard' &&
|
||||
unityPackage.variant !== 'security'
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
if (
|
||||
unityPackage.platform === 'standalonewindows' &&
|
||||
$utils.compareUnityVersion(unityPackage.unitySortNumber)
|
||||
) {
|
||||
assetUrl = unityPackage.assetUrl;
|
||||
if (unityPackage.variant !== 'standard') {
|
||||
variant = unityPackage.variant;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
var id = $utils.extractFileId(assetUrl);
|
||||
var version = parseInt($utils.extractFileVersion(assetUrl), 10);
|
||||
var variantVersion = parseInt(
|
||||
$utils.extractVariantVersion(assetUrl),
|
||||
10
|
||||
);
|
||||
await AssetBundleManager.DeleteCache(
|
||||
id,
|
||||
version,
|
||||
variant,
|
||||
variantVersion
|
||||
);
|
||||
},
|
||||
downloadAndSaveJson(fileName, data) {
|
||||
if (!fileName || !data) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
var link = document.createElement('a');
|
||||
link.setAttribute(
|
||||
'href',
|
||||
`data:application/json;charset=utf-8,${encodeURIComponent(
|
||||
JSON.stringify(data, null, 2)
|
||||
)}`
|
||||
);
|
||||
link.setAttribute('download', `${fileName}.json`);
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
} catch {
|
||||
new Noty({
|
||||
type: 'error',
|
||||
text: $app.escapeTag('Failed to download JSON.')
|
||||
}).show();
|
||||
}
|
||||
},
|
||||
getAvailablePlatforms(unityPackages) {
|
||||
var isPC = false;
|
||||
var isQuest = false;
|
||||
var isIos = false;
|
||||
if (typeof unityPackages === 'object') {
|
||||
for (var unityPackage of unityPackages) {
|
||||
if (
|
||||
unityPackage.variant &&
|
||||
unityPackage.variant !== 'standard' &&
|
||||
unityPackage.variant !== 'security'
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
if (unityPackage.platform === 'standalonewindows') {
|
||||
isPC = true;
|
||||
} else if (unityPackage.platform === 'android') {
|
||||
isQuest = true;
|
||||
} else if (unityPackage.platform === 'ios') {
|
||||
isIos = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return { isPC, isQuest, isIos };
|
||||
},
|
||||
getPlatformInfo(unityPackages) {
|
||||
var pc = {};
|
||||
var android = {};
|
||||
var ios = {};
|
||||
if (typeof unityPackages === 'object') {
|
||||
for (var unityPackage of unityPackages) {
|
||||
if (
|
||||
unityPackage.variant &&
|
||||
unityPackage.variant !== 'standard' &&
|
||||
unityPackage.variant !== 'security'
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
if (unityPackage.platform === 'standalonewindows') {
|
||||
if (
|
||||
unityPackage.performanceRating === 'None' &&
|
||||
pc.performanceRating
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
pc = unityPackage;
|
||||
} else if (unityPackage.platform === 'android') {
|
||||
if (
|
||||
unityPackage.performanceRating === 'None' &&
|
||||
android.performanceRating
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
android = unityPackage;
|
||||
} else if (unityPackage.platform === 'ios') {
|
||||
if (
|
||||
unityPackage.performanceRating === 'None' &&
|
||||
ios.performanceRating
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
ios = unityPackage;
|
||||
}
|
||||
}
|
||||
}
|
||||
return { pc, android, ios };
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { baseClass, $app, API, $t, $utils } from './baseClass.js';
|
||||
import { userRequest } from '../api';
|
||||
import { displayLocation } from '../composables/instance/utils';
|
||||
import { extractFileId, extractFileVersion } from '../composables/shared/utils';
|
||||
import { $app, API, baseClass } from './baseClass.js';
|
||||
|
||||
export default class extends baseClass {
|
||||
constructor(_app, _API, _t) {
|
||||
@@ -356,8 +358,8 @@ export default class extends baseClass {
|
||||
|
||||
async notySaveImage(noty) {
|
||||
var imageUrl = await this.notyGetImage(noty);
|
||||
var fileId = this.extractFileId(imageUrl);
|
||||
var fileVersion = this.extractFileVersion(imageUrl);
|
||||
var fileId = extractFileId(imageUrl);
|
||||
var fileVersion = extractFileVersion(imageUrl);
|
||||
var imageLocation = '';
|
||||
try {
|
||||
if (fileId && fileVersion) {
|
||||
@@ -414,7 +416,7 @@ export default class extends baseClass {
|
||||
break;
|
||||
case 'GPS':
|
||||
this.speak(
|
||||
`${displayName} is in ${this.displayLocation(
|
||||
`${displayName} is in ${displayLocation(
|
||||
noty.location,
|
||||
noty.worldName,
|
||||
noty.groupName
|
||||
@@ -424,7 +426,7 @@ export default class extends baseClass {
|
||||
case 'Online':
|
||||
var locationName = '';
|
||||
if (noty.worldName) {
|
||||
locationName = ` to ${this.displayLocation(
|
||||
locationName = ` to ${displayLocation(
|
||||
noty.location,
|
||||
noty.worldName,
|
||||
noty.groupName
|
||||
@@ -442,7 +444,7 @@ export default class extends baseClass {
|
||||
break;
|
||||
case 'invite':
|
||||
this.speak(
|
||||
`${displayName} has invited you to ${this.displayLocation(
|
||||
`${displayName} has invited you to ${displayLocation(
|
||||
noty.details.worldId,
|
||||
noty.details.worldName,
|
||||
noty.groupName
|
||||
@@ -513,7 +515,7 @@ export default class extends baseClass {
|
||||
case 'PortalSpawn':
|
||||
if (displayName) {
|
||||
this.speak(
|
||||
`${displayName} has spawned a portal to ${this.displayLocation(
|
||||
`${displayName} has spawned a portal to ${displayLocation(
|
||||
noty.instanceId,
|
||||
noty.worldName,
|
||||
noty.groupName
|
||||
@@ -599,7 +601,7 @@ export default class extends baseClass {
|
||||
case 'GPS':
|
||||
AppApi.XSNotification(
|
||||
'VRCX',
|
||||
`${noty.displayName} is in ${this.displayLocation(
|
||||
`${noty.displayName} is in ${displayLocation(
|
||||
noty.location,
|
||||
noty.worldName,
|
||||
noty.groupName
|
||||
@@ -611,7 +613,7 @@ export default class extends baseClass {
|
||||
case 'Online':
|
||||
var locationName = '';
|
||||
if (noty.worldName) {
|
||||
locationName = ` to ${this.displayLocation(
|
||||
locationName = ` to ${displayLocation(
|
||||
noty.location,
|
||||
noty.worldName,
|
||||
noty.groupName
|
||||
@@ -645,7 +647,7 @@ export default class extends baseClass {
|
||||
'VRCX',
|
||||
`${
|
||||
noty.senderUsername
|
||||
} has invited you to ${this.displayLocation(
|
||||
} has invited you to ${displayLocation(
|
||||
noty.details.worldId,
|
||||
noty.details.worldName
|
||||
)}${message}`,
|
||||
@@ -755,7 +757,7 @@ export default class extends baseClass {
|
||||
'VRCX',
|
||||
`${
|
||||
noty.displayName
|
||||
} has spawned a portal to ${this.displayLocation(
|
||||
} has spawned a portal to ${displayLocation(
|
||||
noty.instanceId,
|
||||
noty.worldName,
|
||||
noty.groupName
|
||||
@@ -915,7 +917,7 @@ export default class extends baseClass {
|
||||
playOvrtHudNotifications,
|
||||
playOvrtWristNotifications,
|
||||
'VRCX',
|
||||
`${noty.displayName} is in ${this.displayLocation(
|
||||
`${noty.displayName} is in ${displayLocation(
|
||||
noty.location,
|
||||
noty.worldName,
|
||||
noty.groupName
|
||||
@@ -927,7 +929,7 @@ export default class extends baseClass {
|
||||
case 'Online':
|
||||
var locationName = '';
|
||||
if (noty.worldName) {
|
||||
locationName = ` to ${this.displayLocation(
|
||||
locationName = ` to ${displayLocation(
|
||||
noty.location,
|
||||
noty.worldName,
|
||||
noty.groupName
|
||||
@@ -969,7 +971,7 @@ export default class extends baseClass {
|
||||
'VRCX',
|
||||
`${
|
||||
noty.senderUsername
|
||||
} has invited you to ${this.displayLocation(
|
||||
} has invited you to ${displayLocation(
|
||||
noty.details.worldId,
|
||||
noty.details.worldName
|
||||
)}${message}`,
|
||||
@@ -1155,7 +1157,7 @@ export default class extends baseClass {
|
||||
'VRCX',
|
||||
`${
|
||||
noty.displayName
|
||||
} has spawned a portal to ${this.displayLocation(
|
||||
} has spawned a portal to ${displayLocation(
|
||||
noty.instanceId,
|
||||
noty.worldName,
|
||||
noty.groupName
|
||||
@@ -1345,7 +1347,7 @@ export default class extends baseClass {
|
||||
case 'GPS':
|
||||
this.desktopNotification(
|
||||
noty.displayName,
|
||||
`is in ${this.displayLocation(
|
||||
`is in ${displayLocation(
|
||||
noty.location,
|
||||
noty.worldName,
|
||||
noty.groupName
|
||||
@@ -1356,7 +1358,7 @@ export default class extends baseClass {
|
||||
case 'Online':
|
||||
var locationName = '';
|
||||
if (noty.worldName) {
|
||||
locationName = ` to ${this.displayLocation(
|
||||
locationName = ` to ${displayLocation(
|
||||
noty.location,
|
||||
noty.worldName,
|
||||
noty.groupName
|
||||
@@ -1385,7 +1387,7 @@ export default class extends baseClass {
|
||||
case 'invite':
|
||||
this.desktopNotification(
|
||||
noty.senderUsername,
|
||||
`has invited you to ${this.displayLocation(
|
||||
`has invited you to ${displayLocation(
|
||||
noty.details.worldId,
|
||||
noty.details.worldName
|
||||
)}${message}`,
|
||||
@@ -1515,7 +1517,7 @@ export default class extends baseClass {
|
||||
if (noty.displayName) {
|
||||
this.desktopNotification(
|
||||
noty.displayName,
|
||||
`has spawned a portal to ${this.displayLocation(
|
||||
`has spawned a portal to ${displayLocation(
|
||||
noty.instanceId,
|
||||
noty.worldName,
|
||||
noty.groupName
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import * as workerTimers from 'worker-timers';
|
||||
import Noty from 'noty';
|
||||
import { parseLocation } from '../composables/instance/utils';
|
||||
import { baseClass, $app, API, $utils } from './baseClass.js';
|
||||
import { groupRequest } from '../api';
|
||||
|
||||
@@ -265,8 +266,8 @@ export default class extends baseClass {
|
||||
case 'friend-online':
|
||||
// Where is instanceId, travelingToWorld, travelingToInstance?
|
||||
// More JANK, what a mess
|
||||
var $location = $utils.parseLocation(content.location);
|
||||
var $travelingToLocation = $utils.parseLocation(
|
||||
var $location = parseLocation(content.location);
|
||||
var $travelingToLocation = parseLocation(
|
||||
content.travelingToLocation
|
||||
);
|
||||
if (content?.user?.id) {
|
||||
@@ -367,8 +368,8 @@ export default class extends baseClass {
|
||||
break;
|
||||
|
||||
case 'friend-location':
|
||||
var $location = $utils.parseLocation(content.location);
|
||||
var $travelingToLocation = $utils.parseLocation(
|
||||
var $location = parseLocation(content.location);
|
||||
var $travelingToLocation = parseLocation(
|
||||
content.travelingToLocation
|
||||
);
|
||||
if (!content?.user?.id) {
|
||||
|
||||
Reference in New Issue
Block a user