agx-chat-web 1.1.0 → 1.2.1

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.
Files changed (86) hide show
  1. package/README.md +49 -49
  2. package/dist/agx-chat.esm.js +1 -1
  3. package/dist/agx-chat.esm.js.map +1 -1
  4. package/dist/{agx-chat.min.js → agx-chat.umd.js} +2 -2
  5. package/dist/agx-chat.umd.js.map +1 -0
  6. package/dist/esm/app/Messenger/components/IncomingMessage/IncomingMessage.js +7 -3
  7. package/dist/esm/app/Messenger/components/IncomingMessage/IncomingMessage.js.map +1 -1
  8. package/dist/esm/app/Messenger/components/InputFile/InputFile.js +3 -1
  9. package/dist/esm/app/Messenger/components/InputFile/InputFile.js.map +1 -1
  10. package/dist/esm/app/Messenger/components/RenderFileIcon/RenderFileIcon.js +8 -0
  11. package/dist/esm/app/Messenger/components/RenderFileIcon/RenderFileIcon.js.map +1 -1
  12. package/dist/esm/app/Messenger/components/SendMessageForm/SendMessageForm.js +30 -8
  13. package/dist/esm/app/Messenger/components/SendMessageForm/SendMessageForm.js.map +1 -1
  14. package/dist/esm/app/Messenger/components/SenderMessages/SenderMessages.js +11 -8
  15. package/dist/esm/app/Messenger/components/SenderMessages/SenderMessages.js.map +1 -1
  16. package/dist/esm/app/Messenger/icons/CSVFileIcon.d.ts +4 -0
  17. package/dist/esm/app/Messenger/icons/CSVFileIcon.js +7 -0
  18. package/dist/esm/app/Messenger/icons/CSVFileIcon.js.map +1 -0
  19. package/dist/esm/app/Messenger/icons/MP4FileIcon.d.ts +4 -0
  20. package/dist/esm/app/Messenger/icons/MP4FileIcon.js +7 -0
  21. package/dist/esm/app/Messenger/icons/MP4FileIcon.js.map +1 -0
  22. package/package.json +91 -91
  23. package/src/__tests__/app/Messenger/classes/slaCalculations.spec.ts +122 -122
  24. package/src/app/ChatProvider/ChatProvider.tsx +20 -20
  25. package/src/app/Messenger/classes/slaCalculations.ts +197 -197
  26. package/src/app/Messenger/components/ChatButton/ChatButton.tsx +64 -64
  27. package/src/app/Messenger/components/ChatTabs/ChatTabs.less +18 -18
  28. package/src/app/Messenger/components/ChatTabs/ChatTabs.tsx +32 -32
  29. package/src/app/Messenger/components/DocMessage/DocMessage.less +71 -71
  30. package/src/app/Messenger/components/DocMessage/DocMessage.tsx +50 -50
  31. package/src/app/Messenger/components/ImagesContainer/ImagesContainer.less +79 -79
  32. package/src/app/Messenger/components/ImagesContainer/ImagesContainer.tsx +51 -51
  33. package/src/app/Messenger/components/IncomingMessage/IncomingMessage.tsx +170 -166
  34. package/src/app/Messenger/components/InfiniteScroll/InfiniteScroll.tsx +80 -80
  35. package/src/app/Messenger/components/InputFile/InputFile.tsx +147 -145
  36. package/src/app/Messenger/components/InputFile/inputFile.less +59 -59
  37. package/src/app/Messenger/components/MessageBallon/MessageBalloon.tsx +100 -100
  38. package/src/app/Messenger/components/MessengerAvatar/MessengerAvatar.tsx +29 -29
  39. package/src/app/Messenger/components/MessengerThemeWrapper/MessengerThemeWrapper.tsx +62 -62
  40. package/src/app/Messenger/components/RenderFileIcon/RenderFileIcon.tsx +40 -34
  41. package/src/app/Messenger/components/SearchInput/SearchInput.less +45 -45
  42. package/src/app/Messenger/components/SearchInput/SearchInput.tsx +77 -77
  43. package/src/app/Messenger/components/Select/Select.less +22 -22
  44. package/src/app/Messenger/components/Select/Select.tsx +56 -56
  45. package/src/app/Messenger/components/SendMessageForm/SendMessageForm.tsx +254 -234
  46. package/src/app/Messenger/components/SenderMessages/SenderMessages.tsx +91 -89
  47. package/src/app/Messenger/components/SystemMessage/SystemMessage.tsx +25 -25
  48. package/src/app/Messenger/components/TextArea/TextArea.tsx +35 -35
  49. package/src/app/Messenger/components/TextArea/Textarea.less +22 -22
  50. package/src/app/Messenger/components/Tooltip/Tooltip.less +27 -27
  51. package/src/app/Messenger/components/Tooltip/Tooltip.tsx +17 -17
  52. package/src/app/Messenger/hooks/useConversations.tsx +143 -143
  53. package/src/app/Messenger/hooks/useMessages.tsx +49 -49
  54. package/src/app/Messenger/hooks/useThemes.tsx +14 -14
  55. package/src/app/Messenger/icons/AttachFileIcon.tsx +20 -20
  56. package/src/app/Messenger/icons/CSVFileIcon.tsx +26 -0
  57. package/src/app/Messenger/icons/CloseIcon.tsx +20 -20
  58. package/src/app/Messenger/icons/DOCFileIcon.tsx +54 -54
  59. package/src/app/Messenger/icons/DownloadMinimalistIcon.tsx +37 -37
  60. package/src/app/Messenger/icons/EmptyIcon.tsx +20 -20
  61. package/src/app/Messenger/icons/MP4FileIcon.tsx +26 -0
  62. package/src/app/Messenger/icons/MessageIcon.tsx +27 -27
  63. package/src/app/Messenger/icons/PDFFileIcon.tsx +54 -54
  64. package/src/app/Messenger/icons/ReadIcon.tsx +18 -18
  65. package/src/app/Messenger/icons/SearchIcon.tsx +20 -20
  66. package/src/app/Messenger/icons/TimerIcon.tsx +18 -18
  67. package/src/app/Messenger/icons/TrashIcon.tsx +21 -21
  68. package/src/app/Messenger/views/Messenger.less +623 -623
  69. package/src/app/Messenger/views/MessengerList.tsx +170 -170
  70. package/src/app/Messenger/views/MessengerListItem.tsx +178 -178
  71. package/src/app/Messenger/views/MessengerMessages.tsx +414 -414
  72. package/src/app/Messenger/views/NewFormChat.tsx +145 -145
  73. package/src/app/i18n/index.ts +36 -36
  74. package/src/app/i18n/locales/en.json +64 -64
  75. package/src/app/i18n/locales/pt.json +64 -64
  76. package/src/assets/right-arrow.svg +9 -9
  77. package/src/index.ts +23 -23
  78. package/src/react-app-env.d.ts +19 -19
  79. package/src/setupTests.ts +5 -5
  80. package/src/styles/abstracts/animations.less +8 -8
  81. package/src/styles/abstracts/mixins.less +5 -5
  82. package/src/styles/abstracts/variables.less +31 -31
  83. package/src/styles/base/base.less +6 -6
  84. package/src/styles/index.less +5 -5
  85. package/src/types.ts +174 -174
  86. package/dist/agx-chat.min.js.map +0 -1
