diff --git a/html/src/app.js b/html/src/app.js
index 7a4916a0..0a0d2238 100644
--- a/html/src/app.js
+++ b/html/src/app.js
@@ -362,10 +362,12 @@ speechSynthesis.getVoices();
API.pendingGetRequests = new Map();
API.failedGetRequests = new Map();
+ API.endpointDomainVrchat = 'https://api.vrchat.cloud/api/1';
+ API.endpointDomain = 'https://api.vrchat.cloud/api/1';
API.call = function (endpoint, options) {
var init = {
- url: `https://api.vrchat.cloud/api/1/${endpoint}`,
+ url: `${API.endpointDomain}/${endpoint}`,
method: 'GET',
...options
};
@@ -998,10 +1000,6 @@ speechSynthesis.getVoices();
API.cachedUsers = new Map();
API.currentUser = {};
- API.$on('LOGOUT', function () {
- this.isLoggedIn = false;
- });
-
API.$on('USER:CURRENT', function (args) {
var {json} = args;
args.ref = this.applyCurrentUser(json);
@@ -1965,11 +1963,16 @@ speechSynthesis.getVoices();
API.refreshFriends = async function () {
this.isRefreshFriendsLoading = true;
- var onlineFriends = await this.refreshOnlineFriends();
- var offlineFriends = await this.refreshOfflineFriends();
- var friends = onlineFriends.concat(offlineFriends);
- this.isRefreshFriendsLoading = false;
- return friends;
+ try {
+ var onlineFriends = await this.refreshOnlineFriends();
+ var offlineFriends = await this.refreshOfflineFriends();
+ var friends = onlineFriends.concat(offlineFriends);
+ this.isRefreshFriendsLoading = false;
+ return friends;
+ } catch (err) {
+ this.isRefreshFriendsLoading = false;
+ throw err;
+ }
};
API.refreshOnlineFriends = async function () {
@@ -4146,6 +4149,7 @@ speechSynthesis.getVoices();
if (--this.nextFriendsRefresh <= 0) {
this.nextFriendsRefresh = 7200; // 1hour
API.refreshFriends();
+ this.updateStoredUser(API.currentUser);
if (this.isGameRunning) {
API.refreshPlayerModerations();
}
@@ -5798,12 +5802,15 @@ speechSynthesis.getVoices();
});
API.$on('LOGOUT', function () {
- new Noty({
- type: 'success',
- text: `See you again, ${escapeTag(
- this.currentUser.displayName
- )}!`
- }).show();
+ if (this.isLoggedIn) {
+ new Noty({
+ type: 'success',
+ text: `See you again, ${escapeTag(
+ this.currentUser.displayName
+ )}!`
+ }).show();
+ }
+ this.isLoggedIn = false;
});
API.$on('LOGIN', function (args) {
@@ -5816,10 +5823,6 @@ speechSynthesis.getVoices();
$app.$refs.menu.activeIndex = 'feed';
});
- API.$on('LOGIN', function (args) {
- $app.updateStoredUser(args.ref);
- });
-
API.$on('LOGOUT', function () {
$app.updateStoredUser(this.currentUser);
webApiService.clearCookies();
@@ -5849,8 +5852,7 @@ speechSynthesis.getVoices();
};
$app.data.enablePrimaryPassword = configRepository.getBool(
- 'enablePrimaryPassword',
- false
+ 'enablePrimaryPassword'
);
$app.data.enablePrimaryPasswordDialog = {
visible: false,
@@ -5969,6 +5971,11 @@ speechSynthesis.getVoices();
if (user.cookies) {
webApiService.setCookies(user.cookies);
}
+ if (loginParmas.endpoint) {
+ API.endpointDomain = loginParmas.endpoint;
+ } else {
+ API.endpointDomain = API.endpointDomainVrchat;
+ }
return new Promise((resolve, reject) => {
if (this.enablePrimaryPassword) {
API.logout();
@@ -5981,7 +5988,8 @@ speechSynthesis.getVoices();
.then(() => {
API.login({
username: loginParmas.username,
- password: loginParmas.password
+ password: loginParmas.password,
+ endpoint: loginParmas.endpoint
})
.catch(() => {
this.loginForm.loading = false;
@@ -6031,6 +6039,7 @@ speechSynthesis.getVoices();
loading: true,
username: '',
password: '',
+ endpoint: '',
saveCredentials: false,
savedCredentials:
configRepository.getString('lastUserLoggedIn') !== null
@@ -6057,6 +6066,11 @@ speechSynthesis.getVoices();
this.$refs.loginForm.validate((valid) => {
if (valid && !this.loginForm.loading) {
this.loginForm.loading = true;
+ if (this.loginForm.endpoint) {
+ API.endpointDomain = this.loginForm.endpoint;
+ } else {
+ API.endpointDomain = API.endpointDomainVrchat;
+ }
API.getConfig()
.catch((err) => {
this.loginForm.loading = false;
@@ -6101,6 +6115,9 @@ speechSynthesis.getVoices();
password:
this.loginForm
.password,
+ endpoint:
+ this.loginForm
+ .endpoint,
saveCredentials:
this.loginForm
.saveCredentials,
@@ -6110,6 +6127,8 @@ speechSynthesis.getVoices();
'';
this.loginForm.password =
'';
+ this.loginForm.endpoint =
+ '';
});
});
});
@@ -6122,6 +6141,7 @@ speechSynthesis.getVoices();
API.login({
username: this.loginForm.username,
password: this.loginForm.password,
+ endpoint: this.loginForm.endpoint,
saveCredentials: this.loginForm.saveCredentials
}).finally(() => {
this.loginForm.username = '';
@@ -7349,8 +7369,7 @@ speechSynthesis.getVoices();
}
};
- $app.data.robotUrl =
- 'https://api.vrchat.cloud/api/1/file/file_0e8c4e32-7444-44ea-ade4-313c010d4bae/1/file';
+ $app.data.robotUrl = `${API.endpointDomain}/file/file_0e8c4e32-7444-44ea-ade4-313c010d4bae/1/file`;
API.$on('USER:UPDATE', async function (args) {
var {ref, props} = args;
@@ -15040,7 +15059,7 @@ speechSynthesis.getVoices();
}
var userIcon = '';
if (fileId) {
- userIcon = `https://api.vrchat.cloud/api/1/file/${fileId}/1`;
+ userIcon = `${API.endpointDomain}/file/${fileId}/1`;
}
if (userIcon === API.currentUser.userIcon) {
return;
@@ -16396,7 +16415,7 @@ speechSynthesis.getVoices();
var {fileId, fileVersion} = args.params;
var parmas = {
id: $app.avatarImage.avatarId,
- imageUrl: `https://api.vrchat.cloud/api/1/file/${fileId}/${fileVersion}/file`
+ imageUrl: `${API.endpointDomain}/file/${fileId}/${fileVersion}/file`
};
this.setAvatarImage(parmas);
});
@@ -16730,7 +16749,7 @@ speechSynthesis.getVoices();
var {fileId, fileVersion} = args.params;
var parmas = {
id: $app.worldImage.worldId,
- imageUrl: `https://api.vrchat.cloud/api/1/file/${fileId}/${fileVersion}/file`
+ imageUrl: `${API.endpointDomain}/file/${fileId}/${fileVersion}/file`
};
this.setWorldImage(parmas);
});
@@ -16953,7 +16972,7 @@ speechSynthesis.getVoices();
this.changeAvatarImageDialogLoading = true;
var parmas = {
id: this.avatarDialog.id,
- imageUrl: `https://api.vrchat.cloud/api/1/file/${this.previousImagesTableFileId}/${image.version}/file`
+ imageUrl: `${API.endpointDomain}/file/${this.previousImagesTableFileId}/${image.version}/file`
};
API.setAvatarImage(parmas).finally(() => {
this.changeAvatarImageDialogLoading = false;
@@ -16991,7 +17010,7 @@ speechSynthesis.getVoices();
this.changeWorldImageDialogLoading = true;
var parmas = {
id: this.worldDialog.id,
- imageUrl: `https://api.vrchat.cloud/api/1/file/${this.previousImagesTableFileId}/${image.version}/file`
+ imageUrl: `${API.endpointDomain}/file/${this.previousImagesTableFileId}/${image.version}/file`
};
API.setWorldImage(parmas).finally(() => {
this.changeWorldImageDialogLoading = false;
@@ -17027,7 +17046,7 @@ speechSynthesis.getVoices();
$app.methods.compareCurrentImage = function (image) {
if (
- `https://api.vrchat.cloud/api/1/file/${this.previousImagesTableFileId}/${image.version}/file` ===
+ `${API.endpointDomain}/file/${this.previousImagesTableFileId}/${image.version}/file` ===
this.avatarDialog.ref.imageUrl
) {
return true;
@@ -18204,7 +18223,7 @@ speechSynthesis.getVoices();
}
var profilePicOverride = '';
if (fileId) {
- profilePicOverride = `https://api.vrchat.cloud/api/1/file/${fileId}/1`;
+ profilePicOverride = `${API.endpointDomain}/file/${fileId}/1`;
}
if (profilePicOverride === API.currentUser.profilePicOverride) {
return;
@@ -19025,6 +19044,17 @@ speechSynthesis.getVoices();
};
$app.methods.setDatetimeFormat();
+ $app.data.enableCustomEndpoint = configRepository.getBool(
+ 'VRCX_enableCustomEndpoint'
+ );
+ $app.methods.toggleCustomEndpoint = function () {
+ this.enableCustomEndpoint = !this.enableCustomEndpoint;
+ configRepository.setBool(
+ 'VRCX_enableCustomEndpoint',
+ this.enableCustomEndpoint
+ );
+ };
+
$app = new Vue($app);
window.$app = $app;
})();
diff --git a/html/src/index.pug b/html/src/index.pug
index f9eee155..130a86fe 100644
--- a/html/src/index.pug
+++ b/html/src/index.pug
@@ -26,14 +26,17 @@ html
.detail
span.name(v-text="user.user.displayName")
span.extra(v-text="user.user.username")
+ span.extra(v-text="user.loginParmas.endpoint")
el-button(type="default" @click="deleteSavedLogin(user.user.username)" size="mini" icon="el-icon-delete" circle)
div(style="margin:15px")
h2(style="font-weight:bold;text-align:center;margin:0") Login
el-form(ref="loginForm" :model="loginForm" :rules="loginForm.rules" @submit.native.prevent="login()")
el-form-item(label="Username or Email" prop="username" required)
el-input(v-model="loginForm.username" name="username" placeholder="Username or Email" clearable)
- el-form-item(label="Password" prop="password" required style="margin-top:5px")
+ el-form-item(label="Password" prop="password" required style="margin-top:10px")
el-input(type="password" v-model="loginForm.password" name="password" placeholder="Password" clearable show-password)
+ el-form-item(v-if="enableCustomEndpoint" label="Endpont" prop="endpoint" style="margin-top:10px")
+ el-input(v-model="loginForm.endpoint" name="endpoint" placeholder="Endpoint URL" clearable)
el-checkbox(v-model="loginForm.saveCredentials" style="margin-top:15px") Save Credentials
el-form-item(style="margin-top:15px")
el-button(native-type="submit" type="primary" :loading="loginForm.loading" style="width:100%") Login