diff --git a/web/src/components/UserPicker/FriendPicker.tsx b/web/src/components/UserPicker/FriendPicker.tsx new file mode 100644 index 00000000..fe417213 --- /dev/null +++ b/web/src/components/UserPicker/FriendPicker.tsx @@ -0,0 +1,35 @@ +import React from 'react'; +import { useAppSelector } from 'tailchat-shared'; +import { UserPicker } from './UserPicker'; + +interface FriendPickerProps { + /** + * 排除的用户id + * 在选择好友时会进行过滤 + */ + withoutUserIds?: string[]; + + /** + * 是否包含搜索框 + * 默认为 true + */ + withSearch?: boolean; + + selectedIds: string[]; + onChange: (selectedIds: string[]) => void; +} +export const FriendPicker: React.FC = React.memo((props) => { + const { withoutUserIds = [], selectedIds, onChange } = props; + const friendIds = useAppSelector((state) => + state.user.friends.filter((id) => !withoutUserIds.includes(id)) + ); + + return ( + + ); +}); +FriendPicker.displayName = 'FriendPicker'; diff --git a/web/src/components/FriendPicker.tsx b/web/src/components/UserPicker/UserPicker.tsx similarity index 69% rename from web/src/components/FriendPicker.tsx rename to web/src/components/UserPicker/UserPicker.tsx index 07cb735d..c79b5bd0 100644 --- a/web/src/components/FriendPicker.tsx +++ b/web/src/components/UserPicker/UserPicker.tsx @@ -1,21 +1,17 @@ import { Checkbox, Input } from 'antd'; import React, { useCallback, useState } from 'react'; -import { - getCachedUserInfo, - t, - useAppSelector, - useAsync, -} from 'tailchat-shared'; +import { t, useUserInfoList } from 'tailchat-shared'; import _take from 'lodash/take'; import _without from 'lodash/without'; -import { Avatar } from './Avatar'; +import { Avatar } from 'tailchat-design'; -interface FriendPickerProps { - /** - * 排除的用户id - * 在选择好友时会进行过滤 - */ - withoutUserIds?: string[]; +/** + * 用户选择器 + */ + +interface UserPickerProps { + selectedIds: string[]; + onChange: (selectedIds: string[]) => void; /** * 是否包含搜索框 @@ -23,24 +19,15 @@ interface FriendPickerProps { */ withSearch?: boolean; - selectedIds: string[]; - onChange: (selectedIds: string[]) => void; + /** + * 所有用户的id列表 + */ + allUserIds: string[]; } -export const FriendPicker: React.FC = React.memo((props) => { - const { - withoutUserIds = [], - withSearch = true, - selectedIds, - onChange, - } = props; +export const UserPicker: React.FC = React.memo((props) => { + const { withSearch = true, selectedIds, onChange, allUserIds } = props; const [searchValue, setSearchValue] = useState(''); - const friendIds = useAppSelector((state) => - state.user.friends.filter((id) => !withoutUserIds.includes(id)) - ); - - const { value: friendInfoList = [] } = useAsync(() => { - return Promise.all(friendIds.map((id) => getCachedUserInfo(id))); - }, [friendIds.join(',')]); + const userInfoList = useUserInfoList(allUserIds); const handleSelectUser = useCallback( (userId: string, isSelected: boolean) => { @@ -78,8 +65,8 @@ export const FriendPicker: React.FC = React.memo((props) => { {_take( - friendInfoList.filter((info) => info.nickname.includes(searchValue)), - 5 + userInfoList.filter((info) => info.nickname.includes(searchValue)), + 10 ).map((info) => { return (
@@ -102,4 +89,4 @@ export const FriendPicker: React.FC = React.memo((props) => {
); }); -FriendPicker.displayName = 'FriendPicker'; +UserPicker.displayName = 'UserPicker'; diff --git a/web/src/components/modals/AppendDMConverseMembers.tsx b/web/src/components/modals/AppendDMConverseMembers.tsx index 4d3c6c1c..7474b215 100644 --- a/web/src/components/modals/AppendDMConverseMembers.tsx +++ b/web/src/components/modals/AppendDMConverseMembers.tsx @@ -1,7 +1,7 @@ import { Button } from 'antd'; import React, { useState } from 'react'; import { appendDMConverseMembers, t, useAsyncFn } from 'tailchat-shared'; -import { FriendPicker } from '../FriendPicker'; +import { FriendPicker } from '../UserPicker/FriendPicker'; import { closeModal, ModalWrapper } from '../Modal'; interface AppendDMConverseMembersProps { diff --git a/web/src/components/modals/CreateDMConverse.tsx b/web/src/components/modals/CreateDMConverse.tsx index d945a58d..228749bd 100644 --- a/web/src/components/modals/CreateDMConverse.tsx +++ b/web/src/components/modals/CreateDMConverse.tsx @@ -2,7 +2,7 @@ import { Button } from 'antd'; import React, { useState } from 'react'; import { useHistory } from 'react-router'; import { createDMConverse, t, useAsyncRequest } from 'tailchat-shared'; -import { FriendPicker } from '../FriendPicker'; +import { FriendPicker } from '../UserPicker/FriendPicker'; import { closeModal, ModalWrapper } from '../Modal'; interface CreateDMConverseProps { diff --git a/web/src/components/modals/GroupDetail/Role/index.tsx b/web/src/components/modals/GroupDetail/Role/index.tsx index 4c0578d6..753d5894 100644 --- a/web/src/components/modals/GroupDetail/Role/index.tsx +++ b/web/src/components/modals/GroupDetail/Role/index.tsx @@ -72,7 +72,7 @@ export const GroupRole: React.FC = React.memo((props) => { }, []); return ( - +
{/* 角色列表 */} diff --git a/web/src/hooks/useHistoryNav.ts b/web/src/hooks/useHistoryNav.ts index 648a2e7f..e5e7baa5 100644 --- a/web/src/hooks/useHistoryNav.ts +++ b/web/src/hooks/useHistoryNav.ts @@ -9,7 +9,7 @@ import { useUpdateRef } from 'tailchat-shared'; * * 用于根据 ?nav=xxx 来自动打开代码中的某一个部件 */ -export function useHistoryNav( +export function useLocationNav( pattern: string, callback: (nav: string) => void ) { diff --git a/web/src/routes/Main/Content/Group/useGroupHeaderAction.tsx b/web/src/routes/Main/Content/Group/useGroupHeaderAction.tsx index 900c0aaa..cfc01fa3 100644 --- a/web/src/routes/Main/Content/Group/useGroupHeaderAction.tsx +++ b/web/src/routes/Main/Content/Group/useGroupHeaderAction.tsx @@ -5,7 +5,7 @@ import React from 'react'; import { useCallback } from 'react'; import { useHistory } from 'react-router'; import { quitGroup, showAlert, t, useIsGroupOwner } from 'tailchat-shared'; -import { useHistoryNav } from '@/hooks/useHistoryNav'; +import { useLocationNav } from '@/hooks/useHistoryNav'; /** * 群组 Header 的操作 hooks @@ -41,7 +41,7 @@ export function useGroupHeaderAction(groupId: string) { }); }, [groupId, isOwner]); - useHistoryNav('group.*', (nav) => { + useLocationNav('group.*', (nav) => { if (nav.startsWith('group.detail')) { handleShowGroupDetail(); }