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
+1 -1
View File
@@ -494,7 +494,7 @@ namespace VRCX
public void ExecuteAppFunction(string function, string json) 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); MainForm.Instance.Browser.ExecuteScriptAsync($"$app.{function}", json);
} }
+254 -93
View File
@@ -4738,7 +4738,7 @@ speechSynthesis.getVoices();
break; break;
case 'group-member-updated': case 'group-member-updated':
var groupId = content.groupId; var groupId = content.member.groupId;
$app.onGroupJoined(groupId); $app.onGroupJoined(groupId);
console.log('group-member-updated', content); console.log('group-member-updated', content);
@@ -4758,76 +4758,15 @@ speechSynthesis.getVoices();
case 'instance-queue-joined': case 'instance-queue-joined':
case 'instance-queue-position': case 'instance-queue-position':
var instanceId = content.instanceLocation; var instanceId = content.instanceLocation;
var ref = this.queuedInstances.get(instanceId); var position = content.position ?? 0;
if (typeof ref === 'undefined') { var queueSize = content.queueSize ?? 0;
ref = { $app.instanceQueueUpdate(instanceId, position, queueSize);
$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);
break; break;
case 'instance-queue-ready': case 'instance-queue-ready':
var instanceId = content.instanceLocation; var instanceId = content.instanceLocation;
// var expiry = Date.parse(content.expiry); // var expiry = Date.parse(content.expiry);
var ref = this.queuedInstances.get(instanceId); $app.instanceQueueReady(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);
break; break;
default: default:
@@ -5137,9 +5076,7 @@ speechSynthesis.getVoices();
isSteamVRRunning: false, isSteamVRRunning: false,
appVersion: '', appVersion: '',
latestAppVersion: '', latestAppVersion: '',
ossDialog: false, ossDialog: false
exportFriendsListDialog: false,
exportFriendsListContent: ''
}, },
i18n, i18n,
computed: {}, computed: {},
@@ -5358,6 +5295,7 @@ speechSynthesis.getVoices();
configRepository.setBool('isGameNoVR', this.isGameNoVR); configRepository.setBool('isGameNoVR', this.isGameNoVR);
API.currentUser.$online_for = ''; API.currentUser.$online_for = '';
API.currentUser.$offline_for = Date.now(); API.currentUser.$offline_for = Date.now();
this.removeAllQueuedInstances();
this.autoVRChatCacheManagement(); this.autoVRChatCacheManagement();
this.checkIfGameCrashed(); this.checkIfGameCrashed();
this.ipcTimeout = 0; this.ipcTimeout = 0;
@@ -5453,6 +5391,27 @@ speechSynthesis.getVoices();
wristFeed.unshift(feedEntry); wristFeed.unshift(feedEntry);
} else { } else {
var worldRef = API.cachedWorlds.get(ref.$location.worldId); 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') { if (typeof worldRef !== 'undefined') {
var feedEntry = { var feedEntry = {
created_at: ref.created_at, created_at: ref.created_at,
@@ -5461,6 +5420,7 @@ speechSynthesis.getVoices();
displayName: ref.displayName, displayName: ref.displayName,
location: ref.$location.tag, location: ref.$location.tag,
worldName: worldRef.name, worldName: worldRef.name,
groupName,
previousLocation: '', previousLocation: '',
isFavorite, isFavorite,
time: 0, time: 0,
@@ -7063,6 +7023,10 @@ speechSynthesis.getVoices();
this.promptEmailOTP(); this.promptEmailOTP();
}; };
$app.data.exportFriendsListDialog = false;
$app.data.exportFriendsListCsv = '';
$app.data.exportFriendsListJson = '';
$app.methods.showExportFriendsListDialog = function () { $app.methods.showExportFriendsListDialog = function () {
var { friends } = API.currentUser; var { friends } = API.currentUser;
if (Array.isArray(friends) === false) { if (Array.isArray(friends) === false) {
@@ -7075,6 +7039,7 @@ speechSynthesis.getVoices();
} }
return str; return str;
}; };
var friendsList = [];
for (var userId of friends) { for (var userId of friends) {
var ref = this.friends.get(userId); var ref = this.friends.get(userId);
var name = (typeof ref !== 'undefined' && ref.name) || ''; var name = (typeof ref !== 'undefined' && ref.name) || '';
@@ -7082,13 +7047,19 @@ speechSynthesis.getVoices();
(typeof ref !== 'undefined' && ref.memo.replace(/\n/g, ' ')) || (typeof ref !== 'undefined' && ref.memo.replace(/\n/g, ' ')) ||
''; '';
lines.push(`${_(userId)},${_(name)},${_(memo)}`); 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; this.exportFriendsListDialog = true;
}; };
$app.data.exportAvatarsListDialog = false; $app.data.exportAvatarsListDialog = false;
$app.data.exportAvatarsListContent = ''; $app.data.exportAvatarsListCsv = '';
$app.methods.showExportAvatarsListDialog = function () { $app.methods.showExportAvatarsListDialog = function () {
for (var ref of API.cachedAvatars.values()) { for (var ref of API.cachedAvatars.values()) {
@@ -7132,7 +7103,7 @@ speechSynthesis.getVoices();
for (var avatar of avatars) { for (var avatar of avatars) {
lines.push(`${_(avatar.id)},${_(avatar.name)}`); lines.push(`${_(avatar.id)},${_(avatar.name)}`);
} }
this.exportAvatarsListContent = lines.join('\n'); this.exportAvatarsListCsv = lines.join('\n');
this.exportAvatarsListDialog = true; this.exportAvatarsListDialog = true;
} }
}); });
@@ -9609,6 +9580,7 @@ speechSynthesis.getVoices();
this.lastLocation.location = 'traveling'; this.lastLocation.location = 'traveling';
this.lastLocationDestination = gameLog.location; this.lastLocationDestination = gameLog.location;
this.lastLocationDestinationTime = Date.parse(gameLog.dt); this.lastLocationDestinationTime = Date.parse(gameLog.dt);
this.removeQueuedInstance(gameLog.location);
this.updateCurrentUserLocation(); this.updateCurrentUserLocation();
this.clearNowPlaying(); this.clearNowPlaying();
this.updateCurrentInstanceWorld(); this.updateCurrentInstanceWorld();
@@ -9629,6 +9601,7 @@ speechSynthesis.getVoices();
playerList: new Map(), playerList: new Map(),
friendList: new Map() friendList: new Map()
}; };
this.removeQueuedInstance(gameLog.location);
this.updateCurrentUserLocation(); this.updateCurrentUserLocation();
this.updateVRLastLocation(); this.updateVRLastLocation();
this.updateCurrentInstanceWorld(); this.updateCurrentInstanceWorld();
@@ -10894,18 +10867,29 @@ speechSynthesis.getVoices();
) { ) {
var instance = await API.getInstanceFromShortName({ shortName }); var instance = await API.getInstanceFromShortName({ shortName });
var location = instance.json.location; 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 newShortName = instance.json.shortName;
// var portalType = 'Secure'; // var portalType = 'Secure';
// if (shortName === newShortName) { // if (shortName === newShortName) {
// portalType = 'Unlocked'; // portalType = 'Unlocked';
// } // }
var displayLocation = this.displayLocation(
location,
worldName,
groupName
);
this.addEntryPhotonEvent({ this.addEntryPhotonEvent({
photonId: this.getPhotonIdFromUserId(userId), photonId: this.getPhotonIdFromUserId(userId),
text: `PortalSpawn to ${worldName}`, text: `PortalSpawn to ${displayLocation}`,
type: 'PortalSpawn', type: 'PortalSpawn',
shortName, shortName,
location, location,
worldName, worldName,
groupName,
created_at: gameLogDate created_at: gameLogDate
}); });
this.addPhotonEventToGameLog({ this.addPhotonEventToGameLog({
@@ -10915,7 +10899,8 @@ speechSynthesis.getVoices();
location: this.lastLocation.location, location: this.lastLocation.location,
userId, userId,
instanceId: location, instanceId: location,
worldName worldName,
groupName
}); });
}; };
@@ -11137,6 +11122,8 @@ speechSynthesis.getVoices();
var platform = ''; var platform = '';
if (user.last_platform === 'android') { if (user.last_platform === 'android') {
platform = 'Quest'; platform = 'Quest';
} else if (user.last_platform === 'ios') {
platform = 'iOS';
} else if (user.inVRMode) { } else if (user.inVRMode) {
platform = 'VR'; platform = 'VR';
} else { } else {
@@ -13654,10 +13641,15 @@ speechSynthesis.getVoices();
'VRCX_vrBackgroundEnabled', 'VRCX_vrBackgroundEnabled',
false false
); );
$app.data.asideWidth = configRepository.getInt('VRCX_asidewidth', 350); $app.data.asideWidth = configRepository.getInt('VRCX_sidePanelWidth', 300);
if ($app.data.asideWidth === 236) { if (configRepository.getInt('VRCX_asidewidth')) {
$app.data.asideWidth = 350; // migrate to new defaults
configRepository.setInt('VRCX_asidewidth', $app.data.asideWidth); $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( $app.data.autoUpdateVRCX = configRepository.getString(
'VRCX_autoUpdateVRCX', 'VRCX_autoUpdateVRCX',
@@ -15938,8 +15930,9 @@ speechSynthesis.getVoices();
} }
users.push({ users.push({
ref, ref,
displayName: ref.displayName,
timer: ref.$location_at, timer: ref.$location_at,
$trustSortNum: ref.$trustSortNum ? ref.$trustSortNum : 0, $trustSortNum: ref.$trustSortNum ?? 0,
photonId, photonId,
isMaster, isMaster,
inVRMode, inVRMode,
@@ -18025,6 +18018,8 @@ speechSynthesis.getVoices();
$app.data.newInstanceDialog = { $app.data.newInstanceDialog = {
visible: false, visible: false,
loading: false, loading: false,
instanceCreated: false,
queueEnabled: false,
worldId: '', worldId: '',
instanceId: '', instanceId: '',
instanceName: '', instanceName: '',
@@ -18037,7 +18032,10 @@ speechSynthesis.getVoices();
location: '', location: '',
shortName: '', shortName: '',
url: '', url: '',
secureOrShortName: '' secureOrShortName: '',
lastSelectedGroupId: '',
selectedGroupRoles: [],
roleIds: []
}; };
API.$on('LOGOUT', function () { API.$on('LOGOUT', function () {
@@ -18046,6 +18044,7 @@ speechSynthesis.getVoices();
$app.methods.buildInstance = function () { $app.methods.buildInstance = function () {
var D = this.newInstanceDialog; var D = this.newInstanceDialog;
D.instanceCreated = false;
var tags = []; var tags = [];
if (D.instanceName) { if (D.instanceName) {
D.instanceName = D.instanceName.replace(/[^A-Za-z0-9-_]/g, ''); D.instanceName = D.instanceName.replace(/[^A-Za-z0-9-_]/g, '');
@@ -18091,8 +18090,69 @@ speechSynthesis.getVoices();
if (D.strict) { if (D.strict) {
tags.push('~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(''); D.instanceId = tags.join('');
this.updateNewInstanceDialog(false); 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) { $app.methods.selfInvite = function (location, shortName) {
@@ -18137,7 +18197,7 @@ speechSynthesis.getVoices();
D.url = this.getLaunchURL(L); D.url = this.getLaunchURL(L);
}; };
var saveNewInstanceDialog = function () { $app.methods.saveNewInstanceDialog = function () {
configRepository.setString( configRepository.setString(
'instanceDialogAccessType', 'instanceDialogAccessType',
this.newInstanceDialog.accessType this.newInstanceDialog.accessType
@@ -18170,16 +18230,11 @@ speechSynthesis.getVoices();
'instanceDialogStrict', 'instanceDialogStrict',
this.newInstanceDialog.strict 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) { $app.methods.showNewInstanceDialog = function (tag) {
if (!this.isRealInstance(tag)) { if (!this.isRealInstance(tag)) {
@@ -18202,8 +18257,16 @@ speechSynthesis.getVoices();
D.groupId = configRepository.getString('instanceDialogGroupId', ''); D.groupId = configRepository.getString('instanceDialogGroupId', '');
D.groupAccessType = configRepository.getString( D.groupAccessType = configRepository.getString(
'instanceDialogGroupAccessType', 'instanceDialogGroupAccessType',
'members' 'plus'
); );
D.queueEnabled = configRepository.getBool(
'instanceDialogQueueEnabled',
true
);
D.instanceCreated = false;
D.lastSelectedGroupId = '';
D.selectedGroupRoles = [];
D.roleIds = [];
D.strict = false; D.strict = false;
D.shortName = ''; D.shortName = '';
this.buildInstance(); this.buildInstance();
@@ -22176,7 +22239,7 @@ speechSynthesis.getVoices();
$app.methods.setAsideWidth = function () { $app.methods.setAsideWidth = function () {
document.getElementById('aside').style.width = `${this.asideWidth}px`; document.getElementById('aside').style.width = `${this.asideWidth}px`;
configRepository.setInt('VRCX_asidewidth', this.asideWidth); configRepository.setInt('VRCX_sidePanelWidth', this.asideWidth);
}; };
// VRCX auto update // VRCX auto update
@@ -22509,7 +22572,11 @@ speechSynthesis.getVoices();
API.cachedAvatars.delete(id); 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(); API.cachedAvatarNames = new Map();
}; };
@@ -24757,6 +24824,97 @@ speechSynthesis.getVoices();
API.currentUserGroups = new Map(); API.currentUserGroups = new Map();
API.queuedInstances = 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: { params: {
groupId: string groupId: string
@@ -25707,6 +25865,9 @@ speechSynthesis.getVoices();
}; };
$app.methods.joinGroup = function (groupId) { $app.methods.joinGroup = function (groupId) {
if (!groupId) {
return null;
}
return API.joinGroup({ return API.joinGroup({
groupId groupId
}).then((args) => { }).then((args) => {
+16 -2
View File
@@ -706,12 +706,15 @@ i.x-user-status.busy {
top: 0 !important; top: 0 !important;
} }
.vrc-instance-queue-message .el-message__content {
margin-right: 20px;
}
.el-tab-pane { .el-tab-pane {
height: 100%; height: 100%;
} }
.el-tabs { .el-tabs {
// height: calc(100vh - 60px);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }
@@ -719,5 +722,16 @@ i.x-user-status.busy {
.el-tabs__content { .el-tabs__content {
flex: 1; flex: 1;
max-height: 100%; 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;
} }
+152 -102
View File
@@ -106,10 +106,10 @@ html
el-button(type="default" @click="directAccessPaste" size="mini" icon="el-icon-discover" circle) 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-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-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 el-tab-pane
template(#label) 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-list(style="padding-bottom:10px")
.x-friend-group.x-link(@click="isFriendsGroupMe = !isFriendsGroupMe" style="padding:0px 0px 5px") .x-friend-group.x-link(@click="isFriendsGroupMe = !isFriendsGroupMe" style="padding:0px 0px 5px")
i.el-icon-arrow-right(:class="{ rotate: isFriendsGroupMe }") i.el-icon-arrow-right(:class="{ rotate: isFriendsGroupMe }")
@@ -185,10 +185,9 @@ html
template(v-else) template(v-else)
span(v-text="friend.name || friend.id") 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-button(type="text" icon="el-icon-close" size="mini" @click.stop="confirmDeleteFriend(friend.id)" style="margin-left:5px")
el-tab-pane el-tab-pane
template(#label) 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-list(style="padding-bottom:10px")
.x-friend-item(v-for="instance in groupInstances" :key="instance.id" @click="showGroupDialog(instance.ownerId)") .x-friend-item(v-for="instance in groupInstances" :key="instance.id" @click="showGroupDialog(instance.ownerId)")
.avatar .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(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)") 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-list(style="max-height:none")
.x-friend-item(v-if="groupDialog.ref.membershipStatus === 'member'" style="width:100%;cursor:default") span(v-if="groupDialog.instances.length" style="font-size:12px;font-weight:bold;margin:5px") {{ $t('dialog.group.info.instances') }}
.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)")
div(v-for="room in groupDialog.instances" :key="room.tag" style="width:100%") div(v-for="room in groupDialog.instances" :key="room.tag" style="width:100%")
div(style="margin:5px 0") div(style="margin:5px 0")
location(:location="room.tag") location(:location="room.tag")
@@ -945,6 +928,23 @@ html
timer(:epoch="user.$travelingToTime") timer(:epoch="user.$travelingToTime")
span.extra(v-else) span.extra(v-else)
timer(:epoch="user.$location_at") 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") .x-friend-item(style="width:100%;cursor:default")
.detail .detail
span.name {{ $t('dialog.group.info.rules') }} span.name {{ $t('dialog.group.info.rules') }}
@@ -1168,89 +1168,135 @@ html
//- dialog: new instance //- 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-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-tabs(type="card" ref="newInstanceTabs")
el-form-item(:label="$t('dialog.new_instance.access_type')") el-tab-pane(:label="$t('dialog.new_instance.normal')")
el-radio-group(v-model="newInstanceDialog.accessType" size="mini" @change="buildInstance") el-form(v-if="newInstanceDialog.visible" :model="newInstanceDialog" label-width="130px")
el-radio-button(label="public") {{ $t('dialog.new_instance.access_type_public') }} el-form-item(:label="$t('dialog.new_instance.access_type')")
el-radio-button(label="group") {{ $t('dialog.new_instance.access_type_group') }} el-radio-group(v-model="newInstanceDialog.accessType" size="mini" @change="buildInstance")
el-radio-button(label="friends+") {{ $t('dialog.new_instance.access_type_friend_plus') }} el-radio-button(label="public") {{ $t('dialog.new_instance.access_type_public') }}
el-radio-button(label="friends") {{ $t('dialog.new_instance.access_type_friend') }} el-radio-button(label="group") {{ $t('dialog.new_instance.access_type_group') }}
el-radio-button(label="invite+") {{ $t('dialog.new_instance.access_type_invite_plus') }} el-radio-button(label="friends+") {{ $t('dialog.new_instance.access_type_friend_plus') }}
el-radio-button(label="invite") {{ $t('dialog.new_instance.access_type_invite') }} el-radio-button(label="friends") {{ $t('dialog.new_instance.access_type_friend') }}
el-form-item(:label="$t('dialog.new_instance.group_access_type')" v-if="newInstanceDialog.accessType === 'group'") el-radio-button(label="invite+") {{ $t('dialog.new_instance.access_type_invite_plus') }}
el-radio-group(v-model="newInstanceDialog.groupAccessType" size="mini" @change="buildInstance") el-radio-button(label="invite") {{ $t('dialog.new_instance.access_type_invite') }}
el-radio-button(label="members") {{ $t('dialog.new_instance.group_access_type_members') }} el-form-item(:label="$t('dialog.new_instance.group_access_type')" v-if="newInstanceDialog.accessType === 'group'")
el-radio-button(label="plus") {{ $t('dialog.new_instance.group_access_type_plus') }} el-radio-group(v-model="newInstanceDialog.groupAccessType" size="mini" @change="buildInstance")
el-radio-button(label="public") {{ $t('dialog.new_instance.group_access_type_public') }} el-radio-button(label="members") {{ $t('dialog.new_instance.group_access_type_members') }}
//- el-form-item(label="Strict" v-if="newInstanceDialog.accessType === 'friends' || newInstanceDialog.accessType === 'invite'") el-radio-button(label="plus") {{ $t('dialog.new_instance.group_access_type_plus') }}
//- el-checkbox(v-model="newInstanceDialog.strict") Prevent non friends joining via URL/Instance ID el-radio-button(label="public") {{ $t('dialog.new_instance.group_access_type_public') }}
el-form-item(:label="$t('dialog.new_instance.region')") //- el-form-item(label="Strict" v-if="newInstanceDialog.accessType === 'friends' || newInstanceDialog.accessType === 'invite'")
el-radio-group(v-model="newInstanceDialog.region" size="mini" @change="buildInstance") //- el-checkbox(v-model="newInstanceDialog.strict") Prevent non friends joining via URL/Instance ID
el-radio-button(label="US West") {{ $t('dialog.new_instance.region_usw') }} el-form-item(:label="$t('dialog.new_instance.region')")
el-radio-button(label="US East") {{ $t('dialog.new_instance.region_use') }} el-radio-group(v-model="newInstanceDialog.region" size="mini" @change="buildInstance")
el-radio-button(label="Europe") {{ $t('dialog.new_instance.region_eu') }} el-radio-button(label="US West") {{ $t('dialog.new_instance.region_usw') }}
el-radio-button(label="Japan") {{ $t('dialog.new_instance.region_jp') }} el-radio-button(label="US East") {{ $t('dialog.new_instance.region_use') }}
el-form-item(:label="$t('dialog.new_instance.world_id')") el-radio-button(label="Europe") {{ $t('dialog.new_instance.region_eu') }}
el-input(v-model="newInstanceDialog.worldId" size="mini" @click.native="$event.target.tagName === 'INPUT' && $event.target.select()") el-radio-button(label="Japan") {{ $t('dialog.new_instance.region_jp') }}
el-form-item(:label="$t('dialog.new_instance.instance_id')") el-form-item(:label="$t('dialog.new_instance.world_id')")
el-input(v-model="newInstanceDialog.instanceName" :placeholder="$t('dialog.new_instance.instance_id_placeholder')" size="mini") 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_creator')" v-if="newInstanceDialog.accessType !== 'public' && newInstanceDialog.accessType !== 'group'") el-form-item(:label="$t('dialog.new_instance.instance_id')")
el-select(v-model="newInstanceDialog.userId" clearable :placeholder="$t('dialog.new_instance.instance_creator_placeholder')" filterable style="width:100%") el-input(v-model="newInstanceDialog.instanceName" :placeholder="$t('dialog.new_instance.instance_id_placeholder')" size="mini" @change="buildInstance")
el-option-group(v-if="API.currentUser" :label="$t('side_panel.me')") el-form-item(:label="$t('dialog.new_instance.instance_creator')" v-if="newInstanceDialog.accessType !== 'public' && newInstanceDialog.accessType !== 'group'")
el-option.x-friend-item(:label="API.currentUser.displayName" :value="API.currentUser.id" style="height:auto") el-select(v-model="newInstanceDialog.userId" clearable :placeholder="$t('dialog.new_instance.instance_creator_placeholder')" filterable style="width:100%" @change="buildInstance")
.avatar(:class="userStatusClass(API.currentUser)") el-option-group(v-if="API.currentUser" :label="$t('side_panel.me')")
img(v-lazy="userImage(API.currentUser)") el-option.x-friend-item(:label="API.currentUser.displayName" :value="API.currentUser.id" style="height:auto")
.detail .avatar(:class="userStatusClass(API.currentUser)")
span.name(v-text="API.currentUser.displayName") img(v-lazy="userImage(API.currentUser)")
el-option-group(v-if="friendsGroup0.length" :label="$t('side_panel.favorite')") .detail
el-option.x-friend-item(v-for="friend in friendsGroup0" :key="friend.id" :label="friend.name" :value="friend.id" style="height:auto") span.name(v-text="API.currentUser.displayName")
template(v-if="friend.ref") el-option-group(v-if="friendsGroup0.length" :label="$t('side_panel.favorite')")
.avatar(:class="userStatusClass(friend.ref)") el-option.x-friend-item(v-for="friend in friendsGroup0" :key="friend.id" :label="friend.name" :value="friend.id" style="height:auto")
img(v-lazy="userImage(friend.ref)") template(v-if="friend.ref")
.detail .avatar(:class="userStatusClass(friend.ref)")
span.name(v-text="friend.ref.displayName" :style="{'color':friend.ref.$userColour}") img(v-lazy="userImage(friend.ref)")
span(v-else v-text="friend.id") .detail
el-option-group(v-if="friendsGroup1.length" :label="$t('side_panel.online')") span.name(v-text="friend.ref.displayName" :style="{'color':friend.ref.$userColour}")
el-option.x-friend-item(v-for="friend in friendsGroup1" :key="friend.id" :label="friend.name" :value="friend.id" style="height:auto") span(v-else v-text="friend.id")
template(v-if="friend.ref") el-option-group(v-if="friendsGroup1.length" :label="$t('side_panel.online')")
.avatar(:class="userStatusClass(friend.ref)") el-option.x-friend-item(v-for="friend in friendsGroup1" :key="friend.id" :label="friend.name" :value="friend.id" style="height:auto")
img(v-lazy="userImage(friend.ref)") template(v-if="friend.ref")
.detail .avatar(:class="userStatusClass(friend.ref)")
span.name(v-text="friend.ref.displayName" :style="{'color':friend.ref.$userColour}") img(v-lazy="userImage(friend.ref)")
span(v-else v-text="friend.id") .detail
el-option-group(v-if="friendsGroup2.length" :label="$t('side_panel.active')") span.name(v-text="friend.ref.displayName" :style="{'color':friend.ref.$userColour}")
el-option.x-friend-item(v-for="friend in friendsGroup2" :key="friend.id" :label="friend.name" :value="friend.id" style="height:auto") span(v-else v-text="friend.id")
template(v-if="friend.ref") el-option-group(v-if="friendsGroup2.length" :label="$t('side_panel.active')")
.avatar el-option.x-friend-item(v-for="friend in friendsGroup2" :key="friend.id" :label="friend.name" :value="friend.id" style="height:auto")
img(v-lazy="userImage(friend.ref)") template(v-if="friend.ref")
.detail .avatar
span.name(v-text="friend.ref.displayName" :style="{'color':friend.ref.$userColour}") img(v-lazy="userImage(friend.ref)")
span(v-else v-text="friend.id") .detail
el-option-group(v-if="friendsGroup3.length" :label="$t('side_panel.offline')") span.name(v-text="friend.ref.displayName" :style="{'color':friend.ref.$userColour}")
el-option.x-friend-item(v-for="friend in friendsGroup3" :key="friend.id" :label="friend.name" :value="friend.id" style="height:auto") span(v-else v-text="friend.id")
template(v-if="friend.ref") el-option-group(v-if="friendsGroup3.length" :label="$t('side_panel.offline')")
.avatar el-option.x-friend-item(v-for="friend in friendsGroup3" :key="friend.id" :label="friend.name" :value="friend.id" style="height:auto")
img(v-lazy="userImage(friend.ref)") template(v-if="friend.ref")
.detail .avatar
span.name(v-text="friend.ref.displayName" :style="{'color':friend.ref.$userColour}") img(v-lazy="userImage(friend.ref)")
span(v-else v-text="friend.id") .detail
el-form-item(:label="$t('dialog.new_instance.group_id')" v-if="newInstanceDialog.accessType === 'group'") span.name(v-text="friend.ref.displayName" :style="{'color':friend.ref.$userColour}")
el-select(v-model="newInstanceDialog.groupId" clearable :placeholder="$t('dialog.new_instance.group_placeholder')" filterable style="width:100%") span(v-else v-text="friend.id")
el-option-group(:label="$t('dialog.new_instance.group_placeholder')") el-form-item(:label="$t('dialog.new_instance.group_id')" v-if="newInstanceDialog.accessType === 'group'")
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") el-select(v-model="newInstanceDialog.groupId" clearable :placeholder="$t('dialog.new_instance.group_placeholder')" filterable style="width:100%" @change="buildInstance")
.avatar el-option-group(:label="$t('dialog.new_instance.group_placeholder')")
img(v-lazy="group.iconUrl") 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")
.detail .avatar
span.name(v-text="group.name") img(v-lazy="group.iconUrl")
el-form-item(:label="$t('dialog.new_instance.location')") .detail
el-input(v-model="newInstanceDialog.location" size="mini" readonly) span.name(v-text="group.name")
el-form-item(:label="$t('dialog.new_instance.url')") el-form-item(:label="$t('dialog.new_instance.location')")
el-input(v-model="newInstanceDialog.url" size="mini" readonly @click.native="$event.target.tagName === 'INPUT' && $event.target.select()") el-input(v-model="newInstanceDialog.location" size="mini" readonly)
template(#footer) 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="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="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(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') }} 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 //- 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") 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 //- 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-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 //- 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-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 //- 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") el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" :visible.sync="discordNamesDialogVisible" :title="$t('dialog.discord_names.header')" width="650px")
+12 -3
View File
@@ -477,7 +477,7 @@
"search_result_more": "Search More:", "search_result_more": "Search More:",
"direct_access_tooltip": "Direct access ID/URL from clipboard", "direct_access_tooltip": "Direct access ID/URL from clipboard",
"refresh_tooltip": "Refresh friends", "refresh_tooltip": "Refresh friends",
"groups": "Group Instances", "groups": "Groups",
"friends": "Friends", "friends": "Friends",
"me": "ME", "me": "ME",
"favorite": "FAVORITES", "favorite": "FAVORITES",
@@ -740,6 +740,7 @@
}, },
"info": { "info": {
"header": "Info", "header": "Info",
"instances": "Instances",
"announcement": "Announcement", "announcement": "Announcement",
"instance_full": "full", "instance_full": "full",
"rules": "Rules", "rules": "Rules",
@@ -836,13 +837,19 @@
"instance_creator": "Instance Creator", "instance_creator": "Instance Creator",
"instance_creator_placeholder": "Choose User", "instance_creator_placeholder": "Choose User",
"group_placeholder": "Choose Group", "group_placeholder": "Choose Group",
"role_placeholder": "Choose Roles",
"group_id": "Group", "group_id": "Group",
"location": "Location", "location": "Location",
"url": "URL", "url": "URL",
"copy_url": "Copy URL", "copy_url": "Copy URL",
"self_invite": "Self invite", "self_invite": "Self invite",
"invite": "Invite", "invite": "Invite",
"launch": "Launch" "launch": "Launch",
"create_instance": "Create Instance",
"queueEnabled": "Queue",
"normal": "Normal",
"group": "Group",
"roles": "Roles"
}, },
"launch_options": { "launch_options": {
"header": "VRChat Launch Options", "header": "VRChat Launch Options",
@@ -915,7 +922,9 @@
"launch": "Launch" "launch": "Launch"
}, },
"export_friends_list": { "export_friends_list": {
"header": "Export Friends List" "header": "Export Friends List",
"csv": "CSV",
"json": "JSON"
}, },
"export_own_avatars": { "export_own_avatars": {
"header": "Export Own Avatars" "header": "Export Own Avatars"
+1 -1
View File
@@ -2,7 +2,7 @@ mixin favoritesTab()
.x-container(v-show="$refs.menu && $refs.menu.activeIndex === 'favorite'") .x-container(v-show="$refs.menu && $refs.menu.activeIndex === 'favorite'")
el-tooltip(placement="bottom" :content="$t('view.favorite.refresh_tooltip')" :disabled="hideTooltips") 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-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-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-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') }} el-button(size="small" @click="showFriendExportDialog") {{ $t('view.favorite.export') }}
+3 -1
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(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-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-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(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") el-tag(v-if="currentInstanceWorld.inCache" type="info" effect="plain" size="mini" style="margin-right:5px")
span(v-text="currentInstanceWorld.cacheSize") span(v-text="currentInstanceWorld.cacheSize")
@@ -215,11 +216,12 @@ mixin playerListTab()
template(v-if="scope.row.ref.last_platform") template(v-if="scope.row.ref.last_platform")
span(v-if="scope.row.ref.last_platform === 'standalonewindows'" style="color:#409eff") PC 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 === '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 }} span(v-else) {{ scope.row.ref.last_platform }}
template(v-if="scope.row.inVRMode !== null") template(v-if="scope.row.inVRMode !== null")
span(v-if="scope.row.inVRMode") VR span(v-if="scope.row.inVRMode") VR
span(v-else) D 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") template(v-once #default="scope")
span(v-if="randomUserColours" v-text="scope.row.ref.displayName" :style="{'color':scope.row.ref.$userColour}") 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") span(v-else v-text="scope.row.ref.displayName")
+1 -1
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") 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') }} span.sub-header {{ $t('view.settings.appearance.side_panel.width') }}
div.options-container-item 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 //- Appearance | User Dialog
div.options-container div.options-container
span.header {{ $t('view.settings.appearance.user_dialog.header') }} span.header {{ $t('view.settings.appearance.user_dialog.header') }}
+1
View File
@@ -518,6 +518,7 @@ html
span(v-if="feed.platform === 'Desktop'" style="color:#409eff;margin-left:10px") Desktop 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 === '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 === '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-if="!feed.inCache" style="color:#aaa;margin-left:10px") #[i.el-icon-download]
span(v-text="feed.avatar.name" style="margin-left:10px") span(v-text="feed.avatar.name" style="margin-left:10px")
template(v-else-if="feed.type === 'SpawnEmoji'") template(v-else-if="feed.type === 'SpawnEmoji'")