| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import type { FriendLite } from '../types' |
| | | |
| | | import { computed, type ComputedRef, type Ref } from 'vue' |
| | | |
| | | /** 忝忡¶ç»æï¼letter å 'A'-'Z' æå
åº '#'ï¼list æ¡¶å
ææ¼é³ / ååèªç¶åº */ |
| | | export interface FriendBucket { |
| | | letter: string |
| | | list: FriendLite[] |
| | | } |
| | | |
| | | /** ååæ¡¶ / æåºé®ï¼å¤æ³¨æ¼é³ä¼å
â æµç§°æ¼é³ â ååæ¬èº«ï¼å
åºè±æ / æ°åï¼ */ |
| | | function getSortKey(friend: FriendLite): string { |
| | | return ( |
| | | friend.displayNamePinyin || |
| | | friend.nicknamePinyin || |
| | | (friend.displayName || friend.nickname || '').toLowerCase() |
| | | ) |
| | | } |
| | | |
| | | /** ååæ¡¶åæ¯ï¼æ¼é³é¦åæ¯å¤§åï¼é忝ï¼çº¯ç¬¦å· / æ°å / 䏿ï¼å
åº '#' */ |
| | | function getBucketLetter(friend: FriendLite): string { |
| | | const first = getSortKey(friend).charAt(0) |
| | | return /^[a-zA-Z]$/.test(first) ? first.toUpperCase() : '#' |
| | | } |
| | | |
| | | /** æ¼é³é¦åæ¯æ¼æ¥ï¼ãlao zhangãâ 'lz'ï¼æ¯æãè¾ lz æèå¼ ã */ |
| | | function pinyinInitials(pinyin?: string): string { |
| | | if (!pinyin) { |
| | | return '' |
| | | } |
| | | return pinyin |
| | | .split(' ') |
| | | .map((word) => word.charAt(0)) |
| | | .join('') |
| | | } |
| | | |
| | | /** |
| | | * 好åå表çæç´¢ + 忝忡¶ |
| | | * |
| | | * - æç´¢å¹é
ï¼å¤æ³¨ / æµç§° / å
¨æ¼ï¼å»ç©ºæ ¼ï¼/ é¦åæ¯ä»»ä¸å½ä¸ |
| | | * - åæ¡¶è§åï¼A-Z + '#' å
åºï¼æ¡¶å
æ getSortKey èªç¶åº |
| | | * |
| | | * é讯å½é¡µ FriendList ä¸éæ©ç±»å¼¹çª FriendPickerPanel å
±ç¨ï¼é¿å
è§ååèªå®ç°èµ°å |
| | | */ |
| | | export function useFriendBuckets( |
| | | friends: ComputedRef<FriendLite[]> | Ref<FriendLite[]>, |
| | | keyword: Ref<string> |
| | | ): { |
| | | buckets: ComputedRef<FriendBucket[]> |
| | | filtered: ComputedRef<FriendLite[]> |
| | | } { |
| | | const filtered = computed(() => { |
| | | const keywordLower = keyword.value.trim().toLowerCase() |
| | | if (!keywordLower) { |
| | | return friends.value |
| | | } |
| | | return friends.value.filter((friend) => { |
| | | const nicknamePinyin = friend.nicknamePinyin || '' |
| | | const displayNamePinyin = friend.displayNamePinyin || '' |
| | | // å
¨æ¼æç´¢å»æç©ºæ ¼ï¼è®©ãlaozhangãä¹è½å½ä¸ãlao zhangã |
| | | return ( |
| | | (friend.nickname || '').toLowerCase().includes(keywordLower) || |
| | | (friend.displayName || '').toLowerCase().includes(keywordLower) || |
| | | nicknamePinyin.replaceAll(/\s/g, '').includes(keywordLower) || |
| | | displayNamePinyin.replaceAll(/\s/g, '').includes(keywordLower) || |
| | | pinyinInitials(nicknamePinyin).includes(keywordLower) || |
| | | pinyinInitials(displayNamePinyin).includes(keywordLower) |
| | | ) |
| | | }) |
| | | }) |
| | | |
| | | const buckets = computed<FriendBucket[]>(() => { |
| | | const map = new Map<string, FriendLite[]>() |
| | | for (const friend of filtered.value) { |
| | | const letter = getBucketLetter(friend) |
| | | const bucket = map.get(letter) ?? [] |
| | | bucket.push(friend) |
| | | map.set(letter, bucket) |
| | | } |
| | | const letters = [...map.keys()].toSorted((a, b) => { |
| | | // '#' æ°¸è¿ææ«å°¾ï¼A-Z èµ° localeCompare |
| | | if (a === '#') { |
| | | return 1 |
| | | } |
| | | if (b === '#') { |
| | | return -1 |
| | | } |
| | | return a.localeCompare(b) |
| | | }) |
| | | return letters.map((letter) => ({ |
| | | letter, |
| | | list: (map.get(letter) ?? []).toSorted((a, b) => |
| | | getSortKey(a).localeCompare(getSortKey(b)) |
| | | ) |
| | | })) |
| | | }) |
| | | |
| | | return { filtered, buckets } |
| | | } |