| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <script lang="ts" setup> |
| | | import { computed } from 'vue' |
| | | import { useRoute, useRouter } from 'vue-router' |
| | | |
| | | import { IconifyIcon as Icon } from '#/packages/icons/src' |
| | | import { useUserStore } from '#/packages/stores/src' |
| | | |
| | | import { Badge } from 'ant-design-vue' |
| | | |
| | | import { useConversationStore } from '../store/conversationStore' |
| | | import { useFriendStore } from '../store/friendStore' |
| | | import { useImUiStore } from '../store/uiStore' |
| | | import { UserAvatar } from './user' |
| | | |
| | | defineOptions({ name: 'ImToolBar' }) |
| | | |
| | | const route = useRoute() |
| | | const router = useRouter() |
| | | const userStore = useUserStore() |
| | | const conversationStore = useConversationStore() |
| | | const friendStore = useFriendStore() |
| | | const uiStore = useImUiStore() |
| | | |
| | | /** æ¶æ¯ Tab ç红ç¹ï¼ææéå
ææ°ä¼è¯çæªè¯»æ»å */ |
| | | const totalUnread = computed(() => conversationStore.getTotalUnreadCount) |
| | | /** éè®¯å½ Tab ç红ç¹ï¼æªå¤ç好åç³è¯·æ°ï¼æ¥æ¶æ¹=æï¼ */ |
| | | const unhandledRequestCount = computed(() => friendStore.getUnhandledRequestCount) |
| | | |
| | | const tabs = [ |
| | | { name: 'ImHomeConversation', icon: 'ep:chat-round' }, |
| | | { name: 'ImHomeContact', icon: 'mingcute:contacts-line' } |
| | | ] // 两个主 Tabï¼ç¨è·¯ç± name èé pathï¼é¿å
åç¼ / åµå¥è°æ´å失æ |
| | | |
| | | // å½åè·¯ç±æ¯å¦å½ä¸ Tabï¼ç´æ¥æ¯å¯¹ route.name |
| | | const isActive = (name: string) => route.name === name |
| | | |
| | | // 忢 Tabï¼å½åå·²é䏿¶ï¼æ¶æ¯ Tab 触å"æ»å¨å°ä¸ä¸ä¸ªæªè¯»"ï¼å¯¹é½å¾®ä¿¡ PCï¼ï¼å
¶å® Tab æ å¨ä½ |
| | | const goTab = (name: string) => { |
| | | if (route.name === name) { |
| | | if (name === 'ImHomeConversation') { |
| | | uiStore.requestNextUnreadJump() |
| | | } |
| | | return |
| | | } |
| | | router.push({ name }) |
| | | } |
| | | |
| | | // 跳转个人ä¸å¿ï¼è·¯ç± name=Profileï¼ |
| | | const goProfile = () => router.push({ name: 'Profile' }) |
| | | </script> |
| | | |
| | | <template> |
| | | <!-- |
| | | ToolBarï¼IM 左侧工å
·æ |
| | | å¸å±ï¼é¡¶é¨å¤´å â ä¸é´ä¸ Tabï¼æ¶æ¯/好å/群èï¼â åºé¨è®¾ç½® |
| | | --> |
| | | <div |
| | | class="flex flex-col items-center w-14 pt-4 pb-3 gap-2 flex-shrink-0 select-none bg-[#2b2b2b]" |
| | | > |
| | | <!-- é¡¶é¨ç¨æ·å¤´åï¼ç¹å»è·³ä¸ªäººä¸å¿ï¼èµ° UserAvatar ç»ä¸é¦å / åå¸é
è²è§å --> |
| | | <div class="mb-2 cursor-pointer" @click="goProfile"> |
| | | <UserAvatar |
| | | :url="userStore.userInfo?.avatar" |
| | | :name="userStore.userInfo?.nickname" |
| | | :size="36" |
| | | :clickable="false" |
| | | /> |
| | | </div> |
| | | |
| | | <!-- ä¸é´ä¸ Tab --> |
| | | <div class="flex flex-col items-center gap-2 flex-1 w-full"> |
| | | <div |
| | | v-for="item in tabs" |
| | | :key="item.name" |
| | | class="flex items-center justify-center w-10 h-10 rounded-lg text-[#a0a0a0] cursor-pointer transition-all hover:text-white hover:bg-white/10" |
| | | :class="{ 'bg-white/15 text-white': isActive(item.name) }" |
| | | @click="goTab(item.name)" |
| | | > |
| | | <Badge |
| | | v-if="item.name === 'ImHomeConversation' && totalUnread > 0" |
| | | :count="totalUnread" |
| | | :max="99" |
| | | class="tool-bar__badge" |
| | | > |
| | | <Icon :icon="item.icon" class="tool-bar__icon" /> |
| | | </Badge> |
| | | <Badge |
| | | v-else-if="item.name === 'ImHomeContact' && unhandledRequestCount > 0" |
| | | :count="unhandledRequestCount" |
| | | :max="99" |
| | | class="tool-bar__badge" |
| | | > |
| | | <Icon :icon="item.icon" class="tool-bar__icon" /> |
| | | </Badge> |
| | | <Icon v-else :icon="item.icon" class="tool-bar__icon" /> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- åºé¨è®¾ç½®æé®ï¼ç¹å»è·³ä¸ªäººä¸å¿ --> |
| | | <div class="flex flex-col items-center gap-2 w-full"> |
| | | <div |
| | | class="flex items-center justify-center w-10 h-10 rounded-lg text-[#a0a0a0] cursor-pointer transition-all hover:text-white hover:bg-white/10" |
| | | @click="goProfile" |
| | | > |
| | | <Icon icon="ant-design:setting-outlined" class="tool-bar__icon" /> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <style scoped> |
| | | .tool-bar__icon { |
| | | width: 22px; |
| | | height: 22px; |
| | | } |
| | | |
| | | /* è°æ´ AntD Badge å³ä¸è§çº¢ç¹ä½ç½® */ |
| | | .tool-bar__badge :deep(.ant-badge-count) { |
| | | top: 4px; |
| | | right: 8px; |
| | | border: none; |
| | | } |
| | | </style> |