@@ -8,30 +8,27 @@ import { ChatActionType } from "@/context/Chat/types";
8
8
import { unSubscribeDatabase } from "@/services" ;
9
9
import { firebaseDatabase } from "@/config" ;
10
10
import { onValue , ref } from "firebase/database" ;
11
- import { numberFormatter } from "@/utils" ;
11
+ import { DB_NAME , numberFormatter } from "@/utils" ;
12
+ import SearchBox from "./searchBox" ;
12
13
13
14
const UsersList = ( ) => {
14
15
const [ loading , setLoading ] = useState ( true ) ;
15
16
const { user : authUser } = useAuth ( ) ;
16
17
const { chatRoomId, oneToOneRoomId } = useChat ( ) ;
17
18
const dispatch = useChatDispatch ( ) ;
19
+ const { userList : storeUserList } = useChat ( ) ;
18
20
const [ userList , setUserList ] = useState < User [ ] | [ ] > ( [ ] ) ;
19
21
const [ userCount , setUserCount ] = useState < number > ( 0 ) ;
22
+ const [ startSearch , setStartSearch ] = useState ( false ) ;
20
23
21
24
useEffect ( ( ) => {
22
25
setLoading ( true ) ;
23
- const collectionRef = ref ( firebaseDatabase , "usersTable" ) ;
26
+ const collectionRef = ref ( firebaseDatabase , DB_NAME . USER_TABLE ) ;
24
27
const unsubscribe = onValue ( collectionRef , ( snapshot ) => {
25
28
const data = snapshot . val ( ) ;
26
29
if ( data ) {
27
30
const users = Object . values ( data ) as User [ ] ;
28
31
setUserCount ( users . length || 0 ) ;
29
- // Remove duplicate users and the current user
30
- const uniqueUsers = users . filter (
31
- ( user , index , self ) =>
32
- user . uid && user . uid !== authUser ?. uid && index === self . findIndex ( ( u ) => u . uid === user . uid )
33
- ) ;
34
- setUserList ( uniqueUsers ) ;
35
32
dispatch ( {
36
33
type : ChatActionType . SET_USER_LIST ,
37
34
payload : data ,
@@ -45,11 +42,13 @@ const UsersList = () => {
45
42
} ;
46
43
} , [ authUser ?. uid , dispatch ] ) ;
47
44
48
- const handleUserClick = ( user : User | "chatRoom" ) => {
45
+ const handleUserClick = ( user : User | string ) => {
49
46
const newChatRoomId =
50
- user === "chatRoom" ? "chatRoom" : `${ authUser ?. uid } +${ user . uid } ` ;
47
+ typeof user === "string"
48
+ ? DB_NAME . CHAT_ROOM
49
+ : `${ authUser ?. uid } +${ user . uid } ` ;
51
50
const newOneToOneRoomId =
52
- user !== "chatRoom " ? `${ user . uid } +${ authUser ?. uid } ` : "" ;
51
+ typeof user !== "string " ? `${ user . uid } +${ authUser ?. uid } ` : "" ;
53
52
54
53
// Unsubscribe from the database
55
54
const roomList = [ chatRoomId , oneToOneRoomId ] . filter ( Boolean ) ;
@@ -65,6 +64,16 @@ const UsersList = () => {
65
64
} ) ;
66
65
} ;
67
66
67
+ const handleSearchUserList = ( token : string ) => {
68
+ const sourceList = Object . values ( storeUserList ) as User [ ] ;
69
+ const regex = new RegExp ( token , "i" ) ;
70
+ const result = sourceList
71
+ . filter ( ( user ) => user . userName . toLowerCase ( ) . match ( regex ) )
72
+ . sort ( ( a , b ) => ( a . createdAt < b . createdAt ? 1 : - 1 ) ) ;
73
+ setUserList ( result ) ;
74
+ setStartSearch ( false ) ;
75
+ } ;
76
+
68
77
return (
69
78
< Box
70
79
p = { 2 }
@@ -78,61 +87,81 @@ const UsersList = () => {
78
87
{ loading && < Spinner /> }
79
88
{ ! loading && (
80
89
< Stack gap = "2" >
90
+ < SearchBox
91
+ setSearch = { handleSearchUserList }
92
+ setLoading = { setStartSearch }
93
+ />
81
94
< HStack
82
95
cursor = { "pointer" }
83
96
_hover = { { bg : "orange.50" , color : "orange.400" } }
84
- bg = { chatRoomId === "chatRoom" ? "orange.50" : "gray.subtle" }
97
+ bg = { chatRoomId === DB_NAME . CHAT_ROOM ? "orange.50" : "gray.subtle" }
85
98
color = { "orange.400" }
86
99
borderRadius = { "md" }
87
100
title = "Common Group"
88
101
p = { "2" }
89
- onClick = { ( ) => handleUserClick ( "chatRoom" ) }
102
+ onClick = { ( ) => handleUserClick ( DB_NAME . CHAT_ROOM ) }
90
103
>
91
104
< AvatarGroup size = "sm" >
92
105
< Avatar
93
106
name = { authUser ?. userName }
94
107
src = { authUser ?. profile_picture }
95
108
colorPalette = { "orange" }
96
109
/>
97
- < Avatar colorPalette = { 'orange' } fallback = { `+${ numberFormatter . format ( userCount ) } ` } />
110
+ < Avatar
111
+ colorPalette = { "orange" }
112
+ fallback = { `+${ numberFormatter . format ( userCount ) } ` }
113
+ />
98
114
</ AvatarGroup >
99
115
< Text fontWeight = "medium" textStyle = { "sm" } lineClamp = { 1 } >
100
116
Common Group
101
117
</ Text >
102
118
</ HStack >
103
- { userList ?. map ( ( user ) => (
104
- < HStack
105
- key = { user . uid }
106
- cursor = { "pointer" }
107
- bg = {
108
- chatRoomId === `${ authUser ?. uid } +${ user . uid } `
109
- ? "orange.50"
110
- : "gray.subtle"
111
- }
112
- color = {
113
- chatRoomId === `${ authUser ?. uid } +${ user . uid } `
114
- ? "orange.400"
115
- : "initial"
116
- }
117
- _hover = { { bg : "orange.50" , color : "orange.400" } }
118
- borderRadius = { "md" }
119
- title = { user . userName }
120
- p = { "2" }
121
- onClick = { ( ) => handleUserClick ( user ) }
122
- >
123
- < Avatar
124
- name = { user . userName }
125
- size = "sm"
126
- src = { user . profile_picture }
127
- captionSide = { "bottom" }
128
- />
129
- < Stack gap = "0" >
130
- < Text fontWeight = "medium" textStyle = { "sm" } lineClamp = { 1 } >
131
- { user . userName }
132
- </ Text >
133
- </ Stack >
119
+
120
+ { startSearch ? (
121
+ < Stack alignItems = { "center" } >
122
+ < Spinner />
123
+ </ Stack >
124
+ ) : userList . length < 1 ? (
125
+ < HStack justifyContent = { "center" } >
126
+ < Text fontWeight = "medium" textStyle = { "xs" } >
127
+ No Search result found
128
+ </ Text >
134
129
</ HStack >
135
- ) ) }
130
+ ) : (
131
+ userList ?. map ( ( user ) => (
132
+ < HStack
133
+ key = { user . uid }
134
+ cursor = { "pointer" }
135
+ bg = {
136
+ chatRoomId === `${ authUser ?. uid } +${ user . uid } `
137
+ ? "orange.50"
138
+ : "gray.subtle"
139
+ }
140
+ color = {
141
+ chatRoomId === `${ authUser ?. uid } +${ user . uid } `
142
+ ? "orange.400"
143
+ : "initial"
144
+ }
145
+ _hover = { { bg : "orange.50" , color : "orange.400" } }
146
+ borderRadius = { "md" }
147
+ title = { user . userName }
148
+ p = { "2" }
149
+ onClick = { ( ) => handleUserClick ( user ) }
150
+ >
151
+ < Avatar
152
+ name = { user . userName }
153
+ size = "sm"
154
+ src = { user . profile_picture }
155
+ captionSide = { "bottom" }
156
+ />
157
+ < Stack gap = "1" direction = { "column" } align = { "flex-start" } >
158
+ < Text fontWeight = "medium" textStyle = { "sm" } lineClamp = { 1 } >
159
+ { user . userName }
160
+ </ Text >
161
+ </ Stack >
162
+ </ HStack >
163
+ ) )
164
+ ) }
136
165
</ Stack >
137
166
) }
138
167
</ Box >
0 commit comments