@weavy/uikit-react 13.0.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 +24 -0
- package/dist/cjs/index.js +3 -3
- package/dist/cjs/index.js.map +1 -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/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 +1 -0
- package/dist/cjs/types/types/Message.d.ts +2 -0
- package/dist/cjs/types/types/types.d.ts +47 -4
- package/dist/cjs/types/ui/Spinner.d.ts +2 -1
- package/dist/css/weavy-chat.css +1540 -954
- package/dist/css/weavy-messenger.css +1901 -1298
- package/dist/css/weavy.css +1696 -1093
- package/dist/esm/index.js +3 -3
- package/dist/esm/index.js.map +1 -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/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 +1 -0
- package/dist/esm/types/types/Message.d.ts +2 -0
- package/dist/esm/types/types/types.d.ts +47 -4
- package/dist/esm/types/ui/Spinner.d.ts +2 -1
- package/dist/index.d.ts +2 -1
- package/package.json +2 -2
- package/src/client/WeavyClient.ts +12 -17
- package/src/components/Attachment.tsx +5 -5
- package/src/components/Chat.tsx +6 -5
- package/src/components/Conversation.tsx +26 -20
- 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 +61 -60
- package/src/components/Messenger.tsx +7 -2
- package/src/components/NewConversation.tsx +1 -1
- package/src/components/PdfViewer.tsx +5 -5
- package/src/components/Preview.tsx +2 -2
- package/src/components/Reactions.tsx +11 -5
- package/src/components/SearchUsers.tsx +19 -9
- package/src/components/SeenBy.tsx +13 -7
- package/src/components/Typing.tsx +11 -12
- package/src/contexts/UserContext.tsx +1 -1
- package/src/contexts/WeavyContext.tsx +3 -3
- package/src/hooks/useConversations.ts +15 -5
- package/src/hooks/useMutateMessage.ts +1 -5
- package/src/hooks/useMutateRead.ts +5 -3
- package/src/hooks/usePresence.ts +2 -3
- package/src/hooks/useReactions.ts +11 -12
- package/src/scss/theme/_alert.scss +61 -63
- package/src/scss/theme/_appbar.scss +105 -30
- 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 +3 -3
- package/src/scss/theme/_code-vscode-light.scss +3 -3
- package/src/scss/theme/_code.scss +0 -2
- 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 +76 -47
- 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 +65 -19
- 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 +33 -28
- 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 +11 -2
- package/src/scss/theme/_preview-embed.scss +8 -2
- 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.scss +57 -79
- 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 +10 -4
- package/src/scss/weavy-messenger.scss +37 -21
- package/src/types/Chat.ts +2 -1
- package/src/types/Message.ts +3 -1
- package/src/types/types.ts +56 -5
- package/src/ui/Icon.tsx +1 -1
- package/src/ui/Spinner.tsx +3 -2
- 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
|
@@ -27,22 +27,40 @@ const ConversationListItem = ({ item, refetchConversations }: ConversationListIt
|
|
|
27
27
|
|
|
28
28
|
const ChatRoom = "edb400ac-839b-45a7-b2a8-6a01820d1c44";
|
|
29
29
|
|
|
30
|
-
const handleClick = (e: React.MouseEvent<
|
|
31
|
-
e.
|
|
32
|
-
|
|
30
|
+
const handleClick = (e: React.MouseEvent<HTMLDivElement>, id: any) => {
|
|
31
|
+
if (!e.defaultPrevented) {
|
|
32
|
+
e.preventDefault();
|
|
33
|
+
setSelectedConversationId(id);
|
|
34
|
+
}
|
|
33
35
|
}
|
|
34
36
|
|
|
35
|
-
const handleAppUpdated = useCallback((
|
|
36
|
-
if (
|
|
37
|
+
const handleAppUpdated = useCallback((realtimeEvent: RealtimeApp) => {
|
|
38
|
+
if (realtimeEvent.app.id !== item.id) return;
|
|
37
39
|
refetchConversations();
|
|
38
40
|
|
|
39
|
-
}, [item.id])
|
|
41
|
+
}, [item.id]);
|
|
42
|
+
|
|
43
|
+
const handleMessageCreated = useCallback((realtimeEvent: RealtimeMessage) => {
|
|
44
|
+
if (realtimeEvent.message.app_id !== item.id) return;
|
|
45
|
+
refetchConversations();
|
|
46
|
+
|
|
47
|
+
}, [item.id]);
|
|
48
|
+
|
|
49
|
+
const handleMemberAdded = useCallback((realtimeEvent: RealtimeMember) => {
|
|
50
|
+
if (realtimeEvent.app.id !== item.id) return;
|
|
51
|
+
refetchConversations();
|
|
52
|
+
|
|
53
|
+
}, [item.id]);
|
|
40
54
|
|
|
41
55
|
useEffect(() => {
|
|
42
|
-
client?.subscribe(`a${item.id}`, "
|
|
56
|
+
client?.subscribe(`a${item.id}`, "app_updated", handleAppUpdated);
|
|
57
|
+
client?.subscribe(`a${item.id}`, "message_created", handleMessageCreated);
|
|
58
|
+
client?.subscribe(`a${item.id}`, "member_added", handleMemberAdded);
|
|
43
59
|
|
|
44
60
|
return () => {
|
|
45
|
-
client?.unsubscribe(`a${item.id}`, "
|
|
61
|
+
client?.unsubscribe(`a${item.id}`, "app_updated", handleAppUpdated);
|
|
62
|
+
client?.unsubscribe(`a${item.id}`, "message_created", handleMessageCreated);
|
|
63
|
+
client?.unsubscribe(`a${item.id}`, "member_added", handleMemberAdded);
|
|
46
64
|
}
|
|
47
65
|
}, [item.id])
|
|
48
66
|
|
|
@@ -50,12 +68,12 @@ const ConversationListItem = ({ item, refetchConversations }: ConversationListIt
|
|
|
50
68
|
|
|
51
69
|
const handleUnread = (e: React.MouseEvent<HTMLAnchorElement>) => {
|
|
52
70
|
e.preventDefault();
|
|
53
|
-
readMutation.mutate({ id: item.id, read: false });
|
|
71
|
+
readMutation.mutate({ id: item.id, read: false, messageId: null });
|
|
54
72
|
}
|
|
55
73
|
|
|
56
74
|
const handleRead = (e: React.MouseEvent<HTMLAnchorElement>) => {
|
|
57
75
|
e.preventDefault();
|
|
58
|
-
readMutation.mutate({ id: item.id, read: true });
|
|
76
|
+
readMutation.mutate({ id: item.id, read: true, messageId: item.last_message.id });
|
|
59
77
|
}
|
|
60
78
|
|
|
61
79
|
const handlePin = (e: React.MouseEvent<HTMLAnchorElement>) => {
|
|
@@ -78,18 +96,18 @@ const ConversationListItem = ({ item, refetchConversations }: ConversationListIt
|
|
|
78
96
|
// }
|
|
79
97
|
|
|
80
98
|
return (
|
|
81
|
-
<div className={classNames('wy-conversation', {"wy-unread": item.is_unread})} key={item.id}>
|
|
82
|
-
<
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
<div className="wy-
|
|
86
|
-
<div className="wy-
|
|
87
|
-
|
|
88
|
-
{item.last_message
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
<div className="wy-
|
|
99
|
+
<div className={classNames('wy-item wy-item-lg wy-item-hover wy-conversation', {"wy-unread": item.is_unread, "wy-active": selectedConversationId === item.id})} key={item.id} onClick={(e) => handleClick(e, item.id)}>
|
|
100
|
+
<Avatar src={item.avatar_url} id={otherId || -1} presence={item.type !== ChatRoom ? "away" : ""} name={item.display_name} />
|
|
101
|
+
|
|
102
|
+
<div className="wy-item-body">
|
|
103
|
+
<div className="wy-item-row">
|
|
104
|
+
<div className="wy-item-title">{item.display_name}</div>
|
|
105
|
+
{item.last_message &&
|
|
106
|
+
<time className="wy-meta" dateTime={item.last_message.created_at.toString()} title={date.format('LLLL')}>{date.fromNow()}</time>
|
|
107
|
+
}
|
|
108
|
+
</div>
|
|
109
|
+
<div className="wy-item-row">
|
|
110
|
+
<div className="wy-item-text">
|
|
93
111
|
<Typing id={item.id} context="listitem">
|
|
94
112
|
|
|
95
113
|
{item.last_message?.html &&
|
|
@@ -108,44 +126,43 @@ const ConversationListItem = ({ item, refetchConversations }: ConversationListIt
|
|
|
108
126
|
|
|
109
127
|
</Typing>
|
|
110
128
|
</div>
|
|
111
|
-
|
|
112
|
-
</a>
|
|
129
|
+
|
|
113
130
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
<Icon.UI name="pin" size={.75} />
|
|
118
|
-
</Button.UI>
|
|
119
|
-
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
<Dropdown.UI directionX='left'>
|
|
123
|
-
<>
|
|
124
|
-
{item.is_unread &&
|
|
125
|
-
<Dropdown.Item onClick={handleRead}>Mark as read</Dropdown.Item>
|
|
126
|
-
}
|
|
127
|
-
{!item.is_unread &&
|
|
128
|
-
<Dropdown.Item onClick={handleUnread}>Mark as unread</Dropdown.Item>
|
|
129
|
-
}
|
|
130
|
-
</>
|
|
131
|
-
<>
|
|
131
|
+
</div>
|
|
132
|
+
</div>
|
|
133
|
+
<div className="wy-item-actions wy-item-actions-bottom">
|
|
132
134
|
{item.is_pinned &&
|
|
133
|
-
<
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
<Dropdown.Item onClick={handlePin}>Pin</Dropdown.Item>
|
|
137
|
-
}
|
|
138
|
-
</>
|
|
139
|
-
{item.type === ChatRoom &&
|
|
140
|
-
<Dropdown.Item onClick={handleLeaveConversation}>Leave conversation</Dropdown.Item>
|
|
141
|
-
}
|
|
135
|
+
<Button.UI onClick={handleUnpin}>
|
|
136
|
+
<Icon.UI name="pin" size={1/1.5} />
|
|
137
|
+
</Button.UI>
|
|
142
138
|
|
|
143
|
-
|
|
144
|
-
</Dropdown.UI>
|
|
139
|
+
}
|
|
145
140
|
|
|
141
|
+
<Dropdown.UI directionX='left'>
|
|
142
|
+
<>
|
|
143
|
+
{item.is_unread &&
|
|
144
|
+
<Dropdown.Item onClick={handleRead}>Mark as read</Dropdown.Item>
|
|
145
|
+
}
|
|
146
|
+
{!item.is_unread &&
|
|
147
|
+
<Dropdown.Item onClick={handleUnread}>Mark as unread</Dropdown.Item>
|
|
148
|
+
}
|
|
149
|
+
</>
|
|
150
|
+
<>
|
|
151
|
+
{item.is_pinned &&
|
|
152
|
+
<Dropdown.Item onClick={handleUnpin}>Unpin</Dropdown.Item>
|
|
153
|
+
}
|
|
154
|
+
{!item.is_pinned &&
|
|
155
|
+
<Dropdown.Item onClick={handlePin}>Pin</Dropdown.Item>
|
|
156
|
+
}
|
|
157
|
+
</>
|
|
158
|
+
{item.type === ChatRoom &&
|
|
159
|
+
<Dropdown.Item onClick={handleLeaveConversation}>Leave conversation</Dropdown.Item>
|
|
160
|
+
}
|
|
146
161
|
|
|
162
|
+
{/* <li><Button.UI onClick={handleStar}>Star</Button.UI></li> */}
|
|
163
|
+
</Dropdown.UI>
|
|
147
164
|
|
|
148
|
-
|
|
165
|
+
</div>
|
|
149
166
|
</div>
|
|
150
167
|
)
|
|
151
168
|
}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import React, { useContext, useEffect } from "react";
|
|
1
|
+
import React, { useContext, useEffect, useState, useRef, useCallback } from "react";
|
|
2
2
|
import { WeavyContext } from "../contexts/WeavyContext";
|
|
3
3
|
import Button from '../ui/Button';
|
|
4
|
+
import Spinner from '../ui/Spinner';
|
|
4
5
|
import Icon from '../ui/Icon';
|
|
5
6
|
import useMutateExternalBlobs from '../hooks/useMutateExternalBlobs';
|
|
6
|
-
import
|
|
7
|
+
import Overlay from '../ui/Overlay';
|
|
8
|
+
import WeavyPostal from "../utils/postal-parent";
|
|
7
9
|
|
|
8
10
|
type Props = {
|
|
9
11
|
onFileAdded: Function
|
|
@@ -12,72 +14,73 @@ type Props = {
|
|
|
12
14
|
const FileBrowser = ({ onFileAdded }: Props) => {
|
|
13
15
|
|
|
14
16
|
const { options } = useContext(WeavyContext);
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
+
const [modalOpen, setModalOpen] = useState(false);
|
|
18
|
+
const [visible, setVisible] = useState(false);
|
|
19
|
+
const [frameSrc, setFrameSrc] = useState("");
|
|
17
20
|
const addExternalBlobs = useMutateExternalBlobs();
|
|
21
|
+
const fileBrowserUrl = options?.filebrowserUrl || "";
|
|
22
|
+
|
|
23
|
+
const frameRef = useCallback((node: HTMLIFrameElement | null) => {
|
|
24
|
+
if (node !== null && node.contentWindow != null) {
|
|
25
|
+
WeavyPostal.registerContentWindow(node.contentWindow.self, "weavy-filebrowser", "wy-filebrowser", new URL(fileBrowserUrl).origin);
|
|
26
|
+
}
|
|
27
|
+
}, []);
|
|
18
28
|
|
|
19
29
|
useEffect(() => {
|
|
20
|
-
window.
|
|
30
|
+
const origin = window.top?.document.location.origin;
|
|
31
|
+
|
|
32
|
+
const filebrowserSrc = fileBrowserUrl + "?origin=" + origin + "&v=X&t=" + Date.now().toString() + "&weavyId=wy-filebrowser";
|
|
21
33
|
|
|
34
|
+
setFrameSrc(filebrowserSrc)
|
|
35
|
+
|
|
36
|
+
WeavyPostal.on("add-external-blobs", handleFiles);
|
|
37
|
+
WeavyPostal.on("request:file-browser-close", handleClose);
|
|
22
38
|
|
|
23
39
|
return () => {
|
|
24
|
-
|
|
40
|
+
WeavyPostal.off("add-external-blobs", handleFiles);
|
|
41
|
+
WeavyPostal.off("request:file-browser-close", handleClose);
|
|
25
42
|
}
|
|
26
|
-
}, []);
|
|
43
|
+
}, [onFileAdded]);
|
|
27
44
|
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
switch (messageData.name) {
|
|
32
|
-
case "addExternalBlobs":
|
|
33
|
-
var result = await addExternalBlobs.mutateAsync({ blobs: messageData.blobs });
|
|
34
|
-
onFileAdded(result);
|
|
35
|
-
closeFilebrowser();
|
|
36
|
-
break;
|
|
37
|
-
case "file-browser-close":
|
|
38
|
-
closeFilebrowser();
|
|
39
|
-
break;
|
|
40
|
-
}
|
|
45
|
+
const toggleModal = (open: boolean) => {
|
|
46
|
+
setModalOpen(open);
|
|
41
47
|
}
|
|
42
48
|
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
49
|
+
const handleFiles = async (e: Event, message: any) => {
|
|
50
|
+
var result = await addExternalBlobs.mutateAsync({ blobs: message.blobs });
|
|
51
|
+
onFileAdded(result);
|
|
52
|
+
closeFilebrowser();
|
|
48
53
|
}
|
|
49
54
|
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
if (!fb) {
|
|
54
|
-
const origin = window.top?.document.location.origin;
|
|
55
|
-
const fileBrowserUrl = options?.filebrowserUrl;
|
|
56
|
-
const filebrowserSrc = fileBrowserUrl + "?origin=" + origin + "&v=X&t=" + Date.now().toString() + "&weavyId=-1";
|
|
57
|
-
|
|
58
|
-
let $filebrowserFrame = document.createElement("iframe");
|
|
59
|
-
$filebrowserFrame.id = "weavy-filebrowser";
|
|
60
|
-
$filebrowserFrame.name = "weavy-filebrowser";
|
|
61
|
-
$filebrowserFrame.src = filebrowserSrc;
|
|
62
|
-
$filebrowserFrame.className = "wy-filebrowser-frame";
|
|
63
|
-
$filebrowserFrame.style.cssText = "position: fixed; top: 0; left: 0; height: 100%; width: 100%; background: rgba(1,1,1,.4); z-index: 10000; display:none"
|
|
64
|
-
|
|
65
|
-
window.top?.document.body.appendChild($filebrowserFrame);
|
|
55
|
+
const handleClose = () => {
|
|
56
|
+
closeFilebrowser();
|
|
57
|
+
}
|
|
66
58
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
59
|
+
const closeFilebrowser = () => {
|
|
60
|
+
setModalOpen(false);
|
|
61
|
+
setVisible(false);
|
|
62
|
+
}
|
|
70
63
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}
|
|
64
|
+
const handleFrameLoad = () => {
|
|
65
|
+
setVisible(true);
|
|
74
66
|
}
|
|
75
67
|
|
|
76
68
|
return (
|
|
77
69
|
<>
|
|
78
|
-
{options?.enableCloudFiles &&
|
|
79
|
-
|
|
80
|
-
|
|
70
|
+
{options?.enableCloudFiles &&
|
|
71
|
+
<>
|
|
72
|
+
<Button.UI onClick={() => toggleModal(true)} title="Add file from cloud"><Icon.UI name="cloud" /></Button.UI>
|
|
73
|
+
|
|
74
|
+
<Overlay.UI isOpen={modalOpen} className="wy-modal wy-panel wy-loaded">
|
|
75
|
+
{!visible &&
|
|
76
|
+
<Spinner.UI overlay={true} />
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
<iframe ref={frameRef} onLoad={handleFrameLoad} src={frameSrc} className="wy-panel-frame" id="weavy-filebrowser" name="weavy-filebrowser"></iframe>
|
|
80
|
+
|
|
81
|
+
</Overlay.UI>
|
|
82
|
+
</>
|
|
83
|
+
}
|
|
81
84
|
</>
|
|
82
85
|
)
|
|
83
86
|
}
|
|
@@ -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
|
</>
|