@tellescope/chat 1.3.21 → 1.3.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cjs/components.d.ts +5 -0
- package/lib/cjs/components.d.ts.map +1 -1
- package/lib/cjs/components.js +130 -68
- package/lib/cjs/components.js.map +1 -1
- package/lib/esm/components.d.ts +5 -0
- package/lib/esm/components.d.ts.map +1 -1
- package/lib/esm/components.js +132 -70
- package/lib/esm/components.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +8 -8
- package/src/components.tsx +160 -77
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tellescope/chat",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.23",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "./lib/cjs/index.js",
|
|
6
6
|
"module": "./lib/esm/index.js",
|
|
@@ -34,13 +34,13 @@
|
|
|
34
34
|
"@fontsource/roboto": "^4.5.1",
|
|
35
35
|
"@mui/icons-material": "^5.0.1",
|
|
36
36
|
"@mui/material": "^5.0.2",
|
|
37
|
-
"@tellescope/constants": "^1.3.
|
|
38
|
-
"@tellescope/react-components": "^1.3.
|
|
39
|
-
"@tellescope/sdk": "^1.3.
|
|
40
|
-
"@tellescope/types-client": "^1.3.
|
|
41
|
-
"@tellescope/types-models": "^1.3.
|
|
37
|
+
"@tellescope/constants": "^1.3.23",
|
|
38
|
+
"@tellescope/react-components": "^1.3.23",
|
|
39
|
+
"@tellescope/sdk": "^1.3.23",
|
|
40
|
+
"@tellescope/types-client": "^1.3.23",
|
|
41
|
+
"@tellescope/types-models": "^1.3.23",
|
|
42
42
|
"@tellescope/types-utilities": "^1.3.20",
|
|
43
|
-
"@tellescope/utilities": "^1.3.
|
|
43
|
+
"@tellescope/utilities": "^1.3.23",
|
|
44
44
|
"@typescript-eslint/eslint-plugin": "^4.33.0",
|
|
45
45
|
"@typescript-eslint/parser": "^4.33.0",
|
|
46
46
|
"eslint": "^7.32.0",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"react": "^16.8.0 || ^17.0.0 || ^18.0.0",
|
|
52
52
|
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
|
53
53
|
},
|
|
54
|
-
"gitHead": "
|
|
54
|
+
"gitHead": "23050ae45de66ab1b293ee02d7f98e46b85ea0e6",
|
|
55
55
|
"publishConfig": {
|
|
56
56
|
"access": "public"
|
|
57
57
|
}
|
package/src/components.tsx
CHANGED
|
@@ -1,17 +1,30 @@
|
|
|
1
|
-
import React, { CSSProperties, useEffect, useState } from "react"
|
|
2
|
-
import { ChatMessage, ChatRoom } from "@tellescope/types-client";
|
|
1
|
+
import React, { CSSProperties, useCallback, useEffect, useMemo, useState } from "react"
|
|
2
|
+
import { ChatMessage, ChatRoom, Enduser, User } from "@tellescope/types-client";
|
|
3
3
|
|
|
4
4
|
import {
|
|
5
5
|
APIError,
|
|
6
6
|
AsyncIconButton,
|
|
7
|
+
Button,
|
|
8
|
+
EnduserOrUserSearch,
|
|
9
|
+
EnduserSearch,
|
|
7
10
|
Flex,
|
|
11
|
+
HoverPaper,
|
|
12
|
+
List,
|
|
13
|
+
LoadingButton,
|
|
14
|
+
LoadingData,
|
|
15
|
+
Paper,
|
|
16
|
+
ScrollingList,
|
|
8
17
|
SendIcon,
|
|
9
|
-
|
|
18
|
+
Typography,
|
|
10
19
|
useChatRooms,
|
|
11
20
|
useChats,
|
|
12
21
|
useEndusers,
|
|
22
|
+
useFilters,
|
|
23
|
+
UserSearch,
|
|
13
24
|
useUsers,
|
|
14
25
|
} from "@tellescope/react-components"
|
|
26
|
+
import { user_display_name } from "@tellescope/utilities";
|
|
27
|
+
import { Checkbox, TextField, FormControlLabel, Grid } from "@mui/material";
|
|
15
28
|
|
|
16
29
|
interface SendMessage_T {
|
|
17
30
|
roomId: string,
|
|
@@ -68,7 +81,8 @@ export const SendMessage = ({
|
|
|
68
81
|
return (
|
|
69
82
|
<Flex row flex={1} alignContent="center" style={style}>
|
|
70
83
|
<Flex column flex={1}>
|
|
71
|
-
<TextField variant="outlined" value={message}
|
|
84
|
+
<TextField variant="outlined" value={message} disabled={sending}
|
|
85
|
+
onChange={e => setMessage(e.target.value)}
|
|
72
86
|
aria-label="Enter a message"
|
|
73
87
|
multiline={multiline} maxRows={maxRows}
|
|
74
88
|
placeholder={placeholderText}
|
|
@@ -97,8 +111,13 @@ export interface CreateChatRoomProps {
|
|
|
97
111
|
onGoBack?: () => void,
|
|
98
112
|
onSuccess?: (c: ChatRoom) => void,
|
|
99
113
|
onError?: (e: APIError) => void,
|
|
114
|
+
title?: string,
|
|
100
115
|
roomTitle?: string,
|
|
101
116
|
radio?: boolean,
|
|
117
|
+
minHeight?: React.CSSProperties['maxHeight']
|
|
118
|
+
maxHeight?: React.CSSProperties['maxHeight']
|
|
119
|
+
showTitleInput?: boolean,
|
|
120
|
+
searchBarPlacement?: "top" | "bottom",
|
|
102
121
|
}
|
|
103
122
|
export const CreateChatRoom: React.JSXElementConstructor<CreateChatRoomProps> = ({
|
|
104
123
|
excludeEndusers,
|
|
@@ -106,78 +125,142 @@ export const CreateChatRoom: React.JSXElementConstructor<CreateChatRoomProps> =
|
|
|
106
125
|
onGoBack,
|
|
107
126
|
onSuccess,
|
|
108
127
|
onError=console.error,
|
|
109
|
-
|
|
128
|
+
showTitleInput,
|
|
129
|
+
title="Select Members",
|
|
130
|
+
roomTitle: defaultRoomTitle = "Group Chat",
|
|
131
|
+
minHeight,
|
|
132
|
+
maxHeight='50vh',
|
|
133
|
+
searchBarPlacement="top"
|
|
110
134
|
}) => {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
135
|
+
const [, { createElement: createRoom }] = useChatRooms()
|
|
136
|
+
const [endusersLoading, { loadMore: loadMoreEndusers, doneLoading: doneLoadingEndusers }] = useEndusers()
|
|
137
|
+
const [usersLoading, { loadMore: loadMoreUsers, doneLoading: doneLoadingUsers }] = useUsers()
|
|
138
|
+
const [roomTitle, setRoomTitle] = useState(defaultRoomTitle)
|
|
139
|
+
|
|
140
|
+
const doneLoading = useCallback(() =>
|
|
141
|
+
(excludeUsers || doneLoadingUsers()) && (excludeEndusers || doneLoadingEndusers()),
|
|
142
|
+
[doneLoadingEndusers, excludeUsers, excludeEndusers, doneLoadingUsers]
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
const loadMore = useCallback(async () => {
|
|
146
|
+
if (!excludeEndusers && !doneLoadingEndusers()) { loadMoreEndusers().catch(console.error) };
|
|
147
|
+
if (!excludeUsers && !doneLoadingUsers()) { loadMoreUsers().catch(console.error) };
|
|
148
|
+
}, [doneLoadingEndusers, doneLoadingUsers, loadMoreEndusers, loadMoreUsers])
|
|
149
|
+
|
|
150
|
+
const [selected, setSelected] = useState<string[]>([])
|
|
151
|
+
|
|
152
|
+
const { applyFilters, ...filterProps } = useFilters<any>()
|
|
153
|
+
|
|
154
|
+
const searchbarFullWidth = searchBarPlacement === "bottom"
|
|
155
|
+
|
|
156
|
+
const searchbar = useMemo(() => (
|
|
157
|
+
excludeUsers
|
|
158
|
+
? <EnduserSearch {...filterProps} fullWidth={searchbarFullWidth} />
|
|
159
|
+
: excludeEndusers
|
|
160
|
+
? <UserSearch {...filterProps} fullWidth={searchbarFullWidth} />
|
|
161
|
+
: <EnduserOrUserSearch {...filterProps} fullWidth={searchbarFullWidth} />
|
|
162
|
+
), [excludeUsers, excludeEndusers, filterProps, searchbarFullWidth])
|
|
163
|
+
|
|
164
|
+
const handleCreateRoom = useCallback((users: User[], endusers: Enduser[]) => {
|
|
165
|
+
const userIds = selected.filter(s => users.find(u => u.id === s))
|
|
166
|
+
const enduserIds = selected.filter(s => endusers.find(u => u.id === s))
|
|
167
|
+
|
|
168
|
+
createRoom({
|
|
169
|
+
enduserIds,
|
|
170
|
+
userIds,
|
|
171
|
+
title: roomTitle,
|
|
172
|
+
})
|
|
173
|
+
.then(r => {
|
|
174
|
+
setSelected([])
|
|
175
|
+
onSuccess?.(r)
|
|
176
|
+
})
|
|
177
|
+
.catch(onError)
|
|
178
|
+
}, [createRoom, roomTitle, onSuccess, onError])
|
|
179
|
+
|
|
180
|
+
return (
|
|
181
|
+
<LoadingData data={{ endusers: endusersLoading, users: usersLoading }} render={({ users, endusers }) => {
|
|
182
|
+
const itemsUnfiltered = [...excludeUsers ? [] : users, ... excludeEndusers ? [] : endusers]
|
|
183
|
+
const items = applyFilters(itemsUnfiltered)
|
|
184
|
+
return (
|
|
185
|
+
<Flex flex={1} column>
|
|
186
|
+
<Grid container alignItems="center" justifyContent={"space-between"} wrap="nowrap"
|
|
187
|
+
style={{
|
|
188
|
+
marginBottom: 10,
|
|
189
|
+
}}
|
|
190
|
+
>
|
|
191
|
+
{onGoBack &&
|
|
192
|
+
<Button onClick={onGoBack}>
|
|
193
|
+
Back
|
|
194
|
+
</Button>
|
|
195
|
+
}
|
|
196
|
+
<Typography style={{ fontSize: 16, textAlign: 'center' }}>
|
|
197
|
+
{title}
|
|
198
|
+
</Typography>
|
|
199
|
+
|
|
200
|
+
<LoadingButton submitText='Create' submittingText='Create'
|
|
201
|
+
disabled={selected.length === 0}
|
|
202
|
+
style={{ display: 'flex' }}
|
|
203
|
+
onClick={() => handleCreateRoom(users, endusers)}
|
|
204
|
+
/>
|
|
205
|
+
</Grid>
|
|
206
|
+
|
|
207
|
+
<ScrollingList items={items}
|
|
208
|
+
emptyText={
|
|
209
|
+
itemsUnfiltered.length === 0
|
|
210
|
+
? "No contacts found"
|
|
211
|
+
: "No one found for search"
|
|
212
|
+
}
|
|
213
|
+
minHeight={minHeight} maxHeight={maxHeight}
|
|
214
|
+
doneLoading={doneLoading}
|
|
215
|
+
loadMore={loadMore}
|
|
216
|
+
title={
|
|
217
|
+
showTitleInput &&
|
|
218
|
+
<TextField autoFocus value={roomTitle} onChange={e => setRoomTitle(e.target.value)}
|
|
219
|
+
fullWidth={searchBarPlacement !== 'top'}
|
|
220
|
+
label="Title" placeholder="Enter conversation title..."
|
|
221
|
+
size="small"
|
|
222
|
+
/>
|
|
223
|
+
}
|
|
224
|
+
titleStyle={searchBarPlacement !== "top" ?
|
|
225
|
+
{
|
|
226
|
+
width: '100%',
|
|
227
|
+
}
|
|
228
|
+
: {}
|
|
229
|
+
}
|
|
230
|
+
titleActionsComponent={searchBarPlacement === 'top' ? searchbar : undefined}
|
|
231
|
+
Item={({ item: user }) => (
|
|
232
|
+
<HoverPaper style={{
|
|
233
|
+
marginBottom: 4,
|
|
234
|
+
}}>
|
|
235
|
+
<Flex flex={1} alignItems="center" justifyContent="space-between"
|
|
236
|
+
onClick={() => setSelected(ss => (
|
|
237
|
+
ss.includes(user.id)
|
|
238
|
+
? ss.filter(s => s !== user.id)
|
|
239
|
+
: [user.id, ...ss]
|
|
240
|
+
))}
|
|
241
|
+
style={{
|
|
242
|
+
paddingLeft: 5, paddingRight: 5,
|
|
243
|
+
}}
|
|
244
|
+
>
|
|
245
|
+
<FormControlLabel control={<Checkbox checked={selected.includes(user.id)} />} label="" />
|
|
246
|
+
|
|
247
|
+
<Typography style={{
|
|
248
|
+
fontWeight: selected.includes(user.id) ? 'bold' : undefined,
|
|
249
|
+
}}>
|
|
250
|
+
{user_display_name(user)}
|
|
251
|
+
</Typography>
|
|
252
|
+
</Flex>
|
|
253
|
+
</HoverPaper>
|
|
254
|
+
)}
|
|
255
|
+
/>
|
|
256
|
+
|
|
257
|
+
{searchBarPlacement === 'bottom' &&
|
|
258
|
+
<Grid item alignSelf="flex-end" sx={{ mt: 1, width: '100%' }}>
|
|
259
|
+
{searchbar}
|
|
260
|
+
</Grid>
|
|
261
|
+
}
|
|
262
|
+
</Flex>
|
|
263
|
+
)}
|
|
264
|
+
} />
|
|
265
|
+
)
|
|
183
266
|
}
|