diff --git a/html/src/app.js b/html/src/app.js
index 2b0e34aa..a86d2955 100644
--- a/html/src/app.js
+++ b/html/src/app.js
@@ -7085,7 +7085,7 @@ speechSynthesis.getVoices();
}
// delayed second check to prevent status flapping
var date = this.updateFriendInProgress.get(id);
- if (date && date > Date.now() - 120000) {
+ if (date && date > Date.now() - this.pendingOfflineDelay + 5000) {
// check if already waiting
if (this.debugFriendState) {
console.log(
@@ -7111,7 +7111,7 @@ speechSynthesis.getVoices();
location,
$location_at
);
- }, 110000);
+ }, this.pendingOfflineDelay);
} else {
ctx.ref = ref;
ctx.isVIP = isVIP;
@@ -12247,6 +12247,16 @@ speechSynthesis.getVoices();
configRepository.getString('VRCX_avatarRemoteDatabaseProviderList')
);
}
+ $app.data.pendingOfflineDelay = configRepository.getInt(
+ 'VRCX_pendingOfflineDelay'
+ );
+ if (!configRepository.getInt('VRCX_pendingOfflineDelay')) {
+ $app.data.pendingOfflineDelay = 110000;
+ configRepository.setInt(
+ 'VRCX_pendingOfflineDelay',
+ $app.data.pendingOfflineDelay
+ );
+ }
if (configRepository.getString('VRCX_avatarRemoteDatabaseProvider')) {
// move existing provider to new list
var avatarRemoteDatabaseProvider = configRepository.getString(
@@ -12536,7 +12546,7 @@ speechSynthesis.getVoices();
}
if (!configRepository.getInt('VRCX_maxTableSize')) {
$app.data.maxTableSize = 1000;
- configRepository.getInt('VRCX_maxTableSize', $app.data.maxTableSize);
+ configRepository.setInt('VRCX_maxTableSize', $app.data.maxTableSize);
database.setmaxTableSize($app.data.maxTableSize);
}
if (!configRepository.getString('VRCX_photonLobbyTimeoutThreshold')) {
@@ -21888,6 +21898,38 @@ speechSynthesis.getVoices();
$app.getLocalWorldFavorites();
});
+ // pending offline timer
+
+ $app.methods.promptSetPendingOffline = function () {
+ this.$prompt(
+ 'Set pending offline delay in seconds (default: 110)',
+ 'Pending Offline',
+ {
+ distinguishCancelAndClose: true,
+ confirmButtonText: 'Save',
+ cancelButtonText: 'Cancel',
+ inputValue: this.pendingOfflineDelay,
+ inputPattern: /\d+$/,
+ inputErrorMessage: 'Valid number is required',
+ callback: (action, instance) => {
+ if (
+ action === 'confirm' &&
+ instance.inputValue &&
+ !isNaN(instance.inputValue)
+ ) {
+ this.pendingOfflineDelay = Math.trunc(
+ Number(instance.inputValue) * 1000
+ );
+ configRepository.setInt(
+ 'VRCX_pendingOfflineDelay',
+ this.pendingOfflineDelay
+ );
+ }
+ }
+ }
+ );
+ };
+
$app = new Vue($app);
window.$app = $app;
})();
diff --git a/html/src/index.pug b/html/src/index.pug
index 285ddcce..a169c6d0 100644
--- a/html/src/index.pug
+++ b/html/src/index.pug
@@ -1301,6 +1301,11 @@ html
el-button(size="small" icon="el-icon-s-operation" @click="showVRChatConfig()") VRChat config.json
el-button(size="small" icon="el-icon-s-operation" @click="showLaunchOptions()") Launch Options
div.options-container
+ span.sub-header Pending Offline
+ div.options-container-item
+ span.name Delay before marking user as offline (fixes false positives)
+ el-button-group(style="display:block")
+ el-button(size="small" icon="el-icon-s-operation" @click="promptSetPendingOffline") Set Delay
span.sub-header Primary password
div.options-container-item
span.name(style="min-width:300px") Encrypt password (disables auto login)