admin-vben/apps/web-ele/src/views/im/home/components/friend/friend-item.vue

80 lines
2.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<script lang="ts" setup>
import type { FriendLite } from '../../types'
import { useImUiStore } from '../../store/uiStore'
import { UserAvatar } from '../user'
defineOptions({ name: 'ImFriendItem' })
const props = withDefaults(
defineProps<{
active?: boolean
friend: FriendLite
menu?: boolean // 是否启用右键菜单;在选择器弹窗里一般关闭
}>(),
{
active: false,
menu: true
}
)
const emit = defineEmits<{
chat: [friend: FriendLite]
click: [friend: FriendLite]
delete: [friend: FriendLite]
}>()
const uiStore = useImUiStore()
/** 右键菜单:发送消息 / 删除好友 */
function handleContextMenu(event: MouseEvent) {
if (!props.menu) {
return
}
uiStore.openContextMenu(
{ x: event.clientX, y: event.clientY },
[
{ key: 'chat', name: '发送消息' },
{ key: 'delete', name: '删除好友' }
],
(item) => {
if (item.key === 'chat') emit('chat', props.friend)
else if (item.key === 'delete') emit('delete', props.friend)
}
)
}
</script>
<template>
<!--
好友单行项
- 头像 + 昵称
- 选中态 active
- 右键菜单发消息 / 删除好友由全局 ContextMenu 承接
-->
<div
class="relative flex items-center gap-2.5 px-4 py-3 cursor-pointer transition-colors hover:bg-[var(--ant-color-fill)]"
:class="{ '!bg-[#d9ecff] dark:!bg-[var(--ant-color-primary-bg-hover)]': active }"
@click="$emit('click', friend)"
@contextmenu.prevent="handleContextMenu"
>
<!-- prefix slot放在头像前给选择类弹窗的 checkbox / 圆点用不传则不渲染 -->
<slot name="prefix"></slot>
<!-- 头像 -->
<UserAvatar
:id="friend.id"
:url="friend.avatar"
:name="friend.nickname"
:size="42"
:clickable="false"
/>
<!-- 单行展示 displayName 优先昵称仅在好友详情面板展示列表里不重复 -->
<div class="flex flex-1 min-w-0">
<div class="overflow-hidden text-sm truncate text-[var(--ant-color-text)]">
{{ friend.displayName || friend.nickname }}
</div>
</div>
<slot></slot>
</div>
</template>