Files
VRCX/src/mixins/friendsListSidebar.pug
T
Vivi 212934f08c fix: fix the bug of favorite friends hidding (#1104)
* feat: favorite friends divide by different favorite group

* fix: make the update of dividing by favorite groups compatible with previous features

* fix: fix the bug of favorite friends

* fix: fix the bug of favorite friends

* fix: fix the bug of favorite friends hidding

* fix: fix the vipFriendsDivideByGroup dataSource, now it was couputed by others, no longer managed by the add favorite, delete favorite etc handler

* i18n: chinese translation about split favorite friends

* fix: fix the duplicate friend show in a tab
2025-01-27 09:25:30 +13:00

290 lines
20 KiB
Plaintext

mixin friendsListSidebar
#aside.x-aside-container(v-show='$refs.menu && $refs.menu.activeIndex !== \'friendsList\'')
div(style='display: flex; align-items: baseline')
el-select(
v-model='quickSearch'
clearable
:placeholder='$t("side_panel.search_placeholder")'
filterable
remote
:remote-method='quickSearchRemoteMethod'
popper-class='x-quick-search'
@change='quickSearchChange'
@visible-change='quickSearchVisibleChange'
style='flex: 1; padding: 10px')
el-option(v-for='item in quickSearchItems' :key='item.value' :value='item.value' :label='item.label')
.x-friend-item
template(v-if='item.ref')
.detail
span.name(v-text='item.ref.displayName' :style='{ color: item.ref.$userColour }')
span.extra(v-if='!item.ref.isFriend')
span.extra(v-else-if='item.ref.state === "offline"') {{ $t('side_panel.search_result_active') }}
span.extra(v-else-if='item.ref.state === "active"') {{ $t('side_panel.search_result_offline') }}
location.extra(
v-else
:location='item.ref.location'
:traveling='item.ref.travelingToLocation'
:link='false')
img.avatar(v-lazy='userImage(item.ref)')
span(v-else) {{ $t('side_panel.search_result_more') }} #[span(v-text='item.label' style='font-weight: bold')]
el-tooltip(placement='bottom' :content='$t("side_panel.direct_access_tooltip")' :disabled='hideTooltips')
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-button(
type='default'
@click='refreshFriendsList'
:loading='API.isRefreshFriendsLoading'
size='mini'
icon='el-icon-refresh'
circle
style='margin-right: 10px')
el-tabs.zero-margin-tabs(stretch='true' style='height: calc(100% - 60px); margin-top: 5px')
el-tab-pane
template(#label)
span {{ $t('side_panel.friends') }}
span(style='color: #909399; font-size: 12px; margin-left: 10px') ({{ onlineFriendCount }}/{{ friends.size }})
.x-friend-list(style='padding: 10px 5px')
.x-friend-group.x-link(
@click='isFriendsGroupMe = !isFriendsGroupMe; saveFriendsGroupStates()'
style='padding: 0px 0px 5px')
i.el-icon-arrow-right(:class='{ rotate: isFriendsGroupMe }')
span(style='margin-left: 5px') {{ $t('side_panel.me') }}
div(v-show='isFriendsGroupMe')
.x-friend-item(:key='API.currentUser.id' @click='showUserDialog(API.currentUser.id)')
.avatar(:class='userStatusClass(API.currentUser)')
img(v-lazy='userImage(API.currentUser)')
.detail
span.name(
v-text='API.currentUser.displayName'
:style='{ color: API.currentUser.$userColour }')
location.extra(
v-if='isGameRunning && !gameLogDisabled'
:location='lastLocation.location'
:traveling='lastLocationDestination'
:link='false')
location.extra(
v-else-if='isRealInstance(API.currentUser.$locationTag) || isRealInstance(API.currentUser.$travelingToLocation)'
:location='API.currentUser.$locationTag'
:traveling='API.currentUser.$travelingToLocation'
:link='false')
span.extra(v-else v-text='API.currentUser.statusDescription')
.x-friend-group.x-link(
@click='isVIPFriends = !isVIPFriends; saveFriendsGroupStates()'
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')
template(v-if='isSidebarDivideByFriendGroup')
div(v-for='(group, idx) in vipFriendsDivideByGroup' :key='idx')
div(style='margin-bottom: 3px')
span.extra {{ group.displayName }}
span.extra(style='margin-left: 5px') {{ `(${group.value.length})` }}
div(style='margin-bottom: 10px')
.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')
template(v-else)
.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')
//- Group By Instance
template(v-if='isSidebarGroupByInstance && friendsInSameInstance.length')
.x-friend-group.x-link(@click='toggleSwitchGroupByInstanceCollapsed')
i.el-icon-arrow-right(:class='{ rotate: !isSidebarGroupByInstanceCollapsed }')
span(style='margin-left: 5px') {{ $t('side_panel.same_instance') }} ― {{ friendsInSameInstance.length }}
div(v-show='!isSidebarGroupByInstanceCollapsed')
div(v-for='friendArr in friendsInSameInstance' :key='friendArr[0].ref?.$location.tag')
div(style='margin-bottom: 3px')
location.extra(:location='getFriendsLocations(friendArr)')
span.extra(style='margin-left: 5px') {{ `(${friendArr.length})` }}
div
.x-friend-item(
v-if='friendArr && friendArr.length'
v-for='(friend, idx) in friendArr'
:key='friend.id'
@click='showUserDialog(friend.id)'
:style='{ "margin-bottom": idx === friendArr.length - 1 ? "5px" : undefined }')
template(v-if='friend.ref')
.avatar(:class='userStatusClass(friend.ref, friend.pendingOffline)')
img(v-lazy='userImage(friend.ref)')
.detail
span.name(style='display: flex; align-items: center')
span(
v-if='!hideNicknames && friend.$nickName'
:style='{ color: friend.ref.$userColour }') {{ friend.ref.displayName }} ({{ friend.$nickName }})
span(
v-else
v-text='friend.ref.displayName'
:style='{ color: friend.ref.$userColour }')
i.el-icon-star-on(
v-if='friend.isVIP'
style='color: #ffd700; margin: 1px 0 0 2px')
span.extra(v-if='friend.pendingOffline') #[i.el-icon-warning-outline] {{ $t('side_panel.pending_offline') }}
template(v-else)
i.el-icon.el-icon-loading(
v-if='friend.ref.travelingToLocation'
style='display: inline-block; margin-right: 5px')
timer.extra(:epoch='friend.ref?.$location_at')
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')
.x-friend-group.x-link(
@click='isOnlineFriends = !isOnlineFriends; saveFriendsGroupStates()'
v-show='onlineFriendsByGroupStatus.length')
i.el-icon-arrow-right(:class='{ rotate: isOnlineFriends }')
span(style='margin-left: 5px') {{ $t('side_panel.online') }} ― {{ onlineFriendsByGroupStatus.length }}
div(v-show='isOnlineFriends')
.x-friend-item(
v-for='friend in onlineFriendsByGroupStatus'
: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')
.x-friend-group.x-link(
@click='isActiveFriends = !isActiveFriends; saveFriendsGroupStates()'
v-show='activeFriends.length')
i.el-icon-arrow-right(:class='{ rotate: isActiveFriends }')
span(style='margin-left: 5px') {{ $t('side_panel.active') }} ― {{ activeFriends.length }}
div(v-show='isActiveFriends')
.x-friend-item(
v-for='friend in activeFriends'
:key='friend.id'
@click='showUserDialog(friend.id)')
template(v-if='friend.ref')
.avatar
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-text='friend.ref.statusDescription' :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')
.x-friend-group.x-link(
@click='isOfflineFriends = !isOfflineFriends; saveFriendsGroupStates()'
v-show='offlineFriends.length')
i.el-icon-arrow-right(:class='{ rotate: isOfflineFriends }')
span(style='margin-left: 5px') {{ $t('side_panel.offline') }} ― {{ offlineFriends.length }}
div(v-show='isOfflineFriends')
.x-friend-item(
v-for='friend in offlineFriends'
:key='friend.id'
@click='showUserDialog(friend.id)')
template(v-if='friend.ref')
.avatar
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-text='friend.ref.statusDescription')
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')
el-tab-pane(lazy)
template(#label)
span {{ $t('side_panel.groups') }}
span(style='color: #909399; font-size: 12px; margin-left: 10px') ({{ groupInstances.length }})
groups-sidebar(:group-instances='groupInstances' @show-group-dialog='showGroupDialog')