| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import { computed, type ComputedRef, onScopeDispose, ref } from 'vue' |
| | | |
| | | import { getCurrentUserId } from '#/views/im/utils/auth' |
| | | |
| | | import { ImConversationType, ImGroupMemberRole } from '../../utils/constants' |
| | | import { isGroupQuit } from '../../utils/user' |
| | | import { useConversationStore } from '../store/conversationStore' |
| | | import { useGroupStore } from '../store/groupStore' |
| | | |
| | | export type MuteOverlayInfo = { icon: string; text: string; } |
| | | |
| | | /** |
| | | * 模å级å
±äº« now tick + 订é
计æ°ï¼ |
| | | * MessageItem v-for æ¶æ¯æ¡æ¶æ¯é½ä¼ useMuteOverlay()ï¼åå®ä¾èªèµ· timer ä¼åæå ç¾ä¸ª 30s 宿¶å¨ï¼ |
| | | * æ¹ææ¨¡å级å
±äº«åææè®¢é
è
å
±ç¨ä¸ä»½ setIntervalï¼è®¢é
æ°æ¸
é¶æ¶ä¹æ¸
æ timerï¼é¿å
å
å䏿¶éæ¼ç§» |
| | | */ |
| | | const sharedNow = ref(Date.now()) |
| | | let sharedTickTimer: null | number = null |
| | | let subscriberCount = 0 |
| | | |
| | | function subscribeNowTick(): void { |
| | | subscriberCount++ |
| | | if (!sharedTickTimer) { |
| | | sharedTickTimer = window.setInterval(() => { |
| | | sharedNow.value = Date.now() |
| | | }, 30_000) |
| | | } |
| | | } |
| | | |
| | | function unsubscribeNowTick(): void { |
| | | subscriberCount-- |
| | | if (subscriberCount <= 0) { |
| | | subscriberCount = 0 |
| | | if (sharedTickTimer) { |
| | | window.clearInterval(sharedTickTimer) |
| | | sharedTickTimer = null |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * å½åæ¿æ´»ä¼è¯çç¦è¨ / å°ç¦ç¶æï¼éç¾¤èææ ç¦è¨æ¶è¿å null |
| | | * |
| | | * ä¼å
级ï¼å°ç¦ > å
¨ç¾¤ç¦è¨ï¼ç¾¤ä¸» / 管çåè±å
ï¼> æåç¦è¨ |
| | | * |
| | | * MessageInput é¡¶é¨ overlay / handleResend éè¯ / uploadAndSendMedia ä¸ä¼ å®åé½å
±ç¨ä¸ä»½ï¼ |
| | | * é¿å
ãè¾å
¥æ¡æ¦äºä½éè¯ç»è¿ããä¸ä¼ æé´è¢«ç¦è¨ä½ sendRaw ä»ååºå»ãä¹ç±»çä¸ä¸è´ |
| | | */ |
| | | export function useMuteOverlay(): ComputedRef<MuteOverlayInfo | null> { |
| | | const conversationStore = useConversationStore() |
| | | const groupStore = useGroupStore() |
| | | |
| | | // 订é
模å级 tickï¼scope 鿝æ¶å订é
ï¼æåä¸ä¸ªè®¢é
è
éåºå timer ä¹è·çæ¸
|
| | | subscribeNowTick() |
| | | onScopeDispose(unsubscribeNowTick) |
| | | |
| | | return computed(() => { |
| | | const conversation = conversationStore.activeConversation |
| | | if (!conversation || conversation.type !== ImConversationType.GROUP) { |
| | | return null |
| | | } |
| | | const group = groupStore.getGroup(conversation.targetId) |
| | | if (!group) { |
| | | return null |
| | | } |
| | | // åå²é群群ï¼å·²é群åªè½æ¥çåå²ï¼ç¦æ¢åéï¼ææ¬ / å¾ç / æä»¶ / è¯é³ / éè¯å
±ç¨è¿ä¸å±æ¦æªï¼ |
| | | if (isGroupQuit(group)) { |
| | | return { text: 'ä½ å·²éåºç¾¤èï¼ä»
坿¥çå岿¶æ¯', icon: 'ant-design:logout-outlined' } |
| | | } |
| | | const myId = getCurrentUserId() |
| | | // 群å°ç¦ï¼ç®¡çåå°æä½ï¼ææäººä¸å¯åé |
| | | if (group.banned) { |
| | | return { text: '该群已被管çåå°ç¦ï¼æ æ³åéæ¶æ¯', icon: 'ant-design:stop-outlined' } |
| | | } |
| | | // å
¨ç¾¤ç¦è¨ï¼ç¾¤ä¸»èµ° ownerUserId æ¯è¾ç´æ¥è±å
ï¼å
¶å®äººéè¦æåå表å è½½å®æè½åºå管çå vs æ®éæå |
| | | // - å è½½å® + ææ¯ç®¡çå â è±å
|
| | | // - å è½½å® + æä¸æ¯ç®¡çåï¼å«å·²é群ï¼â æ¦ |
| | | // - å è½½æªå® â 䏿¾ç¤º overlayï¼å端å
åºæç»æ®éæåï¼é¿å
误æ¦ç®¡çå |
| | | if (group.mutedAll && myId !== group.ownerUserId && group.membersLoaded) { |
| | | const myMember = group.members?.find((m) => m.userId === myId) |
| | | if (myMember?.role !== ImGroupMemberRole.ADMIN) { |
| | | return { text: 'å
¨ç¾¤ç¦è¨ä¸ï¼ææ¶æ æ³åéæ¶æ¯', icon: 'ant-design:audio-muted-outlined' } |
| | | } |
| | | } |
| | | // æåç¦è¨ï¼muteEndTime 卿ªæ¥æç®ï¼ç¨ååºå¼ sharedNow æ¯å¯¹ï¼å°æåä¸ä¸ä¸ª tick 就让 overlay æ¶å¤± |
| | | const myMember = group.members?.find((m) => m.userId === myId) |
| | | if (myMember?.muteEndTime) { |
| | | const endTime = new Date(myMember.muteEndTime) |
| | | if (endTime.getTime() > sharedNow.value) { |
| | | const pad = (n: number) => n.toString().padStart(2, '0') |
| | | const timeStr = |
| | | `${pad(endTime.getMonth() + 1)}-${pad(endTime.getDate())} ` + |
| | | `${pad(endTime.getHours())}:${pad(endTime.getMinutes())}` |
| | | return { |
| | | text: `æ¨å·²è¢«ç¦è¨ï¼è§£é¤æ¶é´ï¼${timeStr}`, |
| | | icon: 'ant-design:audio-muted-outlined' |
| | | } |
| | | } |
| | | } |
| | | return null |
| | | }) |
| | | } |