mirror of
https://github.com/vrcx-team/VRCX.git
synced 2026-04-06 00:32:02 +02:00
refactor: spilt user summary header
This commit is contained in:
250
src/components/dialogs/UserDialog/UserActionDropdown.vue
Normal file
250
src/components/dialogs/UserDialog/UserActionDropdown.vue
Normal file
@@ -0,0 +1,250 @@
|
||||
<template>
|
||||
<div style="flex: none">
|
||||
<template v-if="(currentUser.id !== userDialog.ref.id && userDialog.isFriend) || userDialog.isFavorite">
|
||||
<el-tooltip
|
||||
v-if="userDialog.isFavorite"
|
||||
placement="top"
|
||||
:content="t('dialog.user.actions.unfavorite_tooltip')">
|
||||
<el-button
|
||||
type="warning"
|
||||
:icon="StarFilled"
|
||||
size="large"
|
||||
circle
|
||||
@click="userDialogCommand('Add Favorite')"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip v-else placement="top" :content="t('dialog.user.actions.favorite_tooltip')">
|
||||
<el-button
|
||||
type="default"
|
||||
:icon="Star"
|
||||
size="large"
|
||||
circle
|
||||
@click="userDialogCommand('Add Favorite')"></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<el-dropdown trigger="click" size="small" @command="onCommand">
|
||||
<el-button
|
||||
:type="
|
||||
userDialog.incomingRequest || userDialog.outgoingRequest
|
||||
? 'success'
|
||||
: userDialog.isBlock || userDialog.isMute
|
||||
? 'danger'
|
||||
: 'default'
|
||||
"
|
||||
:icon="MoreFilled"
|
||||
size="large"
|
||||
circle
|
||||
style="margin-left: 5px"></el-button>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item :icon="Refresh" command="Refresh">{{
|
||||
t('dialog.user.actions.refresh')
|
||||
}}</el-dropdown-item>
|
||||
<el-dropdown-item :icon="Share" command="Share">{{
|
||||
t('dialog.user.actions.share')
|
||||
}}</el-dropdown-item>
|
||||
<template v-if="userDialog.ref.id === currentUser.id">
|
||||
<el-dropdown-item :icon="Picture" command="Manage Gallery" divided>{{
|
||||
t('dialog.user.actions.manage_gallery_inventory_icon')
|
||||
}}</el-dropdown-item>
|
||||
<el-dropdown-item :icon="UserFilled" command="Show Avatar Author">{{
|
||||
t('dialog.user.actions.show_avatar_author')
|
||||
}}</el-dropdown-item>
|
||||
<el-dropdown-item :icon="UserFilled" command="Show Fallback Avatar Details">{{
|
||||
t('dialog.user.actions.show_fallback_avatar')
|
||||
}}</el-dropdown-item>
|
||||
<el-dropdown-item :icon="Edit" command="Edit Social Status" divided>{{
|
||||
t('dialog.user.actions.edit_status')
|
||||
}}</el-dropdown-item>
|
||||
<el-dropdown-item :icon="Edit" command="Edit Language">{{
|
||||
t('dialog.user.actions.edit_language')
|
||||
}}</el-dropdown-item>
|
||||
<el-dropdown-item :icon="Edit" command="Edit Bio">{{
|
||||
t('dialog.user.actions.edit_bio')
|
||||
}}</el-dropdown-item>
|
||||
<el-dropdown-item :icon="Edit" command="Edit Pronouns">{{
|
||||
t('dialog.user.actions.edit_pronouns')
|
||||
}}</el-dropdown-item>
|
||||
<el-dropdown-item :icon="SwitchButton" command="Logout" divided>{{
|
||||
t('dialog.user.actions.logout')
|
||||
}}</el-dropdown-item>
|
||||
</template>
|
||||
<template v-else>
|
||||
<template v-if="userDialog.isFriend">
|
||||
<el-dropdown-item :icon="Postcard" command="Request Invite" divided>{{
|
||||
t('dialog.user.actions.request_invite')
|
||||
}}</el-dropdown-item>
|
||||
<el-dropdown-item :icon="Postcard" command="Request Invite Message">{{
|
||||
t('dialog.user.actions.request_invite_with_message')
|
||||
}}</el-dropdown-item>
|
||||
<template v-if="isGameRunning">
|
||||
<el-dropdown-item
|
||||
:disabled="!checkCanInvite(lastLocation.location)"
|
||||
:icon="Message"
|
||||
command="Invite"
|
||||
>{{ t('dialog.user.actions.invite') }}</el-dropdown-item
|
||||
>
|
||||
<el-dropdown-item
|
||||
:disabled="!checkCanInvite(lastLocation.location)"
|
||||
:icon="Message"
|
||||
command="Invite Message"
|
||||
>{{ t('dialog.user.actions.invite_with_message') }}</el-dropdown-item
|
||||
>
|
||||
</template>
|
||||
</template>
|
||||
<template v-else-if="userDialog.incomingRequest">
|
||||
<el-dropdown-item :icon="Check" command="Accept Friend Request">{{
|
||||
t('dialog.user.actions.accept_friend_request')
|
||||
}}</el-dropdown-item>
|
||||
<el-dropdown-item :icon="Close" command="Decline Friend Request">{{
|
||||
t('dialog.user.actions.decline_friend_request')
|
||||
}}</el-dropdown-item>
|
||||
</template>
|
||||
<el-dropdown-item
|
||||
v-else-if="userDialog.outgoingRequest"
|
||||
:icon="Close"
|
||||
command="Cancel Friend Request">
|
||||
{{ t('dialog.user.actions.cancel_friend_request') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-else :icon="Plus" command="Send Friend Request">{{
|
||||
t('dialog.user.actions.send_friend_request')
|
||||
}}</el-dropdown-item>
|
||||
<el-dropdown-item :icon="Message" command="Invite To Group">{{
|
||||
t('dialog.user.actions.invite_to_group')
|
||||
}}</el-dropdown-item>
|
||||
<el-dropdown-item :icon="Operation" command="Group Moderation">{{
|
||||
t('dialog.user.actions.group_moderation')
|
||||
}}</el-dropdown-item>
|
||||
<el-dropdown-item :icon="UserFilled" command="Show Avatar Author" divided>{{
|
||||
t('dialog.user.actions.show_avatar_author')
|
||||
}}</el-dropdown-item>
|
||||
<el-dropdown-item :icon="UserFilled" command="Show Fallback Avatar Details">{{
|
||||
t('dialog.user.actions.show_fallback_avatar')
|
||||
}}</el-dropdown-item>
|
||||
<el-dropdown-item :icon="DataLine" command="Previous Instances">{{
|
||||
t('dialog.user.actions.show_previous_instances')
|
||||
}}</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
v-if="userDialog.isBlock"
|
||||
:icon="CircleCheck"
|
||||
command="Moderation Unblock"
|
||||
divided
|
||||
style="color: #f56c6c">
|
||||
{{ t('dialog.user.actions.moderation_unblock') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
v-else
|
||||
:icon="CircleClose"
|
||||
command="Moderation Block"
|
||||
divided
|
||||
:disabled="userDialog.ref.$isModerator">
|
||||
{{ t('dialog.user.actions.moderation_block') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
v-if="userDialog.isMute"
|
||||
:icon="Microphone"
|
||||
command="Moderation Unmute"
|
||||
style="color: #f56c6c">
|
||||
{{ t('dialog.user.actions.moderation_unmute') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
v-else
|
||||
:icon="Mute"
|
||||
command="Moderation Mute"
|
||||
:disabled="userDialog.ref.$isModerator">
|
||||
{{ t('dialog.user.actions.moderation_mute') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
v-if="userDialog.isMuteChat"
|
||||
:icon="ChatLineRound"
|
||||
command="Moderation Enable Chatbox"
|
||||
style="color: #f56c6c">
|
||||
{{ t('dialog.user.actions.moderation_enable_chatbox') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-else :icon="ChatDotRound" command="Moderation Disable Chatbox">
|
||||
{{ t('dialog.user.actions.moderation_disable_chatbox') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item :icon="User" command="Show Avatar">
|
||||
<el-icon v-if="userDialog.isShowAvatar" style="margin-right: 5px"><Check /></el-icon>
|
||||
<span>{{ t('dialog.user.actions.moderation_show_avatar') }}</span>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item :icon="User" command="Hide Avatar">
|
||||
<el-icon v-if="userDialog.isHideAvatar" style="margin-right: 5px"><Check /></el-icon>
|
||||
<span>{{ t('dialog.user.actions.moderation_hide_avatar') }}</span>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
v-if="userDialog.isInteractOff"
|
||||
:icon="Pointer"
|
||||
command="Moderation Enable Avatar Interaction"
|
||||
style="color: #f56c6c">
|
||||
{{ t('dialog.user.actions.moderation_enable_avatar_interaction') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-else :icon="CircleClose" command="Moderation Disable Avatar Interaction">
|
||||
{{ t('dialog.user.actions.moderation_disable_avatar_interaction') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item :icon="Flag" command="Report Hacking" :disabled="userDialog.ref.$isModerator">
|
||||
{{ t('dialog.user.actions.report_hacking') }}
|
||||
</el-dropdown-item>
|
||||
<template v-if="userDialog.isFriend">
|
||||
<el-dropdown-item :icon="Delete" command="Unfriend" divided style="color: #f56c6c">
|
||||
{{ t('dialog.user.actions.unfriend') }}
|
||||
</el-dropdown-item>
|
||||
</template>
|
||||
</template>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ChatDotRound,
|
||||
ChatLineRound,
|
||||
Check,
|
||||
CircleCheck,
|
||||
CircleClose,
|
||||
Close,
|
||||
DataLine,
|
||||
Delete,
|
||||
Edit,
|
||||
Flag,
|
||||
Message,
|
||||
Microphone,
|
||||
MoreFilled,
|
||||
Mute,
|
||||
Operation,
|
||||
Picture,
|
||||
Plus,
|
||||
Pointer,
|
||||
Postcard,
|
||||
Refresh,
|
||||
Share,
|
||||
Star,
|
||||
StarFilled,
|
||||
SwitchButton,
|
||||
User,
|
||||
UserFilled
|
||||
} from '@element-plus/icons-vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import { useGameStore, useLocationStore, useUserStore } from '../../../stores';
|
||||
import { checkCanInvite } from '../../../shared/utils';
|
||||
|
||||
const props = defineProps({
|
||||
userDialogCommand: {
|
||||
type: Function,
|
||||
required: true
|
||||
}
|
||||
});
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const { userDialog, currentUser } = storeToRefs(useUserStore());
|
||||
const { isGameRunning } = storeToRefs(useGameStore());
|
||||
const { lastLocation } = storeToRefs(useLocationStore());
|
||||
|
||||
function onCommand(command) {
|
||||
props.userDialogCommand(command);
|
||||
}
|
||||
</script>
|
||||
@@ -6,491 +6,12 @@
|
||||
:show-close="false"
|
||||
width="770px">
|
||||
<div v-loading="userDialog.loading">
|
||||
<div style="display: flex">
|
||||
<img
|
||||
v-if="
|
||||
!userDialog.loading &&
|
||||
(userDialog.ref.profilePicOverrideThumbnail || userDialog.ref.profilePicOverride)
|
||||
"
|
||||
class="x-link"
|
||||
:src="userDialog.ref.profilePicOverrideThumbnail || userDialog.ref.profilePicOverride"
|
||||
style="flex: none; height: 120px; width: 213.33px; border-radius: 12px; object-fit: cover"
|
||||
@click="showFullscreenImageDialog(userDialog.ref.profilePicOverride)"
|
||||
loading="lazy" />
|
||||
<img
|
||||
v-else-if="!userDialog.loading"
|
||||
class="x-link"
|
||||
:src="userDialog.ref.currentAvatarThumbnailImageUrl"
|
||||
style="flex: none; height: 120px; width: 160px; border-radius: 12px; object-fit: cover"
|
||||
@click="showFullscreenImageDialog(userDialog.ref.currentAvatarImageUrl)"
|
||||
loading="lazy" />
|
||||
|
||||
<div style="flex: 1; display: flex; align-items: center; margin-left: 15px">
|
||||
<div style="flex: 1">
|
||||
<div>
|
||||
<el-tooltip v-if="userDialog.ref.status" placement="top">
|
||||
<template #content>
|
||||
<span>{{ getUserStateText(userDialog.ref) }}</span>
|
||||
</template>
|
||||
<i class="x-user-status" :class="userStatusClass(userDialog.ref)"></i>
|
||||
</el-tooltip>
|
||||
<template v-if="userDialog.previousDisplayNames.length > 0">
|
||||
<el-tooltip placement="bottom">
|
||||
<template #content>
|
||||
<span>{{ t('dialog.user.previous_display_names') }}</span>
|
||||
<div
|
||||
v-for="displayName in userDialog.previousDisplayNames"
|
||||
:key="displayName"
|
||||
placement="top">
|
||||
<span v-text="displayName"></span>
|
||||
</div>
|
||||
</template>
|
||||
<el-icon><CaretBottom /></el-icon>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<span
|
||||
class="dialog-title"
|
||||
style="margin-left: 5px; margin-right: 5px; cursor: pointer"
|
||||
v-text="userDialog.ref.displayName"
|
||||
@click="copyUserDisplayName(userDialog.ref.displayName)"></span>
|
||||
<el-tooltip
|
||||
v-if="userDialog.ref.pronouns"
|
||||
placement="top"
|
||||
:content="t('dialog.user.pronouns')">
|
||||
<span
|
||||
class="x-grey"
|
||||
style="margin-right: 5px; font-family: monospace; font-size: 12px"
|
||||
v-text="userDialog.ref.pronouns"></span>
|
||||
</el-tooltip>
|
||||
<el-tooltip v-for="item in userDialog.ref.$languages" :key="item.key" placement="top">
|
||||
<template #content>
|
||||
<span>{{ item.value }} ({{ item.key }})</span>
|
||||
</template>
|
||||
<span
|
||||
class="flags"
|
||||
:class="languageClass(item.key)"
|
||||
style="display: inline-block; margin-right: 5px"></span>
|
||||
</el-tooltip>
|
||||
<template v-if="userDialog.ref.id === currentUser.id">
|
||||
<br />
|
||||
<span
|
||||
class="x-grey"
|
||||
style="margin-right: 10px; font-family: monospace; font-size: 12px; cursor: pointer"
|
||||
v-text="currentUser.username"
|
||||
@click="copyUserDisplayName(currentUser.username)"></span>
|
||||
</template>
|
||||
</div>
|
||||
<div style="margin-top: 5px" v-show="!userDialog.loading">
|
||||
<el-tag
|
||||
type="info"
|
||||
effect="plain"
|
||||
size="small"
|
||||
class="name"
|
||||
:class="userDialog.ref.$trustClass"
|
||||
style="margin-right: 5px; margin-top: 5px">
|
||||
{{ userDialog.ref.$trustLevel }}
|
||||
</el-tag>
|
||||
<el-tag
|
||||
v-if="userDialog.isFriend && userDialog.friend"
|
||||
type="info"
|
||||
effect="plain"
|
||||
size="small"
|
||||
class="x-tag-friend"
|
||||
style="margin-right: 5px; margin-top: 5px">
|
||||
{{
|
||||
t('dialog.user.tags.friend_no', {
|
||||
number: userDialog.ref.$friendNumber ? userDialog.ref.$friendNumber : ''
|
||||
})
|
||||
}}
|
||||
</el-tag>
|
||||
<el-tag
|
||||
v-if="userDialog.ref.$isTroll"
|
||||
type="info"
|
||||
effect="plain"
|
||||
size="small"
|
||||
class="x-tag-troll"
|
||||
style="margin-right: 5px; margin-top: 5px">
|
||||
Nuisance
|
||||
</el-tag>
|
||||
<el-tag
|
||||
v-if="userDialog.ref.$isProbableTroll"
|
||||
type="info"
|
||||
effect="plain"
|
||||
size="small"
|
||||
class="x-tag-troll"
|
||||
style="margin-right: 5px; margin-top: 5px">
|
||||
Almost Nuisance
|
||||
</el-tag>
|
||||
<el-tag
|
||||
v-if="userDialog.ref.$isModerator"
|
||||
type="info"
|
||||
effect="plain"
|
||||
size="small"
|
||||
class="x-tag-vip"
|
||||
style="margin-right: 5px; margin-top: 5px">
|
||||
{{ t('dialog.user.tags.vrchat_team') }}
|
||||
</el-tag>
|
||||
<el-tag
|
||||
v-if="userDialog.ref.$platform === 'standalonewindows'"
|
||||
type="info"
|
||||
effect="plain"
|
||||
size="small"
|
||||
class="x-tag-platform-pc"
|
||||
style="margin-right: 5px; margin-top: 5px">
|
||||
PC
|
||||
</el-tag>
|
||||
<el-tag
|
||||
v-else-if="userDialog.ref.$platform === 'android'"
|
||||
type="info"
|
||||
effect="plain"
|
||||
size="small"
|
||||
class="x-tag-platform-quest"
|
||||
style="margin-right: 5px; margin-top: 5px">
|
||||
Android
|
||||
</el-tag>
|
||||
<el-tag
|
||||
v-else-if="userDialog.ref.$platform === 'ios'"
|
||||
type="info"
|
||||
effect="plain"
|
||||
size="small"
|
||||
class="x-tag-platform-ios"
|
||||
style="margin-right: 5px; margin-top: 5px"
|
||||
>iOS</el-tag
|
||||
>
|
||||
<el-tag
|
||||
v-else-if="userDialog.ref.$platform"
|
||||
type="info"
|
||||
effect="plain"
|
||||
size="small"
|
||||
class="x-tag-platform-other"
|
||||
style="margin-right: 5px; margin-top: 5px">
|
||||
{{ userDialog.ref.$platform }}
|
||||
</el-tag>
|
||||
<el-tag
|
||||
v-if="userDialog.ref.ageVerified && userDialog.ref.ageVerificationStatus"
|
||||
type="info"
|
||||
effect="plain"
|
||||
size="small"
|
||||
class="x-tag-age-verification"
|
||||
style="margin-right: 5px; margin-top: 5px">
|
||||
<template v-if="userDialog.ref.ageVerificationStatus === '18+'">
|
||||
{{ t('dialog.user.tags.18_plus_verified') }}
|
||||
</template>
|
||||
<template v-else>
|
||||
{{ t('dialog.user.tags.age_verified') }}
|
||||
</template>
|
||||
</el-tag>
|
||||
<el-tag
|
||||
v-if="userDialog.ref.$customTag"
|
||||
type="info"
|
||||
effect="plain"
|
||||
size="small"
|
||||
class="name"
|
||||
:style="{
|
||||
color: userDialog.ref.$customTagColour,
|
||||
'border-color': userDialog.ref.$customTagColour
|
||||
}"
|
||||
style="margin-right: 5px; margin-top: 5px"
|
||||
>{{ userDialog.ref.$customTag }}</el-tag
|
||||
>
|
||||
<br />
|
||||
<el-tooltip v-for="badge in userDialog.ref.badges" :key="badge.badgeId" placement="top">
|
||||
<template #content>
|
||||
<span>{{ badge.badgeName }}</span>
|
||||
<span v-if="badge.hidden"> (Hidden)</span>
|
||||
</template>
|
||||
<div style="display: inline-block">
|
||||
<el-popover placement="bottom" :width="300" trigger="click">
|
||||
<template #reference>
|
||||
<img
|
||||
class="x-link x-user-badge"
|
||||
:src="badge.badgeImageUrl"
|
||||
style="
|
||||
flex: none;
|
||||
height: 32px;
|
||||
width: 32px;
|
||||
border-radius: 3px;
|
||||
object-fit: cover;
|
||||
margin-top: 5px;
|
||||
margin-right: 5px;
|
||||
"
|
||||
:class="{ 'x-user-badge-hidden': badge.hidden }"
|
||||
loading="lazy" />
|
||||
</template>
|
||||
<img
|
||||
:src="badge.badgeImageUrl"
|
||||
:class="['x-link', 'x-popover-image']"
|
||||
@click="showFullscreenImageDialog(badge.badgeImageUrl)"
|
||||
loading="lazy" />
|
||||
<br />
|
||||
<div style="display: block; width: 300px; word-break: normal">
|
||||
<span>{{ badge.badgeName }}</span>
|
||||
<br />
|
||||
<span class="x-grey" style="font-size: 12px">{{
|
||||
badge.badgeDescription
|
||||
}}</span>
|
||||
<br />
|
||||
<span
|
||||
v-if="badge.assignedAt"
|
||||
class="x-grey"
|
||||
style="font-family: monospace; font-size: 12px">
|
||||
{{ t('dialog.user.badges.assigned') }}:
|
||||
{{ formatDateFilter(badge.assignedAt, 'long') }}
|
||||
</span>
|
||||
<template v-if="userDialog.id === currentUser.id">
|
||||
<br />
|
||||
<el-checkbox
|
||||
v-model="badge.hidden"
|
||||
style="margin-top: 5px"
|
||||
@change="toggleBadgeVisibility(badge)">
|
||||
{{ t('dialog.user.badges.hidden') }}
|
||||
</el-checkbox>
|
||||
<br />
|
||||
<el-checkbox
|
||||
v-model="badge.showcased"
|
||||
@change="toggleBadgeShowcased(badge)">
|
||||
{{ t('dialog.user.badges.showcased') }}
|
||||
</el-checkbox>
|
||||
</template>
|
||||
</div>
|
||||
</el-popover>
|
||||
</div>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<div style="margin-top: 5px">
|
||||
<span style="font-size: 12px" v-text="userDialog.ref.statusDescription"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="userDialog.ref.userIcon" style="flex: none; margin-right: 10px">
|
||||
<img
|
||||
class="x-link"
|
||||
:src="userImage(userDialog.ref, true, '256', true)"
|
||||
style="flex: none; width: 120px; height: 120px; border-radius: 12px; object-fit: cover"
|
||||
@click="showFullscreenImageDialog(userDialog.ref.userIcon)"
|
||||
loading="lazy" />
|
||||
</div>
|
||||
|
||||
<div style="flex: none">
|
||||
<template
|
||||
v-if="
|
||||
(currentUser.id !== userDialog.ref.id && userDialog.isFriend) || userDialog.isFavorite
|
||||
">
|
||||
<el-tooltip
|
||||
v-if="userDialog.isFavorite"
|
||||
placement="top"
|
||||
:content="t('dialog.user.actions.unfavorite_tooltip')">
|
||||
<el-button
|
||||
type="warning"
|
||||
:icon="StarFilled"
|
||||
size="large"
|
||||
circle
|
||||
@click="userDialogCommand('Add Favorite')"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip v-else placement="top" :content="t('dialog.user.actions.favorite_tooltip')">
|
||||
<el-button
|
||||
type="default"
|
||||
:icon="Star"
|
||||
size="large"
|
||||
circle
|
||||
@click="userDialogCommand('Add Favorite')"></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<el-dropdown trigger="click" size="small" @command="userDialogCommand">
|
||||
<el-button
|
||||
:type="
|
||||
userDialog.incomingRequest || userDialog.outgoingRequest
|
||||
? 'success'
|
||||
: userDialog.isBlock || userDialog.isMute
|
||||
? 'danger'
|
||||
: 'default'
|
||||
"
|
||||
:icon="MoreFilled"
|
||||
size="large"
|
||||
circle
|
||||
style="margin-left: 5px"></el-button>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item :icon="Refresh" command="Refresh">{{
|
||||
t('dialog.user.actions.refresh')
|
||||
}}</el-dropdown-item>
|
||||
<el-dropdown-item :icon="Share" command="Share">{{
|
||||
t('dialog.user.actions.share')
|
||||
}}</el-dropdown-item>
|
||||
<template v-if="userDialog.ref.id === currentUser.id">
|
||||
<el-dropdown-item :icon="Picture" command="Manage Gallery" divided>{{
|
||||
t('dialog.user.actions.manage_gallery_inventory_icon')
|
||||
}}</el-dropdown-item>
|
||||
<el-dropdown-item :icon="UserFilled" command="Show Avatar Author">{{
|
||||
t('dialog.user.actions.show_avatar_author')
|
||||
}}</el-dropdown-item>
|
||||
<el-dropdown-item :icon="UserFilled" command="Show Fallback Avatar Details">{{
|
||||
t('dialog.user.actions.show_fallback_avatar')
|
||||
}}</el-dropdown-item>
|
||||
<el-dropdown-item :icon="Edit" command="Edit Social Status" divided>{{
|
||||
t('dialog.user.actions.edit_status')
|
||||
}}</el-dropdown-item>
|
||||
<el-dropdown-item :icon="Edit" command="Edit Language">{{
|
||||
t('dialog.user.actions.edit_language')
|
||||
}}</el-dropdown-item>
|
||||
<el-dropdown-item :icon="Edit" command="Edit Bio">{{
|
||||
t('dialog.user.actions.edit_bio')
|
||||
}}</el-dropdown-item>
|
||||
<el-dropdown-item :icon="Edit" command="Edit Pronouns">{{
|
||||
t('dialog.user.actions.edit_pronouns')
|
||||
}}</el-dropdown-item>
|
||||
<el-dropdown-item :icon="SwitchButton" command="Logout" divided>{{
|
||||
t('dialog.user.actions.logout')
|
||||
}}</el-dropdown-item>
|
||||
</template>
|
||||
<template v-else>
|
||||
<template v-if="userDialog.isFriend">
|
||||
<el-dropdown-item :icon="Postcard" command="Request Invite" divided>{{
|
||||
t('dialog.user.actions.request_invite')
|
||||
}}</el-dropdown-item>
|
||||
<el-dropdown-item :icon="Postcard" command="Request Invite Message">{{
|
||||
t('dialog.user.actions.request_invite_with_message')
|
||||
}}</el-dropdown-item>
|
||||
<template v-if="isGameRunning">
|
||||
<el-dropdown-item
|
||||
:disabled="!checkCanInvite(lastLocation.location)"
|
||||
:icon="Message"
|
||||
command="Invite"
|
||||
>{{ t('dialog.user.actions.invite') }}</el-dropdown-item
|
||||
>
|
||||
<el-dropdown-item
|
||||
:disabled="!checkCanInvite(lastLocation.location)"
|
||||
:icon="Message"
|
||||
command="Invite Message"
|
||||
>{{
|
||||
t('dialog.user.actions.invite_with_message')
|
||||
}}</el-dropdown-item
|
||||
>
|
||||
</template>
|
||||
</template>
|
||||
<template v-else-if="userDialog.incomingRequest">
|
||||
<el-dropdown-item :icon="Check" command="Accept Friend Request">{{
|
||||
t('dialog.user.actions.accept_friend_request')
|
||||
}}</el-dropdown-item>
|
||||
<el-dropdown-item :icon="Close" command="Decline Friend Request">{{
|
||||
t('dialog.user.actions.decline_friend_request')
|
||||
}}</el-dropdown-item>
|
||||
</template>
|
||||
<el-dropdown-item
|
||||
v-else-if="userDialog.outgoingRequest"
|
||||
:icon="Close"
|
||||
command="Cancel Friend Request">
|
||||
{{ t('dialog.user.actions.cancel_friend_request') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-else :icon="Plus" command="Send Friend Request">{{
|
||||
t('dialog.user.actions.send_friend_request')
|
||||
}}</el-dropdown-item>
|
||||
<el-dropdown-item :icon="Message" command="Invite To Group">{{
|
||||
t('dialog.user.actions.invite_to_group')
|
||||
}}</el-dropdown-item>
|
||||
<el-dropdown-item :icon="Operation" command="Group Moderation">{{
|
||||
t('dialog.user.actions.group_moderation')
|
||||
}}</el-dropdown-item>
|
||||
<!--//- el-dropdown-item(:icon="Thumb" command="Send Boop" :disabled="!currentUser.isBoopingEnabled") {{ t('dialog.user.actions.send_boop') }}-->
|
||||
<el-dropdown-item :icon="UserFilled" command="Show Avatar Author" divided>{{
|
||||
t('dialog.user.actions.show_avatar_author')
|
||||
}}</el-dropdown-item>
|
||||
<el-dropdown-item :icon="UserFilled" command="Show Fallback Avatar Details">{{
|
||||
t('dialog.user.actions.show_fallback_avatar')
|
||||
}}</el-dropdown-item>
|
||||
<el-dropdown-item :icon="DataLine" command="Previous Instances">{{
|
||||
t('dialog.user.actions.show_previous_instances')
|
||||
}}</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
v-if="userDialog.isBlock"
|
||||
:icon="CircleCheck"
|
||||
command="Moderation Unblock"
|
||||
divided
|
||||
style="color: #f56c6c">
|
||||
{{ t('dialog.user.actions.moderation_unblock') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
v-else
|
||||
:icon="CircleClose"
|
||||
command="Moderation Block"
|
||||
divided
|
||||
:disabled="userDialog.ref.$isModerator">
|
||||
{{ t('dialog.user.actions.moderation_block') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
v-if="userDialog.isMute"
|
||||
:icon="Microphone"
|
||||
command="Moderation Unmute"
|
||||
style="color: #f56c6c">
|
||||
{{ t('dialog.user.actions.moderation_unmute') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
v-else
|
||||
:icon="Mute"
|
||||
command="Moderation Mute"
|
||||
:disabled="userDialog.ref.$isModerator">
|
||||
{{ t('dialog.user.actions.moderation_mute') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
v-if="userDialog.isMuteChat"
|
||||
:icon="ChatLineRound"
|
||||
command="Moderation Enable Chatbox"
|
||||
style="color: #f56c6c">
|
||||
{{ t('dialog.user.actions.moderation_enable_chatbox') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
v-else
|
||||
:icon="ChatDotRound"
|
||||
command="Moderation Disable Chatbox">
|
||||
{{ t('dialog.user.actions.moderation_disable_chatbox') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item :icon="User" command="Show Avatar">
|
||||
<el-icon v-if="userDialog.isShowAvatar" style="margin-right: 5px"
|
||||
><Check
|
||||
/></el-icon>
|
||||
<span>{{ t('dialog.user.actions.moderation_show_avatar') }}</span>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item :icon="User" command="Hide Avatar">
|
||||
<el-icon v-if="userDialog.isHideAvatar" style="margin-right: 5px"
|
||||
><Check
|
||||
/></el-icon>
|
||||
<span>{{ t('dialog.user.actions.moderation_hide_avatar') }}</span>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
v-if="userDialog.isInteractOff"
|
||||
:icon="Pointer"
|
||||
command="Moderation Enable Avatar Interaction"
|
||||
style="color: #f56c6c">
|
||||
{{ t('dialog.user.actions.moderation_enable_avatar_interaction') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
v-else
|
||||
:icon="CircleClose"
|
||||
command="Moderation Disable Avatar Interaction">
|
||||
{{ t('dialog.user.actions.moderation_disable_avatar_interaction') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
:icon="Flag"
|
||||
command="Report Hacking"
|
||||
:disabled="userDialog.ref.$isModerator">
|
||||
{{ t('dialog.user.actions.report_hacking') }}
|
||||
</el-dropdown-item>
|
||||
<template v-if="userDialog.isFriend">
|
||||
<el-dropdown-item
|
||||
:icon="Delete"
|
||||
command="Unfriend"
|
||||
divided
|
||||
style="color: #f56c6c">
|
||||
{{ t('dialog.user.actions.unfriend') }}
|
||||
</el-dropdown-item>
|
||||
</template>
|
||||
</template>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<UserSummaryHeader
|
||||
:get-user-state-text="getUserStateText"
|
||||
:copy-user-display-name="copyUserDisplayName"
|
||||
:toggle-badge-visibility="toggleBadgeVisibility"
|
||||
:toggle-badge-showcased="toggleBadgeShowcased"
|
||||
:user-dialog-command="userDialogCommand" />
|
||||
|
||||
<el-tabs v-model="userDialogLastActiveTab" @tab-click="userDialogTabClick">
|
||||
<el-tab-pane name="Info" :label="t('dialog.user.info.header')">
|
||||
@@ -1692,40 +1213,19 @@
|
||||
import {
|
||||
ArrowDown,
|
||||
Bottom,
|
||||
CaretBottom,
|
||||
ChatDotRound,
|
||||
ChatLineRound,
|
||||
Check,
|
||||
CircleCheck,
|
||||
CircleClose,
|
||||
Close,
|
||||
CollectionTag,
|
||||
CopyDocument,
|
||||
DataLine,
|
||||
Delete,
|
||||
Download,
|
||||
Edit,
|
||||
Flag,
|
||||
Loading,
|
||||
Message,
|
||||
Microphone,
|
||||
More,
|
||||
MoreFilled,
|
||||
Mute,
|
||||
Operation,
|
||||
Picture,
|
||||
Plus,
|
||||
Pointer,
|
||||
Postcard,
|
||||
Refresh,
|
||||
Setting,
|
||||
Share,
|
||||
Star,
|
||||
StarFilled,
|
||||
SwitchButton,
|
||||
Top,
|
||||
User,
|
||||
UserFilled,
|
||||
View,
|
||||
Warning
|
||||
} from '@element-plus/icons-vue';
|
||||
@@ -1735,7 +1235,6 @@
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import {
|
||||
checkCanInvite,
|
||||
compareByMemberCount,
|
||||
compareByName,
|
||||
copyToClipboard,
|
||||
@@ -1744,7 +1243,6 @@
|
||||
getFaviconUrl,
|
||||
isFriendOnline,
|
||||
isRealInstance,
|
||||
languageClass,
|
||||
openExternalLink,
|
||||
parseLocation,
|
||||
refreshInstancePlayerCount,
|
||||
@@ -1764,7 +1262,6 @@
|
||||
useFavoriteStore,
|
||||
useFriendStore,
|
||||
useGalleryStore,
|
||||
useGameStore,
|
||||
useGroupStore,
|
||||
useInviteStore,
|
||||
useLocationStore,
|
||||
@@ -1790,6 +1287,7 @@
|
||||
import { userDialogGroupSortingOptions } from '../../../shared/constants';
|
||||
|
||||
import SendInviteDialog from '../InviteDialog/SendInviteDialog.vue';
|
||||
import UserSummaryHeader from './UserSummaryHeader.vue';
|
||||
|
||||
const BioDialog = defineAsyncComponent(() => import('./BioDialog.vue'));
|
||||
const LanguageDialog = defineAsyncComponent(() => import('./LanguageDialog.vue'));
|
||||
@@ -1828,7 +1326,7 @@
|
||||
const { friendLogTable } = storeToRefs(useFriendStore());
|
||||
const { getFriendRequest, handleFriendDelete } = useFriendStore();
|
||||
const { clearInviteImageUpload, showFullscreenImageDialog } = useGalleryStore();
|
||||
const { isGameRunning } = storeToRefs(useGameStore());
|
||||
|
||||
const { logout } = useAuthStore();
|
||||
const { cachedConfig } = storeToRefs(useAuthStore());
|
||||
const { applyPlayerModeration, handlePlayerModerationDelete } = useModerationStore();
|
||||
@@ -2567,7 +2065,7 @@
|
||||
|
||||
async function sortCurrentUserGroups() {
|
||||
const D = userDialog.value;
|
||||
let sortMethod = (a, b) => 0;
|
||||
let sortMethod = () => 0;
|
||||
|
||||
switch (D.groupSorting.value) {
|
||||
case 'alphabetical':
|
||||
|
||||
458
src/components/dialogs/UserDialog/UserSummaryHeader.vue
Normal file
458
src/components/dialogs/UserDialog/UserSummaryHeader.vue
Normal file
@@ -0,0 +1,458 @@
|
||||
<template>
|
||||
<div style="display: flex">
|
||||
<img
|
||||
v-if="
|
||||
!userDialog.loading && (userDialog.ref.profilePicOverrideThumbnail || userDialog.ref.profilePicOverride)
|
||||
"
|
||||
class="x-link"
|
||||
:src="userDialog.ref.profilePicOverrideThumbnail || userDialog.ref.profilePicOverride"
|
||||
style="flex: none; height: 120px; width: 213.33px; border-radius: 12px; object-fit: cover"
|
||||
@click="showFullscreenImageDialog(userDialog.ref.profilePicOverride)"
|
||||
loading="lazy" />
|
||||
<img
|
||||
v-else-if="!userDialog.loading"
|
||||
class="x-link"
|
||||
:src="userDialog.ref.currentAvatarThumbnailImageUrl"
|
||||
style="flex: none; height: 120px; width: 160px; border-radius: 12px; object-fit: cover"
|
||||
@click="showFullscreenImageDialog(userDialog.ref.currentAvatarImageUrl)"
|
||||
loading="lazy" />
|
||||
|
||||
<div style="flex: 1; display: flex; align-items: center; margin-left: 15px">
|
||||
<div style="flex: 1">
|
||||
<div>
|
||||
<el-tooltip v-if="userDialog.ref.status" placement="top">
|
||||
<template #content>
|
||||
<span>{{ getUserStateText(userDialog.ref) }}</span>
|
||||
</template>
|
||||
<i class="x-user-status" :class="userStatusClass(userDialog.ref)"></i>
|
||||
</el-tooltip>
|
||||
<template v-if="userDialog.previousDisplayNames.length > 0">
|
||||
<el-tooltip placement="bottom">
|
||||
<template #content>
|
||||
<span>{{ t('dialog.user.previous_display_names') }}</span>
|
||||
<div
|
||||
v-for="displayName in userDialog.previousDisplayNames"
|
||||
:key="displayName"
|
||||
placement="top">
|
||||
<span v-text="displayName"></span>
|
||||
</div>
|
||||
</template>
|
||||
<el-icon><CaretBottom /></el-icon>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<span
|
||||
class="dialog-title"
|
||||
style="margin-left: 5px; margin-right: 5px; cursor: pointer"
|
||||
v-text="userDialog.ref.displayName"
|
||||
@click="copyUserDisplayName(userDialog.ref.displayName)"></span>
|
||||
<el-tooltip v-if="userDialog.ref.pronouns" placement="top" :content="t('dialog.user.pronouns')">
|
||||
<span
|
||||
class="x-grey"
|
||||
style="margin-right: 5px; font-family: monospace; font-size: 12px"
|
||||
v-text="userDialog.ref.pronouns"></span>
|
||||
</el-tooltip>
|
||||
<el-tooltip v-for="item in userDialog.ref.$languages" :key="item.key" placement="top">
|
||||
<template #content>
|
||||
<span>{{ item.value }} ({{ item.key }})</span>
|
||||
</template>
|
||||
<span
|
||||
class="flags"
|
||||
:class="languageClass(item.key)"
|
||||
style="display: inline-block; margin-right: 5px"></span>
|
||||
</el-tooltip>
|
||||
<template v-if="userDialog.ref.id === currentUser.id">
|
||||
<br />
|
||||
<span
|
||||
class="x-grey"
|
||||
style="margin-right: 10px; font-family: monospace; font-size: 12px; cursor: pointer"
|
||||
v-text="currentUser.username"
|
||||
@click="copyUserDisplayName(currentUser.username)"></span>
|
||||
</template>
|
||||
</div>
|
||||
<div style="margin-top: 5px" v-show="!userDialog.loading">
|
||||
<el-tag
|
||||
v-if="userDialog.ref.$extraFav === 'pinned'"
|
||||
type="info"
|
||||
effect="plain"
|
||||
size="small"
|
||||
class="x-tag-favorite"
|
||||
style="margin-right: 5px; margin-top: 5px">
|
||||
{{ t('dialog.user.tags.pinned_favorite') }}
|
||||
</el-tag>
|
||||
<el-tag
|
||||
v-if="userDialog.ref.$favoriteGroupName"
|
||||
type="info"
|
||||
effect="plain"
|
||||
size="small"
|
||||
class="x-tag-favorite"
|
||||
style="margin-right: 5px; margin-top: 5px">
|
||||
{{ userDialog.ref.$favoriteGroupName }}
|
||||
</el-tag>
|
||||
<el-tag
|
||||
v-if="userDialog.ref.$isModerator"
|
||||
type="info"
|
||||
effect="plain"
|
||||
size="small"
|
||||
class="x-tag-moderator"
|
||||
style="margin-right: 5px; margin-top: 5px">
|
||||
{{ t('dialog.user.tags.vrchat_moderator') }}
|
||||
</el-tag>
|
||||
<el-tag
|
||||
v-if="userDialog.ref.$isStaff"
|
||||
type="info"
|
||||
effect="plain"
|
||||
size="small"
|
||||
class="x-tag-staff"
|
||||
style="margin-right: 5px; margin-top: 5px">
|
||||
{{ t('dialog.user.tags.vrchat_staff') }}
|
||||
</el-tag>
|
||||
<el-tag
|
||||
v-if="userDialog.ref.$isFriendsPlusSupporter"
|
||||
type="info"
|
||||
effect="plain"
|
||||
size="small"
|
||||
class="x-tag-friends-plus"
|
||||
style="margin-right: 5px; margin-top: 5px">
|
||||
{{ t('dialog.user.tags.vrchat_friends_plus') }}
|
||||
</el-tag>
|
||||
<el-tag
|
||||
v-if="userDialog.ref.$isTrustUpdated"
|
||||
type="warning"
|
||||
effect="plain"
|
||||
size="small"
|
||||
class="x-tag-user trust"
|
||||
style="margin-right: 5px; margin-top: 5px">
|
||||
{{ t('dialog.user.tags.updated_trust') }}
|
||||
</el-tag>
|
||||
<el-tag
|
||||
v-if="userDialog.ref.$isGuardians"
|
||||
type="info"
|
||||
effect="plain"
|
||||
size="small"
|
||||
class="x-tag-guardians"
|
||||
style="margin-right: 5px; margin-top: 5px">
|
||||
{{ t('dialog.user.tags.guardians') }}
|
||||
</el-tag>
|
||||
<el-tag
|
||||
v-if="userDialog.ref.$isSupporter"
|
||||
type="info"
|
||||
effect="plain"
|
||||
size="small"
|
||||
class="x-tag-supporter"
|
||||
style="margin-right: 5px; margin-top: 5px">
|
||||
{{ t('dialog.user.tags.supporter') }}
|
||||
</el-tag>
|
||||
<el-tag
|
||||
v-if="userDialog.ref.$isQuestPatron"
|
||||
type="info"
|
||||
effect="plain"
|
||||
size="small"
|
||||
class="x-tag-quest-patron"
|
||||
style="margin-right: 5px; margin-top: 5px">
|
||||
{{ t('dialog.user.tags.quest_patron') }}
|
||||
</el-tag>
|
||||
<el-tag
|
||||
v-if="userDialog.ref.$isVrcPlus"
|
||||
type="info"
|
||||
effect="plain"
|
||||
size="small"
|
||||
class="x-tag-vrcplus"
|
||||
style="margin-right: 5px; margin-top: 5px">
|
||||
{{ t('dialog.user.tags.vrchat_plus') }}
|
||||
</el-tag>
|
||||
<el-tag
|
||||
v-if="userDialog.ref.$isLegend"
|
||||
type="info"
|
||||
effect="plain"
|
||||
size="small"
|
||||
class="x-tag-legend"
|
||||
style="margin-right: 5px; margin-top: 5px">
|
||||
{{ t('dialog.user.tags.legend') }}
|
||||
</el-tag>
|
||||
<el-tag
|
||||
v-if="userDialog.ref.$isTrusted"
|
||||
type="info"
|
||||
effect="plain"
|
||||
size="small"
|
||||
class="x-tag-trusted"
|
||||
style="margin-right: 5px; margin-top: 5px">
|
||||
{{ t('dialog.user.tags.trusted') }}
|
||||
</el-tag>
|
||||
<el-tag
|
||||
v-if="userDialog.ref.$isNewUser"
|
||||
type="info"
|
||||
effect="plain"
|
||||
size="small"
|
||||
class="x-tag-new-user"
|
||||
style="margin-right: 5px; margin-top: 5px">
|
||||
{{ t('dialog.user.tags.new_user') }}
|
||||
</el-tag>
|
||||
<el-tag
|
||||
v-if="userDialog.ref.$isKnownUser"
|
||||
type="info"
|
||||
effect="plain"
|
||||
size="small"
|
||||
class="x-tag-known-user"
|
||||
style="margin-right: 5px; margin-top: 5px">
|
||||
{{ t('dialog.user.tags.known_user') }}
|
||||
</el-tag>
|
||||
<el-tag
|
||||
v-if="userDialog.ref.$isTrustedUser"
|
||||
type="info"
|
||||
effect="plain"
|
||||
size="small"
|
||||
class="x-tag-trusted-user"
|
||||
style="margin-right: 5px; margin-top: 5px">
|
||||
{{ t('dialog.user.tags.trusted_user') }}
|
||||
</el-tag>
|
||||
<el-tag
|
||||
v-if="userDialog.ref.$isTroll"
|
||||
type="info"
|
||||
effect="plain"
|
||||
size="small"
|
||||
class="x-tag-troll"
|
||||
style="margin-right: 5px; margin-top: 5px">
|
||||
{{ t('dialog.user.tags.troll') }}
|
||||
</el-tag>
|
||||
<el-tag
|
||||
v-if="userDialog.ref.$isNegative"
|
||||
type="info"
|
||||
effect="plain"
|
||||
size="small"
|
||||
class="x-tag-negative"
|
||||
style="margin-right: 5px; margin-top: 5px">
|
||||
{{ t('dialog.user.tags.negative') }}
|
||||
</el-tag>
|
||||
<el-tag
|
||||
v-if="userDialog.ref.$isNuisance"
|
||||
type="info"
|
||||
effect="plain"
|
||||
size="small"
|
||||
class="x-tag-nuisance"
|
||||
style="margin-right: 5px; margin-top: 5px">
|
||||
{{ t('dialog.user.tags.nuisance') }}
|
||||
</el-tag>
|
||||
<el-tag
|
||||
v-if="userDialog.ref.$isVRCXStaff"
|
||||
type="info"
|
||||
effect="plain"
|
||||
size="small"
|
||||
class="x-tag-vrcx-staff"
|
||||
style="margin-right: 5px; margin-top: 5px">
|
||||
{{ t('dialog.user.tags.vrcx_staff') }}
|
||||
</el-tag>
|
||||
<el-tag
|
||||
v-if="userDialog.ref.$isSupporterBadge"
|
||||
type="info"
|
||||
effect="plain"
|
||||
size="small"
|
||||
class="x-tag-supporter"
|
||||
style="margin-right: 5px; margin-top: 5px">
|
||||
{{ t('dialog.user.tags.supporter_badge') }}
|
||||
</el-tag>
|
||||
<el-tag
|
||||
v-if="userDialog.ref.$isTeam"
|
||||
type="info"
|
||||
effect="plain"
|
||||
size="small"
|
||||
class="x-tag-team"
|
||||
style="margin-right: 5px; margin-top: 5px">
|
||||
{{ t('dialog.user.tags.team') }}
|
||||
</el-tag>
|
||||
<el-tag
|
||||
v-if="userDialog.ref.$isVip"
|
||||
type="info"
|
||||
effect="plain"
|
||||
size="small"
|
||||
class="x-tag-vip"
|
||||
style="margin-right: 5px; margin-top: 5px">
|
||||
{{ t('dialog.user.tags.vrchat_team') }}
|
||||
</el-tag>
|
||||
<el-tag
|
||||
v-if="userDialog.ref.$platform === 'standalonewindows'"
|
||||
type="info"
|
||||
effect="plain"
|
||||
size="small"
|
||||
class="x-tag-platform-pc"
|
||||
style="margin-right: 5px; margin-top: 5px">
|
||||
PC
|
||||
</el-tag>
|
||||
<el-tag
|
||||
v-else-if="userDialog.ref.$platform === 'android'"
|
||||
type="info"
|
||||
effect="plain"
|
||||
size="small"
|
||||
class="x-tag-platform-quest"
|
||||
style="margin-right: 5px; margin-top: 5px">
|
||||
Android
|
||||
</el-tag>
|
||||
<el-tag
|
||||
v-else-if="userDialog.ref.$platform === 'ios'"
|
||||
type="info"
|
||||
effect="plain"
|
||||
size="small"
|
||||
class="x-tag-platform-ios"
|
||||
style="margin-right: 5px; margin-top: 5px">
|
||||
iOS
|
||||
</el-tag>
|
||||
<el-tag
|
||||
v-else-if="userDialog.ref.$platform"
|
||||
type="info"
|
||||
effect="plain"
|
||||
size="small"
|
||||
class="x-tag-platform-other"
|
||||
style="margin-right: 5px; margin-top: 5px">
|
||||
{{ userDialog.ref.$platform }}
|
||||
</el-tag>
|
||||
<el-tag
|
||||
v-if="userDialog.ref.ageVerified && userDialog.ref.ageVerificationStatus"
|
||||
type="info"
|
||||
effect="plain"
|
||||
size="small"
|
||||
class="x-tag-age-verification"
|
||||
style="margin-right: 5px; margin-top: 5px">
|
||||
<template v-if="userDialog.ref.ageVerificationStatus === '18+'">
|
||||
{{ t('dialog.user.tags.18_plus_verified') }}
|
||||
</template>
|
||||
<template v-else>
|
||||
{{ t('dialog.user.tags.age_verified') }}
|
||||
</template>
|
||||
</el-tag>
|
||||
<el-tag
|
||||
v-if="userDialog.ref.$customTag"
|
||||
type="info"
|
||||
effect="plain"
|
||||
size="small"
|
||||
class="name"
|
||||
:style="{
|
||||
color: userDialog.ref.$customTagColour,
|
||||
'border-color': userDialog.ref.$customTagColour
|
||||
}"
|
||||
style="margin-right: 5px; margin-top: 5px"
|
||||
>{{ userDialog.ref.$customTag }}</el-tag
|
||||
>
|
||||
<br />
|
||||
<el-tooltip v-for="badge in userDialog.ref.badges" :key="badge.badgeId" placement="top">
|
||||
<template #content>
|
||||
<span>{{ badge.badgeName }}</span>
|
||||
<span v-if="badge.hidden"> (Hidden)</span>
|
||||
</template>
|
||||
<div style="display: inline-block">
|
||||
<el-popover placement="bottom" :width="300" trigger="click">
|
||||
<template #reference>
|
||||
<img
|
||||
class="x-link x-user-badge"
|
||||
:src="badge.badgeImageUrl"
|
||||
style="
|
||||
flex: none;
|
||||
height: 32px;
|
||||
width: 32px;
|
||||
border-radius: 3px;
|
||||
object-fit: cover;
|
||||
margin-top: 5px;
|
||||
margin-right: 5px;
|
||||
"
|
||||
:class="{ 'x-user-badge-hidden': badge.hidden }"
|
||||
loading="lazy" />
|
||||
</template>
|
||||
<img
|
||||
:src="badge.badgeImageUrl"
|
||||
:class="['x-link', 'x-popover-image']"
|
||||
@click="showFullscreenImageDialog(badge.badgeImageUrl)"
|
||||
loading="lazy" />
|
||||
<br />
|
||||
<div style="display: block; width: 300px; word-break: normal">
|
||||
<span>{{ badge.badgeName }}</span>
|
||||
<br />
|
||||
<span class="x-grey" style="font-size: 12px">{{ badge.badgeDescription }}</span>
|
||||
<br />
|
||||
<span
|
||||
v-if="badge.assignedAt"
|
||||
class="x-grey"
|
||||
style="font-family: monospace; font-size: 12px">
|
||||
{{ t('dialog.user.badges.assigned') }}:
|
||||
{{ formatDateFilter(badge.assignedAt, 'long') }}
|
||||
</span>
|
||||
<template v-if="userDialog.id === currentUser.id">
|
||||
<br />
|
||||
<el-checkbox
|
||||
v-model="badge.hidden"
|
||||
style="margin-top: 5px"
|
||||
@change="toggleBadgeVisibility(badge)">
|
||||
{{ t('dialog.user.badges.hidden') }}
|
||||
</el-checkbox>
|
||||
<br />
|
||||
<el-checkbox v-model="badge.showcased" @change="toggleBadgeShowcased(badge)">
|
||||
{{ t('dialog.user.badges.showcased') }}
|
||||
</el-checkbox>
|
||||
</template>
|
||||
</div>
|
||||
</el-popover>
|
||||
</div>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<div style="margin-top: 5px">
|
||||
<span style="font-size: 12px" v-text="userDialog.ref.statusDescription"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="userDialog.ref.userIcon" style="flex: none; margin-right: 10px">
|
||||
<img
|
||||
class="x-link"
|
||||
:src="userImage(userDialog.ref, true, '256', true)"
|
||||
style="flex: none; width: 120px; height: 120px; border-radius: 12px; object-fit: cover"
|
||||
@click="showFullscreenImageDialog(userDialog.ref.userIcon)"
|
||||
loading="lazy" />
|
||||
</div>
|
||||
|
||||
<UserActionDropdown :user-dialog-command="userDialogCommand" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { CaretBottom } from '@element-plus/icons-vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import { formatDateFilter, languageClass, userImage, userStatusClass } from '../../../shared/utils';
|
||||
import { useGalleryStore, useUserStore } from '../../../stores';
|
||||
|
||||
import UserActionDropdown from './UserActionDropdown.vue';
|
||||
|
||||
const props = defineProps({
|
||||
getUserStateText: {
|
||||
type: Function,
|
||||
required: true
|
||||
},
|
||||
|
||||
copyUserDisplayName: {
|
||||
type: Function,
|
||||
required: true
|
||||
},
|
||||
toggleBadgeVisibility: {
|
||||
type: Function,
|
||||
required: true
|
||||
},
|
||||
toggleBadgeShowcased: {
|
||||
type: Function,
|
||||
required: true
|
||||
},
|
||||
userDialogCommand: {
|
||||
type: Function,
|
||||
required: true
|
||||
}
|
||||
});
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const { userDialog, currentUser } = storeToRefs(useUserStore());
|
||||
|
||||
const { showFullscreenImageDialog } = useGalleryStore();
|
||||
|
||||
const getUserStateText = props.getUserStateText;
|
||||
const copyUserDisplayName = props.copyUserDisplayName;
|
||||
const toggleBadgeVisibility = props.toggleBadgeVisibility;
|
||||
const toggleBadgeShowcased = props.toggleBadgeShowcased;
|
||||
const userDialogCommand = props.userDialogCommand;
|
||||
</script>
|
||||
Reference in New Issue
Block a user