mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-04-14 12:23:52 +02:00
Close Instance
This commit is contained in:
@@ -740,7 +740,7 @@ namespace VRCX
|
||||
listener?.Stop();
|
||||
listener?.Close();
|
||||
}
|
||||
catch (ObjectDisposedException ex)
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
// ignore
|
||||
}
|
||||
|
||||
124
html/src/app.js
124
html/src/app.js
@@ -1081,6 +1081,7 @@ speechSynthesis.getVoices();
|
||||
'<div style="display:inline-block;margin-left:5px">' +
|
||||
'<el-tooltip v-if="isValidInstance" placement="bottom">' +
|
||||
'<div slot="content">' +
|
||||
'<el-button :disabled="!canCloseInstance || isClosed || isHardClosed" size="mini" type="primary" @click="$app.closeInstance(location)">{{ $t("dialog.user.info.close_instance") }}</el-button></br></br>' +
|
||||
'<span><span style="color:#409eff">PC: </span>{{ platforms.standalonewindows }}</span></br>' +
|
||||
'<span><span style="color:#67c23a">Android: </span>{{ platforms.android }}</span></br>' +
|
||||
'<span>{{ $t("dialog.user.info.instance_game_version") }} {{ gameServerVersion }}</span></br>' +
|
||||
@@ -1093,6 +1094,8 @@ speechSynthesis.getVoices();
|
||||
'<span v-if="occupants" style="margin-left:5px">{{ occupants }}/{{ capacity }}</span>' +
|
||||
'<span v-if="friendcount" style="margin-left:5px">({{ friendcount }})</span>' +
|
||||
'<span v-if="isFull" style="margin-left:5px;color:lightcoral">{{ $t("dialog.user.info.instance_full") }}</span>' +
|
||||
'<span v-if="isClosed" style="margin-left:5px;color:lightcoral">{{ $t("dialog.user.info.instance_closed") }}</span>' +
|
||||
'<span v-if="isHardClosed" style="margin-left:5px;color:lightcoral">{{ $t("dialog.user.info.instance_hard_closed") }}</span>' +
|
||||
'<span v-if="queueSize" style="margin-left:5px">{{ $t("dialog.user.info.instance_queue") }} {{ queueSize }}</span>' +
|
||||
'</div>',
|
||||
props: {
|
||||
@@ -1105,19 +1108,24 @@ speechSynthesis.getVoices();
|
||||
return {
|
||||
isValidInstance: this.isValidInstance,
|
||||
isFull: this.isFull,
|
||||
isClosed: this.isClosed,
|
||||
isHardClosed: this.isHardClosed,
|
||||
occupants: this.occupants,
|
||||
capacity: this.capacity,
|
||||
queueSize: this.queueSize,
|
||||
queueEnabled: this.queueEnabled,
|
||||
platforms: this.platforms,
|
||||
userList: this.userList,
|
||||
gameServerVersion: this.gameServerVersion
|
||||
gameServerVersion: this.gameServerVersion,
|
||||
canCloseInstance: this.canCloseInstance
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
parse() {
|
||||
this.isValidInstance = false;
|
||||
this.isFull = false;
|
||||
this.isClosed = false;
|
||||
this.isHardClosed = false;
|
||||
this.occupants = 0;
|
||||
this.capacity = 0;
|
||||
this.queueSize = 0;
|
||||
@@ -1125,6 +1133,7 @@ speechSynthesis.getVoices();
|
||||
this.platforms = [];
|
||||
this.userList = [];
|
||||
this.gameServerVersion = '';
|
||||
this.canCloseInstance = false;
|
||||
if (
|
||||
!this.location ||
|
||||
!this.instance ||
|
||||
@@ -1136,6 +1145,13 @@ speechSynthesis.getVoices();
|
||||
this.isFull =
|
||||
typeof this.instance.hasCapacityForYou !== 'undefined' &&
|
||||
!this.instance.hasCapacityForYou;
|
||||
if (this.instance.closedAt) {
|
||||
if (this.instance.hardClose) {
|
||||
this.isHardClosed = true;
|
||||
} else {
|
||||
this.isClosed = true;
|
||||
}
|
||||
}
|
||||
this.occupants = this.instance.n_users;
|
||||
if (this.location === $app.lastLocation.location) {
|
||||
// use gameLog for occupants when in same location
|
||||
@@ -1150,6 +1166,18 @@ speechSynthesis.getVoices();
|
||||
if (this.instance.users) {
|
||||
this.userList = this.instance.users;
|
||||
}
|
||||
if (this.instance.ownerId === API.currentUser.id) {
|
||||
this.canCloseInstance = true;
|
||||
}
|
||||
if (this.instance.ownerId.startsWith('grp_')) {
|
||||
// check group perms
|
||||
var groupId = this.instance.ownerId;
|
||||
var group = API.cachedGroups.get(groupId);
|
||||
this.canCloseInstance = $app.hasGroupPermission(
|
||||
group,
|
||||
'group-instance-moderate'
|
||||
);
|
||||
}
|
||||
},
|
||||
showUserDialog(userId) {
|
||||
API.$emit('SHOW_USER_DIALOG', userId);
|
||||
@@ -2604,6 +2632,8 @@ speechSynthesis.getVoices();
|
||||
queueSize: 0, // only present when queuing is enabled
|
||||
platforms: [],
|
||||
gameServerVersion: 0,
|
||||
hardClose: null, // boolean or null
|
||||
closedAt: null, // string or null
|
||||
secureName: '',
|
||||
shortName: '',
|
||||
world: {},
|
||||
@@ -4998,6 +5028,20 @@ speechSynthesis.getVoices();
|
||||
}
|
||||
break;
|
||||
|
||||
case 'instance-closed':
|
||||
// TODO: get worldName, groupName, hardClose
|
||||
var noty = {
|
||||
type: 'instance.closed',
|
||||
location: content.instanceLocation,
|
||||
message: 'Instance Closed',
|
||||
created_at: new Date().toJSON()
|
||||
};
|
||||
$app.notifyMenu('notification');
|
||||
$app.queueNotificationNoty(noty);
|
||||
$app.notificationTable.data.push(noty);
|
||||
$app.updateSharedFeed(true);
|
||||
break;
|
||||
|
||||
default:
|
||||
console.log('Unknown pipeline type', args.json);
|
||||
}
|
||||
@@ -6572,6 +6616,9 @@ speechSynthesis.getVoices();
|
||||
case 'group.queueReady':
|
||||
this.speak(noty.message);
|
||||
break;
|
||||
case 'instance.closed':
|
||||
this.speak(noty.message);
|
||||
break;
|
||||
case 'PortalSpawn':
|
||||
if (noty.displayName) {
|
||||
this.speak(
|
||||
@@ -6794,6 +6841,9 @@ speechSynthesis.getVoices();
|
||||
case 'group.queueReady':
|
||||
AppApi.XSNotification('VRCX', noty.message, timeout, image);
|
||||
break;
|
||||
case 'instance.closed':
|
||||
AppApi.XSNotification('VRCX', noty.message, timeout, image);
|
||||
break;
|
||||
case 'PortalSpawn':
|
||||
if (noty.displayName) {
|
||||
AppApi.XSNotification(
|
||||
@@ -7070,6 +7120,13 @@ speechSynthesis.getVoices();
|
||||
image
|
||||
);
|
||||
break;
|
||||
case 'instance.closed':
|
||||
AppApi.DesktopNotification(
|
||||
'Instance Closed',
|
||||
noty.message,
|
||||
image
|
||||
);
|
||||
break;
|
||||
case 'PortalSpawn':
|
||||
if (noty.displayName) {
|
||||
AppApi.DesktopNotification(
|
||||
@@ -14995,6 +15052,7 @@ speechSynthesis.getVoices();
|
||||
'group.invite': 'On',
|
||||
'group.joinRequest': 'Off',
|
||||
'group.queueReady': 'On',
|
||||
'instance.closed': 'On',
|
||||
PortalSpawn: 'Everyone',
|
||||
Event: 'On',
|
||||
External: 'On',
|
||||
@@ -15033,6 +15091,7 @@ speechSynthesis.getVoices();
|
||||
'group.invite': 'On',
|
||||
'group.joinRequest': 'On',
|
||||
'group.queueReady': 'On',
|
||||
'instance.closed': 'On',
|
||||
PortalSpawn: 'Everyone',
|
||||
Event: 'On',
|
||||
External: 'On',
|
||||
@@ -15082,6 +15141,10 @@ speechSynthesis.getVoices();
|
||||
$app.data.sharedFeedFilters.noty['group.queueReady'] = 'On';
|
||||
$app.data.sharedFeedFilters.wrist['group.queueReady'] = 'On';
|
||||
}
|
||||
if (!$app.data.sharedFeedFilters.noty['instance.closed']) {
|
||||
$app.data.sharedFeedFilters.noty['instance.closed'] = 'On';
|
||||
$app.data.sharedFeedFilters.wrist['instance.closed'] = 'On';
|
||||
}
|
||||
if (!$app.data.sharedFeedFilters.noty.External) {
|
||||
$app.data.sharedFeedFilters.noty.External = 'On';
|
||||
$app.data.sharedFeedFilters.wrist.External = 'On';
|
||||
@@ -27090,6 +27153,7 @@ speechSynthesis.getVoices();
|
||||
groupName,
|
||||
worldName
|
||||
};
|
||||
this.notifyMenu('notification');
|
||||
this.queueNotificationNoty(noty);
|
||||
this.notificationTable.data.push(noty);
|
||||
this.updateSharedFeed(true);
|
||||
@@ -29962,7 +30026,6 @@ speechSynthesis.getVoices();
|
||||
};
|
||||
|
||||
// #endregion
|
||||
|
||||
// #region | V-Bucks
|
||||
|
||||
API.$on('VBUCKS', function (args) {
|
||||
@@ -29985,6 +30048,63 @@ speechSynthesis.getVoices();
|
||||
API.getVbucks();
|
||||
};
|
||||
|
||||
// #endregion
|
||||
// #region | Close instance
|
||||
|
||||
$app.methods.closeInstance = function (location) {
|
||||
this.$confirm(
|
||||
'Continue? Close Instance, nobody will be able to join',
|
||||
'Confirm',
|
||||
{
|
||||
confirmButtonText: 'Confirm',
|
||||
cancelButtonText: 'Cancel',
|
||||
type: 'warning',
|
||||
callback: (action) => {
|
||||
if (action !== 'confirm') {
|
||||
return;
|
||||
}
|
||||
API.closeInstance({ location, hardClose: false });
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {{
|
||||
location: string,
|
||||
hardClose: boolean
|
||||
}} params
|
||||
* @returns {Promise<{json: any, params}>}
|
||||
*/
|
||||
API.closeInstance = function (params) {
|
||||
return this.call(`instances/${params.location}`, {
|
||||
method: 'DELETE',
|
||||
params: {
|
||||
hardClose: params.hardClose ?? false
|
||||
}
|
||||
}).then((json) => {
|
||||
var args = {
|
||||
json,
|
||||
params
|
||||
};
|
||||
this.$emit('INSTANCE:CLOSE', args);
|
||||
return args;
|
||||
});
|
||||
};
|
||||
|
||||
API.$on('INSTANCE:CLOSE', function (args) {
|
||||
if (args.json) {
|
||||
$app.$message({
|
||||
message: 'Instance closed',
|
||||
type: 'success'
|
||||
});
|
||||
|
||||
this.$emit('INSTANCE', {
|
||||
json: args.json
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// #endregion
|
||||
|
||||
$app = new Vue($app);
|
||||
|
||||
@@ -1858,6 +1858,11 @@ html
|
||||
el-radio-group(v-model="sharedFeedFilters.noty['group.queueReady']" size="mini" @change="saveSharedFeedFilters")
|
||||
el-radio-button(label="Off") {{ $t('dialog.shared_feed_filters.off') }}
|
||||
el-radio-button(label="On") {{ $t('dialog.shared_feed_filters.on') }}
|
||||
.toggle-item
|
||||
span.toggle-name Instance Closed
|
||||
el-radio-group(v-model="sharedFeedFilters.noty['instance.closed']" size="mini" @change="saveSharedFeedFilters")
|
||||
el-radio-button(label="Off") {{ $t('dialog.shared_feed_filters.off') }}
|
||||
el-radio-button(label="On") {{ $t('dialog.shared_feed_filters.on') }}
|
||||
.toggle-item
|
||||
span.toggle-name Portal Spawn
|
||||
el-radio-group(v-model="sharedFeedFilters.noty.PortalSpawn" size="mini" @change="saveSharedFeedFilters")
|
||||
@@ -2080,6 +2085,11 @@ html
|
||||
el-radio-group(v-model="sharedFeedFilters.wrist['group.queueReady']" size="mini" @change="saveSharedFeedFilters")
|
||||
el-radio-button(label="Off") {{ $t('dialog.shared_feed_filters.off') }}
|
||||
el-radio-button(label="On") {{ $t('dialog.shared_feed_filters.on') }}
|
||||
.toggle-item
|
||||
span.toggle-name Instance Closed
|
||||
el-radio-group(v-model="sharedFeedFilters.wrist['instance.closed']" size="mini" @change="saveSharedFeedFilters")
|
||||
el-radio-button(label="Off") {{ $t('dialog.shared_feed_filters.off') }}
|
||||
el-radio-button(label="On") {{ $t('dialog.shared_feed_filters.on') }}
|
||||
.toggle-item
|
||||
span.toggle-name Portal Spawn
|
||||
el-radio-group(v-model="sharedFeedFilters.wrist.PortalSpawn" size="mini" @change="saveSharedFeedFilters")
|
||||
|
||||
@@ -608,7 +608,10 @@
|
||||
"copy_url": "Copy URL",
|
||||
"copy_display_name": "Copy DisplayName",
|
||||
"accuracy_notice": "Info from local database may not be accurate",
|
||||
"instance_full": "full"
|
||||
"instance_full": "full",
|
||||
"instance_closed": "closed",
|
||||
"instance_hard_closed": "hard closed",
|
||||
"close_instance": "Close Instance"
|
||||
},
|
||||
"groups": {
|
||||
"header": "Groups",
|
||||
@@ -1570,7 +1573,7 @@
|
||||
"status": "Status",
|
||||
"language": "Language",
|
||||
"bioLink": "Bio Links",
|
||||
"joinCount": "Join Counts",
|
||||
"joinCount": "Join Count",
|
||||
"timeTogether": "Time Together",
|
||||
"lastSeen": "Last Seen",
|
||||
"lastActivity": "Last Activity",
|
||||
|
||||
@@ -4,7 +4,7 @@ mixin notificationsTab()
|
||||
template(#tool)
|
||||
div(style="margin:0 0 10px;display:flex;align-items:center")
|
||||
el-select(v-model="notificationTable.filters[0].value" @change="saveTableFilters" multiple clearable collapse-tags style="flex:1" :placeholder="$t('view.notification.filter_placeholder')")
|
||||
el-option(v-once v-for="type in ['requestInvite', 'invite', 'requestInviteResponse', 'inviteResponse', 'friendRequest', 'hiddenFriendRequest', 'message', 'group.announcement', 'group.informative', 'group.invite', 'group.joinRequest', 'group.queueReady', 'moderation.warning.group']" :key="type" :label="type" :value="type")
|
||||
el-option(v-once v-for="type in ['requestInvite', 'invite', 'requestInviteResponse', 'inviteResponse', 'friendRequest', 'hiddenFriendRequest', 'message', 'group.announcement', 'group.informative', 'group.invite', 'group.joinRequest', 'group.queueReady', 'moderation.warning.group', 'instance.closed']" :key="type" :label="type" :value="type")
|
||||
el-input(v-model="notificationTable.filters[1].value" :placeholder="$t('view.notification.search_placeholder')" style="flex:none;width:150px;margin:0 10px")
|
||||
el-tooltip(placement="bottom" :content="$t('view.notification.refresh_tooltip')" :disabled="hideTooltips")
|
||||
el-button(type="default" :loading="API.isNotificationsLoading" @click="API.refreshNotifications()" icon="el-icon-refresh" circle style="flex:none")
|
||||
@@ -20,7 +20,7 @@ mixin notificationsTab()
|
||||
template(#content)
|
||||
location(v-if="scope.row.details" :location="scope.row.details.worldId" :hint="scope.row.details.worldName" :grouphint="scope.row.details.groupName" :link="false")
|
||||
span.x-link(v-text="scope.row.type" @click="showWorldDialog(scope.row.details.worldId)")
|
||||
el-tooltip(v-else-if="scope.row.type === 'group.queueReady'" placement="top")
|
||||
el-tooltip(v-else-if="scope.row.type === 'group.queueReady' || scope.row.type === 'instance.closed'" placement="top")
|
||||
template(#content)
|
||||
location(v-if="scope.row.location" :location="scope.row.location" :hint="scope.row.worldName" :grouphint="scope.row.groupName" :link="false")
|
||||
span.x-link(v-text="scope.row.type" @click="showWorldDialog(scope.row.location)")
|
||||
@@ -85,7 +85,7 @@ mixin notificationsTab()
|
||||
template(v-else-if="scope.row.type === 'group.informative'")
|
||||
el-tooltip(placement="top" content="Dismiss" :disabled="hideTooltips")
|
||||
el-button(type="text" icon="el-icon-check" size="mini" style="margin-left:5px" @click="sendNotificationResponse(scope.row.id, scope.row.responses, 'delete')")
|
||||
template(v-if="scope.row.type !== 'requestInviteResponse' && scope.row.type !== 'inviteResponse' && scope.row.type !== 'message' && !scope.row.type.includes('group.') && !scope.row.type.includes('moderation.')")
|
||||
template(v-if="scope.row.type !== 'requestInviteResponse' && scope.row.type !== 'inviteResponse' && scope.row.type !== 'message' && !scope.row.type.includes('group.') && !scope.row.type.includes('moderation.') && !scope.row.type.includes('instance.')")
|
||||
el-tooltip(placement="top" content="Decline" :disabled="hideTooltips")
|
||||
el-button(type="text" icon="el-icon-close" size="mini" style="margin-left:5px" @click="hideNotification(scope.row)")
|
||||
template(v-if="scope.row.type === 'group.queueReady'")
|
||||
|
||||
@@ -454,10 +454,11 @@ Vue.component('marquee-text', MarqueeText);
|
||||
if (dev[0] === 'headset') return 0;
|
||||
if (dev[0] === 'leftController') return 1;
|
||||
if (dev[0] === 'rightController') return 2;
|
||||
if (dev[0].toLowerCase().includes('controller')) return 3;
|
||||
if (dev[0].toLowerCase().includes('controller'))
|
||||
return 3;
|
||||
if (dev[0] === 'tracker' || dev[0] === 'base') return 4;
|
||||
return 5;
|
||||
}
|
||||
};
|
||||
deviceList.sort((a, b) => deviceValue(a) - deviceValue(b));
|
||||
deviceList.sort((a, b) => {
|
||||
if (a[1] === b[1]) {
|
||||
@@ -487,7 +488,9 @@ Vue.component('marquee-text', MarqueeText);
|
||||
}
|
||||
if (this.config.pcUptimeOnFeed) {
|
||||
AppApiVr.GetUptime().then((uptime) => {
|
||||
this.pcUptime = timeToText(uptime);
|
||||
if (uptime) {
|
||||
this.pcUptime = timeToText(uptime);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.pcUptime = '';
|
||||
@@ -594,6 +597,9 @@ Vue.component('marquee-text', MarqueeText);
|
||||
case 'group.queueReady':
|
||||
text = noty.message;
|
||||
break;
|
||||
case 'instance.closed':
|
||||
text = noty.message;
|
||||
break;
|
||||
case 'PortalSpawn':
|
||||
if (noty.displayName) {
|
||||
text = `<strong>${
|
||||
|
||||
@@ -144,6 +144,11 @@ html
|
||||
span.extra
|
||||
span.time {{ feed.created_at | formatDate }}
|
||||
| 📨 #[span.name(v-text="feed.message")]
|
||||
div(v-else-if="feed.type === 'instance.closed'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }")
|
||||
.detail
|
||||
span.extra
|
||||
span.time {{ feed.created_at | formatDate }}
|
||||
| 📫 #[span.name(v-text="feed.message")]
|
||||
div(v-else-if="feed.type === 'PortalSpawn'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }")
|
||||
.detail
|
||||
span.extra
|
||||
@@ -354,6 +359,11 @@ html
|
||||
span.extra
|
||||
span.time {{ feed.created_at | formatDate }}
|
||||
| #[span.name(v-text="feed.message")]
|
||||
div(v-else-if="feed.type === 'instance.closed'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }")
|
||||
.detail
|
||||
span.extra
|
||||
span.time {{ feed.created_at | formatDate }}
|
||||
| #[span.name(v-text="feed.message")]
|
||||
div(v-else-if="feed.type === 'PortalSpawn'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }")
|
||||
.detail
|
||||
span.extra
|
||||
|
||||
Reference in New Issue
Block a user