diff --git a/src/app.js b/src/app.js index d9fc564d..fe399f4f 100644 --- a/src/app.js +++ b/src/app.js @@ -65,11 +65,13 @@ import SimpleSwitch from './components/settings/SimpleSwitch.vue'; import Location from './components/common/Location.vue'; // dialogs -import WorldDialog from './views/dialogs/world/WorldDialog.vue'; -import PreviousInstanceInfoDialog from './views/dialogs/previousInstances/PreviousInstanceInfoDialog.vue'; -import FriendImportDialog from './views/dialogs/favorites/FriendImportDialog.vue'; -import WorldImportDialog from './views/dialogs/favorites/WorldImportDialog.vue'; -import AvatarImportDialog from './views/dialogs/favorites/AvatarImportDialog.vue'; +import WorldDialog from './views/dialogs/WorldDialog.vue'; +import PreviousInstanceInfoDialog from './views/dialogs/PreviousInstanceInfoDialog.vue'; +import FriendImportDialog from './views/dialogs/FriendImportDialog.vue'; +import WorldImportDialog from './views/dialogs/WorldImportDialog.vue'; +import AvatarImportDialog from './views/dialogs/AvatarImportDialog.vue'; +import LaunchDialog from './views/dialogs/launch/LaunchDialog.vue'; +import NewInstanceDialog from './views/dialogs/newInstance/NewInstanceDialog.vue'; // main app classes import _sharedFeed from './classes/sharedFeed.js'; @@ -215,12 +217,18 @@ console.log(`isLinux: ${LINUX}`); SimpleSwitch, // - dialogs + // - previous instances PreviousInstanceInfoDialog, + // - world WorldDialog, - // - import dialogs + // - favorites FriendImportDialog, WorldImportDialog, - AvatarImportDialog + AvatarImportDialog, + // - launch + LaunchDialog, + // - new instance + NewInstanceDialog }, provide() { return { @@ -240,7 +248,11 @@ console.log(`isLinux: ${LINUX}`); dialogMouseDown: this.dialogMouseDown, dialogMouseUp: this.dialogMouseUp, showWorldDialog: this.showWorldDialog, - showAvatarDialog: this.showAvatarDialog + showAvatarDialog: this.showAvatarDialog, + showPreviousInstanceInfoDialog: + this.showPreviousInstanceInfoDialog, + showInviteDialog: this.showInviteDialog, + showLaunchDialog: this.showLaunchDialog }; }, el: '#root', @@ -6477,7 +6489,10 @@ console.log(`isLinux: ${LINUX}`); var { notificationId } = args.params; $app.removeFromArray($app.unseenNotifications, notificationId); if ($app.unseenNotifications.length === 0) { - $app.selectMenu('notification'); + const item = this.$refs.menu.$children[0]?.items['notification']; + if (item) { + item.$el.classList.remove('notify'); + } } }); @@ -10849,16 +10864,32 @@ console.log(`isLinux: ${LINUX}`); }; $app.methods.newInstanceSelfInvite = function (worldId) { - this.newInstanceDialog.worldId = worldId; - this.createNewInstance().then((args) => { - if (!args?.json?.location) { + this.createNewInstance(worldId).then((args) => { + const location = args?.json?.location; + if (!location) { this.$message({ message: 'Failed to create instance', type: 'error' }); return; } - this.selfInvite(args.json.location); + // self invite + var L = $utils.parseLocation(location); + if (!L.isRealInstance) { + return; + } + instanceRequest + .selfInvite({ + instanceId: L.instanceId, + worldId: L.worldId + }) + .then((args) => { + this.$message({ + message: 'Self invite sent', + type: 'success' + }); + return args; + }); }); }; @@ -11726,171 +11757,49 @@ console.log(`isLinux: ${LINUX}`); 'drones' ]; - $app.data.newInstanceDialog = { - visible: false, - loading: false, - selectedTab: '0', - instanceCreated: false, - queueEnabled: await configRepository.getBool( - 'instanceDialogQueueEnabled', - true - ), - worldId: '', - instanceId: '', - instanceName: await configRepository.getString( - 'instanceDialogInstanceName', - '' - ), - userId: await configRepository.getString('instanceDialogUserId', ''), - accessType: await configRepository.getString( - 'instanceDialogAccessType', - 'public' - ), - region: await configRepository.getString('instanceRegion', 'US West'), - groupRegion: '', - groupId: await configRepository.getString('instanceDialogGroupId', ''), - groupAccessType: await configRepository.getString( - 'instanceDialogGroupAccessType', - 'plus' - ), - ageGate: await configRepository.getBool('instanceDialogAgeGate', false), - strict: false, - location: '', - shortName: '', - url: '', - secureOrShortName: '', - lastSelectedGroupId: '', - selectedGroupRoles: [], - roleIds: [], - groupRef: {}, - contentSettings: $app.data.instanceContentSettings, - selectedContentSettings: JSON.parse( - await configRepository.getString( - 'instanceDialogSelectedContentSettings', - JSON.stringify($app.data.instanceContentSettings) - ) - ) - }; + $app.methods.createNewInstance = async function (worldId = '', options) { + let D = options; - API.$on('LOGOUT', function () { - $app.newInstanceDialog.visible = false; - }); + if (!D) { + D = { + loading: false, + accessType: await configRepository.getString( + 'instanceDialogAccessType', + 'public' + ), + region: await configRepository.getString( + 'instanceRegion', + 'US West' + ), + worldId: worldId, + groupId: await configRepository.getString( + 'instanceDialogGroupId', + '' + ), + groupAccessType: await configRepository.getString( + 'instanceDialogGroupAccessType', + 'plus' + ), + ageGate: await configRepository.getBool( + 'instanceDialogAgeGate', + false + ), + queueEnabled: await configRepository.getBool( + 'instanceDialogQueueEnabled', + true + ), + contentSettings: this.instanceContentSettings || [], + selectedContentSettings: JSON.parse( + await configRepository.getString( + 'instanceDialogSelectedContentSettings', + JSON.stringify(this.instanceContentSettings || []) + ) + ), + roleIds: [], + groupRef: {} + }; + } - $app.methods.buildLegacyInstance = function () { - var D = this.newInstanceDialog; - D.instanceCreated = false; - D.shortName = ''; - D.secureOrShortName = ''; - var tags = []; - if (D.instanceName) { - D.instanceName = D.instanceName.replace(/[^A-Za-z0-9]/g, ''); - tags.push(D.instanceName); - } else { - var randValue = (99999 * Math.random() + 1).toFixed(0); - tags.push(String(randValue).padStart(5, '0')); - } - if (!D.userId) { - D.userId = API.currentUser.id; - } - var userId = D.userId; - if (D.accessType !== 'public') { - if (D.accessType === 'friends+') { - tags.push(`~hidden(${userId})`); - } else if (D.accessType === 'friends') { - tags.push(`~friends(${userId})`); - } else if (D.accessType === 'group') { - tags.push(`~group(${D.groupId})`); - tags.push(`~groupAccessType(${D.groupAccessType})`); - } else { - tags.push(`~private(${userId})`); - } - if (D.accessType === 'invite+') { - tags.push('~canRequestInvite'); - } - } - if (D.accessType === 'group' && D.ageGate) { - tags.push('~ageGate'); - } - if (D.region === 'US West') { - tags.push(`~region(us)`); - } else if (D.region === 'US East') { - tags.push(`~region(use)`); - } else if (D.region === 'Europe') { - tags.push(`~region(eu)`); - } else if (D.region === 'Japan') { - tags.push(`~region(jp)`); - } - if (D.accessType !== 'invite' && D.accessType !== 'friends') { - D.strict = false; - } - 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.groupRef = ref; - 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.groupRef = {}; - D.lastSelectedGroupId = ''; - } - D.instanceId = tags.join(''); - this.updateNewInstanceDialog(false); - this.saveNewInstanceDialog(); - }; - - $app.methods.buildInstance = function () { - var D = this.newInstanceDialog; - D.instanceCreated = false; - D.instanceId = ''; - D.shortName = ''; - D.secureOrShortName = ''; - if (!D.userId) { - D.userId = API.currentUser.id; - } - if (D.groupId && D.groupId !== D.lastSelectedGroupId) { - D.roleIds = []; - var ref = API.cachedGroups.get(D.groupId); - if (typeof ref !== 'undefined') { - D.groupRef = ref; - 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.groupRef = {}; - D.selectedGroupRoles = []; - D.lastSelectedGroupId = ''; - } - this.saveNewInstanceDialog(); - }; - - $app.methods.createNewInstance = async function () { - var D = this.newInstanceDialog; - if (D.loading) { - return; - } - D.loading = true; var type = 'public'; var canRequestInvite = false; switch (D.accessType) { @@ -11955,135 +11864,19 @@ console.log(`isLinux: ${LINUX}`); } try { var args = await instanceRequest.createInstance(params); - D.location = args.json.location; - D.instanceId = args.json.instanceId; - D.secureOrShortName = args.json.shortName || args.json.secureName; - D.instanceCreated = true; - this.updateNewInstanceDialog(); - D.loading = false; return args; } catch (err) { - D.loading = false; console.error(err); return null; } }; - $app.methods.selfInvite = function (location, shortName) { - var L = $utils.parseLocation(location); - if (!L.isRealInstance) { - return; - } - instanceRequest - .selfInvite({ - instanceId: L.instanceId, - worldId: L.worldId, - shortName - }) - .then((args) => { - this.$message({ - message: 'Self invite sent', - type: 'success' - }); - return args; - }); - }; - - $app.methods.updateNewInstanceDialog = function (noChanges) { - var D = this.newInstanceDialog; - if (D.instanceId) { - D.location = `${D.worldId}:${D.instanceId}`; - } else { - D.location = D.worldId; - } - var L = $utils.parseLocation(D.location); - if (noChanges) { - L.shortName = D.shortName; - } else { - D.shortName = ''; - } - D.url = this.getLaunchURL(L); - }; - - $app.methods.saveNewInstanceDialog = async function () { - await configRepository.setString( - 'instanceDialogAccessType', - this.newInstanceDialog.accessType - ); - await configRepository.setString( - 'instanceRegion', - this.newInstanceDialog.region - ); - await configRepository.setString( - 'instanceDialogInstanceName', - this.newInstanceDialog.instanceName - ); - if (this.newInstanceDialog.userId === API.currentUser.id) { - await configRepository.setString('instanceDialogUserId', ''); - } else { - await configRepository.setString( - 'instanceDialogUserId', - this.newInstanceDialog.userId - ); - } - await configRepository.setString( - 'instanceDialogGroupId', - this.newInstanceDialog.groupId - ); - await configRepository.setString( - 'instanceDialogGroupAccessType', - this.newInstanceDialog.groupAccessType - ); - await configRepository.setBool( - 'instanceDialogQueueEnabled', - this.newInstanceDialog.queueEnabled - ); - await configRepository.setBool( - 'instanceDialogAgeGate', - this.newInstanceDialog.ageGate - ); - await configRepository.setString( - 'instanceDialogSelectedContentSettings', - JSON.stringify(this.newInstanceDialog.selectedContentSettings) - ); - }; + $app.data.newInstanceDialogLocationTag = ''; $app.methods.showNewInstanceDialog = async function (tag) { - if (!$utils.isRealInstance(tag)) { - return; - } - this.$nextTick(() => - $app.adjustDialogZ(this.$refs.newInstanceDialog.$el) - ); - var D = this.newInstanceDialog; - var L = $utils.parseLocation(tag); - if (D.worldId === L.worldId) { - // reopening dialog, keep last open instance - D.visible = true; - return; - } - D.worldId = L.worldId; - D.instanceCreated = false; - D.lastSelectedGroupId = ''; - D.selectedGroupRoles = []; - D.groupRef = {}; - D.roleIds = []; - D.strict = false; - D.shortName = ''; - D.secureOrShortName = ''; - API.getGroupPermissions({ userId: API.currentUser.id }); - this.buildInstance(); - this.buildLegacyInstance(); - this.updateNewInstanceDialog(); - D.visible = true; - }; - - $app.methods.newInstanceTabClick = function (tab) { - if (tab === '1') { - this.buildInstance(); - } else { - this.buildLegacyInstance(); - } + // trigger watcher + this.newInstanceDialogLocationTag = ''; + this.$nextTick(() => (this.newInstanceDialogLocationTag = tag)); }; $app.methods.makeHome = function (tag) { @@ -12642,92 +12435,22 @@ console.log(`isLinux: ${LINUX}`); // #endregion // #region | App: Launch Dialog - $app.data.launchDialog = { + $app.data.launchDialogData = { visible: false, loading: false, - desktop: await configRepository.getBool('launchAsDesktop'), tag: '', - location: '', - url: '', - shortName: '', - shortUrl: '', - secureOrShortName: '' + shortName: '' }; - $app.methods.saveLaunchDialog = async function () { - await configRepository.setBool( - 'launchAsDesktop', - this.launchDialog.desktop - ); - }; - - API.$on('LOGOUT', function () { - $app.launchDialog.visible = false; - }); - - API.$on('INSTANCE:SHORTNAME', function (args) { - if (!args.json) { - return; - } - var shortName = args.json.shortName; - var secureOrShortName = args.json.shortName || args.json.secureName; - var location = `${args.instance.worldId}:${args.instance.instanceId}`; - if (location === $app.launchDialog.tag) { - var L = $utils.parseLocation(location); - L.shortName = shortName; - $app.launchDialog.shortName = shortName; - $app.launchDialog.secureOrShortName = secureOrShortName; - if (shortName) { - $app.launchDialog.shortUrl = `https://vrch.at/${shortName}`; - } - $app.launchDialog.url = $app.getLaunchURL(L); - } - if (location === $app.newInstanceDialog.location) { - $app.newInstanceDialog.shortName = shortName; - $app.newInstanceDialog.secureOrShortName = secureOrShortName; - $app.updateNewInstanceDialog(true); - } - }); - - $app.methods.addShortNameToFullUrl = function (input, shortName) { - if (input.trim().length === 0 || !shortName) { - return input; - } - var url = new URL(input); - var urlParams = new URLSearchParams(url.search); - urlParams.set('shortName', shortName); - url.search = urlParams.toString(); - return url.toString(); - }; - - $app.methods.showLaunchDialog = function (tag, shortName) { - if (!$utils.isRealInstance(tag)) { - return; - } - this.$nextTick(() => $app.adjustDialogZ(this.$refs.launchDialog.$el)); - var D = this.launchDialog; - D.tag = tag; - D.secureOrShortName = shortName; - D.shortUrl = ''; - D.shortName = shortName; - var L = $utils.parseLocation(tag); - L.shortName = shortName; - if (shortName) { - D.shortUrl = `https://vrch.at/${shortName}`; - } - if (L.instanceId) { - D.location = `${L.worldId}:${L.instanceId}`; - } else { - D.location = L.worldId; - } - D.url = this.getLaunchURL(L); - D.visible = true; - if (!shortName) { - instanceRequest.getInstanceShortName({ - worldId: L.worldId, - instanceId: L.instanceId - }); - } + $app.methods.showLaunchDialog = async function (tag, shortName) { + this.launchDialogData = { + visible: true, + // flag, use for trigger adjustDialogZ + loading: true, + tag, + shortName + }; + this.$nextTick(() => (this.launchDialogData.loading = false)); }; $app.methods.getLaunchURL = function (instance) { @@ -12754,7 +12477,6 @@ console.log(`isLinux: ${LINUX}`); shortName, desktopMode ) { - var D = this.launchDialog; var L = $utils.parseLocation(location); var args = []; if ( @@ -12787,8 +12509,14 @@ console.log(`isLinux: ${LINUX}`); args.push(`vrchat://launch?ref=vrcx.app&id=${location}`); } } - var { launchArguments, vrcLaunchPathOverride } = - this.launchOptionsDialog; + + const launchArguments = + await configRepository.getString('launchArguments'); + + const vrcLaunchPathOverride = await configRepository.getString( + 'vrcLaunchPathOverride' + ); + if (launchArguments) { args.push(launchArguments); } @@ -12830,7 +12558,6 @@ console.log(`isLinux: ${LINUX}`); }); } console.log('Launch Game', args.join(' '), desktopMode); - D.visible = false; }; // #endregion @@ -12850,28 +12577,6 @@ console.log(`isLinux: ${LINUX}`); document.getElementById('copy_to_clipboard').remove(); }; - $app.methods.copyInstanceMessage = function (input) { - this.copyToClipboard(input); - this.$message({ - message: 'Instance copied to clipboard', - type: 'success' - }); - return input; - }; - - $app.methods.copyInstanceUrl = async function (location) { - var L = $utils.parseLocation(location); - var args = await instanceRequest.getInstanceShortName({ - worldId: L.worldId, - instanceId: L.instanceId - }); - if (args.json && args.json.shortName) { - L.shortName = args.json.shortName; - } - var newUrl = this.getLaunchURL(L); - this.copyInstanceMessage(newUrl); - }; - $app.methods.copyAvatarId = function (avatarId) { this.$message({ message: 'Avatar ID copied to clipboard', @@ -16988,6 +16693,25 @@ console.log(`isLinux: ${LINUX}`); resolution = '128', isUserDialogIcon = false ) { + function convertFileUrlToImageUrl(url) { + /** + * possible patterns? + * /file/file_fileId/version + * /file/file_fileId/version/ + * /file/file_fileId/version/file + * /file/file_fileId/version/file/ + */ + const pattern = /file\/file_([a-f0-9-]+)\/(\d+)(\/file)?\/?$/; + const match = url.match(pattern); + + if (match) { + const fileId = match[1]; + const version = match[2]; + return `https://api.vrchat.cloud/api/1/image/file_${fileId}/${version}/${resolution}`; + } + // return /image/file_fileId url? + return url; + } if (!user) { return ''; } @@ -16996,10 +16720,7 @@ console.log(`isLinux: ${LINUX}`); (this.displayVRCPlusIconsAsAvatar && user.userIcon) ) { if (isIcon) { - const baseUrl = user.userIcon.replace('/file/', '/image/'); - return user.userIcon.endsWith('/') - ? `${baseUrl}${resolution}` - : `${baseUrl}/${resolution}`; + return convertFileUrlToImageUrl(user.userIcon); } return user.userIcon; } @@ -17007,8 +16728,8 @@ console.log(`isLinux: ${LINUX}`); if (user.profilePicOverrideThumbnail) { if (isIcon) { return user.profilePicOverrideThumbnail.replace( - '256', - resolution + '/256', + `/${resolution}` ); } return user.profilePicOverrideThumbnail; @@ -17022,21 +16743,15 @@ console.log(`isLinux: ${LINUX}`); if (user.currentAvatarThumbnailImageUrl) { if (isIcon) { return user.currentAvatarThumbnailImageUrl.replace( - '256', - resolution + '/256', + `/${resolution}` ); } return user.currentAvatarThumbnailImageUrl; } if (user.currentAvatarImageUrl) { if (isIcon) { - const baseUrl = user.currentAvatarImageUrl.replace( - '/file/', - '/image/' - ); - const url = baseUrl.split('/'); - url[url.length - 1] = resolution; - return url.join('/'); + return convertFileUrlToImageUrl(user.currentAvatarImageUrl); } return user.currentAvatarImageUrl; } @@ -20406,6 +20121,38 @@ console.log(`isLinux: ${LINUX}`); }; }; + $app.computed.launchDialogBind = function () { + return { + 'check-can-invite': this.checkCanInvite, + 'launch-dialog-data': this.launchDialogData, + 'hide-tooltips': this.hideTooltips, + 'get-launch-u-r-l': this.getLaunchURL + }; + }; + + $app.computed.launchDialogEvent = function () { + return { + 'update:launch-dialog-data': (event) => + (this.launchDialogData = event), + 'launch-game': this.launchGame + }; + }; + + $app.computed.newInstanceDialogBind = function () { + return { + 'new-instance-dialog-location-tag': + this.newInstanceDialogLocationTag, + 'create-new-instance': this.createNewInstance, + 'instance-content-settings': this.instanceContentSettings, + 'offline-friends': this.offlineFriends, + 'active-friends': this.activeFriends, + 'online-friends': this.onlineFriends, + 'vip-friends': this.vipFriends, + 'get-launch-u-r-l': this.getLaunchURL, + 'has-group-permission': this.hasGroupPermission + }; + }; + // #endregion // #region | Electron diff --git a/src/app.pug b/src/app.pug index 6aed1000..2a7b00e2 100644 --- a/src/app.pug +++ b/src/app.pug @@ -92,9 +92,6 @@ doctype html include ./mixins/dialogs/images.pug +images - include ./mixins/dialogs/newInstance.pug - +newInstance - include ./mixins/dialogs/feedFilters.pug +feedFilters @@ -137,4 +134,8 @@ doctype html avatar-import-dialog(v-bind='avatarImportDialogBind' v-on='avatarImportDialogEvent') + launch-dialog(v-bind='launchDialogBind' v-on='launchDialogEvent') + + new-instance-dialog(v-bind='newInstanceDialogBind') + //- el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" ref="templateDialog" :visible.sync="templateDialog.visible" :title="$t('dialog.template_dialog.header')" width="450px") diff --git a/src/classes/groups.js b/src/classes/groups.js index 535cd970..9c2fe8a4 100644 --- a/src/classes/groups.js +++ b/src/classes/groups.js @@ -1188,7 +1188,8 @@ export default class extends baseClass { json, params }; - this.$emit('GROUP:ROLES', args); + // useless code? + // this.$emit('GROUP:ROLES', args); return args; }); }; diff --git a/src/classes/request/instance.js b/src/classes/request/instance.js index a634dc27..08bce4d9 100644 --- a/src/classes/request/instance.js +++ b/src/classes/request/instance.js @@ -71,7 +71,6 @@ const instanceReq = { instance, params }; - window.API.$emit('INSTANCE:SHORTNAME', args); return args; }); }, @@ -95,7 +94,7 @@ const instanceReq = { /** * Send invite to current user. - * @param {{ worldId: string, instanceId: string, shortName: string }} instance + * @param {{ worldId: string, instanceId: string, shortName?: string }} instance * @returns {Promise<{instance, json: any, params}>} */ selfInvite(instance) { diff --git a/src/classes/uiComponents.js b/src/classes/uiComponents.js index ee071fd4..972754f2 100644 --- a/src/classes/uiComponents.js +++ b/src/classes/uiComponents.js @@ -1,7 +1,8 @@ import Vue from 'vue'; import VueMarkdown from 'vue-markdown'; import { baseClass, $app, API, $t, $utils } from './baseClass.js'; -import { userRequest } from './request'; +import { instanceRequest, userRequest } from './request'; +import utils from './utils'; export default class extends baseClass { constructor(_app, _API, _t) { @@ -56,7 +57,26 @@ export default class extends baseClass { : 'none'; }, confirm() { - $app.selfInvite(this.location, this.shortname); + this.selfInvite(this.location, this.shortname); + }, + selfInvite(location, shortName) { + const L = utils.parseLocation(location); + if (!L.isRealInstance) { + return; + } + instanceRequest + .selfInvite({ + instanceId: L.instanceId, + worldId: L.worldId, + shortName + }) + .then((args) => { + this.$message({ + message: 'Self invite sent', + type: 'success' + }); + return args; + }); } }, watch: { diff --git a/src/mixins/dialogs/launch.pug b/src/mixins/dialogs/launch.pug index 3400dc66..14066d1e 100644 --- a/src/mixins/dialogs/launch.pug +++ b/src/mixins/dialogs/launch.pug @@ -1,73 +1,4 @@ mixin launch - //- dialog: launch - el-dialog.x-dialog( - :before-close='beforeDialogClose' - @mousedown.native='dialogMouseDown' - @mouseup.native='dialogMouseUp' - ref='launchDialog' - :visible.sync='launchDialog.visible' - :title='$t("dialog.launch.header")' - width='450px') - el-form(:model='launchDialog' label-width='100px') - el-form-item(:label='$t("dialog.launch.url")') - el-input( - v-model='launchDialog.url' - size='mini' - @click.native='$event.target.tagName === "INPUT" && $event.target.select()' - style='width: 260px') - el-tooltip(placement='right' :content='$t("dialog.launch.copy_tooltip")' :disabled='hideTooltips') - el-button( - @click='copyInstanceMessage(launchDialog.url)' - size='mini' - icon='el-icon-s-order' - style='margin-left: 5px' - circle) - el-form-item(v-if='launchDialog.shortUrl') - template(#label) - span {{ $t('dialog.launch.short_url') }} - el-tooltip( - placement='top' - style='margin-left: 5px' - :content='$t("dialog.launch.short_url_notice")') - i.el-icon-warning - el-input( - v-model='launchDialog.shortUrl' - size='mini' - @click.native='$event.target.tagName === "INPUT" && $event.target.select()' - style='width: 260px') - el-tooltip(placement='right' :content='$t("dialog.launch.copy_tooltip")' :disabled='hideTooltips') - el-button( - @click='copyInstanceMessage(launchDialog.shortUrl)' - size='mini' - icon='el-icon-s-order' - style='margin-left: 5px' - circle) - el-form-item(:label='$t("dialog.launch.location")') - el-input( - v-model='launchDialog.location' - size='mini' - @click.native='$event.target.tagName === "INPUT" && $event.target.select()' - style='width: 260px') - el-tooltip(placement='right' :content='$t("dialog.launch.copy_tooltip")' :disabled='hideTooltips') - el-button( - @click='copyInstanceMessage(launchDialog.location)' - size='mini' - icon='el-icon-s-order' - style='margin-left: 5px' - circle) - el-checkbox(v-model='launchDialog.desktop' @change='saveLaunchDialog' style='float: left; margin-top: 5px') {{ $t('dialog.launch.start_as_desktop') }} - template(#footer) - el-button(size='small' @click='showPreviousInstanceInfoDialog(launchDialog.location)') {{ $t('dialog.launch.info') }} - el-button( - size='small' - @click='showInviteDialog(launchDialog.location)' - :disabled='!checkCanInvite(launchDialog.location)') {{ $t('dialog.launch.invite') }} - el-button( - type='primary' - size='small' - @click='launchGame(launchDialog.location, launchDialog.shortName, launchDialog.desktop)' - :disabled='!launchDialog.secureOrShortName') {{ $t('dialog.launch.launch') }} - //- dialog: launch options el-dialog.x-dialog( :before-close='beforeDialogClose' diff --git a/src/mixins/dialogs/newInstance.pug b/src/mixins/dialogs/newInstance.pug deleted file mode 100644 index 3040c6a7..00000000 --- a/src/mixins/dialogs/newInstance.pug +++ /dev/null @@ -1,308 +0,0 @@ -mixin newInstance - 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-tabs(type='card' v-model='newInstanceDialog.selectedTab' @tab-click='newInstanceTabClick') - el-tab-pane(:label='$t("dialog.new_instance.normal")') - el-form(v-if='newInstanceDialog.visible' :model='newInstanceDialog' label-width='150px') - 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' - :disabled='!hasGroupPermission(newInstanceDialog.groupRef, "group-instance-open-create")') {{ $t('dialog.new_instance.group_access_type_members') }} - el-radio-button( - label='plus' - :disabled='!hasGroupPermission(newInstanceDialog.groupRef, "group-instance-plus-create")') {{ $t('dialog.new_instance.group_access_type_plus') }} - el-radio-button( - label='public' - :disabled='!hasGroupPermission(newInstanceDialog.groupRef, "group-instance-public-create") || newInstanceDialog.groupRef.privacy === "private"') {{ $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.content_settings")') - el-select( - v-model='newInstanceDialog.selectedContentSettings' - multiple - :placeholder='$t("dialog.new_instance.content_placeholder")' - style='width: 100%' - @change='buildInstance') - el-option-group(:label='$t("dialog.new_instance.content_placeholder")') - el-option.x-friend-item(value='emoji' :label='$t("dialog.new_instance.content_emoji")') - el-option.x-friend-item( - value='stickers' - :label='$t("dialog.new_instance.content_stickers")') - el-option.x-friend-item( - value='pedestals' - :label='$t("dialog.new_instance.content_pedestals")') - el-option.x-friend-item( - value='prints' - :label='$t("dialog.new_instance.content_prints")') - el-option.x-friend-item( - value='drones' - :label='$t("dialog.new_instance.content_drones")') - el-form-item( - :label='$t("dialog.new_instance.queueEnabled")' - v-if='newInstanceDialog.accessType === "group"') - el-checkbox(v-model='newInstanceDialog.queueEnabled' @change='buildInstance') - el-form-item( - :label='$t("dialog.new_instance.ageGate")' - v-if='newInstanceDialog.accessType === "group"') - el-checkbox( - v-model='newInstanceDialog.ageGate' - @change='buildInstance' - :disabled='!hasGroupPermission(newInstanceDialog.groupRef, "group-instance-age-gated-create")') - 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 && (hasGroupPermission(group, "group-instance-public-create") || hasGroupPermission(group, "group-instance-plus-create") || hasGroupPermission(group, "group-instance-open-create"))' - 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.accessType === "group" && 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) - el-tab-pane(:label='$t("dialog.new_instance.legacy")') - el-form(v-if='newInstanceDialog.visible' :model='newInstanceDialog' label-width='150px') - el-form-item(:label='$t("dialog.new_instance.access_type")') - el-radio-group( - v-model='newInstanceDialog.accessType' - size='mini' - @change='buildLegacyInstance') - 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='buildLegacyInstance') - 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='buildLegacyInstance') - 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.ageGate")' - v-if='newInstanceDialog.accessType === "group"') - el-checkbox(v-model='newInstanceDialog.ageGate' @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='buildLegacyInstance') - 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='buildLegacyInstance') - 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='buildLegacyInstance') - 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='vipFriends.length' :label='$t("side_panel.favorite")') - el-option.x-friend-item( - v-for='friend in vipFriends' - :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='onlineFriends.length' :label='$t("side_panel.online")') - el-option.x-friend-item( - v-for='friend in onlineFriends' - :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='activeFriends.length' :label='$t("side_panel.active")') - el-option.x-friend-item( - v-for='friend in activeFriends' - :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='offlineFriends.length' :label='$t("side_panel.offline")') - el-option.x-friend-item( - v-for='friend in offlineFriends' - :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='buildLegacyInstance') - 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 - @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) - template(#footer v-if='newInstanceDialog.selectedTab === "0"') - 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.shortName)') {{ $t('dialog.new_instance.launch') }} - template(v-else) - el-button(type='primary' size='small' @click='createNewInstance()') {{ $t('dialog.new_instance.create_instance') }} - template(#footer v-else-if='newInstanceDialog.selectedTab === "1"') - 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.shortName)') {{ $t('dialog.new_instance.launch') }} diff --git a/src/mixins/dialogs/worldDialog.pug b/src/mixins/dialogs/worldDialog.pug index 605bed31..3b16faae 100644 --- a/src/mixins/dialogs/worldDialog.pug +++ b/src/mixins/dialogs/worldDialog.pug @@ -6,13 +6,10 @@ mixin worldDialog :last-location='lastLocation' :instance-join-history='instanceJoinHistory' :update-instance-info='updateInstanceInfo' - @show-fullscreen-image-dialog='showFullscreenImageDialog' @open-folder-generic='openFolderGeneric' @delete-vrchat-cache='deleteVRChatCache' @world-dialog-command='worldDialogCommand' - @show-launch-dialog='showLaunchDialog' @refresh-instance-player-count='refreshInstancePlayerCount' - @show-previous-instance-info-dialog='showPreviousInstanceInfoDialog' @show-previous-instances-world-dialog='showPreviousInstancesWorldDialog' @download-and-save-json='downloadAndSaveJson') diff --git a/src/views/dialogs/launch/LaunchDialog.vue b/src/views/dialogs/launch/LaunchDialog.vue new file mode 100644 index 00000000..b92789b1 --- /dev/null +++ b/src/views/dialogs/launch/LaunchDialog.vue @@ -0,0 +1,228 @@ + + + diff --git a/src/views/dialogs/newInstance/NewInstanceDialog.vue b/src/views/dialogs/newInstance/NewInstanceDialog.vue new file mode 100644 index 00000000..6d325ca3 --- /dev/null +++ b/src/views/dialogs/newInstance/NewInstanceDialog.vue @@ -0,0 +1,877 @@ + + + diff --git a/src/views/dialogs/world/WorldDialog.vue b/src/views/dialogs/world/WorldDialog.vue index a8c89672..c03df9a1 100644 --- a/src/views/dialogs/world/WorldDialog.vue +++ b/src/views/dialogs/world/WorldDialog.vue @@ -740,7 +740,16 @@ import database from '../../../repository/database.js'; export default { name: 'WorldDialog', - inject: ['API', 'showUserDialog', 'userStatusClass', 'userImage', 'adjustDialogZ'], + inject: [ + 'API', + 'showUserDialog', + 'userStatusClass', + 'userImage', + 'adjustDialogZ', + 'showPreviousInstanceInfoDialog', + 'showLaunchDialog', + 'showFullscreenImageDialog' + ], props: { worldDialog: Object, hideTooltips: Boolean, @@ -819,9 +828,6 @@ } }, methods: { - showFullscreenImageDialog(imageUrl) { - this.$emit('show-fullscreen-image-dialog', imageUrl); - }, openFolderGeneric(path) { this.$emit('open-folder-generic', path); }, @@ -835,15 +841,9 @@ this.$emit('world-dialog-command', command); } }, - showLaunchDialog(location, shortName) { - this.$emit('show-launch-dialog', location, shortName); - }, refreshInstancePlayerCount(tag) { this.$emit('refresh-instance-player-count', tag); }, - showPreviousInstanceInfoDialog(location) { - this.$emit('show-previous-instance-info-dialog', location); - }, onWorldMemoChange() { const worldId = this.worldDialog.id; const memo = this.worldDialog.memo;