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