diff --git a/html/src/app.js b/html/src/app.js index eb8803f7..5034f253 100644 --- a/html/src/app.js +++ b/html/src/app.js @@ -731,6 +731,7 @@ speechSynthesis.getVoices(); privateId: null, friendsId: null, groupId: null, + groupAccessType: null, canRequestInvite: false, strict: false }; @@ -772,6 +773,8 @@ speechSynthesis.getVoices(); ctx.region = value; } else if (key === 'group') { ctx.groupId = value; + } else if (key === 'groupAccessType') { + ctx.groupAccessType = value; } else if (key === 'strict') { ctx.strict = true; } @@ -908,6 +911,11 @@ speechSynthesis.getVoices(); } this.text = instanceId; var L = API.parseLocation(instanceId); + var groupAccessType = ''; + if (L.groupAccessType) { + if (L.groupAccessType === 'public') + groupAccessType = 'Public'; + } if (L.isOffline) { this.text = 'Offline'; } else if (L.isPrivate) { @@ -916,7 +924,7 @@ speechSynthesis.getVoices(); this.text = 'Traveling'; } else if (typeof this.hint === 'string' && this.hint !== '') { if (L.instanceId) { - this.text = `${this.hint} #${L.instanceName} ${L.accessType}`; + this.text = `${this.hint} #${L.instanceName} ${L.accessType}${groupAccessType}`; } else { this.text = this.hint; } @@ -926,14 +934,14 @@ speechSynthesis.getVoices(); $app.getWorldName(L.worldId).then((worldName) => { if (L.tag === instanceId) { if (L.instanceId) { - this.text = `${worldName} #${L.instanceName} ${L.accessType}`; + this.text = `${worldName} #${L.instanceName} ${L.accessType}${groupAccessType}`; } else { this.text = worldName; } } }); } else if (L.instanceId) { - this.text = `${ref.name} #${L.instanceName} ${L.accessType}`; + this.text = `${ref.name} #${L.instanceName} ${L.accessType}${groupAccessType}`; } else { this.text = ref.name; } @@ -994,7 +1002,7 @@ speechSynthesis.getVoices(); template: '' + '' + - '#{{ instanceName }} {{ accessType }}' + + '#{{ instanceName }} {{ accessType }}{{ groupAccessType }}' + '({{ groupName }})' + '' + '', @@ -1012,6 +1020,7 @@ speechSynthesis.getVoices(); location: this.location, instanceName: this.instanceName, accessType: this.accessType, + groupAccessType: this.groupAccessType, region: this.region, shortName: this.shortName, isUnlocked: this.isUnlocked, @@ -1038,6 +1047,13 @@ speechSynthesis.getVoices(); this.isUnlocked = true; } + this.groupAccessType = ''; + if (this.locationobject.groupAccessType) { + if (this.locationobject.groupAccessType === 'public') { + this.groupAccessType = 'Public'; + } + } + this.region = this.locationobject.region; if (!this.region) { this.region = 'us'; @@ -3613,12 +3629,14 @@ speechSynthesis.getVoices(); this.cachedFavoritesByObjectId.clear(); this.cachedFavoriteGroups.clear(); this.cachedFavoriteGroupsByTypeName.clear(); + this.currentUserGroups.clear(); this.favoriteFriendGroups = []; this.favoriteWorldGroups = []; this.favoriteAvatarGroups = []; this.isFavoriteLoading = false; this.isFavoriteGroupLoading = false; this.refreshFavorites(); + $app.getCurrentUserGroups(); }); API.$on('FAVORITE', function (args) { @@ -4570,6 +4588,19 @@ speechSynthesis.getVoices(); break; case 'group-joined': + var groupId = content.groupId; + if ( + $app.groupDialog.visible && + $app.groupDialog.id === groupId + ) { + $app.showGroupDialog(groupId); + } + if (!this.currentUserGroups.has(groupId)) { + this.currentUserGroups.set(groupId); + this.getGroup({ groupId }); + } + break; + case 'group-left': var groupId = content.groupId; if ( @@ -4578,7 +4609,9 @@ speechSynthesis.getVoices(); ) { $app.showGroupDialog(groupId); } + this.currentUserGroups.delete(groupId); break; + case 'group-member-updated': // content { // groupId: string, @@ -5054,6 +5087,7 @@ speechSynthesis.getVoices(); API.getCurrentUser().catch((err1) => { throw err1; }); + AppApi.CheckGameRunning(); } if (--this.nextAppUpdateCheck <= 0) { if (this.branch === 'Stable') { @@ -11725,6 +11759,12 @@ speechSynthesis.getVoices(); } else { var platform = 'VR'; } + var groupAccessType = ''; + if (L.groupAccessType) { + if (L.groupAccessType === 'public') { + groupAccessType = 'Public'; + } + } switch (L.accessType) { case 'public': L.joinUrl = this.getLaunchURL(L); @@ -11746,7 +11786,7 @@ speechSynthesis.getVoices(); L.accessName = `Group #${L.instanceName} (${platform})`; this.getGroupName(L.groupId).then((groupName) => { if (groupName) { - L.accessName = `Group(${groupName}) #${L.instanceName} (${platform})`; + L.accessName = `Group${groupAccessType}(${groupName}) #${L.instanceName} (${platform})`; } }); break; @@ -15461,7 +15501,7 @@ speechSynthesis.getVoices(); json: {} }; } - if (L.isOffline || L.isPrivate || L.isTraveling || L.worldId === '') { + if (!this.isRealInstance(L.tag)) { D.instance = { id: L.instanceId, tag: L.tag, @@ -17474,11 +17514,11 @@ speechSynthesis.getVoices(); }; $app.methods.showInviteDialog = function (tag) { - this.$nextTick(() => adjustDialogZ(this.$refs.inviteDialog.$el)); - var L = API.parseLocation(tag); - if (L.isOffline || L.isPrivate || L.isTraveling || L.worldId === '') { + if (!this.isRealInstance(tag)) { return; } + this.$nextTick(() => adjustDialogZ(this.$refs.inviteDialog.$el)); + var L = API.parseLocation(tag); API.getCachedWorld({ worldId: L.worldId }).then((args) => { @@ -17668,6 +17708,7 @@ speechSynthesis.getVoices(); accessType: '', region: '', groupId: '', + groupAccessType: '', strict: false, location: '', shortName: '', @@ -17700,6 +17741,7 @@ speechSynthesis.getVoices(); tags.push(`~friends(${userId})`); } else if (D.accessType === 'group') { tags.push(`~group(${D.groupId})`); + tags.push(`~groupAccessType(${D.groupAccessType})`); } else { tags.push(`~private(${userId})`); } @@ -17796,6 +17838,10 @@ speechSynthesis.getVoices(); 'instanceDialogGroupId', this.newInstanceDialog.groupId ); + configRepository.setString( + 'instanceDialogGroupAccessType', + this.newInstanceDialog.groupAccessType + ); configRepository.setBool( 'instanceDialogStrict', this.newInstanceDialog.strict @@ -17812,40 +17858,29 @@ speechSynthesis.getVoices(); $app.watch['newInstanceDialog.strict'] = saveNewInstanceDialog; $app.methods.showNewInstanceDialog = function (tag) { - this.$nextTick(() => adjustDialogZ(this.$refs.newInstanceDialog.$el)); - var L = API.parseLocation(tag); - if (L.isOffline || L.isPrivate || L.isTraveling || L.worldId === '') { + if (!this.isRealInstance(tag)) { return; } + this.$nextTick(() => adjustDialogZ(this.$refs.newInstanceDialog.$el)); var D = this.newInstanceDialog; + var L = API.parseLocation(tag); D.worldId = L.worldId; - D.accessType = 'public'; - if (configRepository.getString('instanceDialogAccessType') !== null) { - D.accessType = configRepository.getString( - 'instanceDialogAccessType' - ); - } - D.region = 'US West'; - if (configRepository.getString('instanceRegion') !== null) { - D.region = configRepository.getString('instanceRegion'); - } - D.instanceName = ''; - if (configRepository.getString('instanceDialogInstanceName') !== null) { - D.instanceName = configRepository.getString( - 'instanceDialogInstanceName' - ); - } - D.userId = ''; - if (configRepository.getString('instanceDialogUserId') !== null) { - D.userId = configRepository.getString('instanceDialogUserId'); - } - if (configRepository.getString('instanceDialogGroupId') !== null) { - D.groupId = configRepository.getString('instanceDialogGroupId'); - } + D.accessType = configRepository.getString( + 'instanceDialogAccessType', + 'public' + ); + D.region = configRepository.getString('instanceRegion', 'US West'); + D.instanceName = configRepository.getString( + 'instanceDialogInstanceName', + '' + ); + D.userId = configRepository.getString('instanceDialogUserId', ''); + D.groupId = configRepository.getString('instanceDialogGroupId', ''); + D.groupAccessType = configRepository.getString( + 'instanceDialogGroupAccessType', + 'members' + ); D.strict = false; - // if (configRepository.getBool('instanceDialogStrict') !== null) { - // D.strict = configRepository.getBool('instanceDialogStrict'); - // } D.shortName = ''; this.buildInstance(); this.updateNewInstanceDialog(); @@ -18081,6 +18116,9 @@ speechSynthesis.getVoices(); }; $app.methods.showLaunchDialog = function (tag, shortName) { + if (!this.isRealInstance(tag)) { + return; + } this.$nextTick(() => adjustDialogZ(this.$refs.launchDialog.$el)); var D = this.launchDialog; D.tag = tag; @@ -18089,9 +18127,6 @@ speechSynthesis.getVoices(); D.shortName = shortName; var L = API.parseLocation(tag); L.shortName = shortName; - if (L.isOffline || L.isPrivate || L.isTraveling || L.worldId === '') { - return; - } if (shortName) { D.shortUrl = `https://vrch.at/${shortName}`; } @@ -21514,6 +21549,13 @@ speechSynthesis.getVoices(); userId }; var args = await API.getGroups(params); + if (userId === API.currentUser.id) { + // update current user groups + API.currentUserGroups.clear(); + args.json.forEach((group) => { + API.currentUserGroups.set(group.id, group); + }); + } this.userGroups.groups = args.json; for (var i = 0; i < args.json.length; ++i) { var group = args.json[i]; @@ -21540,6 +21582,15 @@ speechSynthesis.getVoices(); } }; + $app.methods.getCurrentUserGroups = async function () { + var args = await API.getGroups({ n: 100, userId: API.currentUser.id }); + this.inviteGroupDialog.groups = args.json; + API.currentUserGroups.clear(); + args.json.forEach((group) => { + API.currentUserGroups.set(group.id, group); + }); + }; + $app.methods.sortCurrentUserGroups = function () { var groupList = []; var sortGroups = function (a, b) { @@ -24350,6 +24401,7 @@ speechSynthesis.getVoices(); // #region | App: Groups API.cachedGroups = new Map(); + API.currentUserGroups = new Map(); /* params: { @@ -24375,6 +24427,9 @@ speechSynthesis.getVoices(); API.$on('GROUP', function (args) { args.ref = this.applyGroup(args.json); this.cachedGroups.set(args.ref.id, args.ref); + if (this.currentUserGroups.has(args.ref.id)) { + this.currentUserGroups.set(args.ref.id, args.ref); + } }); API.$on('GROUP', function (args) { @@ -24497,6 +24552,7 @@ speechSynthesis.getVoices(); $app.groupDialog.inGroup = json.membershipStatus === 'member'; $app.getGroupDialogGroup(groupId); } + this.currentUserGroups.set(groupId, json); }); /* @@ -24530,6 +24586,7 @@ speechSynthesis.getVoices(); ) { $app.getCurrentUserRepresentedGroup(); } + this.currentUserGroups.delete(groupId); }); /* @@ -25523,10 +25580,6 @@ speechSynthesis.getVoices(); }); this.isAllowedToInviteToGroup(); } - API.getGroups({ n: 100, userId: API.currentUser.id }).then((args) => { - this.inviteGroupDialog.groups = args.json; - D.loading = false; - }); if (userId) { API.getCachedUser({ userId }).then((args) => { diff --git a/html/src/index.pug b/html/src/index.pug index efee978a..dcea952c 100644 --- a/html/src/index.pug +++ b/html/src/index.pug @@ -1156,6 +1156,10 @@ html el-radio-button(label="friends") {{ $t('dialog.new_instance.access_type_friend') }} el-radio-button(label="invite+") {{ $t('dialog.new_instance.access_type_invite_plus') }} el-radio-button(label="invite") {{ $t('dialog.new_instance.access_type_invite') }} + el-form-item(:label="$t('dialog.new_instance.group_access_type')" v-if="newInstanceDialog.accessType === 'group'") + el-radio-group(v-model="newInstanceDialog.groupAccessType" size="mini" @change="buildInstance") + el-radio-button(label="members") {{ $t('dialog.new_instance.group_access_type_members') }} + el-radio-button(label="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')") @@ -1209,7 +1213,13 @@ html 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-input(v-model="newInstanceDialog.groupId" placeholder="grp_UUID" size="mini") + el-select(v-model="newInstanceDialog.groupId" clearable :placeholder="$t('dialog.new_instance.group_placeholder')" filterable style="width:100%") + el-option-group(:label="$t('dialog.new_instance.group_placeholder')") + el-option.x-friend-item(v-for="group in API.currentUserGroups.values()" :key="group.id" :label="group.name" :value="group.id" style="height:auto;width:478px") + .avatar + img(v-lazy="group.iconUrl") + .detail + span.name(v-text="group.name") el-form-item(:label="$t('dialog.new_instance.location')") el-input(v-model="newInstanceDialog.location" size="mini" readonly) el-form-item(:label="$t('dialog.new_instance.url')") diff --git a/html/src/localization/strings/en.json b/html/src/localization/strings/en.json index 5cd8398a..be800b44 100644 --- a/html/src/localization/strings/en.json +++ b/html/src/localization/strings/en.json @@ -814,6 +814,9 @@ "access_type_friend": "Friends", "access_type_invite_plus": "Invite+", "access_type_invite": "Invite", + "group_access_type": "Group Access", + "group_access_type_members": "Members", + "group_access_type_public": "Public", "region": "Region", "region_usw": "US West", "region_use": "US East", @@ -824,7 +827,8 @@ "instance_id_placeholder": "Random", "instance_creator": "Instance Creator", "instance_creator_placeholder": "Choose User", - "group_id": "Group ID", + "group_placeholder": "Choose Group", + "group_id": "Group", "location": "Location", "url": "URL", "copy_url": "Copy URL",