New instance for groups, small changes

This commit is contained in:
Natsumi
2023-06-07 01:04:27 +12:00
parent 7b63859de9
commit f674b61b73
9 changed files with 441 additions and 204 deletions

View File

@@ -494,7 +494,7 @@ namespace VRCX
public void ExecuteAppFunction(string function, string json)
{
if (MainForm.Instance?.Browser != null && !MainForm.Instance.Browser.IsLoading)
if (MainForm.Instance?.Browser != null && !MainForm.Instance.Browser.IsLoading && MainForm.Instance.Browser.CanExecuteJavascriptInMainFrame)
MainForm.Instance.Browser.ExecuteScriptAsync($"$app.{function}", json);
}

View File

@@ -4738,7 +4738,7 @@ speechSynthesis.getVoices();
break;
case 'group-member-updated':
var groupId = content.groupId;
var groupId = content.member.groupId;
$app.onGroupJoined(groupId);
console.log('group-member-updated', content);
@@ -4758,76 +4758,15 @@ speechSynthesis.getVoices();
case 'instance-queue-joined':
case 'instance-queue-position':
var instanceId = content.instanceLocation;
var ref = this.queuedInstances.get(instanceId);
if (typeof ref === 'undefined') {
ref = {
$msgBox: null,
$groupName: '',
$worldName: '',
location: instanceId,
position: 0,
queueSize: 0
};
}
if (content.position) {
ref.position = content.position;
}
if (content.queueSize) {
ref.queueSize = content.queueSize;
}
if (!ref.$msgBox) {
ref.$msgBox = $app.$message({
message: '',
type: 'info',
duration: 0,
showClose: true,
customClass: 'vrc-instance-queue-message'
});
}
if (!ref.$groupName) {
$app.getGroupName(instanceId).then((name) => {
ref.$groupName = name;
ref.$msgBox.message = `You are in position ${ref.position} of ${ref.queueSize} in the queue for ${name} `;
});
}
if (!ref.$worldName) {
$app.getWorldName(instanceId).then((name) => {
ref.$worldName = name;
});
}
ref.$msgBox.message = `You are in position ${ref.position} of ${ref.queueSize} in the queue for ${ref.$groupName} `;
API.queuedInstances.set(instanceId, ref);
var position = content.position ?? 0;
var queueSize = content.queueSize ?? 0;
$app.instanceQueueUpdate(instanceId, position, queueSize);
break;
case 'instance-queue-ready':
var instanceId = content.instanceLocation;
// var expiry = Date.parse(content.expiry);
var ref = this.queuedInstances.get(instanceId);
if (typeof ref !== 'undefined') {
ref.$msgBox.close();
this.queuedInstances.delete(instanceId);
}
var L = this.parseLocation(instanceId);
var group = this.cachedGroups.get(L.groupId);
var groupName = group?.name ? group.name : '';
var worldName = ref.$worldName ? ref.$worldName : '';
$app.$message({
message: `Instance ready to join ${groupName} - ${worldName}`,
type: 'success'
});
var noty = {
created_at: new Date().toJSON(),
type: 'group.queueReady',
imageUrl: group?.iconUrl,
message: `Instance ready to join ${groupName} - ${worldName}`,
location: instanceId,
groupName,
worldName
};
$app.queueNotificationNoty(noty);
$app.notificationTable.data.push(noty);
$app.updateSharedFeed(true);
$app.instanceQueueReady(instanceId);
break;
default:
@@ -5137,9 +5076,7 @@ speechSynthesis.getVoices();
isSteamVRRunning: false,
appVersion: '',
latestAppVersion: '',
ossDialog: false,
exportFriendsListDialog: false,
exportFriendsListContent: ''
ossDialog: false
},
i18n,
computed: {},
@@ -5358,6 +5295,7 @@ speechSynthesis.getVoices();
configRepository.setBool('isGameNoVR', this.isGameNoVR);
API.currentUser.$online_for = '';
API.currentUser.$offline_for = Date.now();
this.removeAllQueuedInstances();
this.autoVRChatCacheManagement();
this.checkIfGameCrashed();
this.ipcTimeout = 0;
@@ -5453,6 +5391,27 @@ speechSynthesis.getVoices();
wristFeed.unshift(feedEntry);
} else {
var worldRef = API.cachedWorlds.get(ref.$location.worldId);
var groupName = '';
if (ref.$location.groupId) {
var groupRef = API.cachedGroups.get(
ref.$location.groupId
);
if (typeof groupRef !== 'undefined') {
groupName = groupRef.name;
} else {
// no group cache, fetch group and try again
API.getGroup({
groupId: ref.$location.groupId
}).then((args) => {
workerTimers.setTimeout(() => {
// delay to allow for group cache to update
$app.sharedFeed.pendingUpdate = true;
$app.updateSharedFeed(false);
}, 100);
return args;
});
}
}
if (typeof worldRef !== 'undefined') {
var feedEntry = {
created_at: ref.created_at,
@@ -5461,6 +5420,7 @@ speechSynthesis.getVoices();
displayName: ref.displayName,
location: ref.$location.tag,
worldName: worldRef.name,
groupName,
previousLocation: '',
isFavorite,
time: 0,
@@ -7063,6 +7023,10 @@ speechSynthesis.getVoices();
this.promptEmailOTP();
};
$app.data.exportFriendsListDialog = false;
$app.data.exportFriendsListCsv = '';
$app.data.exportFriendsListJson = '';
$app.methods.showExportFriendsListDialog = function () {
var { friends } = API.currentUser;
if (Array.isArray(friends) === false) {
@@ -7075,6 +7039,7 @@ speechSynthesis.getVoices();
}
return str;
};
var friendsList = [];
for (var userId of friends) {
var ref = this.friends.get(userId);
var name = (typeof ref !== 'undefined' && ref.name) || '';
@@ -7082,13 +7047,19 @@ speechSynthesis.getVoices();
(typeof ref !== 'undefined' && ref.memo.replace(/\n/g, ' ')) ||
'';
lines.push(`${_(userId)},${_(name)},${_(memo)}`);
friendsList.push(userId);
}
this.exportFriendsListContent = lines.join('\n');
this.exportFriendsListJson = JSON.stringify(
{ friends: friendsList },
null,
4
);
this.exportFriendsListCsv = lines.join('\n');
this.exportFriendsListDialog = true;
};
$app.data.exportAvatarsListDialog = false;
$app.data.exportAvatarsListContent = '';
$app.data.exportAvatarsListCsv = '';
$app.methods.showExportAvatarsListDialog = function () {
for (var ref of API.cachedAvatars.values()) {
@@ -7132,7 +7103,7 @@ speechSynthesis.getVoices();
for (var avatar of avatars) {
lines.push(`${_(avatar.id)},${_(avatar.name)}`);
}
this.exportAvatarsListContent = lines.join('\n');
this.exportAvatarsListCsv = lines.join('\n');
this.exportAvatarsListDialog = true;
}
});
@@ -9609,6 +9580,7 @@ speechSynthesis.getVoices();
this.lastLocation.location = 'traveling';
this.lastLocationDestination = gameLog.location;
this.lastLocationDestinationTime = Date.parse(gameLog.dt);
this.removeQueuedInstance(gameLog.location);
this.updateCurrentUserLocation();
this.clearNowPlaying();
this.updateCurrentInstanceWorld();
@@ -9629,6 +9601,7 @@ speechSynthesis.getVoices();
playerList: new Map(),
friendList: new Map()
};
this.removeQueuedInstance(gameLog.location);
this.updateCurrentUserLocation();
this.updateVRLastLocation();
this.updateCurrentInstanceWorld();
@@ -10894,18 +10867,29 @@ speechSynthesis.getVoices();
) {
var instance = await API.getInstanceFromShortName({ shortName });
var location = instance.json.location;
var L = API.parseLocation(location);
var groupName = '';
if (L.groupId) {
groupName = await this.getGroupName(L.groupId);
}
// var newShortName = instance.json.shortName;
// var portalType = 'Secure';
// if (shortName === newShortName) {
// portalType = 'Unlocked';
// }
var displayLocation = this.displayLocation(
location,
worldName,
groupName
);
this.addEntryPhotonEvent({
photonId: this.getPhotonIdFromUserId(userId),
text: `PortalSpawn to ${worldName}`,
text: `PortalSpawn to ${displayLocation}`,
type: 'PortalSpawn',
shortName,
location,
worldName,
groupName,
created_at: gameLogDate
});
this.addPhotonEventToGameLog({
@@ -10915,7 +10899,8 @@ speechSynthesis.getVoices();
location: this.lastLocation.location,
userId,
instanceId: location,
worldName
worldName,
groupName
});
};
@@ -11137,6 +11122,8 @@ speechSynthesis.getVoices();
var platform = '';
if (user.last_platform === 'android') {
platform = 'Quest';
} else if (user.last_platform === 'ios') {
platform = 'iOS';
} else if (user.inVRMode) {
platform = 'VR';
} else {
@@ -13654,10 +13641,15 @@ speechSynthesis.getVoices();
'VRCX_vrBackgroundEnabled',
false
);
$app.data.asideWidth = configRepository.getInt('VRCX_asidewidth', 350);
if ($app.data.asideWidth === 236) {
$app.data.asideWidth = 350;
configRepository.setInt('VRCX_asidewidth', $app.data.asideWidth);
$app.data.asideWidth = configRepository.getInt('VRCX_sidePanelWidth', 300);
if (configRepository.getInt('VRCX_asidewidth')) {
// migrate to new defaults
$app.data.asideWidth = configRepository.getInt('VRCX_asidewidth');
if ($app.data.asideWidth < 300) {
$app.data.asideWidth = 300;
}
configRepository.setInt('VRCX_sidePanelWidth', $app.data.asideWidth);
configRepository.remove('VRCX_asidewidth');
}
$app.data.autoUpdateVRCX = configRepository.getString(
'VRCX_autoUpdateVRCX',
@@ -15938,8 +15930,9 @@ speechSynthesis.getVoices();
}
users.push({
ref,
displayName: ref.displayName,
timer: ref.$location_at,
$trustSortNum: ref.$trustSortNum ? ref.$trustSortNum : 0,
$trustSortNum: ref.$trustSortNum ?? 0,
photonId,
isMaster,
inVRMode,
@@ -18025,6 +18018,8 @@ speechSynthesis.getVoices();
$app.data.newInstanceDialog = {
visible: false,
loading: false,
instanceCreated: false,
queueEnabled: false,
worldId: '',
instanceId: '',
instanceName: '',
@@ -18037,7 +18032,10 @@ speechSynthesis.getVoices();
location: '',
shortName: '',
url: '',
secureOrShortName: ''
secureOrShortName: '',
lastSelectedGroupId: '',
selectedGroupRoles: [],
roleIds: []
};
API.$on('LOGOUT', function () {
@@ -18046,6 +18044,7 @@ speechSynthesis.getVoices();
$app.methods.buildInstance = function () {
var D = this.newInstanceDialog;
D.instanceCreated = false;
var tags = [];
if (D.instanceName) {
D.instanceName = D.instanceName.replace(/[^A-Za-z0-9-_]/g, '');
@@ -18091,8 +18090,69 @@ speechSynthesis.getVoices();
if (D.strict) {
tags.push('~strict');
}
if (D.groupId && D.groupId !== D.lastSelectedGroupId) {
D.roleIds = [];
var ref = API.cachedGroups.get(D.groupId);
if (typeof ref !== 'undefined') {
D.selectedGroupRoles = ref.roles;
API.getGroupRoles({
groupId: D.groupId
}).then((args) => {
D.lastSelectedGroupId = D.groupId;
D.selectedGroupRoles = args.json;
ref.roles = args.json;
});
}
}
if (!D.groupId) {
D.roleIds = [];
D.selectedGroupRoles = [];
D.lastSelectedGroupId = '';
}
D.instanceId = tags.join('');
this.updateNewInstanceDialog(false);
this.saveNewInstanceDialog();
};
$app.methods.createGroupInstance = function () {
var D = this.newInstanceDialog;
if (D.loading) {
return;
}
D.loading = true;
var region = 'us';
if (D.region === 'US East') {
region = 'use';
} else if (D.region === 'Europe') {
region = 'eu';
} else if (D.region === 'Japan') {
region = 'jp';
}
var roleIds = [];
if (D.groupAccessType === 'member') {
roleIds = D.roleIds;
}
API.createInstance({
type: 'group',
groupAccessType: D.groupAccessType,
worldId: D.worldId,
ownerId: D.groupId,
region,
queueEnabled: D.queueEnabled,
roleIds
})
.then((args) => {
D.location = args.json.location;
D.instanceId = args.json.instanceId;
D.secureOrShortName =
args.json.shortName || args.json.secureName;
D.instanceCreated = true;
this.updateNewInstanceDialog();
return args;
})
.finally(() => {
D.loading = false;
});
};
$app.methods.selfInvite = function (location, shortName) {
@@ -18137,7 +18197,7 @@ speechSynthesis.getVoices();
D.url = this.getLaunchURL(L);
};
var saveNewInstanceDialog = function () {
$app.methods.saveNewInstanceDialog = function () {
configRepository.setString(
'instanceDialogAccessType',
this.newInstanceDialog.accessType
@@ -18170,16 +18230,11 @@ speechSynthesis.getVoices();
'instanceDialogStrict',
this.newInstanceDialog.strict
);
$app.buildInstance();
configRepository.setBool(
'instanceDialogQueueEnabled',
this.newInstanceDialog.queueEnabled
);
};
$app.watch['newInstanceDialog.worldId'] =
$app.methods.updateNewInstanceDialog;
$app.watch['newInstanceDialog.instanceName'] = saveNewInstanceDialog;
$app.watch['newInstanceDialog.accessType'] = saveNewInstanceDialog;
$app.watch['newInstanceDialog.region'] = saveNewInstanceDialog;
$app.watch['newInstanceDialog.userId'] = saveNewInstanceDialog;
$app.watch['newInstanceDialog.groupId'] = saveNewInstanceDialog;
$app.watch['newInstanceDialog.strict'] = saveNewInstanceDialog;
$app.methods.showNewInstanceDialog = function (tag) {
if (!this.isRealInstance(tag)) {
@@ -18202,8 +18257,16 @@ speechSynthesis.getVoices();
D.groupId = configRepository.getString('instanceDialogGroupId', '');
D.groupAccessType = configRepository.getString(
'instanceDialogGroupAccessType',
'members'
'plus'
);
D.queueEnabled = configRepository.getBool(
'instanceDialogQueueEnabled',
true
);
D.instanceCreated = false;
D.lastSelectedGroupId = '';
D.selectedGroupRoles = [];
D.roleIds = [];
D.strict = false;
D.shortName = '';
this.buildInstance();
@@ -22176,7 +22239,7 @@ speechSynthesis.getVoices();
$app.methods.setAsideWidth = function () {
document.getElementById('aside').style.width = `${this.asideWidth}px`;
configRepository.setInt('VRCX_asidewidth', this.asideWidth);
configRepository.setInt('VRCX_sidePanelWidth', this.asideWidth);
};
// VRCX auto update
@@ -22509,7 +22572,11 @@ speechSynthesis.getVoices();
API.cachedAvatars.delete(id);
}
});
API.cachedGroups = new Map();
API.cachedGroups.forEach((ref, id) => {
if (!API.currentUserGroups.has(id)) {
API.cachedGroups.delete(id);
}
});
API.cachedAvatarNames = new Map();
};
@@ -24757,6 +24824,97 @@ speechSynthesis.getVoices();
API.currentUserGroups = new Map();
API.queuedInstances = new Map();
$app.methods.removeAllQueuedInstances = function () {
API.queuedInstances.forEach((ref) => {
ref.$msgBox?.close();
});
API.queuedInstances.clear();
};
$app.methods.removeQueuedInstance = function (instanceId) {
var ref = API.queuedInstances.get(instanceId);
if (typeof ref !== 'undefined') {
ref.$msgBox.close();
API.queuedInstances.delete(instanceId);
}
};
$app.methods.instanceQueueReady = function (instanceId) {
var ref = API.queuedInstances.get(instanceId);
if (typeof ref !== 'undefined') {
ref.$msgBox.close();
API.queuedInstances.delete(instanceId);
}
var L = API.parseLocation(instanceId);
var group = API.cachedGroups.get(L.groupId);
var groupName = group?.name ?? '';
var worldName = ref?.$worldName ?? '';
var displayLocation = $app.displayLocation(
instanceId,
worldName,
groupName
);
this.$message({
message: `Instance ready to join ${displayLocation}`,
type: 'success'
});
var noty = {
created_at: new Date().toJSON(),
type: 'group.queueReady',
imageUrl: group?.iconUrl,
message: `Instance ready to join ${displayLocation}`,
location: instanceId,
groupName,
worldName
};
this.queueNotificationNoty(noty);
this.notificationTable.data.push(noty);
this.updateSharedFeed(true);
};
$app.methods.instanceQueueUpdate = function (
instanceId,
position,
queueSize
) {
var ref = API.queuedInstances.get(instanceId);
if (typeof ref === 'undefined') {
ref = {
$msgBox: null,
$groupName: '',
$worldName: '',
location: instanceId,
position: 0,
queueSize: 0
};
}
ref.position = position;
ref.queueSize = queueSize;
if (!ref.$msgBox || ref.$msgBox.closed) {
ref.$msgBox = this.$message({
message: '',
type: 'info',
duration: 0,
showClose: true,
customClass: 'vrc-instance-queue-message'
});
}
if (!ref.$groupName) {
this.getGroupName(instanceId).then((name) => {
ref.$groupName = name;
ref.$msgBox.message = `You are in position ${ref.position} of ${ref.queueSize} in the queue for ${name} `;
});
}
if (!ref.$worldName) {
this.getWorldName(instanceId).then((name) => {
ref.$worldName = name;
});
}
ref.$msgBox.message = `You are in position ${ref.position} of ${ref.queueSize} in the queue for ${ref.$groupName} `;
API.queuedInstances.set(instanceId, ref);
};
/*
params: {
groupId: string
@@ -25707,6 +25865,9 @@ speechSynthesis.getVoices();
};
$app.methods.joinGroup = function (groupId) {
if (!groupId) {
return null;
}
return API.joinGroup({
groupId
}).then((args) => {

View File

@@ -706,12 +706,15 @@ i.x-user-status.busy {
top: 0 !important;
}
.vrc-instance-queue-message .el-message__content {
margin-right: 20px;
}
.el-tab-pane {
height: 100%;
}
.el-tabs {
// height: calc(100vh - 60px);
display: flex;
flex-direction: column;
}
@@ -719,5 +722,16 @@ i.x-user-status.busy {
.el-tabs__content {
flex: 1;
max-height: 100%;
overflow: auto;
overflow-y: auto;
}
.x-aside-container .el-tabs,
.x-aside-container .el-tabs__nav-wrap,
.x-aside-container .el-tabs__item {
padding: 0 !important;
font-size: 13px;
}
.x-aside-container .el-tabs__header {
padding: 0 1px;
}

View File

@@ -106,10 +106,10 @@ html
el-button(type="default" @click="directAccessPaste" size="mini" icon="el-icon-discover" circle)
el-tooltip(placement="bottom" :content="$t('side_panel.refresh_tooltip')" :disabled="hideTooltips")
el-button(type="default" @click="refreshFriendsList" :loading="API.isRefreshFriendsLoading" size="mini" icon="el-icon-refresh" circle style="margin-right:10px")
el-tabs(type="card" stretch="true" style="height: calc(100vh - 60px")
el-tabs(type="card" stretch="true" style="height:calc(100vh - 60px")
el-tab-pane
template(#label)
span {{ $t('side_panel.friends') }}: {{ onlineFriendCount }}/{{ friends.size }}
span {{ $t('side_panel.friends') }} ({{ onlineFriendCount }}/{{ friends.size }})
.x-friend-list(style="padding-bottom:10px")
.x-friend-group.x-link(@click="isFriendsGroupMe = !isFriendsGroupMe" style="padding:0px 0px 5px")
i.el-icon-arrow-right(:class="{ rotate: isFriendsGroupMe }")
@@ -185,10 +185,9 @@ html
template(v-else)
span(v-text="friend.name || friend.id")
el-button(type="text" icon="el-icon-close" size="mini" @click.stop="confirmDeleteFriend(friend.id)" style="margin-left:5px")
el-tab-pane
template(#label)
span {{ $t('side_panel.groups') }}: {{ groupInstances.length }}
span {{ $t('side_panel.groups') }} ({{ groupInstances.length }})
.x-friend-list(style="padding-bottom:10px")
.x-friend-item(v-for="instance in groupInstances" :key="instance.id" @click="showGroupDialog(instance.ownerId)")
.avatar
@@ -908,23 +907,7 @@ html
img.x-link(slot="reference" v-lazy="groupDialog.ref.bannerUrl" style="flex:none;width:100%;aspect-ratio:6/1;object-fit:cover;border-radius:4px")
img.x-link(v-lazy="groupDialog.ref.bannerUrl" style="width:854px;height:480px" @click="downloadAndSaveImage(groupDialog.ref.bannerUrl)")
.x-friend-list(style="max-height:none")
.x-friend-item(v-if="groupDialog.ref.membershipStatus === 'member'" style="width:100%;cursor:default")
.detail
span.name {{ $t('dialog.group.info.announcement') }}
span(style="display:block" v-text="groupDialog.announcement.title")
div(v-if="groupDialog.announcement.imageUrl" style="display:inline-block;margin-right:5px")
el-popover(placement="right" width="500px" trigger="click")
img.x-link(slot="reference" v-lazy="groupDialog.announcement.imageUrl" style="flex:none;width:60px;height:60px;border-radius:4px;object-fit:cover")
img.x-link(v-lazy="groupDialog.announcement.imageUrl" style="height:500px" @click="downloadAndSaveImage(groupDialog.announcement.imageUrl)")
pre.extra(style="display:inline-block;vertical-align:top;font-family:inherit;font-size:12px;white-space:pre-wrap;margin:0") {{ groupDialog.announcement.text || '-' }}
br
.extra(v-if="groupDialog.announcement.id" style="float:right;margin-left:5px")
el-tooltip(placement="bottom")
template(#content)
span {{ groupDialog.announcement.updatedAt | formatDate('long') }}
span(@click="showUserDialog(groupDialog.announcement.authorId)" style="cursor:pointer")
span(v-text="groupDialog.announcementDisplayName" style="margin-right:5px")
timer(:epoch="Date.parse(groupDialog.announcement.updatedAt)")
span(v-if="groupDialog.instances.length" style="font-size:12px;font-weight:bold;margin:5px") {{ $t('dialog.group.info.instances') }}
div(v-for="room in groupDialog.instances" :key="room.tag" style="width:100%")
div(style="margin:5px 0")
location(:location="room.tag")
@@ -945,6 +928,23 @@ html
timer(:epoch="user.$travelingToTime")
span.extra(v-else)
timer(:epoch="user.$location_at")
.x-friend-item(v-if="groupDialog.ref.membershipStatus === 'member'" style="width:100%;cursor:default")
.detail
span.name {{ $t('dialog.group.info.announcement') }}
span(style="display:block" v-text="groupDialog.announcement.title")
div(v-if="groupDialog.announcement.imageUrl" style="display:inline-block;margin-right:5px")
el-popover(placement="right" width="500px" trigger="click")
img.x-link(slot="reference" v-lazy="groupDialog.announcement.imageUrl" style="flex:none;width:60px;height:60px;border-radius:4px;object-fit:cover")
img.x-link(v-lazy="groupDialog.announcement.imageUrl" style="height:500px" @click="downloadAndSaveImage(groupDialog.announcement.imageUrl)")
pre.extra(style="display:inline-block;vertical-align:top;font-family:inherit;font-size:12px;white-space:pre-wrap;margin:0") {{ groupDialog.announcement.text || '-' }}
br
.extra(v-if="groupDialog.announcement.id" style="float:right;margin-left:5px")
el-tooltip(placement="bottom")
template(#content)
span {{ groupDialog.announcement.updatedAt | formatDate('long') }}
span(@click="showUserDialog(groupDialog.announcement.authorId)" style="cursor:pointer")
span(v-text="groupDialog.announcementDisplayName" style="margin-right:5px")
timer(:epoch="Date.parse(groupDialog.announcement.updatedAt)")
.x-friend-item(style="width:100%;cursor:default")
.detail
span.name {{ $t('dialog.group.info.rules') }}
@@ -1168,89 +1168,135 @@ html
//- dialog: new instance
el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" ref="newInstanceDialog" :visible.sync="newInstanceDialog.visible" :title="$t('dialog.new_instance.header')" width="650px")
el-form(v-if="newInstanceDialog.visible" :model="newInstanceDialog" label-width="130px")
el-form-item(:label="$t('dialog.new_instance.access_type')")
el-radio-group(v-model="newInstanceDialog.accessType" size="mini" @change="buildInstance")
el-radio-button(label="public") {{ $t('dialog.new_instance.access_type_public') }}
el-radio-button(label="group") {{ $t('dialog.new_instance.access_type_group') }}
el-radio-button(label="friends+") {{ $t('dialog.new_instance.access_type_friend_plus') }}
el-radio-button(label="friends") {{ $t('dialog.new_instance.access_type_friend') }}
el-radio-button(label="invite+") {{ $t('dialog.new_instance.access_type_invite_plus') }}
el-radio-button(label="invite") {{ $t('dialog.new_instance.access_type_invite') }}
el-form-item(:label="$t('dialog.new_instance.group_access_type')" v-if="newInstanceDialog.accessType === 'group'")
el-radio-group(v-model="newInstanceDialog.groupAccessType" size="mini" @change="buildInstance")
el-radio-button(label="members") {{ $t('dialog.new_instance.group_access_type_members') }}
el-radio-button(label="plus") {{ $t('dialog.new_instance.group_access_type_plus') }}
el-radio-button(label="public") {{ $t('dialog.new_instance.group_access_type_public') }}
//- el-form-item(label="Strict" v-if="newInstanceDialog.accessType === 'friends' || newInstanceDialog.accessType === 'invite'")
//- el-checkbox(v-model="newInstanceDialog.strict") Prevent non friends joining via URL/Instance ID
el-form-item(:label="$t('dialog.new_instance.region')")
el-radio-group(v-model="newInstanceDialog.region" size="mini" @change="buildInstance")
el-radio-button(label="US West") {{ $t('dialog.new_instance.region_usw') }}
el-radio-button(label="US East") {{ $t('dialog.new_instance.region_use') }}
el-radio-button(label="Europe") {{ $t('dialog.new_instance.region_eu') }}
el-radio-button(label="Japan") {{ $t('dialog.new_instance.region_jp') }}
el-form-item(:label="$t('dialog.new_instance.world_id')")
el-input(v-model="newInstanceDialog.worldId" size="mini" @click.native="$event.target.tagName === 'INPUT' && $event.target.select()")
el-form-item(:label="$t('dialog.new_instance.instance_id')")
el-input(v-model="newInstanceDialog.instanceName" :placeholder="$t('dialog.new_instance.instance_id_placeholder')" size="mini")
el-form-item(:label="$t('dialog.new_instance.instance_creator')" v-if="newInstanceDialog.accessType !== 'public' && newInstanceDialog.accessType !== 'group'")
el-select(v-model="newInstanceDialog.userId" clearable :placeholder="$t('dialog.new_instance.instance_creator_placeholder')" filterable style="width:100%")
el-option-group(v-if="API.currentUser" :label="$t('side_panel.me')")
el-option.x-friend-item(:label="API.currentUser.displayName" :value="API.currentUser.id" style="height:auto")
.avatar(:class="userStatusClass(API.currentUser)")
img(v-lazy="userImage(API.currentUser)")
.detail
span.name(v-text="API.currentUser.displayName")
el-option-group(v-if="friendsGroup0.length" :label="$t('side_panel.favorite')")
el-option.x-friend-item(v-for="friend in friendsGroup0" :key="friend.id" :label="friend.name" :value="friend.id" style="height:auto")
template(v-if="friend.ref")
.avatar(:class="userStatusClass(friend.ref)")
img(v-lazy="userImage(friend.ref)")
.detail
span.name(v-text="friend.ref.displayName" :style="{'color':friend.ref.$userColour}")
span(v-else v-text="friend.id")
el-option-group(v-if="friendsGroup1.length" :label="$t('side_panel.online')")
el-option.x-friend-item(v-for="friend in friendsGroup1" :key="friend.id" :label="friend.name" :value="friend.id" style="height:auto")
template(v-if="friend.ref")
.avatar(:class="userStatusClass(friend.ref)")
img(v-lazy="userImage(friend.ref)")
.detail
span.name(v-text="friend.ref.displayName" :style="{'color':friend.ref.$userColour}")
span(v-else v-text="friend.id")
el-option-group(v-if="friendsGroup2.length" :label="$t('side_panel.active')")
el-option.x-friend-item(v-for="friend in friendsGroup2" :key="friend.id" :label="friend.name" :value="friend.id" style="height:auto")
template(v-if="friend.ref")
.avatar
img(v-lazy="userImage(friend.ref)")
.detail
span.name(v-text="friend.ref.displayName" :style="{'color':friend.ref.$userColour}")
span(v-else v-text="friend.id")
el-option-group(v-if="friendsGroup3.length" :label="$t('side_panel.offline')")
el-option.x-friend-item(v-for="friend in friendsGroup3" :key="friend.id" :label="friend.name" :value="friend.id" style="height:auto")
template(v-if="friend.ref")
.avatar
img(v-lazy="userImage(friend.ref)")
.detail
span.name(v-text="friend.ref.displayName" :style="{'color':friend.ref.$userColour}")
span(v-else v-text="friend.id")
el-form-item(:label="$t('dialog.new_instance.group_id')" v-if="newInstanceDialog.accessType === 'group'")
el-select(v-model="newInstanceDialog.groupId" clearable :placeholder="$t('dialog.new_instance.group_placeholder')" filterable style="width:100%")
el-option-group(:label="$t('dialog.new_instance.group_placeholder')")
el-option.x-friend-item(v-if="group" v-for="group in API.currentUserGroups.values()" :key="group.id" :label="group.name" :value="group.id" style="height:auto;width:478px")
.avatar
img(v-lazy="group.iconUrl")
.detail
span.name(v-text="group.name")
el-form-item(:label="$t('dialog.new_instance.location')")
el-input(v-model="newInstanceDialog.location" size="mini" readonly)
el-form-item(:label="$t('dialog.new_instance.url')")
el-input(v-model="newInstanceDialog.url" size="mini" readonly @click.native="$event.target.tagName === 'INPUT' && $event.target.select()")
template(#footer)
el-tabs(type="card" ref="newInstanceTabs")
el-tab-pane(:label="$t('dialog.new_instance.normal')")
el-form(v-if="newInstanceDialog.visible" :model="newInstanceDialog" label-width="130px")
el-form-item(:label="$t('dialog.new_instance.access_type')")
el-radio-group(v-model="newInstanceDialog.accessType" size="mini" @change="buildInstance")
el-radio-button(label="public") {{ $t('dialog.new_instance.access_type_public') }}
el-radio-button(label="group") {{ $t('dialog.new_instance.access_type_group') }}
el-radio-button(label="friends+") {{ $t('dialog.new_instance.access_type_friend_plus') }}
el-radio-button(label="friends") {{ $t('dialog.new_instance.access_type_friend') }}
el-radio-button(label="invite+") {{ $t('dialog.new_instance.access_type_invite_plus') }}
el-radio-button(label="invite") {{ $t('dialog.new_instance.access_type_invite') }}
el-form-item(:label="$t('dialog.new_instance.group_access_type')" v-if="newInstanceDialog.accessType === 'group'")
el-radio-group(v-model="newInstanceDialog.groupAccessType" size="mini" @change="buildInstance")
el-radio-button(label="members") {{ $t('dialog.new_instance.group_access_type_members') }}
el-radio-button(label="plus") {{ $t('dialog.new_instance.group_access_type_plus') }}
el-radio-button(label="public") {{ $t('dialog.new_instance.group_access_type_public') }}
//- el-form-item(label="Strict" v-if="newInstanceDialog.accessType === 'friends' || newInstanceDialog.accessType === 'invite'")
//- el-checkbox(v-model="newInstanceDialog.strict") Prevent non friends joining via URL/Instance ID
el-form-item(:label="$t('dialog.new_instance.region')")
el-radio-group(v-model="newInstanceDialog.region" size="mini" @change="buildInstance")
el-radio-button(label="US West") {{ $t('dialog.new_instance.region_usw') }}
el-radio-button(label="US East") {{ $t('dialog.new_instance.region_use') }}
el-radio-button(label="Europe") {{ $t('dialog.new_instance.region_eu') }}
el-radio-button(label="Japan") {{ $t('dialog.new_instance.region_jp') }}
el-form-item(:label="$t('dialog.new_instance.world_id')")
el-input(v-model="newInstanceDialog.worldId" size="mini" @click.native="$event.target.tagName === 'INPUT' && $event.target.select()" @change="buildInstance")
el-form-item(:label="$t('dialog.new_instance.instance_id')")
el-input(v-model="newInstanceDialog.instanceName" :placeholder="$t('dialog.new_instance.instance_id_placeholder')" size="mini" @change="buildInstance")
el-form-item(:label="$t('dialog.new_instance.instance_creator')" v-if="newInstanceDialog.accessType !== 'public' && newInstanceDialog.accessType !== 'group'")
el-select(v-model="newInstanceDialog.userId" clearable :placeholder="$t('dialog.new_instance.instance_creator_placeholder')" filterable style="width:100%" @change="buildInstance")
el-option-group(v-if="API.currentUser" :label="$t('side_panel.me')")
el-option.x-friend-item(:label="API.currentUser.displayName" :value="API.currentUser.id" style="height:auto")
.avatar(:class="userStatusClass(API.currentUser)")
img(v-lazy="userImage(API.currentUser)")
.detail
span.name(v-text="API.currentUser.displayName")
el-option-group(v-if="friendsGroup0.length" :label="$t('side_panel.favorite')")
el-option.x-friend-item(v-for="friend in friendsGroup0" :key="friend.id" :label="friend.name" :value="friend.id" style="height:auto")
template(v-if="friend.ref")
.avatar(:class="userStatusClass(friend.ref)")
img(v-lazy="userImage(friend.ref)")
.detail
span.name(v-text="friend.ref.displayName" :style="{'color':friend.ref.$userColour}")
span(v-else v-text="friend.id")
el-option-group(v-if="friendsGroup1.length" :label="$t('side_panel.online')")
el-option.x-friend-item(v-for="friend in friendsGroup1" :key="friend.id" :label="friend.name" :value="friend.id" style="height:auto")
template(v-if="friend.ref")
.avatar(:class="userStatusClass(friend.ref)")
img(v-lazy="userImage(friend.ref)")
.detail
span.name(v-text="friend.ref.displayName" :style="{'color':friend.ref.$userColour}")
span(v-else v-text="friend.id")
el-option-group(v-if="friendsGroup2.length" :label="$t('side_panel.active')")
el-option.x-friend-item(v-for="friend in friendsGroup2" :key="friend.id" :label="friend.name" :value="friend.id" style="height:auto")
template(v-if="friend.ref")
.avatar
img(v-lazy="userImage(friend.ref)")
.detail
span.name(v-text="friend.ref.displayName" :style="{'color':friend.ref.$userColour}")
span(v-else v-text="friend.id")
el-option-group(v-if="friendsGroup3.length" :label="$t('side_panel.offline')")
el-option.x-friend-item(v-for="friend in friendsGroup3" :key="friend.id" :label="friend.name" :value="friend.id" style="height:auto")
template(v-if="friend.ref")
.avatar
img(v-lazy="userImage(friend.ref)")
.detail
span.name(v-text="friend.ref.displayName" :style="{'color':friend.ref.$userColour}")
span(v-else v-text="friend.id")
el-form-item(:label="$t('dialog.new_instance.group_id')" v-if="newInstanceDialog.accessType === 'group'")
el-select(v-model="newInstanceDialog.groupId" clearable :placeholder="$t('dialog.new_instance.group_placeholder')" filterable style="width:100%" @change="buildInstance")
el-option-group(:label="$t('dialog.new_instance.group_placeholder')")
el-option.x-friend-item(v-if="group" v-for="group in API.currentUserGroups.values()" :key="group.id" :label="group.name" :value="group.id" style="height:auto;width:478px")
.avatar
img(v-lazy="group.iconUrl")
.detail
span.name(v-text="group.name")
el-form-item(:label="$t('dialog.new_instance.location')")
el-input(v-model="newInstanceDialog.location" size="mini" readonly)
el-form-item(:label="$t('dialog.new_instance.url')")
el-input(v-model="newInstanceDialog.url" size="mini" readonly @click.native="$event.target.tagName === 'INPUT' && $event.target.select()")
el-tab-pane(:label="$t('dialog.new_instance.group')")
el-form(v-if="newInstanceDialog.visible" :model="newInstanceDialog" label-width="130px")
el-form-item(:label="$t('dialog.new_instance.group_access_type')")
el-radio-group(v-model="newInstanceDialog.groupAccessType" size="mini" @change="buildInstance")
el-radio-button(label="members") {{ $t('dialog.new_instance.group_access_type_members') }}
el-radio-button(label="plus") {{ $t('dialog.new_instance.group_access_type_plus') }}
el-radio-button(label="public") {{ $t('dialog.new_instance.group_access_type_public') }}
el-form-item(:label="$t('dialog.new_instance.region')")
el-radio-group(v-model="newInstanceDialog.region" size="mini" @change="buildInstance")
el-radio-button(label="US West") {{ $t('dialog.new_instance.region_usw') }}
el-radio-button(label="US East") {{ $t('dialog.new_instance.region_use') }}
el-radio-button(label="Europe") {{ $t('dialog.new_instance.region_eu') }}
el-radio-button(label="Japan") {{ $t('dialog.new_instance.region_jp') }}
el-form-item(:label="$t('dialog.new_instance.queueEnabled')")
el-checkbox(v-model="newInstanceDialog.queueEnabled" @change="buildInstance")
el-form-item(:label="$t('dialog.new_instance.world_id')")
el-input(v-model="newInstanceDialog.worldId" size="mini" @click.native="$event.target.tagName === 'INPUT' && $event.target.select()" @change="buildInstance")
el-form-item(:label="$t('dialog.new_instance.group_id')" v-if="newInstanceDialog.accessType === 'group'")
el-select(v-model="newInstanceDialog.groupId" clearable :placeholder="$t('dialog.new_instance.group_placeholder')" filterable style="width:100%" @change="buildInstance")
el-option-group(:label="$t('dialog.new_instance.group_placeholder')")
el-option.x-friend-item(v-if="group" v-for="group in API.currentUserGroups.values()" :key="group.id" :label="group.name" :value="group.id" style="height:auto;width:478px")
.avatar
img(v-lazy="group.iconUrl")
.detail
span.name(v-text="group.name")
el-form-item(:label="$t('dialog.new_instance.roles')" v-if="newInstanceDialog.groupAccessType === 'members'")
el-select(v-model="newInstanceDialog.roleIds" multiple clearable :placeholder="$t('dialog.new_instance.role_placeholder')" style="width:100%" @change="buildInstance")
el-option-group(:label="$t('dialog.new_instance.role_placeholder')")
el-option.x-friend-item(v-for="role in newInstanceDialog.selectedGroupRoles" :key="role.id" :label="role.name" :value="role.id" style="height:auto;width:478px")
.detail
span.name(v-text="role.name")
template(v-if="newInstanceDialog.instanceCreated")
el-form-item(:label="$t('dialog.new_instance.location')")
el-input(v-model="newInstanceDialog.location" size="mini" readonly @click.native="$event.target.tagName === 'INPUT' && $event.target.select()")
el-form-item(:label="$t('dialog.new_instance.url')")
el-input(v-model="newInstanceDialog.url" size="mini" readonly @click.native="$event.target.tagName === 'INPUT' && $event.target.select()")
template(#footer v-if="$refs.newInstanceTabs?.currentName === '0'")
el-button(size="small" @click="copyInstanceUrl(newInstanceDialog.location)") {{ $t('dialog.new_instance.copy_url') }}
el-button(size="small" @click="selfInvite(newInstanceDialog.location)") {{ $t('dialog.new_instance.self_invite') }}
el-button(size="small" @click="showInviteDialog(newInstanceDialog.location)" :disabled="(newInstanceDialog.accessType === 'friends' || newInstanceDialog.accessType === 'invite') && newInstanceDialog.userId !== API.currentUser.id") {{ $t('dialog.new_instance.invite') }}
el-button(type="primary" size="small" @click="showLaunchDialog(newInstanceDialog.location, newInstanceDialog.secureOrShortName)") {{ $t('dialog.new_instance.launch') }}
template(#footer v-else)
template(v-if="newInstanceDialog.instanceCreated")
el-button(size="small" @click="copyInstanceUrl(newInstanceDialog.location)") {{ $t('dialog.new_instance.copy_url') }}
el-button(size="small" @click="selfInvite(newInstanceDialog.location)") {{ $t('dialog.new_instance.self_invite') }}
el-button(size="small" @click="showInviteDialog(newInstanceDialog.location)" :disabled="(newInstanceDialog.accessType === 'friends' || newInstanceDialog.accessType === 'invite') && newInstanceDialog.userId !== API.currentUser.id") {{ $t('dialog.new_instance.invite') }}
el-button(type="primary" size="small" @click="showLaunchDialog(newInstanceDialog.location, newInstanceDialog.secureOrShortName)") {{ $t('dialog.new_instance.launch') }}
template(v-else)
el-button(type="primary" size="small" @click="createGroupInstance()" :disabled="!newInstanceDialog.groupId") {{ $t('dialog.new_instance.create_instance') }}
//- dialog: launch options
el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" ref="launchOptionsDialog" :visible.sync="launchOptionsDialog.visible" :title="$t('dialog.launch_options.header')" width="500px")
@@ -1405,11 +1451,15 @@ html
//- dialog: export friends list
el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" :visible.sync="exportFriendsListDialog" :title="$t('dialog.export_friends_list.header')" width="650px")
el-input(type="textarea" v-if="exportFriendsListDialog" v-model="exportFriendsListContent" size="mini" rows="15" resize="none" readonly style="margin-top:15px" @click.native="$event.target.tagName === 'TEXTAREA' && $event.target.select()")
el-tabs(type="card")
el-tab-pane(:label="$t('dialog.export_friends_list.csv')")
el-input(type="textarea" v-if="exportFriendsListDialog" v-model="exportFriendsListCsv" size="mini" rows="15" resize="none" readonly style="margin-top:15px" @click.native="$event.target.tagName === 'TEXTAREA' && $event.target.select()")
el-tab-pane(:label="$t('dialog.export_friends_list.json')")
el-input(type="textarea" v-if="exportFriendsListDialog" v-model="exportFriendsListJson" size="mini" rows="15" resize="none" readonly style="margin-top:15px" @click.native="$event.target.tagName === 'TEXTAREA' && $event.target.select()")
//- dialog: export avatars list
el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" :visible.sync="exportAvatarsListDialog" :title="$t('dialog.export_own_avatars.header')" width="650px")
el-input(type="textarea" v-if="exportAvatarsListDialog" v-model="exportAvatarsListContent" size="mini" rows="15" resize="none" readonly style="margin-top:15px" @click.native="$event.target.tagName === 'TEXTAREA' && $event.target.select()")
el-input(type="textarea" v-if="exportAvatarsListDialog" v-model="exportAvatarsListCsv" size="mini" rows="15" resize="none" readonly style="margin-top:15px" @click.native="$event.target.tagName === 'TEXTAREA' && $event.target.select()")
//- dialog: Discord username list
el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" :visible.sync="discordNamesDialogVisible" :title="$t('dialog.discord_names.header')" width="650px")

View File

@@ -477,7 +477,7 @@
"search_result_more": "Search More:",
"direct_access_tooltip": "Direct access ID/URL from clipboard",
"refresh_tooltip": "Refresh friends",
"groups": "Group Instances",
"groups": "Groups",
"friends": "Friends",
"me": "ME",
"favorite": "FAVORITES",
@@ -740,6 +740,7 @@
},
"info": {
"header": "Info",
"instances": "Instances",
"announcement": "Announcement",
"instance_full": "full",
"rules": "Rules",
@@ -836,13 +837,19 @@
"instance_creator": "Instance Creator",
"instance_creator_placeholder": "Choose User",
"group_placeholder": "Choose Group",
"role_placeholder": "Choose Roles",
"group_id": "Group",
"location": "Location",
"url": "URL",
"copy_url": "Copy URL",
"self_invite": "Self invite",
"invite": "Invite",
"launch": "Launch"
"launch": "Launch",
"create_instance": "Create Instance",
"queueEnabled": "Queue",
"normal": "Normal",
"group": "Group",
"roles": "Roles"
},
"launch_options": {
"header": "VRChat Launch Options",
@@ -915,7 +922,9 @@
"launch": "Launch"
},
"export_friends_list": {
"header": "Export Friends List"
"header": "Export Friends List",
"csv": "CSV",
"json": "JSON"
},
"export_own_avatars": {
"header": "Export Own Avatars"

View File

@@ -2,7 +2,7 @@ mixin favoritesTab()
.x-container(v-show="$refs.menu && $refs.menu.activeIndex === 'favorite'")
el-tooltip(placement="bottom" :content="$t('view.favorite.refresh_tooltip')" :disabled="hideTooltips")
el-button(type="default" :loading="API.isFavoriteLoading" @click="API.refreshFavorites(); getLocalWorldFavorites()" size="small" icon="el-icon-refresh" circle style="position:relative;float:right;z-index:1")
el-tabs(ref="favoriteTabRef" type="card" v-loading="API.isFavoriteLoading")
el-tabs(ref="favoriteTabRef" type="card" v-loading="API.isFavoriteLoading" style="height:100%")
el-tab-pane(:label="$t('view.favorite.friends.header')")
el-collapse(v-if="$refs.menu && $refs.menu.activeIndex === 'favorite' && $refs.favoriteTabRef && $refs.favoriteTabRef.currentName === '0'" style="border:0")
el-button(size="small" @click="showFriendExportDialog") {{ $t('view.favorite.export') }}

View File

@@ -17,6 +17,7 @@ mixin playerListTab()
el-tag(v-else-if="currentInstanceWorld.ref.releaseStatus === 'private'" type="danger" effect="plain" size="mini" style="margin-right:5px") {{ $t('dialog.world.tags.private') }}
el-tag.x-tag-platform-pc(v-if="currentInstanceWorld.isPC" type="info" effect="plain" size="mini" style="margin-right:5px") PC
el-tag.x-tag-platform-quest(v-if="currentInstanceWorld.isQuest" type="info" effect="plain" size="mini" style="margin-right:5px") Quest
el-tag.x-tag-platform-ios(v-if="currentInstanceWorld.isIOS" type="info" effect="plain" size="mini" style="margin-right:5px") iOS
el-tag(type="info" effect="plain" size="mini" v-text="currentInstanceWorld.fileSize" style="margin-right:5px")
el-tag(v-if="currentInstanceWorld.inCache" type="info" effect="plain" size="mini" style="margin-right:5px")
span(v-text="currentInstanceWorld.cacheSize")
@@ -215,11 +216,12 @@ mixin playerListTab()
template(v-if="scope.row.ref.last_platform")
span(v-if="scope.row.ref.last_platform === 'standalonewindows'" style="color:#409eff") PC
span(v-else-if="scope.row.ref.last_platform === 'android'" style="color:#67c23a") Q
span(v-else-if="scope.row.ref.last_platform === 'ios'" style="color:#c7c7ce") iOS
span(v-else) {{ scope.row.ref.last_platform }}
template(v-if="scope.row.inVRMode !== null")
span(v-if="scope.row.inVRMode") VR
span(v-else) D
el-table-column(:label="$t('table.playerList.displayName')" min-width="140" prop="ref.displayName")
el-table-column(:label="$t('table.playerList.displayName')" min-width="140" prop="displayName" sortable="custom")
template(v-once #default="scope")
span(v-if="randomUserColours" v-text="scope.row.ref.displayName" :style="{'color':scope.row.ref.$userColour}")
span(v-else v-text="scope.row.ref.displayName")

View File

@@ -165,7 +165,7 @@ mixin settingsTab()
el-switch(v-model="orderFriendsGroup3" :inactive-text="$t('view.settings.appearance.side_panel.sorting.sort_offline_by_alphabet')" :active-text="$t('view.settings.appearance.side_panel.sorting.sort_offline_by_offline_time')" @change="saveOrderFriendGroup")
span.sub-header {{ $t('view.settings.appearance.side_panel.width') }}
div.options-container-item
el-slider(v-model="asideWidth" @input="setAsideWidth" :show-tooltip="false" :marks="{350: ''}" :min="141" :max="500" style="width:300px")
el-slider(v-model="asideWidth" @input="setAsideWidth" :show-tooltip="false" :marks="{300: ''}" :min="200" :max="500" style="width:300px")
//- Appearance | User Dialog
div.options-container
span.header {{ $t('view.settings.appearance.user_dialog.header') }}

View File

@@ -518,6 +518,7 @@ html
span(v-if="feed.platform === 'Desktop'" style="color:#409eff;margin-left:10px") Desktop
span(v-else-if="feed.platform === 'VR'" style="color:#409eff;margin-left:10px") VR
span(v-else-if="feed.platform === 'Quest'" style="color:#67c23a;margin-left:10px") Quest
span(v-else-if="feed.platform === 'iOS'" style="color:#c7c7ce;margin-left:10px") iOS
span(v-if="!feed.inCache" style="color:#aaa;margin-left:10px") #[i.el-icon-download]
span(v-text="feed.avatar.name" style="margin-left:10px")
template(v-else-if="feed.type === 'SpawnEmoji'")