Files
VRCX/src/mixins/tabs/playerList.pug
T
pa d5e789ef0e improve: UI (#1152)
* improve: UI (#1033)

* fix: instance activity chart not displaying properly

* fix
2025-02-25 02:57:43 +13:00

480 lines
36 KiB
Plaintext

mixin playerListTab
.x-container(v-show='$refs.menu && $refs.menu.activeIndex === \'playerList\'' style='padding-top: 5px')
div(style='display: flex; flex-direction: column; height: 100%')
div(v-if='currentInstanceWorld.ref.id' style='display: flex')
el-popover(placement='right' width='500px' trigger='click' style='height: 120px')
img.x-link(
slot='reference'
v-lazy='currentInstanceWorld.ref.thumbnailImageUrl'
style='flex: none; width: 160px; height: 120px; border-radius: 4px')
img.x-link(
v-lazy='currentInstanceWorld.ref.imageUrl'
style='width: 500px; height: 375px'
@click='showFullscreenImageDialog(currentInstanceWorld.ref.imageUrl)')
div(style='margin-left: 10px; display: flex; flex-direction: column; min-width: 320px; width: 100%')
div
span.x-link(
@click='showWorldDialog(currentInstanceWorld.ref.id)'
style='font-weight: bold; overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 1')
|#[i.el-icon-s-home(v-show='API.currentUser.$homeLocation && API.currentUser.$homeLocation.worldId === currentInstanceWorld.ref.id' style='margin-right: 5px')] {{ currentInstanceWorld.ref.name }}
div
span.x-link.x-grey(
v-text='currentInstanceWorld.ref.authorName'
@click='showUserDialog(currentInstanceWorld.ref.authorId)'
style='font-family: monospace')
div(style='margin-top: 5px')
el-tag(
v-if='currentInstanceWorld.ref.$isLabs'
type='primary'
effect='plain'
size='mini'
style='margin-right: 5px') {{ $t('dialog.world.tags.labs') }}
el-tag(
v-else-if='currentInstanceWorld.ref.releaseStatus === "public"'
type='success'
effect='plain'
size='mini'
style='margin-right: 5px') {{ $t('dialog.world.tags.public') }}
el-tag(
v-else-if='currentInstanceWorld.ref.releaseStatus === "private"'
type='danger'
effect='plain'
size='mini'
style='margin-right: 5px') {{ $t('dialog.world.tags.private') }}
el-tag.x-tag-platform-pc(
v-if='currentInstanceWorld.isPC'
type='info'
effect='plain'
size='mini'
style='margin-right: 5px') PC
span.x-grey(
v-if='currentInstanceWorld.bundleSizes["standalonewindows"]'
style='margin-left: 5px; border-left: inherit; padding-left: 5px') {{ currentInstanceWorld.bundleSizes['standalonewindows'].fileSize }}
el-tag.x-tag-platform-quest(
v-if='currentInstanceWorld.isQuest'
type='info'
effect='plain'
size='mini'
style='margin-right: 5px') Android
span.x-grey(
v-if='currentInstanceWorld.bundleSizes["android"]'
style='margin-left: 5px; border-left: inherit; padding-left: 5px') {{ currentInstanceWorld.bundleSizes['android'].fileSize }}
el-tag.x-tag-platform-ios(
v-if='currentInstanceWorld.isIOS'
type='info'
effect='plain'
size='mini'
style='margin-right: 5px') iOS
span.x-grey(
v-if='currentInstanceWorld.bundleSizes["ios"]'
style='margin-left: 5px; border-left: inherit; padding-left: 5px') {{ currentInstanceWorld.bundleSizes['ios'].fileSize }}
el-tag(
v-if='currentInstanceWorld.avatarScalingDisabled'
type='warning'
effect='plain'
size='mini'
style='margin-right: 5px; margin-top: 5px') {{ $t('dialog.world.tags.avatar_scaling_disabled') }}
el-tag(
v-if='currentInstanceWorld.inCache'
type='info'
effect='plain'
size='mini'
style='margin-right: 5px')
span {{ currentInstanceWorld.cacheSize }} {{ $t('dialog.world.tags.cache') }}
div(style='margin-top: 5px')
location-world(
:locationobject='currentInstanceLocation'
:currentuserid='API.currentUser.id'
@show-launch-dialog='showLaunchDialog')
span(v-if='lastLocation.playerList.size > 0' style='margin-left: 5px')
| {{ lastLocation.playerList.size }}
| #[template(v-if='lastLocation.friendList.size > 0') ({{ lastLocation.friendList.size }})]
|  ― #[timer(v-if='lastLocation.date' :epoch='lastLocation.date')]
div(style='margin-top: 5px')
span(
v-show='currentInstanceWorld.ref.name !== currentInstanceWorld.ref.description'
v-text='currentInstanceWorld.ref.description'
:style='{ fontSize: "12px", overflow: "hidden", textOverflow: "ellipsis", display: "-webkit-box", WebkitBoxOrient: "vertical", WebkitLineClamp: currentInstanceWorldDescriptionExpanded ? "none" : "2" }')
div(style='display: flex; justify-content: end')
el-button(
v-if='currentInstanceWorld.ref.description.length > 50 && !currentInstanceWorldDescriptionExpanded'
type='text'
size='mini'
@click='currentInstanceWorldDescriptionExpanded = true') {{ !currentInstanceWorldDescriptionExpanded && 'Show more' }}
div(style='display: flex; flex-direction: column; margin-left: 20px')
.x-friend-item(style='cursor: default')
.detail
span.name {{ $t('dialog.world.info.capacity') }}
span.extra {{ currentInstanceWorld.ref.recommendedCapacity | commaNumber }} ({{ currentInstanceWorld.ref.capacity | commaNumber }})
.x-friend-item(style='cursor: default')
.detail
span.name {{ $t('dialog.world.info.last_updated') }}
span.extra {{ currentInstanceWorld.lastUpdated | formatDate('long') }}
.x-friend-item(style='cursor: default')
.detail
span.name {{ $t('dialog.world.info.created_at') }}
span.extra {{ currentInstanceWorld.ref.created_at | formatDate('long') }}
.photon-event-table(v-if='photonLoggingEnabled')
div(style='position: absolute; width: 600px; margin-left: 215px; z-index: 1')
el-select(
v-model='photonEventTableTypeFilter'
@change='photonEventTableFilterChange'
multiple
clearable
collapse-tags
style='flex: 1; width: 220px'
:placeholder='$t("view.player_list.photon.filter_placeholder")')
el-option(
v-for='type in photonEventTableTypeFilterList'
:key='type'
:label='type'
:value='type')
el-input(
v-model='photonEventTableFilter'
@input='photonEventTableFilterChange'
:placeholder='$t("view.player_list.photon.search_placeholder")'
clearable
style='width: 150px; margin-left: 10px')
el-button(@click='showChatboxBlacklistDialog' style='margin-left: 10px') {{ $t('view.player_list.photon.chatbox_blacklist') }}
el-tooltip(
placement='bottom'
:content='$t("view.player_list.photon.status_tooltip")'
:disabled='hideTooltips')
div(
style='display: inline-block; margin-left: 15px; font-size: 14px; vertical-align: text-top; margin-top: 1px')
span(v-if='ipcEnabled && !photonEventIcon') 🟢
span(v-else-if='ipcEnabled') ⚪
span(v-else) 🔴
el-tabs(type='card')
el-tab-pane(:label='$t("view.player_list.photon.current")')
data-tables(v-bind='photonEventTable' style='margin-bottom: 10px')
el-table-column(:label='$t("table.playerList.date")' prop='created_at' width='120')
template(#default='scope')
el-tooltip(placement='right')
template(#content)
span {{ scope.row.created_at | formatDate('long') }}
span {{ scope.row.created_at | formatDate('short') }}
el-table-column(:label='$t("table.playerList.user")' prop='photonId' width='160')
template(#default='scope')
span.x-link(
v-text='scope.row.displayName'
@click='showUserFromPhotonId(scope.row.photonId)'
style='padding-right: 10px')
el-table-column(:label='$t("table.playerList.type")' prop='type' width='140')
el-table-column(:label='$t("table.playerList.detail")' prop='text')
template(#default='scope')
template(v-if='scope.row.type === "ChangeAvatar"')
span.x-link(
v-text='scope.row.avatar.name'
@click='showAvatarDialog(scope.row.avatar.id)')
|  
span(v-if='!scope.row.inCache' style='color: #aaa') #[i.el-icon-download] 
span.avatar-info-public(v-if='scope.row.avatar.releaseStatus === "public"') {{ $t('dialog.avatar.labels.public') }}
span.avatar-info-own(v-else-if='scope.row.avatar.releaseStatus === "private"') {{ $t('dialog.avatar.labels.private') }}
template(
v-if='scope.row.avatar.description && scope.row.avatar.name !== scope.row.avatar.description')
|
| - {{ scope.row.avatar.description }}
template(v-else-if='scope.row.type === "ChangeStatus"')
template(v-if='scope.row.status !== scope.row.previousStatus')
el-tooltip(placement='top')
template(#content)
span(v-if='scope.row.previousStatus === "active"') {{ $t('dialog.user.status.active') }}
span(v-else-if='scope.row.previousStatus === "join me"') {{ $t('dialog.user.status.join_me') }}
span(v-else-if='scope.row.previousStatus === "ask me"') {{ $t('dialog.user.status.ask_me') }}
span(v-else-if='scope.row.previousStatus === "busy"') {{ $t('dialog.user.status.busy') }}
span(v-else) {{ $t('dialog.user.status.offline') }}
i.x-user-status(:class='statusClass(scope.row.previousStatus)')
span
i.el-icon-right
el-tooltip(placement='top')
template(#content)
span(v-if='scope.row.status === "active"') {{ $t('dialog.user.status.active') }}
span(v-else-if='scope.row.status === "join me"') {{ $t('dialog.user.status.join_me') }}
span(v-else-if='scope.row.status === "ask me"') {{ $t('dialog.user.status.ask_me') }}
span(v-else-if='scope.row.status === "busy"') {{ $t('dialog.user.status.busy') }}
span(v-else) {{ $t('dialog.user.status.offline') }}
i.x-user-status(
:class='statusClass(scope.row.status)'
style='margin-right: 5px')
span(
v-if='scope.row.statusDescription !== scope.row.previousStatusDescription'
v-text='scope.row.statusDescription')
template(v-else-if='scope.row.type === "ChangeGroup"')
span.x-link(
v-if='scope.row.previousGroupName'
v-text='scope.row.previousGroupName'
@click='showGroupDialog(scope.row.previousGroupId)'
style='margin-right: 5px')
span.x-link(
v-else
v-text='scope.row.previousGroupId'
@click='showGroupDialog(scope.row.previousGroupId)'
style='margin-right: 5px')
span
i.el-icon-right
span.x-link(
v-if='scope.row.groupName'
v-text='scope.row.groupName'
@click='showGroupDialog(scope.row.groupId)'
style='margin-left: 5px')
span.x-link(
v-else
v-text='scope.row.groupId'
@click='showGroupDialog(scope.row.groupId)'
style='margin-left: 5px')
span.x-link(
v-else-if='scope.row.type === "PortalSpawn"'
@click='showWorldDialog(scope.row.location, scope.row.shortName)')
location(
:location='scope.row.location'
:hint='scope.row.worldName'
:grouphint='scope.row.groupName'
:link='false')
span(v-else-if='scope.row.type === "ChatBoxMessage"' v-text='scope.row.text')
span(v-else-if='scope.row.type === "OnPlayerJoined"')
span(v-if='scope.row.platform === "Desktop"' style='color: #409eff') Desktop 
span(v-else-if='scope.row.platform === "VR"' style='color: #409eff') VR 
span(v-else-if='scope.row.platform === "Quest"' style='color: #67c23a') Android 
span.x-link(
v-text='scope.row.avatar.name'
@click='showAvatarDialog(scope.row.avatar.id)')
|  
span(v-if='!scope.row.inCache' style='color: #aaa') #[i.el-icon-download] 
span.avatar-info-public(v-if='scope.row.avatar.releaseStatus === "public"') {{ $t('dialog.avatar.labels.public') }}
span.avatar-info-own(v-else-if='scope.row.avatar.releaseStatus === "private"') {{ $t('dialog.avatar.labels.private') }}
span(v-else-if='scope.row.type === "SpawnEmoji"')
span(v-if='scope.row.imageUrl')
el-tooltip(placement='right')
template(#content)
img.friends-list-avatar(
v-lazy='scope.row.imageUrl'
style='height: 500px; cursor: pointer'
@click='showFullscreenImageDialog(scope.row.imageUrl)')
span(v-text='scope.row.fileId')
span(v-else v-text='scope.row.text')
span(
v-else-if='scope.row.color === "yellow"'
v-text='scope.row.text'
style='color: yellow')
span(v-else v-text='scope.row.text')
el-tab-pane(:label='$t("view.player_list.photon.previous")')
data-tables(v-bind='photonEventTablePrevious' style='margin-bottom: 10px')
el-table-column(:label='$t("table.playerList.date")' prop='created_at' width='120')
template(#default='scope')
el-tooltip(placement='right')
template(#content)
span {{ scope.row.created_at | formatDate('long') }}
span {{ scope.row.created_at | formatDate('short') }}
el-table-column(:label='$t("table.playerList.user")' prop='photonId' width='160')
template(#default='scope')
span.x-link(
v-text='scope.row.displayName'
@click='lookupUser(scope.row)'
style='padding-right: 10px')
el-table-column(:label='$t("table.playerList.type")' prop='type' width='140')
el-table-column(:label='$t("table.playerList.detail")' prop='text')
template(#default='scope')
template(v-if='scope.row.type === "ChangeAvatar"')
span.x-link(
v-text='scope.row.avatar.name'
@click='showAvatarDialog(scope.row.avatar.id)')
|  
span(v-if='!scope.row.inCache' style='color: #aaa') #[i.el-icon-download] 
span.avatar-info-public(v-if='scope.row.avatar.releaseStatus === "public"') {{ $t('dialog.avatar.labels.public') }}
span.avatar-info-own(v-else-if='scope.row.avatar.releaseStatus === "private"') {{ $t('dialog.avatar.labels.private') }}
template(
v-if='scope.row.avatar.description && scope.row.avatar.name !== scope.row.avatar.description')
|
| - {{ scope.row.avatar.description }}
template(v-else-if='scope.row.type === "ChangeStatus"')
template(v-if='scope.row.status !== scope.row.previousStatus')
el-tooltip(placement='top')
template(#content)
span(v-if='scope.row.previousStatus === "active"') {{ $t('dialog.user.status.active') }}
span(v-else-if='scope.row.previousStatus === "join me"') {{ $t('dialog.user.status.join_me') }}
span(v-else-if='scope.row.previousStatus === "ask me"') {{ $t('dialog.user.status.ask_me') }}
span(v-else-if='scope.row.previousStatus === "busy"') {{ $t('dialog.user.status.busy') }}
span(v-else) {{ $t('dialog.user.status.offline') }}
i.x-user-status(:class='statusClass(scope.row.previousStatus)')
span
i.el-icon-right
el-tooltip(placement='top')
template(#content)
span(v-if='scope.row.status === "active"') {{ $t('dialog.user.status.active') }}
span(v-else-if='scope.row.status === "join me"') {{ $t('dialog.user.status.join_me') }}
span(v-else-if='scope.row.status === "ask me"') {{ $t('dialog.user.status.ask_me') }}
span(v-else-if='scope.row.status === "busy"') {{ $t('dialog.user.status.busy') }}
span(v-else) {{ $t('dialog.user.status.offline') }}
i.x-user-status(
:class='statusClass(scope.row.status)'
style='margin-right: 5px')
span(
v-if='scope.row.statusDescription !== scope.row.previousStatusDescription'
v-text='scope.row.statusDescription')
template(v-else-if='scope.row.type === "ChangeGroup"')
span.x-link(
v-if='scope.row.previousGroupName'
v-text='scope.row.previousGroupName'
@click='showGroupDialog(scope.row.previousGroupId)'
style='margin-right: 5px')
span.x-link(
v-else
v-text='scope.row.previousGroupId'
@click='showGroupDialog(scope.row.previousGroupId)'
style='margin-right: 5px')
span
i.el-icon-right
span.x-link(
v-if='scope.row.groupName'
v-text='scope.row.groupName'
@click='showGroupDialog(scope.row.groupId)'
style='margin-left: 5px')
span.x-link(
v-else
v-text='scope.row.groupId'
@click='showGroupDialog(scope.row.groupId)'
style='margin-left: 5px')
span.x-link(
v-else-if='scope.row.type === "PortalSpawn"'
@click='showWorldDialog(scope.row.location, scope.row.shortName)')
location(
:location='scope.row.location'
:hint='scope.row.worldName'
:grouphint='scope.row.groupName'
:link='false')
span(v-else-if='scope.row.type === "ChatBoxMessage"' v-text='scope.row.text')
span(v-else-if='scope.row.type === "OnPlayerJoined"')
span(v-if='scope.row.platform === "Desktop"' style='color: #409eff') Desktop 
span(v-else-if='scope.row.platform === "VR"' style='color: #409eff') VR 
span(v-else-if='scope.row.platform === "Quest"' style='color: #67c23a') Android 
span.x-link(
v-text='scope.row.avatar.name'
@click='showAvatarDialog(scope.row.avatar.id)')
|  
span(v-if='!scope.row.inCache' style='color: #aaa') #[i.el-icon-download] 
span.avatar-info-public(v-if='scope.row.avatar.releaseStatus === "public"') {{ $t('dialog.avatar.labels.public') }}
span.avatar-info-own(v-else-if='scope.row.avatar.releaseStatus === "private"') {{ $t('dialog.avatar.labels.private') }}
span(v-else-if='scope.row.type === "SpawnEmoji"')
span(v-if='scope.row.imageUrl')
el-tooltip(placement='right')
template(#content)
img.friends-list-avatar(
v-lazy='scope.row.imageUrl'
style='height: 500px; cursor: pointer'
@click='showFullscreenImageDialog(scope.row.imageUrl)')
span(v-text='scope.row.fileId')
span(v-else v-text='scope.row.text')
span(
v-else-if='scope.row.color === "yellow"'
v-text='scope.row.text'
style='color: yellow')
span(v-else v-text='scope.row.text')
.current-instance-table
data-tables(
v-bind='currentInstanceUserList'
@row-click='selectCurrentInstanceRow'
style='margin-top: 10px; cursor: pointer')
el-table-column(:label='$t("table.playerList.avatar")' width='70' prop='photo')
template(#default='scope')
template(v-if='userImage(scope.row.ref)')
el-popover(placement='right' height='500px' trigger='hover')
img.friends-list-avatar(slot='reference' v-lazy='userImage(scope.row.ref)')
img.friends-list-avatar(
v-lazy='userImageFull(scope.row.ref)'
style='height: 500px; cursor: pointer'
@click='showFullscreenImageDialog(userImageFull(scope.row.ref))')
el-table-column(:label='$t("table.playerList.timer")' width='80' prop='timer' sortable)
template(#default='scope')
timer(:epoch='scope.row.timer')
el-table-column(
v-if='photonLoggingEnabled'
:label='$t("table.playerList.photonId")'
width='110'
prop='photonId'
sortable)
template(#default='scope')
template(v-if='chatboxUserBlacklist.has(scope.row.ref.id)')
el-tooltip(placement='left' content='Unblock chatbox messages')
el-button(
type='text'
icon='el-icon-turn-off-microphone'
size='mini'
style='color: red; margin-right: 5px'
@click.stop='deleteChatboxUserBlacklist(scope.row.ref.id)')
template(v-else)
el-tooltip(placement='left' content='Block chatbox messages')
el-button(
type='text'
icon='el-icon-microphone'
size='mini'
style='margin-right: 5px'
@click.stop='addChatboxUserBlacklist(scope.row.ref)')
span(v-text='scope.row.photonId')
el-table-column(:label='$t("table.playerList.icon")' prop='isMaster' width='70' align='center')
template(#default='scope')
el-tooltip(v-if='scope.row.isMaster' placement='left' content='Instance Master')
span 👑
el-tooltip(v-if='scope.row.isModerator' placement='left' content='Moderator')
span ⚔️
el-tooltip(v-if='scope.row.isFriend' placement='left' content='Friend')
span 💚
el-tooltip(v-if='scope.row.timeoutTime' placement='left' content='Timeout')
span(style='color: red') 🔴{{ scope.row.timeoutTime }}s
el-table-column(:label='$t("table.playerList.platform")' prop='inVRMode' width='80')
template(#default='scope')
template(v-if='scope.row.ref.last_platform')
span(v-if='scope.row.ref.last_platform === "standalonewindows"' style='color: #409eff') PC
span(v-else-if='scope.row.ref.last_platform === "android"' style='color: #67c23a') A
span(v-else-if='scope.row.ref.last_platform === "ios"' style='color: #c7c7ce') iOS
span(v-else) {{ scope.row.ref.last_platform }}
template(v-if='scope.row.inVRMode !== null')
span(v-if='scope.row.inVRMode') VR
span(
v-else-if='scope.row.ref.last_platform === "android" || scope.row.ref.last_platform === "ios"') M
span(v-else) D
el-table-column(
:label='$t("table.playerList.displayName")'
min-width='140'
prop='displayName'
sortable='custom')
template(#default='scope')
span(
v-if='randomUserColours'
v-text='scope.row.ref.displayName'
:style='{ color: scope.row.ref.$userColour }')
span(v-else v-text='scope.row.ref.displayName')
el-table-column(:label='$t("table.playerList.status")' min-width='180' prop='ref.status')
template(#default='scope')
template(v-if='scope.row.ref.status')
i.x-user-status(:class='statusClass(scope.row.ref.status)' style='margin-right: 3px')
span(v-text='scope.row.ref.statusDescription')
//- el-table-column(label="Group" min-width="180" prop="groupOnNameplate" sortable)
//- template(v-once #default="scope")
//- span(v-text="scope.row.groupOnNameplate")
el-table-column(
:label='$t("table.playerList.rank")'
width='110'
prop='$trustSortNum'
sortable='custom')
template(#default='scope')
span.name(v-text='scope.row.ref.$trustLevel' :class='scope.row.ref.$trustClass')
el-table-column(:label='$t("table.playerList.language")' width='100' prop='ref.$languages')
template(#default='scope')
el-tooltip(v-for='item in scope.row.ref.$languages' :key='item.key' placement='top')
template(#content)
span {{ item.value }} ({{ item.key }})
span.flags(
:class='languageClass(item.key)'
style='display: inline-block; margin-right: 5px')
el-table-column(:label='$t("table.playerList.bioLink")' width='100' prop='ref.bioLinks')
template(#default='scope')
div(style='display: flex; align-items: center')
el-tooltip(v-if='link' v-for='(link, index) in scope.row.ref.bioLinks' :key='index')
template(#content)
span(v-text='link')
img(
:src='getFaviconUrl(link)'
style='width: 16px; height: 16px; vertical-align: middle; margin-right: 5px; cursor: pointer'
@click.stop='openExternalLink(link)')