| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <script lang="ts" setup> |
| | | import type { GroupLite } from '../../types' |
| | | |
| | | import { computed, onMounted, onUnmounted } from 'vue' |
| | | import { useRouter } from 'vue-router' |
| | | |
| | | import { prompt } from '#/packages/effects/common-ui/src' |
| | | |
| | | import { Input, message } from 'ant-design-vue' |
| | | |
| | | import { applyJoinGroup } from '#/api/im/group/request' |
| | | |
| | | import { ImConversationType, ImGroupAddSource } from '../../../utils/constants' |
| | | import { getGroupDisplayName } from '../../../utils/user' |
| | | import { useConversationStore } from '../../store/conversationStore' |
| | | import { useGroupStore } from '../../store/groupStore' |
| | | import { useImUiStore } from '../../store/uiStore' |
| | | import GroupInfo from './group-info.vue' |
| | | |
| | | defineOptions({ name: 'ImGroupInfoCard' }) |
| | | |
| | | const uiStore = useImUiStore() |
| | | const conversationStore = useConversationStore() |
| | | const groupStore = useGroupStore() |
| | | const router = useRouter() |
| | | |
| | | const card = computed(() => uiStore.groupInfoCard) |
| | | |
| | | /** å
³éæµ®å± */ |
| | | function handleClose() { |
| | | uiStore.closeGroupInfoCard() |
| | | } |
| | | |
| | | /** Esc å
³é */ |
| | | function handleKeydown(e: KeyboardEvent) { |
| | | if (e.key === 'Escape' && card.value.show) { |
| | | handleClose() |
| | | } |
| | | } |
| | | |
| | | onMounted(() => window.addEventListener('keydown', handleKeydown)) |
| | | onUnmounted(() => window.removeEventListener('keydown', handleKeydown)) |
| | | |
| | | /** è¿å
¥ç¾¤èï¼åæ¬å°ææ°ç¾¤ä¿¡æ¯ï¼å« silent / ç¾¤å¤æ³¨ï¼ï¼æ°å»ºææ¿æ´»ä¼è¯ + è·³è·¯ç± */ |
| | | function handleChat(group: GroupLite) { |
| | | const cached = groupStore.getGroup(group.id) |
| | | // cached å½ä¸èµ° getGroupDisplayName è®©ç¾¤å¤æ³¨ä¼å
ï¼ä¸ contact / ä¼è¯å表çå±ç¤ºåä¸è´ï¼ï¼ç¼º cached æ¶åè½ showGroupName / å群å |
| | | const displayName = cached |
| | | ? getGroupDisplayName(cached) |
| | | : group.showGroupName || group.name || '' |
| | | // æå¼ææ°å»ºä¼è¯ |
| | | conversationStore.openConversation( |
| | | group.id, |
| | | ImConversationType.GROUP, |
| | | displayName, |
| | | cached?.avatar || group.showImage || '', |
| | | { silent: !!cached?.silent } |
| | | ) |
| | | |
| | | // 妿ä¸å¨ä¼è¯é¡µï¼å
è·³è¿å»ï¼å¦æå¨äºï¼MessagePanel ä¼èªå·±æç¥ä¼è¯ååå·æ°ï¼ |
| | | if (router.currentRoute.value.name !== 'ImHomeConversation') { |
| | | router.push({ name: 'ImHomeConversation' }) |
| | | } |
| | | handleClose() |
| | | } |
| | | |
| | | /** å å
¥ç¾¤èï¼å
å
³æµ®å±ï¼é¿å
ä¸ prompt ç mask äºç¸é®æ¡ï¼â å¼¹ç³è¯·çç±ï¼å¯éï¼â applyJoinGroup */ |
| | | async function handleApply(group: GroupLite) { |
| | | handleClose() |
| | | let applyContent: string |
| | | try { |
| | | const result = await prompt<string>({ |
| | | cancelText: 'åæ¶', |
| | | component: Input, |
| | | componentProps: { |
| | | allowClear: true, |
| | | placeholder: '请填åéªè¯æ¶æ¯ï¼å¯éï¼' |
| | | }, |
| | | content: '', |
| | | defaultValue: '', |
| | | confirmText: 'åéç³è¯·', |
| | | modelPropName: 'value', |
| | | title: `ç³è¯·å å
¥ã${group.name || ''}ã` |
| | | }) |
| | | applyContent = (result || '').trim() |
| | | } catch { |
| | | return |
| | | } |
| | | await applyJoinGroup({ |
| | | groupId: group.id, |
| | | applyContent: applyContent || undefined, |
| | | addSource: ImGroupAddSource.SHARE_LINK |
| | | }) |
| | | message.success('å 群ç³è¯·å·²åé') |
| | | } |
| | | </script> |
| | | |
| | | <template> |
| | | <!-- |
| | | ç¾¤ä¿¡æ¯æµ®å±ï¼ä¸ UserInfoCard 对ä½ï¼ |
| | | - ä»
æ¿æ
ãæµ®å±å®ä½ + å
³éé»è¾ï¼ç¹é®ç½© / Escï¼ãï¼ç¾¤ä¿¡æ¯è§è§èµ° <GroupInfo>ï¼ä¸é讯å½è¯¦æ
å
±ç¨ä¸ä»½ç»ä»¶ |
| | | - 触åï¼useImUiStore.openGroupInfoCardAtEvent(group, e) |
| | | - GroupInfo å
鍿 groupStore ç¼åæ¨å¯¼ member / strangerï¼æµ®å±åªè´è´£æ¥ chat / apply äºä»¶åä¸å¡ |
| | | --> |
| | | <teleport to="body"> |
| | | <div v-if="card.show" class="fixed inset-0 z-9998" @click.self="handleClose"> |
| | | <div |
| | | class="fixed w-80 p-4 bg-[var(--ant-color-bg-elevated)] rounded-md shadow-xl" |
| | | :style="{ left: `${card.position.x }px`, top: `${card.position.y }px` }" |
| | | @click.stop |
| | | > |
| | | <GroupInfo v-if="card.group" :group="card.group" @chat="handleChat" @apply="handleApply" /> |
| | | </div> |
| | | </div> |
| | | </teleport> |
| | | </template> |