diff --git a/html/src/app.js b/html/src/app.js index a81a5547..f575fc57 100644 --- a/html/src/app.js +++ b/html/src/app.js @@ -15632,6 +15632,111 @@ speechSynthesis.getVoices(); this.updateTimers(); }; + $app.methods.applyGroupDialogInstances = function (inputInstances) { + var D = this.groupDialog; + if (!D.visible) { + return; + } + var instances = {}; + for (var instance of inputInstances) { + instances[instance.location] = { + id: instance.instanceId, + tag: instance.location, + occupants: instance.memberCount, + friendCount: 0, + users: [] + }; + } + var currentLocation = this.lastLocation.location; + if (this.lastLocation.location === 'traveling') { + currentLocation = this.lastLocationDestination; + } + var lastLocation$ = API.parseLocation(currentLocation); + var playersInInstance = this.lastLocation.playerList; + if (lastLocation$.groupId === D.id && playersInInstance.size > 0) { + var friendsInInstance = this.lastLocation.friendList; + var instance = { + id: lastLocation$.instanceId, + tag: currentLocation, + occupants: playersInInstance.size, + friendCount: friendsInInstance.size, + users: [] + }; + instances[currentLocation] = instance; + var ref = API.cachedUsers.get(API.currentUser.id); + if (typeof ref === 'undefined') { + ref = API.currentUser; + } + if (playersInInstance.has(ref.displayName)) { + instance.users.push(ref); // add self + } + for (var friend of friendsInInstance.values()) { + // if friend isn't in instance add them + var addUser = true; + for (var k = 0; k < instance.users.length; k++) { + var user = instance.users[k]; + if (friend.displayName === user.displayName) { + addUser = false; + break; + } + } + if (addUser) { + var ref = API.cachedUsers.get(friend.userId); + if (typeof ref !== 'undefined') { + instance.users.push(ref); + } + } + } + } + for (var {ref} of this.friends.values()) { + if ( + typeof ref === 'undefined' || + typeof ref.$location === 'undefined' || + ref.$location.groupId !== D.id || + (ref.$location.instanceId === lastLocation$.instanceId && + playersInInstance.size > 0) + ) { + continue; + } + var {instanceId, tag} = ref.$location; + var instance = instances[tag]; + if (typeof instance === 'undefined') { + instance = { + id: instanceId, + tag, + occupants: 0, + friendCount: 0, + users: [] + }; + instances[tag] = instance; + } + instance.users.push(ref); + } + var rooms = []; + for (var instance of Object.values(instances)) { + // due to references on callback of API.getUser() + // this should be block scope variable + const L = API.parseLocation(instance.tag); + instance.location = instance.tag; + instance.$location = L; + if (instance.friendCount === 0) { + instance.friendCount = instance.users.length; + } + if (this.instanceUsersSortAlphabetical) { + instance.users.sort(compareByDisplayName); + } else { + instance.users.sort(compareByLocationAt); + } + rooms.push(instance); + } + // sort by more friends, occupants + rooms.sort(function (a, b) { + return b.users.length - a.users.length || b.occupants - a.occupants; + }); + D.instances = rooms; + this.updateTimers(); + }; + $app.methods.worldDialogCommand = function (command) { var D = this.worldDialog; if (D.visible === false) { @@ -22763,7 +22868,7 @@ speechSynthesis.getVoices(); }); if ($app.groupDialog.visible && $app.groupDialog.id === groupId) { $app.groupDialog.inGroup = json.membershipStatus === 'member'; - this.getGroup({groupId}); + this.getGroupDialogGroup(groupId); } }); @@ -22789,7 +22894,7 @@ speechSynthesis.getVoices(); var groupId = args.params.groupId; if ($app.groupDialog.visible && $app.groupDialog.id === groupId) { $app.groupDialog.inGroup = false; - this.getGroup({groupId}); + this.getGroupDialogGroup(groupId); } if ( $app.userDialog.visible && @@ -23032,6 +23137,38 @@ speechSynthesis.getVoices(); }); }; + /* + params: { + groupId: string + } + */ + + API.getGroupInstances = function (params) { + return this.call(`groups/${params.groupId}/instances`, { + method: 'GET', + params + }).then((json) => { + var args = { + json, + params + }; + this.$emit('GROUP:INSTANCES', args); + return args; + }); + }; + + API.$on('GROUP:INSTANCES', function (args) { + for (var json of args.json) { + this.$emit('WORLD', { + json: json.world, + params: { + worldId: json.world.id + } + }); + json.world = this.applyWorld(json.world); + } + }); + /* params: { groupId: string @@ -23163,7 +23300,8 @@ speechSynthesis.getVoices(); announcementDisplayName: '', ref: {}, announcement: {}, - members: [] + members: [], + instances: [] }; $app.methods.showGroupDialog = function (groupId) { @@ -23180,6 +23318,7 @@ speechSynthesis.getVoices(); D.announcementDisplayName = ''; D.treeData = []; D.announcement = {}; + D.instances = []; if (this.groupDialogLastMembers !== groupId) { D.members = []; } @@ -23249,6 +23388,13 @@ speechSynthesis.getVoices(); } } }); + API.getGroupInstances({ + groupId + }).then((args3) => { + if (groupId === args3.params.groupId) { + this.applyGroupDialogInstances(args3.json); + } + }); } if (this.$refs.groupDialogTabs.currentName === '0') { this.groupDialogLastActiveTab = 'Info'; diff --git a/html/src/index.pug b/html/src/index.pug index 7a87f9fd..5e2ea20a 100644 --- a/html/src/index.pug +++ b/html/src/index.pug @@ -1481,7 +1481,9 @@ html template(v-if="item.ref") .detail span.name(v-text="item.ref.displayName" :style="{'color':item.ref.$userColour}") - location.extra(:location="item.ref.location" :traveling="item.ref.travelingToLocation" :link="false") + span.extra(v-if="item.ref.state === 'offline'") Offline + span.extra(v-else-if="item.ref.state === 'active'") Active + location.extra(v-else :location="item.ref.location" :traveling="item.ref.travelingToLocation" :link="false") img.avatar(v-lazy="userImage(item.ref)") span(v-else) Search More: #[span(v-text="item.label" style="font-weight:bold")] el-tooltip(placement="bottom" content="Direct access ID/URL from clipboard" :disabled="hideTooltips") @@ -1644,12 +1646,12 @@ html template(v-if="lastLocation.location && isGameRunning && checkCanInvite(lastLocation.location)") el-dropdown-item(icon="el-icon-message" command="Invite") Invite el-dropdown-item(icon="el-icon-message" command="Invite Message") Invite With Message - el-dropdown-item(icon="el-icon-message" command="Invite To Group") Invite To Group template(v-else-if="userDialog.incomingRequest") el-dropdown-item(icon="el-icon-check" command="Accept Friend Request") Accept Friend Request el-dropdown-item(icon="el-icon-close" command="Decline Friend Request") Decline Friend Request el-dropdown-item(v-else-if="userDialog.outgoingRequest" icon="el-icon-close" command="Cancel Friend Request") Cancel Friend Request el-dropdown-item(v-else icon="el-icon-plus" command="Send Friend Request") Send Friend Request + el-dropdown-item(icon="el-icon-message" command="Invite To Group") Invite To Group el-dropdown-item(icon="el-icon-s-custom" command="Show Avatar Author" divided) Show Avatar Author el-dropdown-item(icon="el-icon-s-custom" command="Show Fallback Avatar Details") Show Fallback Avatar Details el-dropdown-item(icon="el-icon-tickets" command="Previous Instances") Show Previous Instances @@ -2267,6 +2269,25 @@ html 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(style="margin:5px 0") + location(:location="room.tag") + el-tooltip(placement="top" content="Invite yourself" :disabled="hideTooltips") + invite-yourself(:location="room.tag" style="margin-left:5px") + el-tooltip(placement="top" content="Refresh player count" :disabled="hideTooltips") + el-button(v-if="room.tag !== lastLocation.location" @click="refreshInstancePlayerCount(room.tag)" size="mini" icon="el-icon-refresh" style="margin-left:5px" circle) + span(v-if="room.occupants" style="margin-left:5px") {{ room.occupants }} #[template(v-if="room.friendCount > 0") ({{ room.friendCount }})] + .x-friend-list(style="margin:10px 0;max-height:unset" v-if="room.users.length") + .x-friend-item(v-for="user in room.users" :key="user.id" @click="showUserDialog(user.id)" class="x-friend-item-border") + .avatar(:class="userStatusClass(user)") + img(v-lazy="userImage(user)") + .detail + span.name(v-text="user.displayName" :style="{'color':user.$userColour}") + span.extra(v-if="user.location === 'traveling'") + i.el-icon-loading(style="margin-right:5px") + timer(:epoch="user.$travelingToTime") + span.extra(v-else) + timer(:epoch="user.$location_at") .x-friend-item(style="width:100%;cursor:default") .detail span.name Rules