@weavy/uikit-react 12.1.0 → 14.0.0
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/changelog.md +60 -0
- package/dist/cjs/index.js +28 -6
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/types/client/WeavyClient.d.ts +8 -1
- package/dist/cjs/types/components/Attachment.d.ts +2 -1
- package/dist/cjs/types/components/Chat.d.ts +1 -1
- package/dist/cjs/types/components/Messages.d.ts +3 -1
- package/dist/cjs/types/components/PdfViewer.d.ts +3 -1
- package/dist/cjs/types/components/Preview.d.ts +8 -10
- package/dist/cjs/types/contexts/PreviewContext.d.ts +2 -1
- package/dist/cjs/types/contexts/WeavyContext.d.ts +2 -3
- package/dist/cjs/types/hooks/useConversations.d.ts +1 -1
- package/dist/cjs/types/hooks/useMutateMessage.d.ts +1 -1
- package/dist/cjs/types/hooks/useMutateRead.d.ts +1 -0
- package/dist/cjs/types/types/Chat.d.ts +2 -1
- package/dist/cjs/types/types/Message.d.ts +2 -0
- package/dist/cjs/types/types/types.d.ts +63 -9
- package/dist/cjs/types/ui/Spinner.d.ts +10 -0
- package/dist/cjs/types/utils/fileUtilities.d.ts +1 -4
- package/dist/css/weavy-chat.css +1803 -1041
- package/dist/css/weavy-messenger.css +2141 -1360
- package/dist/css/weavy.css +1943 -1162
- package/dist/esm/index.js +28 -6
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/types/client/WeavyClient.d.ts +8 -1
- package/dist/esm/types/components/Attachment.d.ts +2 -1
- package/dist/esm/types/components/Chat.d.ts +1 -1
- package/dist/esm/types/components/Messages.d.ts +3 -1
- package/dist/esm/types/components/PdfViewer.d.ts +3 -1
- package/dist/esm/types/components/Preview.d.ts +8 -10
- package/dist/esm/types/contexts/PreviewContext.d.ts +2 -1
- package/dist/esm/types/contexts/WeavyContext.d.ts +2 -3
- package/dist/esm/types/hooks/useConversations.d.ts +1 -1
- package/dist/esm/types/hooks/useMutateMessage.d.ts +1 -1
- package/dist/esm/types/hooks/useMutateRead.d.ts +1 -0
- package/dist/esm/types/types/Chat.d.ts +2 -1
- package/dist/esm/types/types/Message.d.ts +2 -0
- package/dist/esm/types/types/types.d.ts +63 -9
- package/dist/esm/types/ui/Spinner.d.ts +10 -0
- package/dist/esm/types/utils/fileUtilities.d.ts +1 -4
- package/dist/index.d.ts +15 -7
- package/package.json +2 -2
- package/rollup.config.js +3 -1
- package/src/client/WeavyClient.ts +105 -29
- package/src/components/Attachment.tsx +8 -7
- package/src/components/Chat.tsx +8 -7
- package/src/components/Conversation.tsx +29 -23
- package/src/components/ConversationBadge.tsx +7 -5
- package/src/components/ConversationForm.tsx +1 -1
- package/src/components/ConversationList.tsx +59 -11
- package/src/components/ConversationListItem.tsx +71 -54
- package/src/components/FileBrowser.tsx +53 -50
- package/src/components/MeetingCard.tsx +35 -13
- package/src/components/Meetings.tsx +1 -1
- package/src/components/Message.tsx +41 -41
- package/src/components/Messages.tsx +62 -61
- package/src/components/Messenger.tsx +7 -2
- package/src/components/NewConversation.tsx +1 -1
- package/src/components/PdfViewer.tsx +93 -88
- package/src/components/Preview.tsx +115 -54
- package/src/components/Reactions.tsx +11 -5
- package/src/components/SearchUsers.tsx +21 -11
- package/src/components/SeenBy.tsx +13 -7
- package/src/components/Typing.tsx +11 -12
- package/src/contexts/PreviewContext.tsx +90 -16
- package/src/contexts/UserContext.tsx +1 -1
- package/src/contexts/WeavyContext.tsx +10 -7
- package/src/hooks/useBadge.ts +2 -6
- package/src/hooks/useChat.ts +3 -14
- package/src/hooks/useConversation.ts +1 -7
- package/src/hooks/useConversations.ts +15 -11
- package/src/hooks/useFileUploader.ts +6 -8
- package/src/hooks/useMembers.ts +1 -7
- package/src/hooks/useMessages.ts +1 -7
- package/src/hooks/useMutateChat.ts +6 -11
- package/src/hooks/useMutateConversation.ts +7 -10
- package/src/hooks/useMutateConversationName.ts +10 -12
- package/src/hooks/useMutateDeleteReaction.ts +3 -8
- package/src/hooks/useMutateExternalBlobs.ts +6 -11
- package/src/hooks/useMutateMeeting.ts +6 -11
- package/src/hooks/useMutateMembers.ts +8 -13
- package/src/hooks/useMutateMessage.ts +9 -18
- package/src/hooks/useMutatePinned.ts +3 -8
- package/src/hooks/useMutateReaction.ts +6 -12
- package/src/hooks/useMutateRead.ts +5 -12
- package/src/hooks/useMutateRemoveMembers.ts +7 -12
- package/src/hooks/useMutateTyping.ts +6 -11
- package/src/hooks/usePresence.ts +2 -3
- package/src/hooks/useReactions.ts +11 -12
- package/src/hooks/useSearchUsers.ts +1 -6
- package/src/hooks/useUser.ts +3 -14
- package/src/scss/theme/_alert.scss +61 -63
- package/src/scss/theme/_appbar.scss +105 -28
- package/src/scss/theme/_avatar.scss +23 -28
- package/src/scss/theme/_badge.scss +26 -18
- package/src/scss/theme/_buttons.scss +107 -52
- package/src/scss/theme/_card.scss +102 -4
- package/src/scss/theme/_checkbox.scss +16 -20
- package/src/scss/theme/_code-vscode-dark.scss +184 -0
- package/src/scss/theme/_code-vscode-light.scss +179 -0
- package/src/scss/theme/_code.scss +9 -114
- package/src/scss/theme/_comment-editor-cm.scss +97 -0
- package/src/scss/theme/_comment-editor.scss +129 -0
- package/src/scss/theme/_comments.scss +66 -0
- package/src/scss/theme/_content.scss +33 -5
- package/src/scss/theme/_conversations.scss +19 -78
- package/src/scss/theme/_dropdown.scss +102 -15
- package/src/scss/theme/_embed.scss +135 -0
- package/src/scss/theme/_facepile.scss +11 -0
- package/src/scss/theme/_filebrowser.scss +1 -1
- package/src/scss/theme/_files.scss +77 -48
- package/src/scss/theme/_grid.scss +8 -0
- package/src/scss/theme/_icons.scss +155 -19
- package/src/scss/theme/_image-grid.scss +7 -10
- package/src/scss/theme/_input.scss +160 -0
- package/src/scss/theme/_item.scss +169 -0
- package/src/scss/theme/_list.scss +57 -0
- package/src/scss/theme/_meeting.scss +11 -0
- package/src/scss/theme/_message-editor-cm.scss +95 -0
- package/src/scss/theme/_message-editor.scss +66 -20
- package/src/scss/theme/_messages.scss +51 -105
- package/src/scss/theme/_meta.scss +12 -0
- package/src/scss/theme/_overlays.scss +31 -76
- package/src/scss/theme/_pager.scss +5 -1
- package/src/scss/theme/_pane.scss +13 -2
- package/src/scss/theme/_panels.scss +34 -25
- package/src/scss/theme/_picker-list.scss +5 -3
- package/src/scss/theme/_placeholder.scss +19 -0
- package/src/scss/theme/_poll.scss +49 -0
- package/src/scss/theme/_post-editor-cm.scss +100 -0
- package/src/scss/theme/_post-editor.scss +127 -0
- package/src/scss/theme/_post.scss +83 -0
- package/src/scss/theme/_preview-code.scss +14 -0
- package/src/scss/theme/_preview-embed.scss +11 -5
- package/src/scss/theme/_preview-image.scss +8 -26
- package/src/scss/theme/_preview-media.scss +1 -0
- package/src/scss/theme/_preview-pdf.scss +10 -15
- package/src/scss/theme/_preview-text.scss +1 -1
- package/src/scss/theme/_preview.scss +59 -76
- package/src/scss/theme/_reactions.scss +48 -17
- package/src/scss/theme/_sheet.scss +59 -0
- package/src/scss/theme/_sidebar.scss +86 -0
- package/src/scss/theme/_spinner.scss +11 -7
- package/src/scss/theme/_tab.scss +72 -0
- package/src/scss/theme/_tables.scss +70 -23
- package/src/scss/theme/_toasts.scss +56 -26
- package/src/scss/theme/_type.scss +41 -0
- package/src/scss/theme/{mixins → base}/_backdrop.scss +0 -0
- package/src/scss/theme/{bootstrap/mixins → base}/_breakpoints.scss +9 -0
- package/src/scss/theme/base/_colors.scss +315 -0
- package/src/scss/theme/base/_md.scss +19 -0
- package/src/scss/theme/base/_palette.scss +130 -0
- package/src/scss/theme/{mixins → base}/_position.scss +5 -5
- package/src/scss/theme/base/_reboot.scss +51 -0
- package/src/scss/theme/base/_scroll.scss +180 -0
- package/src/scss/theme/base/_svg.scss +49 -0
- package/src/scss/theme/base/_text.scss +23 -0
- package/src/scss/theme/base/_vars.scss +203 -0
- package/src/scss/theme/{fonts → base/fonts}/_fontmapping-roboto.scss +0 -0
- package/src/scss/theme/{fonts → base/fonts}/_fontmapping-segoe-ui.scss +0 -0
- package/src/scss/theme/base/fonts/_index.scss +2 -0
- package/src/scss/weavy-chat.scss +11 -4
- package/src/scss/weavy-messenger.scss +38 -21
- package/src/types/Chat.ts +2 -1
- package/src/types/Message.ts +3 -1
- package/src/types/types.ts +72 -10
- package/src/ui/Icon.tsx +1 -1
- package/src/ui/Spinner.tsx +19 -0
- package/src/utils/fileUtilities.ts +11 -125
- package/src/utils/infiniteScroll.js +11 -2
- package/src/utils/postal-parent.js +398 -0
- package/src/utils/promise.js +187 -0
- package/src/utils/scrollbarDetection.js +68 -9
- package/src/utils/utils.js +547 -0
- package/src/scss/theme/_attachments.scss +0 -74
- package/src/scss/theme/_cm-editor.scss +0 -42
- package/src/scss/theme/_colors.scss +0 -520
- package/src/scss/theme/_config.scss +0 -6
- package/src/scss/theme/_inputs.scss +0 -28
- package/src/scss/theme/_nav.scss +0 -52
- package/src/scss/theme/_palette.scss +0 -165
- package/src/scss/theme/_preview-icon.scss +0 -41
- package/src/scss/theme/_reboot.scss +0 -41
- package/src/scss/theme/_root.scss +0 -2
- package/src/scss/theme/_scroll.scss +0 -55
- package/src/scss/theme/_search.scss +0 -68
- package/src/scss/theme/_turbo.scss +0 -17
- package/src/scss/theme/_variables.scss +0 -139
- package/src/scss/theme/bootstrap/_accordion.scss +0 -146
- package/src/scss/theme/bootstrap/_alert.scss +0 -71
- package/src/scss/theme/bootstrap/_badge.scss +0 -38
- package/src/scss/theme/bootstrap/_breadcrumb.scss +0 -40
- package/src/scss/theme/bootstrap/_button-group.scss +0 -142
- package/src/scss/theme/bootstrap/_buttons.scss +0 -186
- package/src/scss/theme/bootstrap/_card.scss +0 -234
- package/src/scss/theme/bootstrap/_carousel.scss +0 -229
- package/src/scss/theme/bootstrap/_close.scss +0 -40
- package/src/scss/theme/bootstrap/_containers.scss +0 -41
- package/src/scss/theme/bootstrap/_dropdown.scss +0 -248
- package/src/scss/theme/bootstrap/_forms.scss +0 -9
- package/src/scss/theme/bootstrap/_functions.scss +0 -302
- package/src/scss/theme/bootstrap/_grid.scss +0 -33
- package/src/scss/theme/bootstrap/_helpers.scss +0 -10
- package/src/scss/theme/bootstrap/_images.scss +0 -42
- package/src/scss/theme/bootstrap/_list-group.scss +0 -191
- package/src/scss/theme/bootstrap/_maps.scss +0 -54
- package/src/scss/theme/bootstrap/_mixins.scss +0 -43
- package/src/scss/theme/bootstrap/_modal.scss +0 -237
- package/src/scss/theme/bootstrap/_nav.scss +0 -172
- package/src/scss/theme/bootstrap/_navbar.scss +0 -276
- package/src/scss/theme/bootstrap/_offcanvas.scss +0 -143
- package/src/scss/theme/bootstrap/_pagination.scss +0 -109
- package/src/scss/theme/bootstrap/_placeholders.scss +0 -51
- package/src/scss/theme/bootstrap/_popover.scss +0 -196
- package/src/scss/theme/bootstrap/_progress.scss +0 -59
- package/src/scss/theme/bootstrap/_reboot.scss +0 -610
- package/src/scss/theme/bootstrap/_root.scss +0 -73
- package/src/scss/theme/bootstrap/_spinners.scss +0 -85
- package/src/scss/theme/bootstrap/_tables.scss +0 -164
- package/src/scss/theme/bootstrap/_toasts.scss +0 -70
- package/src/scss/theme/bootstrap/_tooltip.scss +0 -120
- package/src/scss/theme/bootstrap/_transitions.scss +0 -27
- package/src/scss/theme/bootstrap/_type.scss +0 -106
- package/src/scss/theme/bootstrap/_utilities.scss +0 -647
- package/src/scss/theme/bootstrap/_variables.scss +0 -1633
- package/src/scss/theme/bootstrap/forms/_floating-labels.scss +0 -74
- package/src/scss/theme/bootstrap/forms/_form-check.scss +0 -175
- package/src/scss/theme/bootstrap/forms/_form-control.scss +0 -194
- package/src/scss/theme/bootstrap/forms/_form-range.scss +0 -91
- package/src/scss/theme/bootstrap/forms/_form-select.scss +0 -71
- package/src/scss/theme/bootstrap/forms/_form-text.scss +0 -11
- package/src/scss/theme/bootstrap/forms/_input-group.scss +0 -129
- package/src/scss/theme/bootstrap/forms/_labels.scss +0 -36
- package/src/scss/theme/bootstrap/forms/_validation.scss +0 -12
- package/src/scss/theme/bootstrap/helpers/_clearfix.scss +0 -3
- package/src/scss/theme/bootstrap/helpers/_color-bg.scss +0 -10
- package/src/scss/theme/bootstrap/helpers/_colored-links.scss +0 -12
- package/src/scss/theme/bootstrap/helpers/_position.scss +0 -36
- package/src/scss/theme/bootstrap/helpers/_ratio.scss +0 -26
- package/src/scss/theme/bootstrap/helpers/_stacks.scss +0 -15
- package/src/scss/theme/bootstrap/helpers/_stretched-link.scss +0 -15
- package/src/scss/theme/bootstrap/helpers/_text-truncation.scss +0 -7
- package/src/scss/theme/bootstrap/helpers/_visually-hidden.scss +0 -8
- package/src/scss/theme/bootstrap/helpers/_vr.scss +0 -8
- package/src/scss/theme/bootstrap/mixins/_alert.scss +0 -15
- package/src/scss/theme/bootstrap/mixins/_backdrop.scss +0 -14
- package/src/scss/theme/bootstrap/mixins/_banner.scss +0 -9
- package/src/scss/theme/bootstrap/mixins/_border-radius.scss +0 -78
- package/src/scss/theme/bootstrap/mixins/_box-shadow.scss +0 -18
- package/src/scss/theme/bootstrap/mixins/_buttons.scss +0 -70
- package/src/scss/theme/bootstrap/mixins/_caret.scss +0 -64
- package/src/scss/theme/bootstrap/mixins/_clearfix.scss +0 -9
- package/src/scss/theme/bootstrap/mixins/_color-scheme.scss +0 -7
- package/src/scss/theme/bootstrap/mixins/_container.scss +0 -11
- package/src/scss/theme/bootstrap/mixins/_deprecate.scss +0 -10
- package/src/scss/theme/bootstrap/mixins/_forms.scss +0 -152
- package/src/scss/theme/bootstrap/mixins/_gradients.scss +0 -47
- package/src/scss/theme/bootstrap/mixins/_grid.scss +0 -151
- package/src/scss/theme/bootstrap/mixins/_image.scss +0 -16
- package/src/scss/theme/bootstrap/mixins/_list-group.scss +0 -24
- package/src/scss/theme/bootstrap/mixins/_lists.scss +0 -7
- package/src/scss/theme/bootstrap/mixins/_pagination.scss +0 -10
- package/src/scss/theme/bootstrap/mixins/_reset-text.scss +0 -17
- package/src/scss/theme/bootstrap/mixins/_resize.scss +0 -6
- package/src/scss/theme/bootstrap/mixins/_table-variants.scss +0 -24
- package/src/scss/theme/bootstrap/mixins/_text-truncate.scss +0 -8
- package/src/scss/theme/bootstrap/mixins/_transition.scss +0 -26
- package/src/scss/theme/bootstrap/mixins/_utilities.scss +0 -97
- package/src/scss/theme/bootstrap/mixins/_visually-hidden.scss +0 -29
- package/src/scss/theme/bootstrap/utilities/_api.scss +0 -47
- package/src/scss/theme/bootstrap/vendor/_rfs.scss +0 -354
- package/src/scss/theme/bs/_badge.scss +0 -20
- package/src/scss/theme/bs/_buttons.scss +0 -185
- package/src/scss/theme/bs/_dropdown.scss +0 -86
- package/src/scss/theme/bs/_forms.scss +0 -161
- package/src/scss/theme/bs/_list-group.scss +0 -73
- package/src/scss/theme/bs/_tables.scss +0 -46
- package/src/scss/theme/fonts/_index.scss +0 -2
- package/src/scss/theme/mixins/_palette.scss +0 -165
- package/src/scss/theme/mixins/_scrollbar.scss +0 -110
|
@@ -1,27 +1,49 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import Button from '../ui/Button';
|
|
3
3
|
import Icon from '../ui/Icon';
|
|
4
|
-
|
|
4
|
+
import dayjs from 'dayjs';
|
|
5
5
|
type Props = {
|
|
6
6
|
meeting: MeetingCardType
|
|
7
7
|
|
|
8
8
|
}
|
|
9
9
|
const MeetingCard = ({ meeting }: Props) => {
|
|
10
10
|
|
|
11
|
-
const handleJoin = () => {
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
|
|
15
11
|
return (
|
|
16
|
-
<div className="wy-
|
|
17
|
-
|
|
18
|
-
<div className="wy-
|
|
19
|
-
|
|
20
|
-
<div className="wy-
|
|
21
|
-
|
|
22
|
-
|
|
12
|
+
<div className="wy-list">
|
|
13
|
+
{meeting.ended_at &&
|
|
14
|
+
<div className="wy-item wy-meeting">
|
|
15
|
+
<Icon.UI name="zoom" size={4} color="#cccccc"/>
|
|
16
|
+
<div className="wy-item-body">
|
|
17
|
+
<div className="wy-item-title">Zoom meeting</div>
|
|
18
|
+
<div className="wy-item-body">
|
|
19
|
+
<div>Ended {dayjs.utc(meeting.ended_at).tz(dayjs.tz.guess()).fromNow()}</div>
|
|
20
|
+
{meeting.recording_url &&
|
|
21
|
+
<div className="wy-meeting-actions">
|
|
22
|
+
<a href={meeting.recording_url} target="_blank" className="wy-button wy-button-primary">Play recording</a>
|
|
23
|
+
</div>
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
</div>
|
|
27
|
+
</div>
|
|
23
28
|
</div>
|
|
24
|
-
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
{!meeting.ended_at &&
|
|
32
|
+
<a className="wy-item wy-meeting" href={meeting.join_url} target="_blank">
|
|
33
|
+
<Icon.UI name="zoom" color="#4a8cff" size={4} />
|
|
34
|
+
<div className="wy-item-body">
|
|
35
|
+
<div className="wy-item-title">Zoom meeting</div>
|
|
36
|
+
<div className="wy-item-body">
|
|
37
|
+
<div>ID: {`${meeting.provider_id.substring(0, 3)}-${meeting.provider_id.substring(3, 6)}-${meeting.provider_id.substring(6)}`}</div>
|
|
38
|
+
<div className="wy-meeting-actions">
|
|
39
|
+
<Button.UI className="wy-button-primary">Join meeting</Button.UI>
|
|
40
|
+
</div>
|
|
41
|
+
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
</a>
|
|
45
|
+
}
|
|
46
|
+
|
|
25
47
|
</div>
|
|
26
48
|
|
|
27
49
|
)
|
|
@@ -11,12 +11,12 @@ import MeetingCard from './MeetingCard';
|
|
|
11
11
|
import usePreview from '../hooks/usePreview';
|
|
12
12
|
import classNames from 'classnames';
|
|
13
13
|
|
|
14
|
-
const Message: FC<MessageProps> = ({ id, html, temp, me, avatar, name, created_at, attachments, meeting, parentId, reactions, seenBy }) => {
|
|
14
|
+
const Message: FC<MessageProps> = ({ id, html, temp, me, avatar, name, created_at, created_by, attachments, meeting, parentId, reactions, seenBy, chatRoom }) => {
|
|
15
15
|
|
|
16
16
|
const { open, close } = usePreview(attachments);
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
let images = attachments?.filter((a: AttachmentType) => a.kind === "image" && a.thumbnail_url);
|
|
19
|
+
let files = attachments?.filter((a: AttachmentType) => a.kind !== "image" || !a.thumbnail_url);
|
|
20
20
|
|
|
21
21
|
const date = dayjs.utc(created_at).tz(dayjs.tz.guess());
|
|
22
22
|
|
|
@@ -35,50 +35,50 @@ const Message: FC<MessageProps> = ({ id, html, temp, me, avatar, name, created_a
|
|
|
35
35
|
)}
|
|
36
36
|
<div className="wy-message-content">
|
|
37
37
|
<div className="wy-message-meta">
|
|
38
|
+
{chatRoom && !me &&
|
|
39
|
+
<span>{created_by} · </span>
|
|
40
|
+
}
|
|
38
41
|
<time dateTime={created_at} title={date.format('LLLL')}>{date.fromNow()}</time>
|
|
39
42
|
</div>
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
43
|
+
|
|
44
|
+
<div className="wy-message-bubble">
|
|
45
|
+
{temp &&
|
|
46
|
+
<div className="wy-content">{html}</div>
|
|
47
|
+
}
|
|
48
|
+
{!temp &&
|
|
49
|
+
<>
|
|
50
|
+
{images && !!images.length && <ImageGrid>
|
|
51
|
+
{images.map((a: AttachmentType) =>
|
|
52
|
+
<Image onClick={(e) => handlePreviewClick(e, a.id)} key={a.id} src={a.download_url} previewSrc={a.preview_url} width={a.width} height={a.height} />
|
|
53
|
+
)}
|
|
54
|
+
</ImageGrid>}
|
|
55
|
+
|
|
56
|
+
{html && <div className="wy-content" dangerouslySetInnerHTML={{ __html: joypixels.shortnameToUnicode(html || "") }}></div>}
|
|
57
|
+
|
|
58
|
+
{meeting &&
|
|
59
|
+
<MeetingCard meeting={meeting} />
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
{files && !!files.length && <div className="wy-list-items wy-attachments">
|
|
63
|
+
{files.map((a: AttachmentType) =>
|
|
64
|
+
<Attachment key={a.id} onClick={(e) => handlePreviewClick(e, a.id)} name={a.name} previewFormat={a.kind} provider={a.provider} url={a.download_url} previewUrl={a.provider ? a.external_url : a.preview_url} mediaType={a.media_type} kind={a.kind} size={a.size} />
|
|
65
|
+
)}
|
|
66
|
+
</div>}
|
|
67
|
+
<div className="wy-reactions-line">
|
|
68
|
+
<div className="wy-reactions">
|
|
69
|
+
<ReactionsList id={id} parentId={parentId} reactions={reactions} />
|
|
70
|
+
</div>
|
|
71
|
+
{!temp && <ReactionsMenu id={id} reactions={reactions} />}
|
|
72
|
+
</div>
|
|
73
|
+
</>
|
|
74
|
+
}
|
|
71
75
|
</div>
|
|
72
76
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
<ReactionsList id={id} parentId={parentId} reactions={reactions} />
|
|
76
|
-
</div>
|
|
77
|
-
)}
|
|
78
|
-
|
|
77
|
+
|
|
78
|
+
|
|
79
79
|
</div>
|
|
80
80
|
|
|
81
|
-
|
|
81
|
+
|
|
82
82
|
</div>
|
|
83
83
|
<SeenBy id={id} parentId={parentId} seenBy={seenBy} createdAt={created_at} />
|
|
84
84
|
</>
|
|
@@ -17,11 +17,13 @@ type Props = {
|
|
|
17
17
|
id: number,
|
|
18
18
|
members: MembersResult | undefined,
|
|
19
19
|
displayName?: string,
|
|
20
|
-
avatarUrl?: string
|
|
20
|
+
avatarUrl?: string,
|
|
21
|
+
lastMessageId: number | null,
|
|
22
|
+
chatRoom: boolean
|
|
21
23
|
}
|
|
22
24
|
|
|
23
|
-
const Messages = ({ id, members, displayName, avatarUrl }: Props) => {
|
|
24
|
-
var reverseScroller:IntersectionObserver | null;
|
|
25
|
+
const Messages = ({ id, members, displayName, avatarUrl, lastMessageId, chatRoom }: Props) => {
|
|
26
|
+
var reverseScroller: IntersectionObserver | null;
|
|
25
27
|
|
|
26
28
|
const { user } = useContext(UserContext);
|
|
27
29
|
|
|
@@ -31,7 +33,7 @@ const Messages = ({ id, members, displayName, avatarUrl }: Props) => {
|
|
|
31
33
|
const readMoreRef = useRef<any>();
|
|
32
34
|
const messagesEndRef = useRef<any>();
|
|
33
35
|
const [resolveScrollerFetch, setResolveScrollerFetch] = useState<Function | null>()
|
|
34
|
-
|
|
36
|
+
|
|
35
37
|
const { dispatch, on, events } = useEvents();
|
|
36
38
|
|
|
37
39
|
const { isLoading, isError, data, error, fetchNextPage, hasNextPage, isFetching, isFetchingNextPage } = useMessages(id, {});
|
|
@@ -44,7 +46,6 @@ const Messages = ({ id, members, displayName, avatarUrl }: Props) => {
|
|
|
44
46
|
useLayoutEffect(() => {
|
|
45
47
|
//if (id && !isLoading && !isLoadingMembers && !isLoadingConversation) {
|
|
46
48
|
if (id && !isLoading) {
|
|
47
|
-
//console.log("useLayoutEffect scroller", id)
|
|
48
49
|
// scroll to bottom when selecting a conversation
|
|
49
50
|
scrollParentToBottom(messagesEndRef.current);
|
|
50
51
|
|
|
@@ -63,7 +64,7 @@ const Messages = ({ id, members, displayName, avatarUrl }: Props) => {
|
|
|
63
64
|
})
|
|
64
65
|
}
|
|
65
66
|
})
|
|
66
|
-
|
|
67
|
+
|
|
67
68
|
} else {
|
|
68
69
|
reverseScroller?.disconnect();
|
|
69
70
|
reverseScroller = null;
|
|
@@ -85,60 +86,63 @@ const Messages = ({ id, members, displayName, avatarUrl }: Props) => {
|
|
|
85
86
|
}, [data]);
|
|
86
87
|
|
|
87
88
|
useEffect(() => {
|
|
89
|
+
// mark conversation as read
|
|
90
|
+
if (id && lastMessageId) {
|
|
91
|
+
readMessageMutation.mutate({ id: id, read: true, messageId: lastMessageId })
|
|
92
|
+
}
|
|
93
|
+
}, [id, lastMessageId])
|
|
88
94
|
|
|
95
|
+
useEffect(() => {
|
|
89
96
|
if (id) {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
readMessageMutation.mutate({ id: id, read: true })
|
|
95
|
-
|
|
96
|
-
client?.subscribe(`a${id}`, "message-inserted", handleRealtimeMessage);
|
|
97
|
-
client?.subscribe(`a${id}`, "conversation-read", handleRealtimeSeenBy);
|
|
98
|
-
client?.subscribe(`a${id}`, "reaction-inserted", handleRealtimeReactionInserted);
|
|
99
|
-
client?.subscribe(`a${id}`, "reaction-deleted", handleRealtimeReactionDeleted);
|
|
97
|
+
client?.subscribe(`a${id}`, "message_created", handleRealtimeMessage);
|
|
98
|
+
client?.subscribe(`a${id}`, "conversation_marked", handleRealtimeSeenBy);
|
|
99
|
+
client?.subscribe(`a${id}`, "reaction_added", handleRealtimeReactionInserted);
|
|
100
|
+
client?.subscribe(`a${id}`, "reaction_removed", handleRealtimeReactionDeleted);
|
|
100
101
|
}
|
|
101
102
|
|
|
102
103
|
return () => {
|
|
103
|
-
|
|
104
|
+
|
|
105
|
+
//window.removeEventListener('focus', handleFocus, false);
|
|
104
106
|
|
|
105
107
|
if (id) {
|
|
106
108
|
// remove additional pages in cache. Only get first page
|
|
107
109
|
let qd = queryClient.getQueryData(["messages", id]);
|
|
108
|
-
|
|
110
|
+
|
|
109
111
|
if (qd) {
|
|
110
|
-
|
|
112
|
+
|
|
111
113
|
queryClient.setQueryData(["messages", id], (data: any) => ({
|
|
112
|
-
pages: data?.pages.slice(0,1),
|
|
113
|
-
pageParams: [undefined]
|
|
114
|
-
}));
|
|
114
|
+
pages: data?.pages.slice(0, 1),
|
|
115
|
+
pageParams: [undefined]
|
|
116
|
+
}));
|
|
115
117
|
}
|
|
116
118
|
|
|
117
|
-
client?.unsubscribe(`a${id}`, "
|
|
118
|
-
client?.unsubscribe(`a${id}`, "
|
|
119
|
-
client?.unsubscribe(`a${id}`, "
|
|
120
|
-
client?.unsubscribe(`a${id}`, "
|
|
119
|
+
client?.unsubscribe(`a${id}`, "message_created", handleRealtimeMessage);
|
|
120
|
+
client?.unsubscribe(`a${id}`, "conversation_marked", handleRealtimeSeenBy);
|
|
121
|
+
client?.unsubscribe(`a${id}`, "reaction_added", handleRealtimeReactionInserted);
|
|
122
|
+
client?.unsubscribe(`a${id}`, "reaction_removed", handleRealtimeReactionDeleted);
|
|
121
123
|
}
|
|
122
124
|
}
|
|
123
125
|
}, [id]);
|
|
124
126
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
+
|
|
128
|
+
const handleRealtimeReactionInserted = useCallback((realtimeEvent: RealtimeReaction) => {
|
|
129
|
+
dispatch("reaction_added_" + realtimeEvent.entity.id, realtimeEvent);
|
|
127
130
|
}, [id]);
|
|
128
131
|
|
|
129
|
-
const handleRealtimeReactionDeleted = useCallback((
|
|
130
|
-
dispatch("
|
|
132
|
+
const handleRealtimeReactionDeleted = useCallback((realtimeEvent: RealtimeReaction) => {
|
|
133
|
+
dispatch("reaction_deleted_" + realtimeEvent.entity.id, realtimeEvent);
|
|
131
134
|
}, [id]);
|
|
132
135
|
|
|
133
136
|
// handle new message from post form
|
|
134
137
|
const handleNewMessage = (text: string, attachments: [], meetings: []) => {
|
|
135
138
|
addMessageMutation.mutate({ id: id, text: text, userId: user.id, attachments: attachments, meetings: meetings }, {
|
|
136
|
-
onSuccess: () => {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
// mark conversation as read
|
|
140
|
-
setTimeout(() => { readMessageMutation.mutate({ id: id, read: true }) }, 1000);
|
|
139
|
+
onSuccess: (data: MessageType) => {
|
|
140
|
+
// mark conversation as read
|
|
141
|
+
readMessageMutation.mutate({ id: id, read: true, messageId: data.id });
|
|
141
142
|
|
|
143
|
+
requestAnimationFrame(() => scrollParentToBottom(messagesEndRef.current, true))
|
|
144
|
+
}
|
|
145
|
+
});
|
|
142
146
|
|
|
143
147
|
requestAnimationFrame(() => scrollParentToBottom(readMoreRef.current, true));
|
|
144
148
|
}
|
|
@@ -146,7 +150,7 @@ const Messages = ({ id, members, displayName, avatarUrl }: Props) => {
|
|
|
146
150
|
const handleRealtimeSeenBy = async (data: any) => {
|
|
147
151
|
let isAtBottom = isParentAtBottom(readMoreRef.current);
|
|
148
152
|
// how to do this better?
|
|
149
|
-
queryClient.invalidateQueries(["members", id])
|
|
153
|
+
queryClient.invalidateQueries(["members", id]);
|
|
150
154
|
|
|
151
155
|
if (isAtBottom) {
|
|
152
156
|
requestAnimationFrame(() => scrollParentToBottom(readMoreRef.current, true));
|
|
@@ -154,11 +158,14 @@ const Messages = ({ id, members, displayName, avatarUrl }: Props) => {
|
|
|
154
158
|
}
|
|
155
159
|
|
|
156
160
|
// real time insert-message handler
|
|
157
|
-
const handleRealtimeMessage = useCallback((
|
|
158
|
-
if (message.app_id !== id || message.
|
|
161
|
+
const handleRealtimeMessage = useCallback((realtimeEvent: RealtimeMessage) => {
|
|
162
|
+
if (realtimeEvent.message.app_id !== id || realtimeEvent.message.created_by_id === user.id) return;
|
|
163
|
+
|
|
164
|
+
// set created_by
|
|
165
|
+
realtimeEvent.message.created_by = realtimeEvent.actor;
|
|
159
166
|
|
|
160
167
|
// mark conversation as read
|
|
161
|
-
readMessageMutation.mutate({ id: id, read: true })
|
|
168
|
+
readMessageMutation.mutate({ id: id, read: true, messageId: realtimeEvent.message.id })
|
|
162
169
|
|
|
163
170
|
const previousData = queryClient.getQueryData<any>(['messages', id]);
|
|
164
171
|
|
|
@@ -166,13 +173,13 @@ const Messages = ({ id, members, displayName, avatarUrl }: Props) => {
|
|
|
166
173
|
let isAtBottom = isParentAtBottom(readMoreRef.current);
|
|
167
174
|
|
|
168
175
|
const newPagesArray = previousData.pages.map((page: any, i: number) => {
|
|
169
|
-
//
|
|
176
|
+
// add realtime message
|
|
177
|
+
|
|
170
178
|
if (i === 0) {
|
|
171
179
|
page.data = [
|
|
172
180
|
...page.data,
|
|
173
|
-
message
|
|
181
|
+
realtimeEvent.message
|
|
174
182
|
]
|
|
175
|
-
|
|
176
183
|
}
|
|
177
184
|
return page;
|
|
178
185
|
|
|
@@ -191,15 +198,9 @@ const Messages = ({ id, members, displayName, avatarUrl }: Props) => {
|
|
|
191
198
|
|
|
192
199
|
}, [id]);
|
|
193
200
|
|
|
194
|
-
const handleFocus = useCallback(() => {
|
|
195
|
-
if (!id) return;
|
|
196
|
-
|
|
197
|
-
readMessageMutation.mutate({ id: id, read: true })
|
|
198
|
-
}, [id]);
|
|
199
|
-
|
|
200
201
|
let messageHeader = <div className="wy-avatar-header">
|
|
201
202
|
{avatarUrl && displayName && <Avatar src={avatarUrl} name={displayName} id={id} size={128} /> || ''}
|
|
202
|
-
{displayName && <div className="wy-
|
|
203
|
+
{displayName && <div className="wy-headline">{displayName}</div> || ''}
|
|
203
204
|
</div>;
|
|
204
205
|
|
|
205
206
|
let loadMoreButton = <Button.UI onClick={() => fetchNextPage()} disabled={!hasNextPage || isFetchingNextPage} className="wy-message-readmore">Load more</Button.UI>;
|
|
@@ -207,19 +208,19 @@ const Messages = ({ id, members, displayName, avatarUrl }: Props) => {
|
|
|
207
208
|
let messages = (
|
|
208
209
|
<>
|
|
209
210
|
<div className="wy-message-readmore" ref={readMoreRef}>
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
211
|
+
{isFetchingNextPage
|
|
212
|
+
? 'Loading more...'
|
|
213
|
+
: hasNextPage
|
|
214
|
+
? loadMoreButton
|
|
215
|
+
: messageHeader}
|
|
216
|
+
|
|
216
217
|
</div>
|
|
217
218
|
{data && members && data.pages && data.pages.map((group, i) => {
|
|
218
219
|
// Reverse key since page loading is reversed
|
|
219
220
|
return <React.Fragment key={data.pages.length - i}>
|
|
220
221
|
{
|
|
221
222
|
group.data?.map((item: MessageType) => {
|
|
222
|
-
|
|
223
|
+
|
|
223
224
|
return <Message
|
|
224
225
|
key={item.id}
|
|
225
226
|
id={item.id}
|
|
@@ -229,15 +230,15 @@ const Messages = ({ id, members, displayName, avatarUrl }: Props) => {
|
|
|
229
230
|
avatar={item.created_by.avatar_url}
|
|
230
231
|
name={item.created_by.display_name}
|
|
231
232
|
created_at={item.created_at}
|
|
233
|
+
created_by={item.created_by.display_name}
|
|
232
234
|
attachments={item.attachments}
|
|
233
235
|
meeting={item.meeting}
|
|
234
236
|
parentId={id}
|
|
235
237
|
reactions={item.reactions}
|
|
238
|
+
chatRoom={chatRoom}
|
|
236
239
|
//reactions_count={item.reactions_count}
|
|
237
|
-
seenBy={members.data.length > 0 ? members.data.filter((member) => {
|
|
238
|
-
|
|
239
|
-
const nothingLaterRead = !data.pages.map((p) => p.data).flat().find((message: MessageType) => { return message.id > item.id && member.read_at >= message.created_at });
|
|
240
|
-
return hasRead && nothingLaterRead && member.id !== user.id;
|
|
240
|
+
seenBy={(members.data && members.data.length > 0) ? members.data.filter((member) => {
|
|
241
|
+
return member.marked_id === item.id && member.id !== user.id;
|
|
241
242
|
}) : []}
|
|
242
243
|
/>
|
|
243
244
|
})
|
|
@@ -260,7 +261,7 @@ const Messages = ({ id, members, displayName, avatarUrl }: Props) => {
|
|
|
260
261
|
<div id="container" className="wy-messages">
|
|
261
262
|
{messages}
|
|
262
263
|
</div>
|
|
263
|
-
<div className="wy-message-editor">
|
|
264
|
+
<div className="wy-footerbar wy-footerbar-sticky wy-message-editor wy-message-editor-bottom">
|
|
264
265
|
<ConversationForm key={id} conversationId={id} handleInsert={handleNewMessage} />
|
|
265
266
|
</div>
|
|
266
267
|
</>
|
|
@@ -4,8 +4,13 @@ import Conversation from './Conversation';
|
|
|
4
4
|
import ConversationList from './ConversationList';
|
|
5
5
|
import { Messenger } from '../types/Messenger';
|
|
6
6
|
import { WeavyContext } from '../contexts/WeavyContext';
|
|
7
|
+
import classNames from 'classnames';
|
|
7
8
|
|
|
8
|
-
|
|
9
|
+
type Props = {
|
|
10
|
+
className?: string,
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const Messenger: FC<Messenger> = ({ className }: Props) => {
|
|
9
14
|
|
|
10
15
|
const { client } = useContext(WeavyContext);
|
|
11
16
|
|
|
@@ -15,7 +20,7 @@ const Messenger: FC<Messenger> = () => {
|
|
|
15
20
|
|
|
16
21
|
return (
|
|
17
22
|
<MessengerProvider>
|
|
18
|
-
<div className="wy-messenger-provider">
|
|
23
|
+
<div className={classNames("wy-messenger-provider", className)}>
|
|
19
24
|
|
|
20
25
|
<div className="wy-messenger-sidebar wy-scroll-y">
|
|
21
26
|
<ConversationList />
|
|
@@ -29,7 +29,7 @@ const NewConversation = () => {
|
|
|
29
29
|
<Button.UI onClick={handleOpen}><Icon.UI name="plus" /></Button.UI>
|
|
30
30
|
|
|
31
31
|
<Overlay.UI isOpen={modalOpen} className="wy-modal">
|
|
32
|
-
<header className="wy-appbars">
|
|
32
|
+
<header className="wy-appbars" data-adjust-scrollbar-top>
|
|
33
33
|
<nav className="wy-appbar">
|
|
34
34
|
<Button.UI onClick={handleClose}><Icon.UI name='close' /></Button.UI>
|
|
35
35
|
<div className="wy-appbar-text">Create conversation</div>
|