@weavy/uikit-react 11.1.0 → 13.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.
Files changed (256) hide show
  1. package/.github/workflows/publish.yml +1 -1
  2. package/README.md +3 -4
  3. package/changelog.md +57 -0
  4. package/dist/cjs/index.js +28 -6
  5. package/dist/cjs/index.js.map +1 -1
  6. package/dist/cjs/types/client/WeavyClient.d.ts +8 -1
  7. package/dist/cjs/types/components/Attachment.d.ts +2 -1
  8. package/dist/cjs/types/components/Chat.d.ts +1 -1
  9. package/dist/cjs/types/components/Image.d.ts +2 -0
  10. package/dist/cjs/types/components/PdfViewer.d.ts +8 -0
  11. package/dist/cjs/types/components/Preview.d.ts +56 -0
  12. package/dist/cjs/types/contexts/MessengerContext.d.ts +1 -2
  13. package/dist/cjs/types/contexts/PreviewContext.d.ts +2 -1
  14. package/dist/cjs/types/contexts/WeavyContext.d.ts +2 -3
  15. package/dist/cjs/types/types/Chat.d.ts +1 -1
  16. package/dist/cjs/types/types/Messenger.d.ts +0 -1
  17. package/dist/cjs/types/types/types.d.ts +18 -8
  18. package/dist/cjs/types/ui/Spinner.d.ts +9 -0
  19. package/dist/cjs/types/utils/fileUtilities.d.ts +13 -1
  20. package/dist/css/weavy-chat.css +2860 -0
  21. package/dist/css/weavy-messenger.css +3217 -0
  22. package/dist/css/weavy.css +3217 -0
  23. package/dist/esm/index.js +28 -6
  24. package/dist/esm/index.js.map +1 -1
  25. package/dist/esm/types/client/WeavyClient.d.ts +8 -1
  26. package/dist/esm/types/components/Attachment.d.ts +2 -1
  27. package/dist/esm/types/components/Chat.d.ts +1 -1
  28. package/dist/esm/types/components/Image.d.ts +2 -0
  29. package/dist/esm/types/components/PdfViewer.d.ts +8 -0
  30. package/dist/esm/types/components/Preview.d.ts +56 -0
  31. package/dist/esm/types/contexts/MessengerContext.d.ts +1 -2
  32. package/dist/esm/types/contexts/PreviewContext.d.ts +2 -1
  33. package/dist/esm/types/contexts/WeavyContext.d.ts +2 -3
  34. package/dist/esm/types/types/Chat.d.ts +1 -1
  35. package/dist/esm/types/types/Messenger.d.ts +0 -1
  36. package/dist/esm/types/types/types.d.ts +18 -8
  37. package/dist/esm/types/ui/Spinner.d.ts +9 -0
  38. package/dist/esm/types/utils/fileUtilities.d.ts +13 -1
  39. package/dist/index.d.ts +15 -9
  40. package/package.json +14 -4
  41. package/rollup.config.js +3 -3
  42. package/src/client/WeavyClient.ts +105 -24
  43. package/src/components/Attachment.tsx +8 -8
  44. package/src/components/Avatar.tsx +2 -3
  45. package/src/components/Chat.tsx +13 -17
  46. package/src/components/Conversation.tsx +23 -32
  47. package/src/components/ConversationBadge.tsx +1 -2
  48. package/src/components/ConversationForm.tsx +11 -18
  49. package/src/components/ConversationList.tsx +4 -5
  50. package/src/components/ConversationListItem.tsx +11 -13
  51. package/src/components/FileBrowser.tsx +2 -3
  52. package/src/components/Image.tsx +39 -7
  53. package/src/components/MeetingCard.tsx +7 -8
  54. package/src/components/Message.tsx +13 -14
  55. package/src/components/Messages.tsx +7 -8
  56. package/src/components/Messenger.tsx +5 -6
  57. package/src/components/NewConversation.tsx +5 -7
  58. package/src/components/PdfViewer.tsx +276 -0
  59. package/src/components/Presence.tsx +2 -2
  60. package/src/components/Preview.tsx +355 -0
  61. package/src/components/Reactions.tsx +8 -8
  62. package/src/components/SearchUsers.tsx +19 -18
  63. package/src/components/SeenBy.tsx +1 -2
  64. package/src/contexts/MessengerContext.tsx +4 -12
  65. package/src/contexts/PreviewContext.tsx +89 -17
  66. package/src/contexts/WeavyContext.tsx +15 -5
  67. package/src/hooks/useBadge.ts +2 -6
  68. package/src/hooks/useChat.ts +3 -14
  69. package/src/hooks/useConversation.ts +1 -8
  70. package/src/hooks/useConversations.ts +1 -7
  71. package/src/hooks/useFileUploader.ts +6 -8
  72. package/src/hooks/useMembers.ts +1 -7
  73. package/src/hooks/useMessages.ts +1 -7
  74. package/src/hooks/useMutateChat.ts +6 -11
  75. package/src/hooks/useMutateConversation.ts +7 -10
  76. package/src/hooks/useMutateConversationName.ts +10 -12
  77. package/src/hooks/useMutateDeleteReaction.ts +3 -8
  78. package/src/hooks/useMutateExternalBlobs.ts +6 -11
  79. package/src/hooks/useMutateMeeting.ts +6 -11
  80. package/src/hooks/useMutateMembers.ts +8 -13
  81. package/src/hooks/useMutateMessage.ts +10 -15
  82. package/src/hooks/useMutatePinned.ts +3 -8
  83. package/src/hooks/useMutateReaction.ts +6 -12
  84. package/src/hooks/useMutateRead.ts +1 -10
  85. package/src/hooks/useMutateRemoveMembers.ts +7 -12
  86. package/src/hooks/useMutateTyping.ts +6 -11
  87. package/src/hooks/usePresence.ts +4 -5
  88. package/src/hooks/useReactions.ts +0 -1
  89. package/src/hooks/useSearchUsers.ts +1 -6
  90. package/src/hooks/useUser.ts +3 -14
  91. package/src/index.ts +2 -2
  92. package/src/scss/theme/_alert.scss +73 -0
  93. package/src/scss/theme/_appbar.scss +114 -0
  94. package/src/scss/theme/_attachments.scss +74 -0
  95. package/src/scss/theme/_avatar.scss +54 -0
  96. package/src/scss/theme/_badge.scss +47 -0
  97. package/src/scss/theme/_buttons.scss +96 -0
  98. package/src/scss/theme/_card.scss +7 -0
  99. package/src/scss/theme/_checkbox.scss +56 -0
  100. package/src/scss/theme/_cm-editor.scss +42 -0
  101. package/src/scss/theme/_code-vscode-dark.scss +184 -0
  102. package/src/scss/theme/_code-vscode-light.scss +179 -0
  103. package/src/scss/theme/_code.scss +12 -0
  104. package/src/scss/theme/_colors.scss +520 -0
  105. package/src/scss/theme/_config.scss +6 -0
  106. package/src/scss/theme/_content.scss +15 -0
  107. package/src/scss/theme/_conversations.scss +91 -0
  108. package/src/scss/theme/_dropdown.scss +86 -0
  109. package/src/scss/theme/_emoji.scss +5 -0
  110. package/src/scss/theme/_filebrowser.scss +26 -0
  111. package/src/scss/theme/_files.scss +140 -0
  112. package/src/scss/theme/_icons.scss +62 -0
  113. package/src/scss/theme/_image-grid.scss +63 -0
  114. package/src/scss/theme/_inputs.scss +28 -0
  115. package/src/scss/theme/_message-editor.scss +90 -0
  116. package/src/scss/theme/_messages.scss +238 -0
  117. package/src/scss/theme/_nav.scss +52 -0
  118. package/src/scss/theme/_overlays.scss +157 -0
  119. package/src/scss/theme/_pager.scss +19 -0
  120. package/src/scss/theme/_palette.scss +165 -0
  121. package/src/scss/theme/_pane.scss +16 -0
  122. package/src/scss/theme/_panels.scss +141 -0
  123. package/src/scss/theme/_picker-list.scss +37 -0
  124. package/src/scss/theme/_preview-code.scss +5 -0
  125. package/src/scss/theme/_preview-embed.scss +38 -0
  126. package/src/scss/theme/_preview-html.scss +7 -0
  127. package/src/scss/theme/_preview-icon.scss +41 -0
  128. package/src/scss/theme/_preview-image.scss +86 -0
  129. package/src/scss/theme/_preview-media.scss +28 -0
  130. package/src/scss/theme/_preview-pdf.scss +838 -0
  131. package/src/scss/theme/_preview-text.scss +5 -0
  132. package/src/scss/theme/_preview.scss +110 -0
  133. package/src/scss/theme/_reactions.scss +58 -0
  134. package/src/scss/theme/_reboot.scss +41 -0
  135. package/src/scss/theme/_root.scss +2 -0
  136. package/src/scss/theme/_scroll.scss +55 -0
  137. package/src/scss/theme/_search.scss +68 -0
  138. package/src/scss/theme/_spinner.scss +63 -0
  139. package/src/scss/theme/_tables.scss +53 -0
  140. package/src/scss/theme/_toasts.scss +47 -0
  141. package/src/scss/theme/_turbo.scss +17 -0
  142. package/src/scss/theme/_typing.scss +26 -0
  143. package/src/scss/theme/_variables.scss +139 -0
  144. package/src/scss/theme/bootstrap/_accordion.scss +146 -0
  145. package/src/scss/theme/bootstrap/_alert.scss +71 -0
  146. package/src/scss/theme/bootstrap/_badge.scss +38 -0
  147. package/src/scss/theme/bootstrap/_breadcrumb.scss +40 -0
  148. package/src/scss/theme/bootstrap/_button-group.scss +142 -0
  149. package/src/scss/theme/bootstrap/_buttons.scss +186 -0
  150. package/src/scss/theme/bootstrap/_card.scss +234 -0
  151. package/src/scss/theme/bootstrap/_carousel.scss +229 -0
  152. package/src/scss/theme/bootstrap/_close.scss +40 -0
  153. package/src/scss/theme/bootstrap/_containers.scss +41 -0
  154. package/src/scss/theme/bootstrap/_dropdown.scss +248 -0
  155. package/src/scss/theme/bootstrap/_forms.scss +9 -0
  156. package/src/scss/theme/bootstrap/_functions.scss +302 -0
  157. package/src/scss/theme/bootstrap/_grid.scss +33 -0
  158. package/src/scss/theme/bootstrap/_helpers.scss +10 -0
  159. package/src/scss/theme/bootstrap/_images.scss +42 -0
  160. package/src/scss/theme/bootstrap/_list-group.scss +191 -0
  161. package/src/scss/theme/bootstrap/_maps.scss +54 -0
  162. package/src/scss/theme/bootstrap/_mixins.scss +43 -0
  163. package/src/scss/theme/bootstrap/_modal.scss +237 -0
  164. package/src/scss/theme/bootstrap/_nav.scss +172 -0
  165. package/src/scss/theme/bootstrap/_navbar.scss +276 -0
  166. package/src/scss/theme/bootstrap/_offcanvas.scss +143 -0
  167. package/src/scss/theme/bootstrap/_pagination.scss +109 -0
  168. package/src/scss/theme/bootstrap/_placeholders.scss +51 -0
  169. package/src/scss/theme/bootstrap/_popover.scss +196 -0
  170. package/src/scss/theme/bootstrap/_progress.scss +59 -0
  171. package/src/scss/theme/bootstrap/_reboot.scss +610 -0
  172. package/src/scss/theme/bootstrap/_root.scss +73 -0
  173. package/src/scss/theme/bootstrap/_spinners.scss +85 -0
  174. package/src/scss/theme/bootstrap/_tables.scss +164 -0
  175. package/src/scss/theme/bootstrap/_toasts.scss +70 -0
  176. package/src/scss/theme/bootstrap/_tooltip.scss +120 -0
  177. package/src/scss/theme/bootstrap/_transitions.scss +27 -0
  178. package/src/scss/theme/bootstrap/_type.scss +106 -0
  179. package/src/scss/theme/bootstrap/_utilities.scss +647 -0
  180. package/src/scss/theme/bootstrap/_variables.scss +1633 -0
  181. package/src/scss/theme/bootstrap/forms/_floating-labels.scss +74 -0
  182. package/src/scss/theme/bootstrap/forms/_form-check.scss +175 -0
  183. package/src/scss/theme/bootstrap/forms/_form-control.scss +194 -0
  184. package/src/scss/theme/bootstrap/forms/_form-range.scss +91 -0
  185. package/src/scss/theme/bootstrap/forms/_form-select.scss +71 -0
  186. package/src/scss/theme/bootstrap/forms/_form-text.scss +11 -0
  187. package/src/scss/theme/bootstrap/forms/_input-group.scss +129 -0
  188. package/src/scss/theme/bootstrap/forms/_labels.scss +36 -0
  189. package/src/scss/theme/bootstrap/forms/_validation.scss +12 -0
  190. package/src/scss/theme/bootstrap/helpers/_clearfix.scss +3 -0
  191. package/src/scss/theme/bootstrap/helpers/_color-bg.scss +10 -0
  192. package/src/scss/theme/bootstrap/helpers/_colored-links.scss +12 -0
  193. package/src/scss/theme/bootstrap/helpers/_position.scss +36 -0
  194. package/src/scss/theme/bootstrap/helpers/_ratio.scss +26 -0
  195. package/src/scss/theme/bootstrap/helpers/_stacks.scss +15 -0
  196. package/src/scss/theme/bootstrap/helpers/_stretched-link.scss +15 -0
  197. package/src/scss/theme/bootstrap/helpers/_text-truncation.scss +7 -0
  198. package/src/scss/theme/bootstrap/helpers/_visually-hidden.scss +8 -0
  199. package/src/scss/theme/bootstrap/helpers/_vr.scss +8 -0
  200. package/src/scss/theme/bootstrap/mixins/_alert.scss +15 -0
  201. package/src/scss/theme/bootstrap/mixins/_backdrop.scss +14 -0
  202. package/src/scss/theme/bootstrap/mixins/_banner.scss +9 -0
  203. package/src/scss/theme/bootstrap/mixins/_border-radius.scss +78 -0
  204. package/src/scss/theme/bootstrap/mixins/_box-shadow.scss +18 -0
  205. package/src/scss/theme/bootstrap/mixins/_breakpoints.scss +127 -0
  206. package/src/scss/theme/bootstrap/mixins/_buttons.scss +70 -0
  207. package/src/scss/theme/bootstrap/mixins/_caret.scss +64 -0
  208. package/src/scss/theme/bootstrap/mixins/_clearfix.scss +9 -0
  209. package/src/scss/theme/bootstrap/mixins/_color-scheme.scss +7 -0
  210. package/src/scss/theme/bootstrap/mixins/_container.scss +11 -0
  211. package/src/scss/theme/bootstrap/mixins/_deprecate.scss +10 -0
  212. package/src/scss/theme/bootstrap/mixins/_forms.scss +152 -0
  213. package/src/scss/theme/bootstrap/mixins/_gradients.scss +47 -0
  214. package/src/scss/theme/bootstrap/mixins/_grid.scss +151 -0
  215. package/src/scss/theme/bootstrap/mixins/_image.scss +16 -0
  216. package/src/scss/theme/bootstrap/mixins/_list-group.scss +24 -0
  217. package/src/scss/theme/bootstrap/mixins/_lists.scss +7 -0
  218. package/src/scss/theme/bootstrap/mixins/_pagination.scss +10 -0
  219. package/src/scss/theme/bootstrap/mixins/_reset-text.scss +17 -0
  220. package/src/scss/theme/bootstrap/mixins/_resize.scss +6 -0
  221. package/src/scss/theme/bootstrap/mixins/_table-variants.scss +24 -0
  222. package/src/scss/theme/bootstrap/mixins/_text-truncate.scss +8 -0
  223. package/src/scss/theme/bootstrap/mixins/_transition.scss +26 -0
  224. package/src/scss/theme/bootstrap/mixins/_utilities.scss +97 -0
  225. package/src/scss/theme/bootstrap/mixins/_visually-hidden.scss +29 -0
  226. package/src/scss/theme/bootstrap/utilities/_api.scss +47 -0
  227. package/src/scss/theme/bootstrap/vendor/_rfs.scss +354 -0
  228. package/src/scss/theme/bs/_badge.scss +20 -0
  229. package/src/scss/theme/bs/_buttons.scss +185 -0
  230. package/src/scss/theme/bs/_dropdown.scss +86 -0
  231. package/src/scss/theme/bs/_forms.scss +161 -0
  232. package/src/scss/theme/bs/_list-group.scss +73 -0
  233. package/src/scss/theme/bs/_tables.scss +46 -0
  234. package/src/scss/theme/fonts/_fontmapping-roboto.scss +129 -0
  235. package/src/scss/theme/fonts/_fontmapping-segoe-ui.scss +127 -0
  236. package/src/scss/theme/fonts/_index.scss +2 -0
  237. package/src/scss/theme/mixins/_backdrop.scss +13 -0
  238. package/src/scss/theme/mixins/_palette.scss +165 -0
  239. package/src/scss/theme/mixins/_position.scss +33 -0
  240. package/src/scss/theme/mixins/_scrollbar.scss +110 -0
  241. package/src/scss/weavy-chat.scss +32 -0
  242. package/src/scss/weavy-messenger.scss +61 -0
  243. package/src/scss/weavy.scss +2 -0
  244. package/src/types/Chat.ts +1 -1
  245. package/src/types/Messenger.ts +1 -1
  246. package/src/types/types.ts +20 -11
  247. package/src/ui/Button.tsx +3 -4
  248. package/src/ui/Dropdown.tsx +4 -5
  249. package/src/ui/Icon.tsx +75 -39
  250. package/src/ui/Overlay.tsx +2 -3
  251. package/src/ui/Spinner.tsx +18 -0
  252. package/src/utils/fileUtilities.ts +166 -72
  253. package/src/utils/scrollbarDetection.js +48 -0
  254. package/dist/cjs/types/utils/styles.d.ts +0 -17
  255. package/dist/esm/types/utils/styles.d.ts +0 -17
  256. package/src/utils/styles.ts +0 -42
