mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-04-18 22:33:50 +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"
|
:show-close="false"
|
||||||
width="770px">
|
width="770px">
|
||||||
<div v-loading="userDialog.loading">
|
<div v-loading="userDialog.loading">
|
||||||
<div style="display: flex">
|
<UserSummaryHeader
|
||||||
<img
|
:get-user-state-text="getUserStateText"
|
||||||
v-if="
|
:copy-user-display-name="copyUserDisplayName"
|
||||||
!userDialog.loading &&
|
:toggle-badge-visibility="toggleBadgeVisibility"
|
||||||
(userDialog.ref.profilePicOverrideThumbnail || userDialog.ref.profilePicOverride)
|
:toggle-badge-showcased="toggleBadgeShowcased"
|
||||||
"
|
:user-dialog-command="userDialogCommand" />
|
||||||
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>
|
|
||||||
|
|
||||||
<el-tabs v-model="userDialogLastActiveTab" @tab-click="userDialogTabClick">
|
<el-tabs v-model="userDialogLastActiveTab" @tab-click="userDialogTabClick">
|
||||||
<el-tab-pane name="Info" :label="t('dialog.user.info.header')">
|
<el-tab-pane name="Info" :label="t('dialog.user.info.header')">
|
||||||
@@ -1692,40 +1213,19 @@
|
|||||||
import {
|
import {
|
||||||
ArrowDown,
|
ArrowDown,
|
||||||
Bottom,
|
Bottom,
|
||||||
CaretBottom,
|
|
||||||
ChatDotRound,
|
|
||||||
ChatLineRound,
|
|
||||||
Check,
|
Check,
|
||||||
CircleCheck,
|
|
||||||
CircleClose,
|
|
||||||
Close,
|
Close,
|
||||||
CollectionTag,
|
CollectionTag,
|
||||||
CopyDocument,
|
CopyDocument,
|
||||||
DataLine,
|
|
||||||
Delete,
|
Delete,
|
||||||
Download,
|
Download,
|
||||||
Edit,
|
Edit,
|
||||||
Flag,
|
|
||||||
Loading,
|
Loading,
|
||||||
Message,
|
|
||||||
Microphone,
|
|
||||||
More,
|
More,
|
||||||
MoreFilled,
|
MoreFilled,
|
||||||
Mute,
|
|
||||||
Operation,
|
|
||||||
Picture,
|
|
||||||
Plus,
|
|
||||||
Pointer,
|
|
||||||
Postcard,
|
|
||||||
Refresh,
|
Refresh,
|
||||||
Setting,
|
Setting,
|
||||||
Share,
|
|
||||||
Star,
|
|
||||||
StarFilled,
|
|
||||||
SwitchButton,
|
|
||||||
Top,
|
Top,
|
||||||
User,
|
|
||||||
UserFilled,
|
|
||||||
View,
|
View,
|
||||||
Warning
|
Warning
|
||||||
} from '@element-plus/icons-vue';
|
} from '@element-plus/icons-vue';
|
||||||
@@ -1735,7 +1235,6 @@
|
|||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
checkCanInvite,
|
|
||||||
compareByMemberCount,
|
compareByMemberCount,
|
||||||
compareByName,
|
compareByName,
|
||||||
copyToClipboard,
|
copyToClipboard,
|
||||||
@@ -1744,7 +1243,6 @@
|
|||||||
getFaviconUrl,
|
getFaviconUrl,
|
||||||
isFriendOnline,
|
isFriendOnline,
|
||||||
isRealInstance,
|
isRealInstance,
|
||||||
languageClass,
|
|
||||||
openExternalLink,
|
openExternalLink,
|
||||||
parseLocation,
|
parseLocation,
|
||||||
refreshInstancePlayerCount,
|
refreshInstancePlayerCount,
|
||||||
@@ -1764,7 +1262,6 @@
|
|||||||
useFavoriteStore,
|
useFavoriteStore,
|
||||||
useFriendStore,
|
useFriendStore,
|
||||||
useGalleryStore,
|
useGalleryStore,
|
||||||
useGameStore,
|
|
||||||
useGroupStore,
|
useGroupStore,
|
||||||
useInviteStore,
|
useInviteStore,
|
||||||
useLocationStore,
|
useLocationStore,
|
||||||
@@ -1790,6 +1287,7 @@
|
|||||||
import { userDialogGroupSortingOptions } from '../../../shared/constants';
|
import { userDialogGroupSortingOptions } from '../../../shared/constants';
|
||||||
|
|
||||||
import SendInviteDialog from '../InviteDialog/SendInviteDialog.vue';
|
import SendInviteDialog from '../InviteDialog/SendInviteDialog.vue';
|
||||||
|
import UserSummaryHeader from './UserSummaryHeader.vue';
|
||||||
|
|
||||||
const BioDialog = defineAsyncComponent(() => import('./BioDialog.vue'));
|
const BioDialog = defineAsyncComponent(() => import('./BioDialog.vue'));
|
||||||
const LanguageDialog = defineAsyncComponent(() => import('./LanguageDialog.vue'));
|
const LanguageDialog = defineAsyncComponent(() => import('./LanguageDialog.vue'));
|
||||||
@@ -1828,7 +1326,7 @@
|
|||||||
const { friendLogTable } = storeToRefs(useFriendStore());
|
const { friendLogTable } = storeToRefs(useFriendStore());
|
||||||
const { getFriendRequest, handleFriendDelete } = useFriendStore();
|
const { getFriendRequest, handleFriendDelete } = useFriendStore();
|
||||||
const { clearInviteImageUpload, showFullscreenImageDialog } = useGalleryStore();
|
const { clearInviteImageUpload, showFullscreenImageDialog } = useGalleryStore();
|
||||||
const { isGameRunning } = storeToRefs(useGameStore());
|
|
||||||
const { logout } = useAuthStore();
|
const { logout } = useAuthStore();
|
||||||
const { cachedConfig } = storeToRefs(useAuthStore());
|
const { cachedConfig } = storeToRefs(useAuthStore());
|
||||||
const { applyPlayerModeration, handlePlayerModerationDelete } = useModerationStore();
|
const { applyPlayerModeration, handlePlayerModerationDelete } = useModerationStore();
|
||||||
@@ -2567,7 +2065,7 @@
|
|||||||
|
|
||||||
async function sortCurrentUserGroups() {
|
async function sortCurrentUserGroups() {
|
||||||
const D = userDialog.value;
|
const D = userDialog.value;
|
||||||
let sortMethod = (a, b) => 0;
|
let sortMethod = () => 0;
|
||||||
|
|
||||||
switch (D.groupSorting.value) {
|
switch (D.groupSorting.value) {
|
||||||
case 'alphabetical':
|
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