@@ -1,51 +1,51 @@
1
- import React, { useEffect, useState } from 'react'
2
- import { IImagesContainer } from 'types'
3
- import RenderFileIcon from '../RenderFileIcon/RenderFileIcon'
4
-
5
- function ImagesContainer ({ file, onClose }: IImagesContainer) {
6
- const [fileInfo, setFileInfo] = useState<{ name: string; type: string }>({
7
- name: '',
8
- type: '',
9
- })
10
-
11
- const [b64, setB64] = useState<string>('')
12
-
13
- useEffect(() => {
14
- function getBase64 (file: File) {
15
- return new Promise((resolve, reject) => {
16
- const reader = new FileReader()
17
- reader.readAsDataURL(file)
18
- reader.onload = () => resolve(reader.result)
19
- reader.onerror = (error) => reject(error)
20
- })
21
- }
22
-
23
- if (file) getBase64(file).then((base64) => setB64(base64 as string))
24
- }, [file])
25
-
26
- useEffect(() => {
27
- if (file) {
28
- setFileInfo({
29
- name: file.name,
30
- type: file.type,
31
- })
32
- }
33
- }, [file])
34
-
35
- return (
36
- <div className='images-container'>
37
- <div className='images-container__close'>
38
- <button className='images-container__close--icon' onClick={onClose} />
39
- </div>
40
-
41
- <div className='images-container__container'>
42
- <div className='images-container__image'>
43
- <RenderFileIcon fileType={fileInfo.type} b64={b64} />
44
- <span className='images-container__title-img'>{fileInfo.name}</span>
45
- </div>
46
- </div>
47
- </div>
48
- )
49
- }
50
-
51
- export default ImagesContainer
1
+ import React, { useEffect, useState } from 'react'
2
+ import { IImagesContainer } from 'types'
3
+ import RenderFileIcon from '../RenderFileIcon/RenderFileIcon'
4
+
5
+ function ImagesContainer ({ file, onClose }: IImagesContainer) {
6
+ const [fileInfo, setFileInfo] = useState<{ name: string; type: string }>({
7
+ name: '',
8
+ type: '',
9
+ })
10
+
11
+ const [b64, setB64] = useState<string>('')
12
+
13
+ useEffect(() => {
14
+ function getBase64 (file: File) {
15
+ return new Promise((resolve, reject) => {
16
+ const reader = new FileReader()
17
+ reader.readAsDataURL(file)
18
+ reader.onload = () => resolve(reader.result)
19
+ reader.onerror = (error) => reject(error)
20
+ })
21
+ }
22
+
23
+ if (file) getBase64(file).then((base64) => setB64(base64 as string))
24
+ }, [file])
25
+
26
+ useEffect(() => {
27
+ if (file) {
28
+ setFileInfo({
29
+ name: file.name,
30
+ type: file.type,
31
+ })
32
+ }
33
+ }, [file])
34
+
35
+ return (
36
+ <div className='images-container'>
37
+ <div className='images-container__close'>
38
+ <button className='images-container__close--icon' onClick={onClose} />
39
+ </div>
40
+
41
+ <div className='images-container__container'>
42
+ <div className='images-container__image'>
43
+ <RenderFileIcon fileType={fileInfo.type} b64={b64} />
44
+ <span className='images-container__title-img'>{fileInfo.name}</span>
45
+ </div>
46
+ </div>
47
+ </div>
48
+ )
49
+ }
50
+
51
+ export default ImagesContainer
@@ -1,166 +1,170 @@
1
- import useTheme from '../../hooks/useThemes'
2
- import React, { useCallback, useState } from 'react'
3
- import { Iimages, IInconmingMessage } from 'types'
4
- import MessengerAvatar from '../MessengerAvatar/MessengerAvatar'
5
- import ReactSimpleImageViewer from '../../../../../node_modules/react-simple-image-viewer'
6
- import DocMessage from '../DocMessage/DocMessage'
7
- import { useTranslation } from 'react-i18next'
8
-
9
- interface IMessagesWithFile {
10
- file:
11
- | Iimages
12
- | {
13
- contentType: string
14
- location: string
15
- mimetype: string
16
- originalname: string
17
- size?: number
18
- pages?: number
19
- key?: string
20
- }
21
- | undefined
22
- message: string
23
- date: string
24
- openImageViewer: (index: number) => void
25
- id: string
26
- formatDate: (date: string | Date) => string | undefined
27
- currentImage: number
28
- }
29
-
30
- export const MessageImage = ({ ...rest }) => {
31
- const { t } = useTranslation('messengerMessages')
32
- return (
33
- <div className='messenger__message--file'>
34
- <img
35
- {...rest}
36
- width={200}
37
- height={200}
38
- alt={t('incommingMessage.messageImage')}
39
- />
40
- </div>
41
- )
42
- }
43
-
44
- const MessageWithFile = ({
45
- file,
46
- message,
47
- date,
48
- openImageViewer,
49
- id,
50
- formatDate,
51
- currentImage,
52
- }: IMessagesWithFile) => {
53
- const isImage = (
54
- file:
55
- | {
56
- contentType: string
57
- location: string
58
- mimetype: string
59
- originalname: string
60
- size?: number
61
- pages?: number
62
- key?: string
63
- }
64
- | Iimages
65
- | undefined
66
- ): file is Iimages =>
67
- !!file?.mimetype?.includes('image/png') ||
68
- !!file?.mimetype?.includes('image/jpeg')
69
-
70
- return (
71
- <>
72
- {isImage(file) ? (
73
- <MessageImage
74
- src={file?.location}
75
- onClick={() => openImageViewer(currentImage)}
76
- />
77
- ) : (
78
- file && (
79
- <DocMessage
80
- file={file}
81
- message={message}
82
- date={date}
83
- read={false}
84
- id={id}
85
- formatDate={formatDate}
86
- />
87
- )
88
- )}
89
- </>
90
- )
91
- }
92
-
93
- function IncomingMessage ({
94
- date,
95
- message,
96
- user,
97
- hasFile,
98
- file,
99
- isSystemMessage,
100
- formatDate,
101
- id,
102
- }: IInconmingMessage) {
103
- const { theme } = useTheme()
104
- const [currentImage, setCurrentImage] = useState(0)
105
- const [isViewerOpen, setIsViewerOpen] = useState(false)
106
-
107
- const openImageViewer = useCallback((index: number) => {
108
- setCurrentImage(index)
109
- setIsViewerOpen(true)
110
- }, [])
111
-
112
- const closeImageViewer = () => {
113
- setCurrentImage(0)
114
- setIsViewerOpen(false)
115
- }
116
-
117
- return (
118
- <div className='messenger__messages-row--received' id={id}>
119
- {(user.avatar || user.name) && !isSystemMessage && (
120
- <div className='messenger__message-avatar mr-2'>
121
- <MessengerAvatar image={user.avatar}>
122
- {user.name.slice(0, 1)}
123
- </MessengerAvatar>
124
- </div>
125
- )}
126
-
127
- <div
128
- className='messenger__messages-received'
129
- style={{ background: theme?.messengerIncomerColor }}
130
- >
131
- {!isSystemMessage && (
132
- <p className='messenger__message-title'>{user.name}</p>
133
- )}
134
-
135
- <span>
136
- {hasFile && (
137
- <MessageWithFile
138
- file={file}
139
- message={message}
140
- date={date}
141
- openImageViewer={openImageViewer}
142
- id={id}
143
- formatDate={formatDate}
144
- currentImage={currentImage}
145
- />
146
- )}
147
- {message && <p className='messenger__message'>{message}</p>}
148
- <p className='messenger__message--date'>
149
- {formatDate(date) ?? new Date(date).toLocaleString()}
150
- </p>
151
- </span>
152
- </div>
153
- {file && isViewerOpen && (
154
- <ReactSimpleImageViewer
155
- src={[file.location]}
156
- currentIndex={0}
157
- disableScroll={false}
158
- closeOnClickOutside={true}
159
- onClose={closeImageViewer}
160
- />
161
- )}
162
- </div>
163
- )
164
- }
165
-
166
- export default IncomingMessage
1
+ import useTheme from '../../hooks/useThemes'
2
+ import React, { useCallback, useState } from 'react'
3
+ import { Iimages, IInconmingMessage } from 'types'
4
+ import MessengerAvatar from '../MessengerAvatar/MessengerAvatar'
5
+ import ReactSimpleImageViewer from '../../../../../node_modules/react-simple-image-viewer'
6
+ import DocMessage from '../DocMessage/DocMessage'
7
+ import { useTranslation } from 'react-i18next'
8
+
9
+ interface IMessagesWithFile {
10
+ file:
11
+ | Iimages
12
+ | {
13
+ contentType: string
14
+ location: string
15
+ mimetype: string
16
+ originalname: string
17
+ size?: number
18
+ pages?: number
19
+ key?: string
20
+ }
21
+ | undefined
22
+ message: string
23
+ date: string
24
+ openImageViewer: (index: number) => void
25
+ id: string
26
+ formatDate: (date: string | Date) => string | undefined
27
+ currentImage: number
28
+ }
29
+
30
+ export const MessageImage = ({ ...rest }) => {
31
+ const { t } = useTranslation('messengerMessages')
32
+ return (
33
+ <div className='messenger__message--file'>
34
+ <img
35
+ {...rest}
36
+ width={200}
37
+ height={200}
38
+ alt={t('incommingMessage.messageImage')}
39
+ />
40
+ </div>
41
+ )
42
+ }
43
+
44
+ const MessageWithFile = ({
45
+ file,
46
+ message,
47
+ date,
48
+ openImageViewer,
49
+ id,
50
+ formatDate,
51
+ currentImage,
52
+ }: IMessagesWithFile) => {
53
+ const isImage = (
54
+ file:
55
+ | {
56
+ contentType: string
57
+ location: string
58
+ mimetype: string
59
+ originalname: string
60
+ size?: number
61
+ pages?: number
62
+ key?: string
63
+ }
64
+ | Iimages
65
+ | undefined
66
+ ): file is Iimages => {
67
+ if (!file) return false
68
+ if (['image/png', 'image/jpeg'].includes(file?.mimetype ?? '')) {
69
+ return true
70
+ }
71
+ return false
72
+ }
73
+
74
+ return (
75
+ <>
76
+ {isImage(file) ? (
77
+ <MessageImage
78
+ src={file?.location}
79
+ onClick={() => openImageViewer(currentImage)}
80
+ />
81
+ ) : (
82
+ file && (
83
+ <DocMessage
84
+ file={file}
85
+ message={message}
86
+ date={date}
87
+ read={false}
88
+ id={id}
89
+ formatDate={formatDate}
90
+ />
91
+ )
92
+ )}
93
+ </>
94
+ )
95
+ }
96
+
97
+ function IncomingMessage ({
98
+ date,
99
+ message,
100
+ user,
101
+ hasFile,
102
+ file,
103
+ isSystemMessage,
104
+ formatDate,
105
+ id,
106
+ }: IInconmingMessage) {
107
+ const { theme } = useTheme()
108
+ const [currentImage, setCurrentImage] = useState(0)
109
+ const [isViewerOpen, setIsViewerOpen] = useState(false)
110
+
111
+ const openImageViewer = useCallback((index: number) => {
112
+ setCurrentImage(index)
113
+ setIsViewerOpen(true)
114
+ }, [])
115
+
116
+ const closeImageViewer = () => {
117
+ setCurrentImage(0)
118
+ setIsViewerOpen(false)
119
+ }
120
+
121
+ return (
122
+ <div className='messenger__messages-row--received' id={id}>
123
+ {(user.avatar || user.name) && !isSystemMessage && (
124
+ <div className='messenger__message-avatar mr-2'>
125
+ <MessengerAvatar image={user.avatar}>
126
+ {user.name.slice(0, 1)}
127
+ </MessengerAvatar>
128
+ </div>
129
+ )}
130
+
131
+ <div
132
+ className='messenger__messages-received'
133
+ style={{ background: theme?.messengerIncomerColor }}
134
+ >
135
+ {!isSystemMessage && (
136
+ <p className='messenger__message-title'>{user.name}</p>
137
+ )}
138
+
139
+ <span>
140
+ {hasFile && (
141
+ <MessageWithFile
142
+ file={file}
143
+ message={message}
144
+ date={date}
145
+ openImageViewer={openImageViewer}
146
+ id={id}
147
+ formatDate={formatDate}
148
+ currentImage={currentImage}
149
+ />
150
+ )}
151
+ {message && <p className='messenger__message'>{message}</p>}
152
+ <p className='messenger__message--date'>
153
+ {formatDate(date) ?? new Date(date).toLocaleString()}
154
+ </p>
155
+ </span>
156
+ </div>
157
+ {file && isViewerOpen && (
158
+ <ReactSimpleImageViewer
159
+ src={[file.location]}
160
+ currentIndex={0}
161
+ disableScroll={false}
162
+ closeOnClickOutside={true}
163
+ onClose={closeImageViewer}
164
+ />
165
+ )}
166
+ </div>
167
+ )
168
+ }
169
+
170
+ export default IncomingMessage
@@ -1,80 +1,80 @@
1
- import React, { ReactNode, CSSProperties } from 'react'
2
-
3
- interface IInfiniteScroll {
4
- loading: boolean
5
- more: boolean
6
- fetch: () => void
7
- children: ReactNode
8
- loadingCover: React.ReactElement
9
- root: Element | null
10
- reverse?: boolean
11
- rootMargin?: number
12
- }
13
-
14
- const intersectDivStyle: CSSProperties = {
15
- width: 25,
16
- height: 25,
17
- visibility: 'hidden',
18
- }
19
-
20
- function InfiniteScroll ({
21
- loading,
22
- loadingCover,
23
- more,
24
- fetch,
25
- children,
26
- root,
27
- reverse = false,
28
- rootMargin = 400,
29
- }: IInfiniteScroll) {
30
- const [infiniteElement, setInfiniteElement] =
31
- React.useState<HTMLDivElement | null>(null)
32
-
33
- React.useEffect(() => {
34
- if (!root) return
35
- const currentElement = infiniteElement
36
- const observer = new IntersectionObserver(
37
- (entries) => {
38
- const first = entries[0]
39
- if (first.isIntersecting === true) fetch()
40
- },
41
- {
42
- root,
43
- rootMargin: rootMargin.toString() + 'px',
44
- threshold: 0.5,
45
- }
46
- )
47
-
48
- if (currentElement) {
49
- observer.observe(currentElement)
50
- }
51
-
52
- return () => {
53
- if (currentElement) observer.unobserve(currentElement)
54
- }
55
- }, [infiniteElement])
56
-
57
- if (reverse) {
58
- return (
59
- <>
60
- {more && !loading && (
61
- <div ref={setInfiniteElement} style={intersectDivStyle}></div>
62
- )}
63
- {loading && loadingCover}
64
- {children}
65
- </>
66
- )
67
- }
68
-
69
- return (
70
- <>
71
- {children}
72
- {loading && loadingCover}
73
- {more && !loading && (
74
- <div ref={setInfiniteElement} style={intersectDivStyle}></div>
75
- )}
76
- </>
77
- )
78
- }
79
-
80
- export default InfiniteScroll
1
+ import React, { ReactNode, CSSProperties } from 'react'
2
+
3
+ interface IInfiniteScroll {
4
+ loading: boolean
5
+ more: boolean
6
+ fetch: () => void
7
+ children: ReactNode
8
+ loadingCover: React.ReactElement
9
+ root: Element | null
10
+ reverse?: boolean
11
+ rootMargin?: number
12
+ }
13
+
14
+ const intersectDivStyle: CSSProperties = {
15
+ width: 25,
16
+ height: 25,
17
+ visibility: 'hidden',
18
+ }
19
+
20
+ function InfiniteScroll ({
21
+ loading,
22
+ loadingCover,
23
+ more,
24
+ fetch,
25
+ children,
26
+ root,
27
+ reverse = false,
28
+ rootMargin = 400,
29
+ }: IInfiniteScroll) {
30
+ const [infiniteElement, setInfiniteElement] =
31
+ React.useState<HTMLDivElement | null>(null)
32
+
33
+ React.useEffect(() => {
34
+ if (!root) return
35
+ const currentElement = infiniteElement
36
+ const observer = new IntersectionObserver(
37
+ (entries) => {
38
+ const first = entries[0]
39
+ if (first.isIntersecting === true) fetch()
40
+ },
41
+ {
42
+ root,
43
+ rootMargin: rootMargin.toString() + 'px',
44
+ threshold: 0.5,
45
+ }
46
+ )
47
+
48
+ if (currentElement) {
49
+ observer.observe(currentElement)
50
+ }
51
+
52
+ return () => {
53
+ if (currentElement) observer.unobserve(currentElement)
54
+ }
55
+ }, [infiniteElement])
56
+
57
+ if (reverse) {
58
+ return (
59
+ <>
60
+ {more && !loading && (
61
+ <div ref={setInfiniteElement} style={intersectDivStyle}></div>
62
+ )}
63
+ {loading && loadingCover}
64
+ {children}
65
+ </>
66
+ )
67
+ }
68
+
69
+ return (
70
+ <>
71
+ {children}
72
+ {loading && loadingCover}
73
+ {more && !loading && (
74
+ <div ref={setInfiniteElement} style={intersectDivStyle}></div>
75
+ )}
76
+ </>
77
+ )
78
+ }
79
+
80
+ export default InfiniteScroll