@@ -2,18 +2,25 @@ import React, { createContext, useEffect, useState } from "react";
2
2
  import Overlay from '../ui/Overlay';
3
3
  import Button from '../ui/Button';
4
4
  import Icon from '../ui/Icon';
5
- import { prefix as wy } from "../utils/styles";
5
+ import Preview from '../components/Preview';
6
+ import { getIcon, getExtension } from "../utils/fileUtilities";
6
7
 
7
8
  export const PreviewContext = createContext<PreviewContextProps>({
8
9
  openPreview: Function,
9
10
  closePreview: Function
10
11
  });
11
12
 
13
+ function allowedKeyTarget(e: any) {
14
+ var notInputField = !e.target.matches("input, textarea, select") && !e.target.closest('[contenteditable="true"]');
15
+ return notInputField;
16
+ }
17
+
12
18
  type Props = {
19
+ client: any,
13
20
  children: React.ReactNode
14
21
  }
15
22
 
16
- const PreviewProvider = ({ children }: Props) => {
23
+ const PreviewProvider = ({ client, children }: Props) => {
17
24
  const [modalPreviewOpen, setModalPreviewOpen] = useState<boolean>(false);
18
25
  const [attachments, setAttachments] = useState<AttachmentType[]>([]);
19
26
  const [activeAttachment, setActiveAttchment] = useState<AttachmentType>();
@@ -54,50 +61,115 @@ const PreviewProvider = ({ children }: Props) => {
54
61
  }
55
62
 
56
63
  const handleDownload = () => {
57
- window.open(`${activeAttachment?.download_url}&d=1`, "_blank");
64
+ window.open(`${activeAttachment?.download_url}&d=1`, "_top");
65
+ }
66
+
67
+ const handleExternal = () => {
68
+ window.open(`${activeAttachment?.external_url}`, "_blank");
69
+ }
70
+
71
+ const handleApplication = () => {
72
+ // TODO: Change to webdav-url
73
+ window.open(`${activeAttachment?.application_url}`, "_top");
74
+ }
75
+
76
+ // Keyboard handlers
77
+ useEffect(() => {
78
+ if (activeAttachment) {
79
+ const handleKey = (e: any) => {
80
+ if (e.which === 27) { // ESC
81
+ e.stopImmediatePropagation();
82
+ closePreview()
83
+ } else if (e.which === 37) { // LEFT
84
+ if (allowedKeyTarget(e)) {
85
+ setCurrentAttachmentId(previousAttachmentId);
86
+ }
87
+ } else if (e.which === 39) { // RIGHT
88
+ if (allowedKeyTarget(e)) {
89
+ setCurrentAttachmentId(nextAttachmentId);
90
+ }
91
+ }
92
+ };
93
+
94
+ document.addEventListener("keyup", handleKey);
95
+
96
+ return () => {
97
+ // cleanup
98
+ document.removeEventListener("keyup", handleKey);
99
+ }
100
+ }
101
+
102
+ }, [activeAttachment])
103
+
104
+
105
+ let activeExt: string = getExtension(activeAttachment?.name || '');
106
+ let activeIcon: string = getIcon(activeAttachment?.name || '').icon;
107
+
108
+ let activeSrc = activeAttachment?.preview_url || activeAttachment?.download_url || '';
109
+
110
+ // Let GIF and SVG display raw content
111
+ let animatedImage = activeAttachment?.preview_format === "image" && (activeExt === ".gif" || activeExt === ".svg");
112
+ if (animatedImage) {
113
+ activeSrc = activeAttachment?.download_url || '';
58
114
  }
59
115
 
60
116
  return (
61
117
  <>
62
-
63
118
  <PreviewContext.Provider value={{ openPreview: openPreview, closePreview: closePreview }}>
64
119
  {children}
65
120
  </PreviewContext.Provider>
66
121
 
67
- <Overlay.UI isOpen={modalPreviewOpen} className={wy('dark')}>
68
- <header className={wy('appbars')}>
69
- <nav className={wy('appbar')}>
122
+ <Overlay.UI isOpen={modalPreviewOpen} className="wy-dark">
123
+ <header className="wy-appbars">
124
+ <nav className="wy-appbar">
70
125
  <Button.UI onClick={closePreview}><Icon.UI name='close' /></Button.UI>
71
- <div className={wy('appbar-text')}>
126
+ <div className="wy-appbar-text">
72
127
  {activeAttachment &&
73
128
  <span>{activeAttachment.name}</span>
74
129
  }
75
130
 
76
131
  </div>
77
- <Button.UI onClick={handleDownload}><Icon.UI name='download' /></Button.UI>
132
+ <div className="wy-appbar-buttons">
133
+ {activeAttachment?.application_url ?
134
+ <Button.UI onClick={handleApplication} title={`Open in app`}><Icon.UI name={activeIcon} /></Button.UI>
135
+ :
136
+ activeAttachment?.external_url ?
137
+ <Button.UI onClick={handleExternal} title={`Open in ${activeAttachment.provider}`}><Icon.UI name={activeIcon} /></Button.UI>
138
+ :
139
+ <Button.UI onClick={handleDownload}><Icon.UI name='download' /></Button.UI>
140
+ }
141
+ </div>
142
+
78
143
  </nav>
79
144
  </header>
80
- <div style={{ display: "flex", alignItems: "center", justifyContent: "center", height: "100%" }}>
81
-
145
+ <div className="wy-preview wy-scroll-y wy-scroll-x">
82
146
  {activeAttachment &&
83
147
  <>
84
148
  {previousAttachmentId &&
85
- <Button.UI onClick={handlePrevious} style={{ position: "absolute", top: "50%", left: "0" }}><Icon.UI name="previous" /></Button.UI>
149
+ <nav className="wy-nav-prev"><Button.UI onClick={handlePrevious}><Icon.UI name="previous" /></Button.UI></nav>
86
150
  }
87
151
  {nextAttachmentId &&
88
- <Button.UI onClick={handleNext} style={{ position: "absolute", top: "50%", right: "0", }}><Icon.UI name="next" /></Button.UI>
152
+ <nav className="wy-nav-next"><Button.UI onClick={handleNext}><Icon.UI name="next" /></Button.UI></nav>
89
153
  }
90
-
91
- <img style={{ maxWidth: "100%" }} src={activeAttachment.preview_url} />
154
+ <Preview
155
+ client={client}
156
+ src={activeSrc}
157
+ link={activeAttachment.external_url}
158
+ format={activeAttachment.preview_format}
159
+ name={activeAttachment.name}
160
+ icon={activeIcon}
161
+ width={activeAttachment.width}
162
+ height={activeAttachment.height}
163
+ mediaType={activeAttachment.media_type}
164
+ provider={activeAttachment.provider}
165
+ />
92
166
  </>
93
167
  }
94
-
95
168
  </div>
96
169
  </Overlay.UI>
97
170
 
98
171
  </>
99
172
 
100
-
101
173
  )
102
174
  };
103
175
 
@@ -7,7 +7,7 @@ import utc from 'dayjs/plugin/utc';
7
7
  import timezone from 'dayjs/plugin/timezone';
8
8
  import localizedFormat from 'dayjs/plugin/localizedFormat';
9
9
  import PreviewProvider from "./PreviewContext";
10
- import WeavyClient from "../client/WeavyClient";
10
+ import detectScrollbars from '../utils/scrollbarDetection';
11
11
 
12
12
  dayjs.extend(relativeTime);
13
13
  dayjs.extend(utc);
@@ -20,7 +20,7 @@ export const WeavyContext = createContext<WeavyContextProps>({
20
20
  options: {}
21
21
  });
22
22
 
23
- type Props = {
23
+ type WeavyProviderProperties = {
24
24
  children: React.ReactNode,
25
25
  client: WeavyClient,
26
26
  options?: WeavyContextOptions
@@ -34,24 +34,34 @@ const queryClient = new QueryClient({
34
34
  },
35
35
  })
36
36
 
37
- const WeavyProvider = ({ children, client, options }: Props) => {
37
+ const WeavyProvider = ({ children, client, options }: WeavyProviderProperties) => {
38
38
 
39
39
  let defaultOptions: WeavyContextOptions = {
40
40
  zoomAuthenticationUrl: undefined,
41
41
  teamsAuthenticationUrl: undefined,
42
42
  enableCloudFiles: true,
43
- filebrowserUrl: "https://filebrowser.weavycloud.com/index10.html"
43
+ enableScrollbarDetection: true,
44
+ filebrowserUrl: "https://filebrowser.weavycloud.com/index10.html",
45
+ reactions: ['😍', '😎', '😉', '😜', '👍']
44
46
  };
45
47
 
46
48
  let opts = { ...defaultOptions, ...options }
47
49
 
50
+ if (opts.enableScrollbarDetection) {
51
+ detectScrollbars();
52
+ }
53
+
54
+ if(!client){
55
+ queryClient.clear();
56
+ }
57
+
48
58
  return (
49
59
  <>
50
60
  {client &&
51
61
  <QueryClientProvider client={queryClient}>
52
62
  <WeavyContext.Provider value={{ client, options: opts }}>
53
63
  <UserProvider client={client}>
54
- <PreviewProvider>
64
+ <PreviewProvider client={client}>
55
65
  {children}
56
66
  </PreviewProvider>
57
67
  </UserProvider>
@@ -12,12 +12,8 @@ export default function useBadge() {
12
12
 
13
13
  const getBadge = async () => {
14
14
 
15
- const response = await fetch(client.url + "/api/conversations/badge", {
16
- headers: {
17
- "content-type": "application/json",
18
- "Authorization": "Bearer " + await client.tokenFactory()
19
- }
20
- });
15
+ const response = await client.get("/api/conversations/badge")
16
+
21
17
  if(response.ok){
22
18
  const data = await response.json();
23
19
  return data;
@@ -11,20 +11,9 @@ export default function useChat(id: string, options: any) {
11
11
  }
12
12
 
13
13
  const getConversation = async () => {
14
-
15
- const response = await fetch(client.url + "/api/apps/idf/" + id, {
16
- headers: {
17
- "content-type": "application/json",
18
- "Authorization": "Bearer " + await client.tokenFactory()
19
- }
20
- });
21
- if(response.ok){
22
- const data = await response.json();
23
- return data;
24
- }
25
-
26
- return null;
27
-
14
+ const response = await client.get("/api/apps/" + id);
15
+ const data = await response.json();
16
+ return data;
28
17
  };
29
18
 
30
19
 
@@ -1,5 +1,4 @@
1
1
  import { useContext } from "react";
2
-
3
2
  import { useQuery } from "react-query";
4
3
  import { WeavyContext } from "../contexts/WeavyContext";
5
4
 
@@ -12,13 +11,7 @@ export default function useConversation(id: number | null, options: any) {
12
11
  }
13
12
 
14
13
  const getConversation = async () => {
15
-
16
- const response = await fetch(client.url + "/api/conversations/" + id, {
17
- headers: {
18
- "content-type": "application/json",
19
- "Authorization": "Bearer " + await client.tokenFactory()
20
- }
21
- });
14
+ const response = await client.get("/api/conversations/" + id);
22
15
  const data = await response.json();
23
16
  return data;
24
17
  };
@@ -11,13 +11,7 @@ export default function useConversations() {
11
11
  }
12
12
 
13
13
  const getConversations = async () => {
14
-
15
- const response = await fetch(client.url + "/api/conversations?contextual=false", {
16
- headers: {
17
- "content-type": "application/json",
18
- "Authorization": "Bearer " + await client.tokenFactory()
19
- }
20
- });
14
+ const response = await client.get("/api/conversations?contextual=false");
21
15
  const data = await response.json();
22
16
  return data;
23
17
  };
@@ -17,13 +17,11 @@ export default function useFileUploader(callback: Function) {
17
17
  const formData = new FormData();
18
18
  formData.append('blob', request.file);
19
19
 
20
- var response = await fetch(client.url + "/api/blobs", {
21
- method: 'POST',
22
- body: formData,
23
- headers: {
24
- "Authorization": "Bearer " + await client.tokenFactory()
25
- }
26
- });
20
+
21
+ const response = await client.post("/api/blobs",
22
+ "POST",
23
+ formData,
24
+ "");
27
25
 
28
26
  var uploaded = await response.json();
29
27
  callback(uploaded);
@@ -32,7 +30,7 @@ export default function useFileUploader(callback: Function) {
32
30
  onError: (e: any) => {
33
31
 
34
32
  },
35
- onSuccess: (data: any, variables: any) => {
33
+ onSuccess: (data: any, variables: any) => {
36
34
  },
37
35
  }
38
36
  );
@@ -11,13 +11,7 @@ export default function useMembers(id: number | null, options: any) {
11
11
  }
12
12
 
13
13
  const getConversationMembers = async () => {
14
-
15
- const response = await fetch(client.url + "/api/apps/" + id + "/members", {
16
- headers: {
17
- "content-type": "application/json",
18
- "Authorization": "Bearer " + await client.tokenFactory()
19
- }
20
- });
14
+ const response = await client.get("/api/apps/" + id + "/members");
21
15
  const data = await response.json();
22
16
  return data;
23
17
  };
@@ -13,13 +13,7 @@ export default function useMessages(id: number | null, options: any) {
13
13
 
14
14
  const getMessages = async (opt: any) => {
15
15
  let skip = opt.pageParam || 0;
16
-
17
- const response = await fetch(client.url + "/api/apps/" + id + "/messages?orderby=createdat+desc&skip=" + skip + "&top=" + PAGE_SIZE, {
18
- headers: {
19
- "content-type": "application/json",
20
- "Authorization": "Bearer " + await client.tokenFactory()
21
- }
22
- });
16
+ const response = await client.get("/api/apps/" + id + "/messages?orderby=createdat+desc&skip=" + skip + "&top=" + PAGE_SIZE);
23
17
  let result = await response.json();
24
18
  result.data = result.data?.reverse() || [];
25
19
  return result;
@@ -21,17 +21,12 @@ export default function useMutateChat() {
21
21
  // create new conversation
22
22
  const mutateChat = async ({ identifier, members }: MutateProps) => {
23
23
 
24
- const response = await fetch(client.url + "/api/apps/", {
25
- method: "POST",
26
- body: JSON.stringify({
24
+ const response = await client.post("/api/apps/",
25
+ "POST",
26
+ JSON.stringify({
27
27
  identifier: identifier,
28
- members: members
29
- }),
30
- headers: {
31
- "content-type": "application/json",
32
- "Authorization": "Bearer " + await client.tokenFactory()
33
- }
34
- });
28
+ members: members
29
+ }));
35
30
 
36
31
  return response.json();
37
32
  };
@@ -39,6 +34,6 @@ export default function useMutateChat() {
39
34
  return useMutation(mutateChat, {
40
35
  onSuccess: () => {
41
36
  //queryClient.invalidateQueries("conversations");
42
- }
37
+ }
43
38
  });
44
39
  }
@@ -20,21 +20,18 @@ export default function useMutateConversation() {
20
20
  // create new conversation
21
21
  const mutateConversation = async ({ members }: MutateProps) => {
22
22
 
23
- const response = await fetch(client.url + "/api/conversations/", {
24
- method: "POST",
25
- body: JSON.stringify({ members: members }),
26
- headers: {
27
- "content-type": "application/json",
28
- "Authorization": "Bearer " + await client.tokenFactory()
29
- }
30
- });
23
+ const response = await client.post("/api/conversations/",
24
+ "POST",
25
+ JSON.stringify({
26
+ members: members
27
+ }));
31
28
 
32
29
  return response.json();
33
30
  };
34
31
 
35
32
  return useMutation(mutateConversation, {
36
33
  onSuccess: () => {
37
- queryClient.invalidateQueries("conversations");
38
- }
34
+ queryClient.invalidateQueries("conversations");
35
+ }
39
36
  });
40
37
  }
@@ -14,28 +14,26 @@ export default function useMutateConversationName() {
14
14
 
15
15
 
16
16
  type MutateProps = {
17
- id: number | null,
17
+ id: number | null,
18
18
  name: string
19
19
  }
20
20
 
21
21
  const mutateConversationName = async ({ id, name }: MutateProps) => {
22
22
 
23
- const response = await fetch(client.url + "/api/apps/" + id, {
24
- method: "PATCH",
25
- body: JSON.stringify({ name: name }),
26
- headers: {
27
- "content-type": "application/json",
28
- "Authorization": "Bearer " + await client.tokenFactory()
29
- }
30
- });
23
+ const response = await client.post("/api/apps/" + id,
24
+ "PATCH",
25
+ JSON.stringify({
26
+ type: 'ChatRoom',
27
+ name: name
28
+ }));
31
29
 
32
30
  return response.json();
33
31
  };
34
32
 
35
33
  return useMutation(mutateConversationName, {
36
34
  onSuccess: (data: any, variables: any, context: any) => {
37
- queryClient.invalidateQueries("conversations");
38
- queryClient.invalidateQueries(["conversation", variables.id]);
39
- }
35
+ queryClient.invalidateQueries("conversations");
36
+ queryClient.invalidateQueries(["conversation", variables.id]);
37
+ }
40
38
  });
41
39
  }
@@ -22,14 +22,9 @@ export default function useMutateDeleteReaction() {
22
22
  const mutateDeleteReaction = async ({ id, reaction }: MutateProps) => {
23
23
 
24
24
  // remove the existing reaction
25
- const response = await fetch(client.url + "/api/messages/" + id + "/reactions/", {
26
- method: "DELETE",
27
- headers: {
28
- "content-type": "application/json",
29
- "Authorization": "Bearer " + await client.tokenFactory()
30
- }
31
- });
32
-
25
+ const response = await client.post("/api/messages/" + id + "/reactions/",
26
+ "DELETE",
27
+ "");
33
28
 
34
29
  return response;
35
30
  };
@@ -14,26 +14,21 @@ export default function useMutateExternalBlobs() {
14
14
 
15
15
 
16
16
  type MutateProps = {
17
- blobs: []
17
+ blobs: []
18
18
  }
19
19
 
20
20
  const mutateExternalBlobs = async ({ blobs }: MutateProps) => {
21
21
 
22
- const response = await fetch(client.url + "/api/blobs/external", {
23
- method: "POST",
24
- body: JSON.stringify(blobs),
25
- headers: {
26
- "content-type": "application/json",
27
- "Authorization": "Bearer " + await client.tokenFactory()
28
- }
29
- });
22
+ const response = await client.post("/api/blobs/external",
23
+ "POST",
24
+ JSON.stringify(blobs));
30
25
 
31
26
  return response.json();
32
27
  };
33
28
 
34
29
  return useMutation(mutateExternalBlobs, {
35
30
  onSuccess: (variables: any) => {
36
-
37
- }
31
+
32
+ }
38
33
  });
39
34
  }
@@ -14,26 +14,21 @@ export default function useMutateMeeting() {
14
14
 
15
15
 
16
16
  type MutateProps = {
17
- provider: string
17
+ provider: string
18
18
  }
19
19
 
20
20
  const mutateMeeting = async ({ provider }: MutateProps) => {
21
21
 
22
- const response = await fetch(client.url + "/api/meetings", {
23
- method: "POST",
24
- body: JSON.stringify({provider: provider}),
25
- headers: {
26
- "content-type": "application/json",
27
- "Authorization": "Bearer " + await client.tokenFactory()
28
- }
29
- });
22
+ const response = await client.post("/api/meetings",
23
+ "POST",
24
+ JSON.stringify({ provider: provider }));
30
25
 
31
26
  return response.json();
32
27
  };
33
28
 
34
29
  return useMutation(mutateMeeting, {
35
30
  onSuccess: (variables: any) => {
36
-
37
- }
31
+
32
+ }
38
33
  });
39
34
  }
@@ -14,30 +14,25 @@ export default function useMutateMembers() {
14
14
 
15
15
 
16
16
  type MutateProps = {
17
- id: number | null,
17
+ id: number | null,
18
18
  members: number[]
19
19
  }
20
20
 
21
21
  // add members to conversation
22
22
  const mutateMembers = async ({ id, members }: MutateProps) => {
23
23
 
24
- const response = await fetch(client.url + "/api/apps/" + id + "/members/", {
25
- method: "POST",
26
- body: JSON.stringify(members),
27
- headers: {
28
- "content-type": "application/json",
29
- "Authorization": "Bearer " + await client.tokenFactory()
30
- }
31
- });
24
+ const response = await client.post("/api/apps/" + id + "/members/",
25
+ "POST",
26
+ JSON.stringify(members));
32
27
 
33
28
  return response;
34
29
  };
35
30
 
36
31
  return useMutation(mutateMembers, {
37
32
  onSuccess: (data: any, variables: any, context: any) => {
38
- queryClient.invalidateQueries("conversations");
39
- queryClient.invalidateQueries(["conversation", variables.id]);
40
- queryClient.invalidateQueries(["members", variables.id]);
41
- }
33
+ queryClient.invalidateQueries("conversations");
34
+ queryClient.invalidateQueries(["conversation", variables.id]);
35
+ queryClient.invalidateQueries(["members", variables.id]);
36
+ }
42
37
  });
43
38
  }
@@ -22,19 +22,14 @@ export default function useMutateMessage() {
22
22
  }
23
23
 
24
24
  const mutateMessage = async ({ id, text, userId, attachments, meetings }: MutateProps) => {
25
- const response = await fetch(client.url + "/api/apps/" + id + "/messages", {
26
- method: "POST",
27
- body: JSON.stringify({
25
+
26
+ const response = await client.post("/api/apps/" + id + "/messages",
27
+ "POST",
28
+ JSON.stringify({
28
29
  text: text,
29
30
  blobs: attachments.map((a: FileType) => { return a.id }),
30
31
  meeting_id: meetings.length > 0 ? meetings[0].id : null
31
- }),
32
- headers: {
33
- "content-type": "application/json",
34
- "Authorization": "Bearer " + await client.tokenFactory()
35
- }
36
- });
37
-
32
+ }));
38
33
  return response.json();
39
34
  };
40
35
 
@@ -46,7 +41,7 @@ export default function useMutateMessage() {
46
41
  // update cache
47
42
  const newPagesArray = previousData.pages.map((page: any, i: number) => {
48
43
 
49
-
44
+
50
45
 
51
46
  // remove temp message
52
47
  if (i === 0) {
@@ -54,7 +49,7 @@ export default function useMutateMessage() {
54
49
  ...page.data.filter((message: MessageType) => message.id !== context.tempId),
55
50
  data
56
51
  ]
57
-
52
+
58
53
  }
59
54
 
60
55
  return page;
@@ -68,7 +63,7 @@ export default function useMutateMessage() {
68
63
  }
69
64
 
70
65
  // refetch conversations list
71
- queryClient.invalidateQueries("conversations");
66
+ queryClient.invalidateQueries("conversations");
72
67
 
73
68
  },
74
69
  onMutate: async (variables: any) => {
@@ -100,8 +95,8 @@ export default function useMutateMessage() {
100
95
 
101
96
  // update cache
102
97
  queryClient.setQueryData(["messages", variables.id], (data: any) => {
103
- let updatedPages = [lastPage];
104
- if (data?.pages.length > 1) {
98
+ let updatedPages = [lastPage];
99
+ if (data?.pages.length > 1) {
105
100
  updatedPages = [lastPage, ...data?.pages.slice(1)];
106
101
  }
107
102
  return {
@@ -20,14 +20,9 @@ export default function useMutatePinned() {
20
20
 
21
21
  const mutatePinned = async ({ id, pin }: MutateProps) => {
22
22
 
23
- const response = await fetch(client.url + "/api/conversations/" + id + "/pin", {
24
- method: + !pin ? "DELETE": "PUT",
25
- body: "",
26
- headers: {
27
- "content-type": "application/json",
28
- "Authorization": "Bearer " + await client.tokenFactory()
29
- }
30
- });
23
+ const response = await client.post("/api/conversations/" + id + "/pin",
24
+ !pin ? "DELETE" : "PUT",
25
+ "");
31
26
 
32
27
  return response.json();
33
28
  };