diff --git a/src/app.js b/src/app.js index 42d911a0..b50dad38 100644 --- a/src/app.js +++ b/src/app.js @@ -2925,6 +2925,9 @@ console.log(`isLinux: ${LINUX}`); // 애초에 $isDeleted인데 여기로 올 수 가 있나..? this.cachedFavoritesByObjectId.delete(args.params.objectId); $app.localFavoriteFriends.delete(args.params.objectId); + for (var group of $app.localFavoriteFriendsDivideByGroup.values()) { + group.delete(args.params.objectId); + } $app.updateSidebarFriendsList(); if (ref.$isDeleted) { return; @@ -2979,6 +2982,9 @@ console.log(`isLinux: ${LINUX}`); } this.cachedFavoritesByObjectId.delete(ref.favoriteId); $app.localFavoriteFriends.delete(ref.favoriteId); + for (var group of $app.localFavoriteFriendsDivideByGroup.values()) { + group.delete(ref.favoriteId); + } $app.updateSidebarFriendsList(); ref.$isDeleted = true; API.$emit('FAVORITE:@DELETE', { @@ -3046,6 +3052,9 @@ console.log(`isLinux: ${LINUX}`); $app.localFavoriteFriendsGroups.includes(ref.groupKey)) ) { $app.localFavoriteFriends.add(ref.favoriteId); + $app.localFavoriteFriendsDivideByGroup + .get(ref.$groupKey) + .push(ref.favoriteId); $app.updateSidebarFriendsList(); } } else { @@ -4223,6 +4232,7 @@ console.log(`isLinux: ${LINUX}`); $app.data.isGroupInstances = false; $app.data.groupInstances = []; $app.data.vipFriends_ = []; + $app.data.vipFriendsDivideByGroup_ = new Map(); $app.data.onlineFriends_ = []; $app.data.activeFriends_ = []; $app.data.offlineFriends_ = []; @@ -4330,6 +4340,7 @@ console.log(`isLinux: ${LINUX}`); $app.isGroupInstances = false; $app.groupInstances = []; $app.vipFriends_ = []; + $app.vipFriendsDivideByGroup_.clear(); $app.onlineFriends_ = []; $app.activeFriends_ = []; $app.offlineFriends_ = []; @@ -4465,6 +4476,16 @@ console.log(`isLinux: ${LINUX}`); if (ctx.state === 'online') { if (ctx.isVIP) { this.vipFriends_.push(ctx); + const key = + Array.from( + this.localFavoriteFriendsDivideByGroup.entries() + ).find(([_, ids]) => ids.includes(ctx.id))?.[0] || ''; + if (!this.vipFriendsDivideByGroup_.has(key)) { + this.vipFriendsDivideByGroup_.set(key, [ctx]); + } else { + this.vipFriendsDivideByGroup_.get(key).push(ctx); + } + this.sortVIPFriends = true; } else { this.onlineFriends_.push(ctx); @@ -4488,6 +4509,13 @@ console.log(`isLinux: ${LINUX}`); if (ctx.state === 'online') { if (ctx.isVIP) { $app.removeFromArray(this.vipFriends_, ctx); + this.vipFriendsDivideByGroup_.forEach((group) => { + for (let i = group.length - 1; i >= 0; i--) { + if (group[i].id === ctx.id) { + group.splice(i, 1); + } + } + }); } else { $app.removeFromArray(this.onlineFriends_, ctx); } @@ -4552,9 +4580,27 @@ console.log(`isLinux: ${LINUX}`); if (ctx.isVIP) { $app.removeFromArray(this.onlineFriends_, ctx); this.vipFriends_.push(ctx); + const key = + Array.from( + this.localFavoriteFriendsDivideByGroup.entries() + ).find(([_, ids]) => ids.includes(ctx.id))?.[0] || + ''; + if (!this.vipFriendsDivideByGroup_.has(key)) { + this.vipFriendsDivideByGroup_.set(key, [ctx]); + } else { + this.vipFriendsDivideByGroup_.get(key).push(ctx); + } + this.sortVIPFriends = true; } else { $app.removeFromArray(this.vipFriends_, ctx); + this.vipFriendsDivideByGroup_.forEach((group) => { + for (let i = group.length - 1; i >= 0; i--) { + if (group[i].id === ctx.id) { + group.splice(i, 1); + } + } + }); this.onlineFriends_.push(ctx); this.sortOnlineFriends = true; } @@ -4748,6 +4794,13 @@ console.log(`isLinux: ${LINUX}`); if (ctx.state === 'online') { if (ctx.isVIP) { $app.removeFromArray(this.vipFriends_, ctx); + this.vipFriendsDivideByGroup_.forEach((group) => { + for (let i = group.length - 1; i >= 0; i--) { + if (group[i].id === ctx.id) { + group.splice(i, 1); + } + } + }); } else { $app.removeFromArray(this.onlineFriends_, ctx); } @@ -4759,6 +4812,16 @@ console.log(`isLinux: ${LINUX}`); if (newState === 'online') { if (isVIP) { this.vipFriends_.push(ctx); + const key = + Array.from( + this.localFavoriteFriendsDivideByGroup.entries() + ).find(([_, ids]) => ids.includes(ctx.id))?.[0] || ''; + if (!this.vipFriendsDivideByGroup_.has(key)) { + this.vipFriendsDivideByGroup_.set(key, [ctx]); + } else { + this.vipFriendsDivideByGroup_.get(key).push(ctx); + } + this.sortVIPFriends = true; } else { this.onlineFriends_.push(ctx); @@ -5121,6 +5184,37 @@ console.log(`isLinux: ${LINUX}`); return this.vipFriends_; }; + // VIP friends devide by group + $app.computed.vipFriendsDividebyGroup = function () { + if (this.sortVIPFriends) { + this.vipFriendsDivideByGroup_.forEach((group) => { + group.sort(getFriendsSortFunction(this.sidebarSortMethods)); + }); + } + this.sortVIPFriends = false; + + const arr = []; + for (const [key, value] of this.vipFriendsDivideByGroup_) { + arr.push({ + key: key, + value: value, + displayName: API.favoriteFriendGroups.find( + (group) => group.key === key + )?.displayName + }); + } + // 对this.vipFriendsDivideByGroup_的每一项的value值数组进行filter操作,只留下id存在于this.vipFriendsByGroupStatus中的所有项的id中的项 + const vipFriendsByGroupStatusIds = new Set( + this.vipFriendsByGroupStatus.map((friend) => friend.id) + ); + arr.forEach((group) => { + group.value = group.value.filter((friend) => + vipFriendsByGroupStatusIds.has(friend.id) + ); + }); + return arr; + }; + // Online friends $app.computed.onlineFriends = function () { if (!this.sortOnlineFriends) { @@ -21953,6 +22047,7 @@ console.log(`isLinux: ${LINUX}`); // #region | Local Favorite Friends $app.data.localFavoriteFriends = new Set(); + $app.data.localFavoriteFriendsDivideByGroup = new Map(); $app.data.localFavoriteFriendsGroups = JSON.parse( await configRepository.getString( 'VRCX_localFavoriteFriendsGroups', @@ -21962,6 +22057,7 @@ console.log(`isLinux: ${LINUX}`); $app.methods.updateLocalFavoriteFriends = function () { this.localFavoriteFriends.clear(); + this.localFavoriteFriendsDivideByGroup.clear(); for (var ref of API.cachedFavorites.values()) { if ( !ref.$isDeleted && @@ -21970,6 +22066,17 @@ console.log(`isLinux: ${LINUX}`); this.localFavoriteFriendsGroups.includes(ref.$groupKey)) ) { this.localFavoriteFriends.add(ref.favoriteId); + if ( + !this.localFavoriteFriendsDivideByGroup.has(ref.$groupKey) + ) { + this.localFavoriteFriendsDivideByGroup.set(ref.$groupKey, [ + ref.favoriteId + ]); + } else { + this.localFavoriteFriendsDivideByGroup + .get(ref.$groupKey) + .push(ref.favoriteId); + } } } this.updateSidebarFriendsList(); @@ -21993,9 +22100,26 @@ console.log(`isLinux: ${LINUX}`); if (ctx.isVIP) { $app.removeFromArray(this.onlineFriends_, ctx); this.vipFriends_.push(ctx); + const key = + Array.from( + this.localFavoriteFriendsDivideByGroup.entries() + ).find(([_, ids]) => ids.includes(ctx.id))?.[0] || ''; + if (!this.vipFriendsDivideByGroup_.has(key)) { + this.vipFriendsDivideByGroup_.set(key, [ctx]); + } else { + this.vipFriendsDivideByGroup_.get(key).push(ctx); + } + this.sortVIPFriends = true; } else { $app.removeFromArray(this.vipFriends_, ctx); + this.vipFriendsDivideByGroup_.forEach((group) => { + for (let i = group.length - 1; i >= 0; i--) { + if (group[i].id === ctx.id) { + group.splice(i, 1); + } + } + }); this.onlineFriends_.push(ctx); this.sortOnlineFriends = true; } diff --git a/src/mixins/friendsListSidebar.pug b/src/mixins/friendsListSidebar.pug index 1e691eee..02291a53 100644 --- a/src/mixins/friendsListSidebar.pug +++ b/src/mixins/friendsListSidebar.pug @@ -63,7 +63,7 @@ mixin friendsListSidebar :traveling='lastLocationDestination' :link='false') location.extra( - v-else-if='isRealInstance(API.currentUser.$locationTag) || isRealInstance(API.currentUser.$travelingToLocation)' + v-else-if='isRealInstance(API.currentUser.$locationTag) || isRealInstance(API.currentUser.$travelingToLocation)' :location='API.currentUser.$locationTag' :traveling='API.currentUser.$travelingToLocation' :link='false') @@ -73,36 +73,24 @@ mixin friendsListSidebar v-show='vipFriendsByGroupStatus.length') i.el-icon-arrow-right(:class='{ rotate: isVIPFriends }') span(style='margin-left: 5px') {{ $t('side_panel.favorite') }} ― {{ vipFriendsByGroupStatus.length }} - div(v-show='isVIPFriends') - .x-friend-item( - v-for='friend in vipFriendsByGroupStatus' - :key='friend.id' - @click='showUserDialog(friend.id)') - template(v-if='friend.ref') - .avatar(:class='userStatusClass(friend.ref, friend.pendingOffline)') - img(v-lazy='userImage(friend.ref)') - .detail - span.name( - v-if='!hideNicknames && friend.$nickName' - :style='{ color: friend.ref.$userColour }') {{ friend.ref.displayName }} ({{ friend.$nickName }}) - span.name( - v-else - v-text='friend.ref.displayName' - :style='{ color: friend.ref.$userColour }') - span.extra(v-if='friend.pendingOffline') #[i.el-icon-warning-outline] {{ $t('side_panel.pending_offline') }} - location.extra( - v-else - :location='friend.ref.location' - :traveling='friend.ref.travelingToLocation' - :link='false') - template(v-else) - span(v-text='friend.name || friend.id') - el-button( - type='text' - icon='el-icon-close' - size='mini' - @click.stop='confirmDeleteFriend(friend.id)' - style='margin-left: 5px') + div(v-show="isVIPFriends") + div(v-for="(group, idx) in vipFriendsDividebyGroup" :key="idx") + div(style="margin-bottom: 3px") + span(style="color:#c7c7c7") {{ group.displayName }} + span(style="margin-left: 5px") {{ `(${group.value.length})` }} + div(style="margin-bottom: 10px") + div.x-friend-item(v-if="group.value && group.value.length" v-for="friend in group.value" :key="friend.id" @click="showUserDialog(friend.id)") + template(v-if="friend.ref") + .avatar(:class="userStatusClass(friend.ref, friend.pendingOffline)") + img(v-lazy="userImage(friend.ref)") + .detail + span.name(v-if="!hideNicknames && friend.$nickName" :style="{'color':friend.ref.$userColour}") {{ friend.ref.displayName }} ({{ friend.$nickName }}) + span.name(v-else v-text="friend.ref.displayName" :style="{'color':friend.ref.$userColour}") + span.extra(v-if="friend.pendingOffline") #[i.el-icon-warning-outline] {{ $t('side_panel.pending_offline') }} + location.extra(v-else :location="friend.ref.location" :traveling="friend.ref.travelingToLocation" :link="false") + template(v-else) + span(v-text="friend.name || friend.id") + el-button(type="text" icon="el-icon-close" size="mini" @click.stop="confirmDeleteFriend(friend.id)" style="margin-left:5px") //- Group By Instance template(v-if='isSidebarGroupByInstance && friendsInSameInstance.length')