feat: 联系人搜索
This commit is contained in:
@@ -85,8 +85,10 @@ function getContacts(socket) {
|
|||||||
nickname: contact.NickName,
|
nickname: contact.NickName,
|
||||||
displayName: getDisplayName(contact),
|
displayName: getDisplayName(contact),
|
||||||
signature: contact.Signature,
|
signature: contact.Signature,
|
||||||
nameInitial: contact.PYInitial || contact.RemarkPYInitial,
|
nameInitial: contact.RemarkPYInitial,
|
||||||
nameQuanPin: contact.PYQuanPin || contact.RemarkPYQuanPin,
|
nickNameInitial: contact.PYInitial,
|
||||||
|
nameQuanPin: contact.RemarkPYQuanPin,
|
||||||
|
nickNameQuanPin: contact.PYQuanPin,
|
||||||
avatar: `${config.baseUrl}/session/${socketIDToSessionID.get(
|
avatar: `${config.baseUrl}/session/${socketIDToSessionID.get(
|
||||||
socket.id
|
socket.id
|
||||||
)}/avatar/${contact.UserName}`,
|
)}/avatar/${contact.UserName}`,
|
||||||
|
|||||||
Generated
+32
@@ -18,6 +18,7 @@
|
|||||||
"dayjs": "^1.10.7",
|
"dayjs": "^1.10.7",
|
||||||
"filesize": "^7.0.0",
|
"filesize": "^7.0.0",
|
||||||
"linaria": "^2.1.0",
|
"linaria": "^2.1.0",
|
||||||
|
"lodash-es": "^4.17.21",
|
||||||
"log4js": "^6.3.0",
|
"log4js": "^6.3.0",
|
||||||
"multer": "^1.4.3",
|
"multer": "^1.4.3",
|
||||||
"normalize.css": "^8.0.1",
|
"normalize.css": "^8.0.1",
|
||||||
@@ -60,6 +61,7 @@
|
|||||||
"@testing-library/jest-dom": "^4.2.4",
|
"@testing-library/jest-dom": "^4.2.4",
|
||||||
"@types/ali-oss": "^6.0.10",
|
"@types/ali-oss": "^6.0.10",
|
||||||
"@types/loadable__component": "^5.13.4",
|
"@types/loadable__component": "^5.13.4",
|
||||||
|
"@types/lodash-es": "^4.17.5",
|
||||||
"@types/platform": "^1.3.4",
|
"@types/platform": "^1.3.4",
|
||||||
"@types/prismjs": "^1.16.6",
|
"@types/prismjs": "^1.16.6",
|
||||||
"@types/pure-render-decorator": "^0.2.28",
|
"@types/pure-render-decorator": "^0.2.28",
|
||||||
@@ -2239,6 +2241,21 @@
|
|||||||
"@types/react": "*"
|
"@types/react": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/lodash": {
|
||||||
|
"version": "4.14.177",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.177.tgz",
|
||||||
|
"integrity": "sha512-0fDwydE2clKe9MNfvXHBHF9WEahRuj+msTuQqOmAApNORFvhMYZKNGGJdCzuhheVjMps/ti0Ak/iJPACMaevvw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"node_modules/@types/lodash-es": {
|
||||||
|
"version": "4.17.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.5.tgz",
|
||||||
|
"integrity": "sha512-SHBoI8/0aoMQWAgUHMQ599VM6ZiSKg8sh/0cFqqlQQMyY9uEplc0ULU5yQNzcvdR4ZKa0ey8+vFmahuRbOCT1A==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@types/lodash": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/minimatch": {
|
"node_modules/@types/minimatch": {
|
||||||
"version": "3.0.5",
|
"version": "3.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz",
|
||||||
@@ -13513,6 +13530,21 @@
|
|||||||
"@types/react": "*"
|
"@types/react": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@types/lodash": {
|
||||||
|
"version": "4.14.177",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.177.tgz",
|
||||||
|
"integrity": "sha512-0fDwydE2clKe9MNfvXHBHF9WEahRuj+msTuQqOmAApNORFvhMYZKNGGJdCzuhheVjMps/ti0Ak/iJPACMaevvw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"@types/lodash-es": {
|
||||||
|
"version": "4.17.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.5.tgz",
|
||||||
|
"integrity": "sha512-SHBoI8/0aoMQWAgUHMQ599VM6ZiSKg8sh/0cFqqlQQMyY9uEplc0ULU5yQNzcvdR4ZKa0ey8+vFmahuRbOCT1A==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@types/lodash": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@types/minimatch": {
|
"@types/minimatch": {
|
||||||
"version": "3.0.5",
|
"version": "3.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz",
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
"dayjs": "^1.10.7",
|
"dayjs": "^1.10.7",
|
||||||
"filesize": "^7.0.0",
|
"filesize": "^7.0.0",
|
||||||
"linaria": "^2.1.0",
|
"linaria": "^2.1.0",
|
||||||
|
"lodash-es": "^4.17.21",
|
||||||
"log4js": "^6.3.0",
|
"log4js": "^6.3.0",
|
||||||
"multer": "^1.4.3",
|
"multer": "^1.4.3",
|
||||||
"normalize.css": "^8.0.1",
|
"normalize.css": "^8.0.1",
|
||||||
@@ -59,6 +60,7 @@
|
|||||||
"@testing-library/jest-dom": "^4.2.4",
|
"@testing-library/jest-dom": "^4.2.4",
|
||||||
"@types/ali-oss": "^6.0.10",
|
"@types/ali-oss": "^6.0.10",
|
||||||
"@types/loadable__component": "^5.13.4",
|
"@types/loadable__component": "^5.13.4",
|
||||||
|
"@types/lodash-es": "^4.17.5",
|
||||||
"@types/platform": "^1.3.4",
|
"@types/platform": "^1.3.4",
|
||||||
"@types/prismjs": "^1.16.6",
|
"@types/prismjs": "^1.16.6",
|
||||||
"@types/pure-render-decorator": "^0.2.28",
|
"@types/pure-render-decorator": "^0.2.28",
|
||||||
|
|||||||
@@ -1,11 +1,25 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { uniq } from 'lodash-es';
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
import { State } from '../../state/reducer';
|
import { State } from '../../state/reducer';
|
||||||
import ContactComponent from './Contact';
|
import ContactComponent from './Contact';
|
||||||
import Style from './ContactList.less';
|
import Style from './ContactList.less';
|
||||||
|
|
||||||
function ContactList() {
|
function ContactList({ keyword = '' }) {
|
||||||
const contacts = useSelector((state: State) => state.contacts);
|
let contacts =
|
||||||
|
useSelector((state: State) => [...state.groups, ...state.contacts]) ||
|
||||||
|
[];
|
||||||
|
if (keyword) {
|
||||||
|
keyword = keyword.toLowerCase();
|
||||||
|
contacts = [
|
||||||
|
...contacts.filter((c) => c.displayName?.toLowerCase().includes(keyword)),
|
||||||
|
...contacts.filter((c) => c.nameQuanPin?.toLowerCase().includes(keyword)),
|
||||||
|
...contacts.filter((c) => c.nickname?.toLowerCase().includes(keyword)),
|
||||||
|
...contacts.filter((c) => c.nickname?.toLowerCase().includes(keyword)),
|
||||||
|
];
|
||||||
|
contacts = uniq(contacts);
|
||||||
|
}
|
||||||
|
console.log(contacts);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={Style.linkmanList}>
|
<div className={Style.linkmanList}>
|
||||||
|
|||||||
@@ -1,23 +1,18 @@
|
|||||||
import React from 'react';
|
import React, { useState } from 'react';
|
||||||
import { useSelector } from 'react-redux';
|
|
||||||
import useAction from '../../hooks/useAction';
|
|
||||||
import useAero from '../../hooks/useAero';
|
|
||||||
import useIsLogin from '../../hooks/useIsLogin';
|
import useIsLogin from '../../hooks/useIsLogin';
|
||||||
import { State } from '../../state/reducer';
|
|
||||||
import ContactList from './ContactList';
|
import ContactList from './ContactList';
|
||||||
import SearchBar from './SearchBar';
|
import SearchBar from './SearchBar';
|
||||||
import Style from './FunctionBarAndContactList.less';
|
import Style from './FunctionBarAndContactList.less';
|
||||||
|
|
||||||
function FunctionBarAndContactList() {
|
function FunctionBarAndContactList() {
|
||||||
const isLogin = useIsLogin();
|
const isLogin = useIsLogin();
|
||||||
const action = useAction();
|
const [keyword, setKeyword] = useState('');
|
||||||
const aero = useAero();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={Style.contactList} role="button">
|
<div className={Style.contactList} role="button">
|
||||||
<div className={Style.container}>
|
<div className={Style.container}>
|
||||||
{isLogin && <SearchBar />}
|
{isLogin && <SearchBar onSearch={setKeyword} />}
|
||||||
<ContactList />
|
<ContactList keyword={keyword} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,47 +1,30 @@
|
|||||||
import React, { useContext, useEffect, useState } from 'react';
|
import React, { useCallback, useContext, useState } from 'react';
|
||||||
import Avatar from '../../components/Avatar';
|
import { debounce } from 'lodash-es';
|
||||||
import IconButton from '../../components/IconButton';
|
|
||||||
import Input from '../../components/Input';
|
import Input from '../../components/Input';
|
||||||
import Message from '../../components/Message';
|
|
||||||
import {
|
|
||||||
ScrollableInkTabBar,
|
|
||||||
TabContent,
|
|
||||||
TabPane,
|
|
||||||
Tabs as div,
|
|
||||||
} from '../../components/Tabs';
|
|
||||||
import { ShowUserOrGroupInfoContext } from '../../context';
|
|
||||||
import Style from './SearchBar.less';
|
import Style from './SearchBar.less';
|
||||||
|
|
||||||
type SearchResult = {
|
function FunctionBar({ onSearch }) {
|
||||||
users: any[];
|
const [keyword, setKeyword] = useState('');
|
||||||
groups: any[];
|
|
||||||
};
|
|
||||||
|
|
||||||
function FunctionBar() {
|
const triggerSearch = useCallback(
|
||||||
const [keywords, setKeywords] = useState('');
|
debounce((kw: string) => {
|
||||||
const [searchResultVisible, toggleSearchResultVisible] = useState(false);
|
onSearch && onSearch(kw);
|
||||||
const [searchResult, setSearchResult] = useState<SearchResult>({
|
}, 500),
|
||||||
users: [],
|
[onSearch],
|
||||||
groups: [],
|
);
|
||||||
});
|
const handleInputChange = useCallback(
|
||||||
|
(kw) => {
|
||||||
|
console.log('aaaaa',kw);
|
||||||
|
|
||||||
const context = useContext(ShowUserOrGroupInfoContext);
|
setKeyword(kw);
|
||||||
const placeholder = '搜索群组/用户';
|
triggerSearch(kw);
|
||||||
|
},
|
||||||
|
[triggerSearch],
|
||||||
|
);
|
||||||
|
|
||||||
function resetSearch() {
|
const handleInputEnter = useCallback(() => {
|
||||||
setSearchResult({ users: [], groups: [] });
|
triggerSearch.flush();
|
||||||
setKeywords('');
|
}, [triggerSearch]);
|
||||||
}
|
|
||||||
|
|
||||||
function handleInputChange(value: string) {
|
|
||||||
setKeywords(value);
|
|
||||||
if (!value) {
|
|
||||||
resetSearch();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleInputEnter() {
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={Style.functionBar}>
|
<div className={Style.functionBar}>
|
||||||
@@ -51,12 +34,10 @@ function FunctionBar() {
|
|||||||
onSubmit={(e) => e.preventDefault()}
|
onSubmit={(e) => e.preventDefault()}
|
||||||
>
|
>
|
||||||
<Input
|
<Input
|
||||||
className={`${Style.input} ${
|
className={Style.input}
|
||||||
searchResultVisible ? Style.inputFocus : ''
|
|
||||||
}`}
|
|
||||||
type="text"
|
type="text"
|
||||||
placeholder={placeholder}
|
placeholder="搜索用户/群组"
|
||||||
value={keywords}
|
value={keyword}
|
||||||
onChange={handleInputChange}
|
onChange={handleInputChange}
|
||||||
onEnter={handleInputEnter}
|
onEnter={handleInputEnter}
|
||||||
/>
|
/>
|
||||||
|
|||||||
Reference in New Issue
Block a user