@appquality/unguess-design-system 3.1.90 → 3.1.91

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 CHANGED
@@ -1,3 +1,17 @@
1
+ # v3.1.91 (Fri May 17 2024)
2
+
3
+ #### 🐛 Bug Fix
4
+
5
+ - new feat media attachments [#350](https://github.com/AppQuality/unguess-design-system/pull/350) ([@iacopolea](https://github.com/iacopolea) [@Kariamos](https://github.com/Kariamos))
6
+ - Fix attachments [#348](https://github.com/AppQuality/unguess-design-system/pull/348) ([@iacopolea](https://github.com/iacopolea) [@Kariamos](https://github.com/Kariamos))
7
+
8
+ #### Authors: 2
9
+
10
+ - Iacopo Leardini ([@iacopolea](https://github.com/iacopolea))
11
+ - Marco ([@Kariamos](https://github.com/Kariamos))
12
+
13
+ ---
14
+
1
15
  # v3.1.90 (Thu May 16 2024)
2
16
 
3
17
  #### 🐛 Bug Fix
package/build/index.js CHANGED
@@ -25,9 +25,9 @@ var sunburst = require('@nivo/sunburst');
25
25
  var waffle = require('@nivo/waffle');
26
26
  var line = require('@nivo/line');
27
27
  var reactForms = require('@zendeskgarden/react-forms');
28
- var uuid = require('uuid');
29
28
  var react = require('@tiptap/react');
30
29
  var reactTooltips = require('@zendeskgarden/react-tooltips');
30
+ var uuid = require('uuid');
31
31
  var Typography = require('@tiptap/extension-typography');
32
32
  var Link = require('@tiptap/extension-link');
33
33
  var StarterKit = require('@tiptap/starter-kit');
@@ -38,10 +38,10 @@ var Mention = require('@tiptap/extension-mention');
38
38
  var tippy = require('tippy.js');
39
39
  var Image$2 = require('@tiptap/extension-image');
40
40
  var Dropcursor = require('@tiptap/extension-dropcursor');
41
- var reactGrid = require('@zendeskgarden/react-grid');
42
41
  var reactModals = require('@zendeskgarden/react-modals');
43
42
  var SlickSlider = require('react-slick');
44
43
  var Video = require('@appquality/stream-player');
44
+ var reactGrid = require('@zendeskgarden/react-grid');
45
45
  var containerUtilities = require('@zendeskgarden/container-utilities');
46
46
  var reactColorpickers = require('@zendeskgarden/react-colorpickers');
47
47
  var reactDropdowns = require('@zendeskgarden/react-dropdowns');
@@ -2339,7 +2339,7 @@ const ChatContextProvider = ({ onSave, onFileUpload, onDeleteThumbnail, setMenti
2339
2339
  setThumbnails,
2340
2340
  afterUploadCallback: (failed) => {
2341
2341
  setThumbnails(thumbnails.map((file) => {
2342
- if (failed.includes(file.name)) {
2342
+ if (failed.includes(file.id)) {
2343
2343
  file.isLoadingMedia = false;
2344
2344
  //file.isError = true;
2345
2345
  }
@@ -2351,7 +2351,6 @@ const ChatContextProvider = ({ onSave, onFileUpload, onDeleteThumbnail, setMenti
2351
2351
  }));
2352
2352
  },
2353
2353
  addThumbnails: ({ files }) => {
2354
- files.forEach((file) => (file.isLoadingMedia = true));
2355
2354
  setThumbnails((prev) => [...prev, ...files]);
2356
2355
  if (onFileUpload) {
2357
2356
  onFileUpload(files).then((data) => {
@@ -2360,7 +2359,7 @@ const ChatContextProvider = ({ onSave, onFileUpload, onDeleteThumbnail, setMenti
2360
2359
  setThumbnails((prev) => {
2361
2360
  return prev.map((file) => {
2362
2361
  file.isLoadingMedia = false;
2363
- if ((failed === null || failed === void 0 ? void 0 : failed.length) && failed.includes(file.name)) {
2362
+ if ((failed === null || failed === void 0 ? void 0 : failed.length) && failed.includes(file.id)) {
2364
2363
  file.isError = true;
2365
2364
  }
2366
2365
  else {
@@ -2737,74 +2736,6 @@ const ChatTitle = styled__default["default"](Title$1) `
2737
2736
  padding: ${({ theme }) => `${theme.space.sm} ${theme.space.md}`};
2738
2737
  `;
2739
2738
 
2740
- const UgClose$1 = styled__default["default"](reactNotifications.Close) `
2741
- display: flex;
2742
- align-items: center;
2743
- justify-content: center;
2744
- width: ${({ theme }) => theme.space.xl};
2745
- height: ${({ theme }) => theme.space.xl};
2746
- `;
2747
- /**
2748
- * Title is a basic component used to display a title. Often used in card headers.
2749
- */
2750
- const Close = (props) => jsxRuntime.jsx(UgClose$1, Object.assign({}, props));
2751
-
2752
- const NOTIFICATION_COMPONENT_ID = "notifications.notification";
2753
- const CLOSE_COMPONENT_ID = "notifications.notification.close";
2754
- const CLOSE_ICON_COMPONENT_ID = "notifications.notification.close-icon";
2755
- const TITLE_COMPONENT_ID = "notifications.notification.title";
2756
- const UgClose = styled__default["default"](Close).attrs((props) => {
2757
- var _a;
2758
- return ({
2759
- "data-custom-id": (_a = props["data-custom-id"]) !== null && _a !== void 0 ? _a : CLOSE_ICON_COMPONENT_ID,
2760
- });
2761
- }) `
2762
- ${(props) => reactTheming.retrieveComponentStyles(CLOSE_ICON_COMPONENT_ID, props)};
2763
- `;
2764
- const UgAnchor = styled__default["default"](reactButtons.Anchor).attrs((props) => {
2765
- var _a;
2766
- return ({
2767
- "data-custom-id": (_a = props["data-custom-id"]) !== null && _a !== void 0 ? _a : CLOSE_COMPONENT_ID,
2768
- });
2769
- }) `
2770
- ${(props) => reactTheming.retrieveComponentStyles(CLOSE_COMPONENT_ID, props)};
2771
- `;
2772
- const UgTitle = styled__default["default"](Title$1).attrs((props) => {
2773
- var _a;
2774
- return ({
2775
- "data-custom-id": (_a = props["data-custom-id"]) !== null && _a !== void 0 ? _a : TITLE_COMPONENT_ID,
2776
- });
2777
- }) `
2778
- ${(props) => reactTheming.retrieveComponentStyles(TITLE_COMPONENT_ID, props)};
2779
- `;
2780
- const UgNotification = styled__default["default"](reactNotifications.Notification) `
2781
- display: flex;
2782
- align-items: center;
2783
- justify-content: space-between;
2784
- padding-right: ${({ theme }) => theme.space.md};
2785
- white-space: pre;
2786
-
2787
- ${UgAnchor} {
2788
- flex-shrink: 0;
2789
- margin-left: ${({ theme }) => theme.space.md};
2790
- }
2791
-
2792
- ${(props) => reactTheming.retrieveComponentStyles(NOTIFICATION_COMPONENT_ID, props)};
2793
- `;
2794
- /**
2795
- * A Notification is a passive status update that keeps users informed of system progress.
2796
- * <hr>
2797
- * Used for this:
2798
- - For a passive status update about user or system activity
2799
- */
2800
- const Notification = (_a) => {
2801
- var { closeText, message, onClose, type, isPrimary, isRegular } = _a, props = __rest(_a, ["closeText", "message", "onClose", "type", "isPrimary", "isRegular"]);
2802
- return (jsxRuntime.jsxs(UgNotification, Object.assign({ type: type, isPrimary: isPrimary }, props, { children: [jsxRuntime.jsx(UgTitle, Object.assign({ isRegular: isRegular, type: type, isPrimary: isPrimary }, { children: message })), jsxRuntime.jsx(UgAnchor, Object.assign({ type: type, isPrimary: isPrimary, onClick: onClose }, { children: closeText !== null && closeText !== void 0 ? closeText : jsxRuntime.jsx(UgClose, {}) }))] })));
2803
- };
2804
- // ToastProvider
2805
- const ToastProvider = (props) => (jsxRuntime.jsx(reactNotifications.ToastProvider, Object.assign({}, props)));
2806
- const useToast = reactNotifications.useToast;
2807
-
2808
2739
  var _path$w;
2809
2740
  function _extends$E() { _extends$E = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$E.apply(this, arguments); }
2810
2741
  const SvgBoldFill = props => /*#__PURE__*/React__namespace.createElement("svg", _extends$E({
@@ -3049,6 +2980,98 @@ const SvgClipboard = props => /*#__PURE__*/React__namespace.createElement("svg",
3049
2980
  d: "M9.5 4v7.7c0 .8-.7 1.5-1.5 1.5s-1.5-.7-1.5-1.5V3C6.5 1.6 7.6.5 9 .5s2.5 1.1 2.5 2.5v9c0 1.9-1.6 3.5-3.5 3.5S4.5 13.9 4.5 12V4"
3050
2981
  })));
3051
2982
 
2983
+ const UgClose$1 = styled__default["default"](reactNotifications.Close) `
2984
+ display: flex;
2985
+ align-items: center;
2986
+ justify-content: center;
2987
+ width: ${({ theme }) => theme.space.xl};
2988
+ height: ${({ theme }) => theme.space.xl};
2989
+ `;
2990
+ /**
2991
+ * Title is a basic component used to display a title. Often used in card headers.
2992
+ */
2993
+ const Close = (props) => jsxRuntime.jsx(UgClose$1, Object.assign({}, props));
2994
+
2995
+ const NOTIFICATION_COMPONENT_ID = "notifications.notification";
2996
+ const CLOSE_COMPONENT_ID = "notifications.notification.close";
2997
+ const CLOSE_ICON_COMPONENT_ID = "notifications.notification.close-icon";
2998
+ const TITLE_COMPONENT_ID = "notifications.notification.title";
2999
+ const UgClose = styled__default["default"](Close).attrs((props) => {
3000
+ var _a;
3001
+ return ({
3002
+ "data-custom-id": (_a = props["data-custom-id"]) !== null && _a !== void 0 ? _a : CLOSE_ICON_COMPONENT_ID,
3003
+ });
3004
+ }) `
3005
+ ${(props) => reactTheming.retrieveComponentStyles(CLOSE_ICON_COMPONENT_ID, props)};
3006
+ `;
3007
+ const UgAnchor = styled__default["default"](reactButtons.Anchor).attrs((props) => {
3008
+ var _a;
3009
+ return ({
3010
+ "data-custom-id": (_a = props["data-custom-id"]) !== null && _a !== void 0 ? _a : CLOSE_COMPONENT_ID,
3011
+ });
3012
+ }) `
3013
+ ${(props) => reactTheming.retrieveComponentStyles(CLOSE_COMPONENT_ID, props)};
3014
+ `;
3015
+ const UgTitle = styled__default["default"](Title$1).attrs((props) => {
3016
+ var _a;
3017
+ return ({
3018
+ "data-custom-id": (_a = props["data-custom-id"]) !== null && _a !== void 0 ? _a : TITLE_COMPONENT_ID,
3019
+ });
3020
+ }) `
3021
+ ${(props) => reactTheming.retrieveComponentStyles(TITLE_COMPONENT_ID, props)};
3022
+ `;
3023
+ const UgNotification = styled__default["default"](reactNotifications.Notification) `
3024
+ display: flex;
3025
+ align-items: center;
3026
+ justify-content: space-between;
3027
+ padding-right: ${({ theme }) => theme.space.md};
3028
+ white-space: pre;
3029
+
3030
+ ${UgAnchor} {
3031
+ flex-shrink: 0;
3032
+ margin-left: ${({ theme }) => theme.space.md};
3033
+ }
3034
+
3035
+ ${(props) => reactTheming.retrieveComponentStyles(NOTIFICATION_COMPONENT_ID, props)};
3036
+ `;
3037
+ /**
3038
+ * A Notification is a passive status update that keeps users informed of system progress.
3039
+ * <hr>
3040
+ * Used for this:
3041
+ - For a passive status update about user or system activity
3042
+ */
3043
+ const Notification = (_a) => {
3044
+ var { closeText, message, onClose, type, isPrimary, isRegular } = _a, props = __rest(_a, ["closeText", "message", "onClose", "type", "isPrimary", "isRegular"]);
3045
+ return (jsxRuntime.jsxs(UgNotification, Object.assign({ type: type, isPrimary: isPrimary }, props, { children: [jsxRuntime.jsx(UgTitle, Object.assign({ isRegular: isRegular, type: type, isPrimary: isPrimary }, { children: message })), jsxRuntime.jsx(UgAnchor, Object.assign({ type: type, isPrimary: isPrimary, onClick: onClose }, { children: closeText !== null && closeText !== void 0 ? closeText : jsxRuntime.jsx(UgClose, {}) }))] })));
3046
+ };
3047
+ // ToastProvider
3048
+ const ToastProvider = (props) => (jsxRuntime.jsx(reactNotifications.ToastProvider, Object.assign({}, props)));
3049
+ const useToast = reactNotifications.useToast;
3050
+
3051
+ const acceptedMediaTypes = /^(image|video)\//;
3052
+ function useMedia() {
3053
+ const { addToast } = useToast();
3054
+ function getValidMedia(data) {
3055
+ const wrongFiles = Array.from(data).filter((file) => !acceptedMediaTypes.test(file.type));
3056
+ if (wrongFiles.length) {
3057
+ addToast(({ close }) => (jsxRuntime.jsx(Notification, { onClose: close, type: "error", message: wrongFiles.length === 1
3058
+ ? `${wrongFiles[0].name} not supported, please upload video or image only`
3059
+ : "Some attachments are not supported, please upload video or image only", isPrimary: true })), { placement: "top" });
3060
+ }
3061
+ return Array.from(data).filter((file) => acceptedMediaTypes.test(file.type));
3062
+ }
3063
+ function getMedia(data) {
3064
+ return getValidMedia(data).map((file) => {
3065
+ return Object.assign(file, {
3066
+ url: URL.createObjectURL(file),
3067
+ isLoadingMedia: true,
3068
+ id: uuid.v4(),
3069
+ });
3070
+ });
3071
+ }
3072
+ return { getMedia };
3073
+ }
3074
+
3052
3075
  const MenuContainer = styled__default["default"].div `
3053
3076
  padding: ${({ theme }) => theme.space.xs} 0;
3054
3077
  display: flex;
@@ -3066,59 +3089,33 @@ const VerticalDivider = styled__default["default"].div `
3066
3089
  const CommentBar = ({ editor, i18n, }) => {
3067
3090
  var _a, _b, _c, _d, _e, _f, _g, _h;
3068
3091
  const { addThumbnails } = useChatContext();
3092
+ const { getMedia } = useMedia();
3069
3093
  if (!editor)
3070
3094
  return null;
3071
- const getIcon = (type) => {
3072
- switch (type) {
3073
- case "bold":
3074
- return jsxRuntime.jsx(SvgBoldStroke, {});
3075
- case "italic":
3076
- return jsxRuntime.jsx(SvgItalicStroke, {});
3077
- case "mention":
3078
- return jsxRuntime.jsx(SvgAtStroke, {});
3079
- case "attachment":
3080
- return jsxRuntime.jsx(SvgClipboard, {});
3081
- default:
3082
- return null;
3083
- }
3095
+ const handleBoldClick = () => {
3096
+ editor.chain().focus().toggleBold().run();
3084
3097
  };
3085
- const handleClick = (type) => {
3086
- switch (type) {
3087
- case "bold":
3088
- return editor.chain().focus().toggleBold().run();
3089
- case "italic":
3090
- return editor.chain().focus().toggleItalic().run();
3091
- case "mention":
3092
- const { from } = editor.state.selection;
3093
- const char = from > 1 ? " @" : "@";
3094
- return editor.chain().focus().insertContent(char).run();
3095
- case "attachment":
3096
- //open a file browser to select one or more images
3097
- const fileInput = document.createElement("input");
3098
- fileInput.type = "file";
3099
- fileInput.accept = "image/*,video/*";
3100
- fileInput.multiple = true;
3101
- fileInput.click();
3102
- fileInput.onchange = () => {
3103
- const files = fileInput.files;
3104
- if (files) {
3105
- const mediaFiles = Array.from(files).map((file) => {
3106
- return Object.assign(file, {
3107
- isLoadingMedia: false,
3108
- internal_id: uuid.v4(),
3109
- });
3110
- });
3111
- if (mediaFiles.length === 0)
3112
- return;
3113
- addThumbnails({ files: mediaFiles });
3114
- }
3115
- };
3116
- return;
3117
- default:
3118
- return;
3119
- }
3098
+ const handleItalicClick = () => {
3099
+ editor.chain().focus().toggleItalic().run();
3120
3100
  };
3121
- return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: jsxRuntime.jsxs(MenuContainer, Object.assign({ id: "menu-container" }, { children: [jsxRuntime.jsx(Tooltip, Object.assign({ content: `${(_b = (_a = i18n === null || i18n === void 0 ? void 0 : i18n.menu) === null || _a === void 0 ? void 0 : _a.bold) !== null && _b !== void 0 ? _b : "Bold text"} ${isMac() ? "Cmd" : "Ctrl"} + B`, placement: "top", type: "light", size: "small", hasArrow: false }, { children: jsxRuntime.jsx(IconButton, Object.assign({ size: "small", isBasic: !editor.isActive("bold"), isPrimary: editor.isActive("bold"), isPill: false, onClick: () => handleClick("bold") }, { children: getIcon("bold") })) })), jsxRuntime.jsx(Tooltip, Object.assign({ content: `${(_d = (_c = i18n === null || i18n === void 0 ? void 0 : i18n.menu) === null || _c === void 0 ? void 0 : _c.italic) !== null && _d !== void 0 ? _d : "Italic text"} ${isMac() ? "Cmd" : "Ctrl"} + I`, placement: "top", type: "light", size: "small", hasArrow: false }, { children: jsxRuntime.jsx(IconButton, Object.assign({ size: "small", isBasic: !editor.isActive("italic"), isPrimary: editor.isActive("italic"), isPill: false, onClick: () => handleClick("italic") }, { children: getIcon("italic") })) })), jsxRuntime.jsx(VerticalDivider, {}), jsxRuntime.jsx(Tooltip, Object.assign({ content: (_f = (_e = i18n === null || i18n === void 0 ? void 0 : i18n.menu) === null || _e === void 0 ? void 0 : _e.mention) !== null && _f !== void 0 ? _f : "Add a mention", placement: "top", type: "light", size: "small", hasArrow: false }, { children: jsxRuntime.jsx(IconButton, Object.assign({ size: "small", isBasic: !editor.isActive("mention"), isPrimary: editor.isActive("mention"), isPill: false, onClick: () => handleClick("mention") }, { children: getIcon("mention") })) })), jsxRuntime.jsx(Tooltip, Object.assign({ content: (_h = (_g = i18n === null || i18n === void 0 ? void 0 : i18n.menu) === null || _g === void 0 ? void 0 : _g.attachment) !== null && _h !== void 0 ? _h : "Upload images and video. Max size: 5GB", placement: "top", type: "light", size: "small", hasArrow: true }, { children: jsxRuntime.jsx(IconButton, Object.assign({ size: "small", isBasic: !editor.isActive("attachment"), isPrimary: editor.isActive("attachment"), isPill: false, onClick: () => handleClick("attachment") }, { children: getIcon("attachment") })) }))] })) }));
3101
+ const handleMentionClick = () => {
3102
+ const { from } = editor.state.selection;
3103
+ const char = from > 1 ? " @" : "@";
3104
+ editor.chain().focus().insertContent(char).run();
3105
+ };
3106
+ const handleAttachmentClick = () => {
3107
+ const fileInput = document.createElement("input");
3108
+ fileInput.type = "file";
3109
+ fileInput.accept = "image/*,video/*";
3110
+ fileInput.multiple = true;
3111
+ fileInput.click();
3112
+ fileInput.onchange = () => {
3113
+ if (fileInput.files) {
3114
+ addThumbnails({ files: getMedia(fileInput.files) });
3115
+ }
3116
+ };
3117
+ };
3118
+ return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: jsxRuntime.jsxs(MenuContainer, Object.assign({ id: "menu-container" }, { children: [jsxRuntime.jsx(Tooltip, Object.assign({ content: `${(_b = (_a = i18n === null || i18n === void 0 ? void 0 : i18n.menu) === null || _a === void 0 ? void 0 : _a.bold) !== null && _b !== void 0 ? _b : "Bold text"} ${isMac() ? "Cmd" : "Ctrl"} + B`, placement: "top", type: "light", size: "small", hasArrow: false }, { children: jsxRuntime.jsx(IconButton, Object.assign({ size: "small", isBasic: !editor.isActive("bold"), isPrimary: editor.isActive("bold"), isPill: false, onClick: handleBoldClick }, { children: jsxRuntime.jsx(SvgBoldStroke, {}) })) })), jsxRuntime.jsx(Tooltip, Object.assign({ content: `${(_d = (_c = i18n === null || i18n === void 0 ? void 0 : i18n.menu) === null || _c === void 0 ? void 0 : _c.italic) !== null && _d !== void 0 ? _d : "Italic text"} ${isMac() ? "Cmd" : "Ctrl"} + I`, placement: "top", type: "light", size: "small", hasArrow: false }, { children: jsxRuntime.jsx(IconButton, Object.assign({ size: "small", isBasic: !editor.isActive("italic"), isPrimary: editor.isActive("italic"), isPill: false, onClick: handleItalicClick }, { children: jsxRuntime.jsx(SvgItalicStroke, {}) })) })), jsxRuntime.jsx(VerticalDivider, {}), jsxRuntime.jsx(Tooltip, Object.assign({ content: (_f = (_e = i18n === null || i18n === void 0 ? void 0 : i18n.menu) === null || _e === void 0 ? void 0 : _e.mention) !== null && _f !== void 0 ? _f : "Add a mention", placement: "top", type: "light", size: "small", hasArrow: false }, { children: jsxRuntime.jsx(IconButton, Object.assign({ size: "small", isBasic: !editor.isActive("mention"), isPrimary: editor.isActive("mention"), isPill: false, onClick: handleMentionClick }, { children: jsxRuntime.jsx(SvgAtStroke, {}) })) })), jsxRuntime.jsx(Tooltip, Object.assign({ content: (_h = (_g = i18n === null || i18n === void 0 ? void 0 : i18n.menu) === null || _g === void 0 ? void 0 : _g.attachment) !== null && _h !== void 0 ? _h : (jsxRuntime.jsxs("span", { children: ["Upload images and video.", " ", jsxRuntime.jsxs("span", Object.assign({ style: { color: theme.palette.grey[600] } }, { children: [" ", jsxRuntime.jsx("br", {}), " Max size: 5GB", " "] }))] })), placement: "top", type: "light", size: "small", hasArrow: true }, { children: jsxRuntime.jsx(IconButton, Object.assign({ size: "small", isBasic: !editor.isActive("attachment"), isPrimary: editor.isActive("attachment"), isPill: false, onClick: handleAttachmentClick }, { children: jsxRuntime.jsx(SvgClipboard, {}) })) }))] })) }));
3122
3119
  };
3123
3120
 
3124
3121
  const CustomMention = Mention__default["default"].extend({
@@ -3399,45 +3396,13 @@ const StyledDeleteThumbnailX = styled__default["default"].div `
3399
3396
  width: 32px;
3400
3397
  height: 32px;
3401
3398
  opacity: 0;
3399
+ transition: opacity 0.2s;
3402
3400
  z-index: 2;
3403
3401
  `;
3404
3402
  const DeleteThumbnailX = ({ deleteThumbnail }) => {
3405
3403
  return (jsxRuntime.jsx(StyledDeleteThumbnailX, Object.assign({ className: "deleteThumbnail" }, { children: jsxRuntime.jsx(SvgRemoveMediaIcon, { onClick: (e) => deleteThumbnail(e) }) })));
3406
3404
  };
3407
3405
 
3408
- const ImageCard = styled__default["default"](SpecialCard) `
3409
- padding: 0;
3410
- :hover .deleteThumbnail {
3411
- opacity: 1;
3412
- }
3413
- `;
3414
- const Preview$1 = styled__default["default"].div `
3415
- display: flex;
3416
- justify-content: center;
3417
- align-items: center;
3418
- height: 150px;
3419
- width: 100%;
3420
- background-image: url(${(props) => props.url});
3421
- background-color: ${({ theme }) => theme.palette.grey[100]};
3422
- background-size: contain;
3423
- background-position: center;
3424
- background-repeat: no-repeat;
3425
- `;
3426
- const ImageThumbnail = ({ src, index = 0, removeThumbnail, clickThumbnail, showX = true, isLoadingMedia = true, isError = false, }) => {
3427
- const handleCancel = (e) => {
3428
- e.stopPropagation();
3429
- if (removeThumbnail)
3430
- removeThumbnail(index);
3431
- };
3432
- return (jsxRuntime.jsxs(ImageCard, Object.assign({ onClick: clickThumbnail }, { children: [isLoadingMedia && (jsxRuntime.jsx(Preview$1, Object.assign({ url: "" }, { children: jsxRuntime.jsx(reactLoaders.Spinner, { style: {
3433
- display: "flex",
3434
- alignItems: "center",
3435
- justifyContent: "center",
3436
- }, size: "large" }) }))), isError && (
3437
- // todo: add error icon
3438
- jsxRuntime.jsx("span", { children: "error uploading media" })), !isLoadingMedia && (jsxRuntime.jsx(Preview$1, Object.assign({ url: src }, { children: showX && (jsxRuntime.jsx(DeleteThumbnailX, { deleteThumbnail: (e) => handleCancel(e) })) })))] })));
3439
- };
3440
-
3441
3406
  var _circle$2, _path$o;
3442
3407
  function _extends$t() { _extends$t = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$t.apply(this, arguments); }
3443
3408
  const SvgVideoPlayIcon = props => /*#__PURE__*/React__namespace.createElement("svg", _extends$t({
@@ -3456,15 +3421,11 @@ const SvgVideoPlayIcon = props => /*#__PURE__*/React__namespace.createElement("s
3456
3421
  fill: "currentColor"
3457
3422
  })));
3458
3423
 
3459
- const VideoCard = styled__default["default"](SpecialCard) `
3424
+ const ImageCard = styled__default["default"](SpecialCard) `
3460
3425
  padding: 0;
3461
3426
  position: relative;
3462
3427
  overflow: hidden;
3463
-
3464
- &:hover .deleteThumbnail {
3465
- opacity: 1;
3466
- z-index: 9999;
3467
- }
3428
+ min-width: 90px;
3468
3429
 
3469
3430
  &:before {
3470
3431
  content: "";
@@ -3474,103 +3435,93 @@ const VideoCard = styled__default["default"](SpecialCard) `
3474
3435
  width: 100%;
3475
3436
  height: 100%;
3476
3437
  background-color: ${({ theme }) => theme.palette.grey[800]};
3477
- opacity: 0.3;
3438
+ opacity: 0;
3439
+ transition: opacity 0.2s;
3478
3440
  z-index: 1;
3479
3441
  }
3480
3442
 
3481
- > svg {
3482
- position: absolute;
3483
- top: 50%;
3484
- left: 50%;
3485
- transform: translate(-50%, -50%);
3486
- width: 32px;
3487
- height: 32px;
3488
- z-index: 2;
3443
+ &:hover {
3444
+ .deleteThumbnail {
3445
+ opacity: 1;
3446
+ }
3447
+ &:before {
3448
+ opacity: 0.3;
3449
+ }
3450
+ }
3451
+
3452
+ &.video {
3453
+ svg {
3454
+ position: absolute;
3455
+ top: 50%;
3456
+ left: 50%;
3457
+ transform: translate(-50%, -50%);
3458
+ width: 32px;
3459
+ height: 32px;
3460
+ z-index: 2;
3461
+ }
3489
3462
  }
3490
3463
  `;
3491
3464
  const Preview = styled__default["default"].div `
3492
- padding: ${({ theme }) => theme.space.md};
3493
3465
  display: flex;
3494
3466
  justify-content: center;
3495
3467
  align-items: center;
3496
- height: 150px;
3468
+ height: 100px;
3497
3469
  width: 100%;
3498
3470
 
3471
+ ${(p) => p.url &&
3472
+ `
3473
+ background-image: url(${p.url});
3474
+ background-color: ${p.theme.palette.grey[100]};
3475
+ background-size: cover;
3476
+ background-position: center;
3477
+ background-repeat: no-repeat;
3478
+ `}
3479
+
3499
3480
  > video {
3500
3481
  width: 100%;
3501
3482
  height: 100%;
3502
3483
  }
3503
3484
  `;
3504
- const VideoThumbnail = ({ src, index = 0, removeThumbnail, clickThumbnail, showX = true, isLoadingMedia = true, isError = false, }) => {
3485
+ const Thumbnail = ({ src, type, removeThumbnail, clickThumbnail, showX, isLoadingMedia = true, isError = false, }) => {
3505
3486
  const handleCancel = (e) => {
3506
3487
  e.stopPropagation();
3507
3488
  if (removeThumbnail)
3508
- removeThumbnail(index);
3489
+ removeThumbnail();
3509
3490
  };
3510
- return (jsxRuntime.jsxs(VideoCard, Object.assign({ onClick: clickThumbnail }, { children: [isLoadingMedia && (jsxRuntime.jsx(Preview, { children: jsxRuntime.jsx(reactLoaders.Spinner, { style: {
3491
+ return (jsxRuntime.jsxs(ImageCard, Object.assign({ onClick: clickThumbnail, className: type.includes("video") ? "video" : "image" }, { children: [isError && (
3492
+ // todo: add error icon
3493
+ jsxRuntime.jsx("span", { children: "error uploading media" })), isLoadingMedia ? (jsxRuntime.jsx(Preview, { children: jsxRuntime.jsx(reactLoaders.Spinner, { style: {
3511
3494
  display: "flex",
3512
3495
  alignItems: "center",
3513
3496
  justifyContent: "center",
3514
- }, size: "large" }) })), isError && (
3515
- // todo: add error icon
3516
- jsxRuntime.jsx("span", { children: "error uploading media" })), !isLoadingMedia && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [showX && (jsxRuntime.jsx(DeleteThumbnailX, { deleteThumbnail: (e) => handleCancel(e) })), jsxRuntime.jsx(Preview, { children: jsxRuntime.jsx("video", Object.assign({ src: src }, { children: jsxRuntime.jsx("track", { kind: "captions" }) })) }), jsxRuntime.jsx(SvgVideoPlayIcon, {})] }))] })));
3497
+ }, size: "large" }) })) : (jsxRuntime.jsxs(Preview, Object.assign({ url: src }, { children: [showX && (jsxRuntime.jsx(DeleteThumbnailX, { deleteThumbnail: (e) => handleCancel(e) })), type.includes("video") && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("video", Object.assign({ src: src }, { children: jsxRuntime.jsx("track", { kind: "captions" }) })), jsxRuntime.jsx(SvgVideoPlayIcon, {})] }))] })))] })));
3517
3498
  };
3518
3499
 
3519
- const UgGrid = styled__default["default"](reactGrid.Grid) `
3520
- padding-left: 0;
3521
- padding-right: 0;
3522
- `;
3523
- /**
3524
- * The Grid component is a framework for building modular layouts.
3525
- * <hr>
3526
- * Used for this:
3527
- - To structure the layout of a page
3528
- */
3529
- const Grid = (props) => jsxRuntime.jsx(UgGrid, Object.assign({}, props));
3530
-
3531
- const Row$1 = (props) => jsxRuntime.jsx(reactGrid.Row, Object.assign({}, props));
3532
-
3533
- const StyledCol$1 = styled__default["default"](reactGrid.Col) `
3534
- margin-bottom: ${theme.space.lg};
3535
-
3536
- @media screen and (max-width: ${theme.breakpoints.sm}) {
3537
- margin-bottom: ${theme.space.md};
3538
- }
3500
+ const FlexContainer = styled.styled.div `
3501
+ display: flex;
3502
+ gap: ${({ theme }) => theme.space.xs};
3503
+ flex-wrap: wrap;
3539
3504
  `;
3540
- const Col = (props) => jsxRuntime.jsx(StyledCol$1, Object.assign({}, props));
3541
-
3542
3505
  const ThumbnailContainer = ({ openLightbox }) => {
3543
3506
  const { thumbnails, removeThumbnail, onDeleteThumbnail } = useChatContext();
3544
3507
  const mediaFiles = React.useMemo(() => {
3545
3508
  return thumbnails.map((file) => ({
3546
3509
  fileName: file.name,
3547
3510
  fileType: file.type,
3548
- previewUrl: URL.createObjectURL(file),
3549
- internal_id: file.internal_id,
3511
+ previewUrl: file.url,
3512
+ id: file.id,
3550
3513
  isLoadingMedia: file.isLoadingMedia,
3551
3514
  }));
3552
3515
  }, [thumbnails]);
3553
3516
  if (!mediaFiles || mediaFiles.length === 0) {
3554
3517
  return null;
3555
3518
  }
3556
- return (jsxRuntime.jsx(Grid, { children: jsxRuntime.jsx(Row$1, Object.assign({ className: "responsive-container" }, { children: mediaFiles.map((file, index) => {
3557
- // Check if item is an image or a video
3558
- if (file.fileType.includes("image"))
3559
- return (jsxRuntime.jsx(Col, Object.assign({ xs: 12, sm: 3, xl: 3, lg: 3, className: "flex-3-sm" }, { children: jsxRuntime.jsx(ImageThumbnail, { src: file.previewUrl, index: index, showX: true, isLoadingMedia: file.isLoadingMedia, removeThumbnail: () => {
3560
- removeThumbnail(index);
3561
- onDeleteThumbnail(file.internal_id);
3562
- }, clickThumbnail: () => {
3563
- openLightbox(thumbnails[index], index);
3564
- } }, index) })));
3565
- if (file.fileType.includes("video"))
3566
- return (jsxRuntime.jsx(Col, Object.assign({ xs: 12, sm: 3, className: "flex-3-sm" }, { children: jsxRuntime.jsx(VideoThumbnail, { src: file.previewUrl, index: index, showX: true, isLoadingMedia: file.isLoadingMedia, removeThumbnail: () => {
3567
- removeThumbnail(index);
3568
- onDeleteThumbnail(file.internal_id);
3569
- }, clickThumbnail: () => {
3570
- openLightbox(thumbnails[index], index);
3571
- } }, index) })));
3572
- return null;
3573
- }) })) }));
3519
+ return (jsxRuntime.jsx(FlexContainer, { children: mediaFiles.map((file, index) => (jsxRuntime.jsx(Thumbnail, { src: file.previewUrl, showX: true, type: file.fileType, isLoadingMedia: file.isLoadingMedia, removeThumbnail: () => {
3520
+ removeThumbnail(index);
3521
+ onDeleteThumbnail(file.id);
3522
+ }, clickThumbnail: () => {
3523
+ openLightbox(index);
3524
+ } }, file.id))) }));
3574
3525
  };
3575
3526
 
3576
3527
  const UgModalBody = styled__default["default"](reactModals.Body) `
@@ -4762,6 +4713,15 @@ const PlayerCore = React.forwardRef((props, forwardRef) => {
4762
4713
  return (jsxRuntime.jsxs(Container$1, Object.assign({ isLoaded: isLoaded, isPlaying: context.isPlaying, ref: containerRef }, { children: [!isLoaded ? (jsxRuntime.jsx(VideoSpinner, {})) : (jsxRuntime.jsx(FloatingControls, { isPlaying: context.isPlaying, onClick: togglePlay })), jsxRuntime.jsx(Video__default["default"].Player, { className: "player-container" }), jsxRuntime.jsx(ProgressContextProvider, { children: jsxRuntime.jsx(Controls, { container: containerRef.current, onCutHandler: onCutHandler, bookmarks: bookmarks, isCutting: isCutting, onBookMarkUpdated: props.handleBookmarkUpdate, i18n: props.i18n }) })] })));
4763
4714
  });
4764
4715
 
4716
+ const MediaLightBox = ({ header, onClose, slideChange, selectedImageIndex, thumbnails, videoRefs, isOpen, details }) => {
4717
+ if (!isOpen) {
4718
+ return null;
4719
+ }
4720
+ return (jsxRuntime.jsxs(Lightbox, Object.assign({ onClose: onClose }, { children: [jsxRuntime.jsx(Lightbox.Header, { children: header }), jsxRuntime.jsxs(Lightbox.Body, { children: [jsxRuntime.jsx(Lightbox.Body.Main, Object.assign({ style: { flex: details ? 2 : 3 } }, { children: jsxRuntime.jsx(Slider, Object.assign({ prevArrow: jsxRuntime.jsx(Slider.PrevButton, { isBright: true }), nextArrow: jsxRuntime.jsx(Slider.NextButton, { isBright: true }), onSlideChange: slideChange, initialSlide: selectedImageIndex }, { children: thumbnails.map((item) => (jsxRuntime.jsxs(Slider.Slide, { children: [item.type.includes("image") && (jsxRuntime.jsx("img", { src: item.url, alt: `media ${item.name}`, style: { maxHeight: "100%", height: "auto" } })), item.type.includes("video") && item.url && (jsxRuntime.jsx(Player, { ref: (ref) => {
4721
+ videoRefs.current.push(ref);
4722
+ }, url: item.url }))] }, item.id))) })) })), details && (jsxRuntime.jsx(Lightbox.Body.Details, Object.assign({ style: { flex: 1 } }, { children: details })))] }), jsxRuntime.jsx(Lightbox.Close, { "aria-label": "Close modal" })] })));
4723
+ };
4724
+
4765
4725
  const ChatBoxContainer = styled__default["default"].div `
4766
4726
  display: flex;
4767
4727
  border-top: 1px solid ${({ theme }) => theme.palette.grey[200]};
@@ -4781,14 +4741,19 @@ const ChatBoxContainer = styled__default["default"].div `
4781
4741
  - Simple text input, use textarea instead.
4782
4742
  */
4783
4743
  const CommentBox = (_a) => {
4744
+ var _b;
4784
4745
  var { placeholderOptions } = _a, props = __rest(_a, ["placeholderOptions"]);
4785
4746
  const { children, hasFloatingMenu, hasButtonsMenu, bubbleOptions, i18n } = props;
4786
4747
  const { editor, setEditor, mentionableUsers, triggerSave, thumbnails, addThumbnails, } = useChatContext();
4787
- const { addToast } = useToast();
4788
4748
  const [isOpen, setIsOpen] = React.useState(false);
4789
- const [selectedImage, setSelectedImage] = React.useState({});
4790
4749
  const [selectedImageIndex, setSelectedImageIndex] = React.useState(0);
4750
+ const { getMedia } = useMedia();
4791
4751
  const ext = editorExtensions({ placeholderOptions, mentionableUsers });
4752
+ function handleEvent(data) {
4753
+ if (!data || !data.files)
4754
+ return;
4755
+ addThumbnails({ files: getMedia(data.files) });
4756
+ }
4792
4757
  const closeLightbox = () => {
4793
4758
  setIsOpen(false);
4794
4759
  };
@@ -4801,10 +4766,7 @@ const CommentBox = (_a) => {
4801
4766
  }
4802
4767
  });
4803
4768
  }, [videoRefs]);
4804
- const handleOpenLightbox = (file, index) => {
4805
- if (!file)
4806
- throw Error("Error with the image");
4807
- setSelectedImage(file);
4769
+ const handleOpenLightbox = (index) => {
4808
4770
  setSelectedImageIndex(index);
4809
4771
  setIsOpen(true);
4810
4772
  };
@@ -4816,48 +4778,12 @@ const CommentBox = (_a) => {
4816
4778
  return false;
4817
4779
  },
4818
4780
  handleDrop: function (view, event, slice, moved) {
4819
- if (!event.dataTransfer || !event.dataTransfer.files)
4820
- return false;
4821
4781
  event.preventDefault();
4822
- const files = Array.from(event.dataTransfer.files).map((file) => {
4823
- return Object.assign(file, {
4824
- isLoadingMedia: false,
4825
- internal_id: uuid.v4(),
4826
- });
4827
- });
4828
- const wrongFiles = files.filter((file) => !/^(image|video)\//.test(file.type));
4829
- if (wrongFiles.length > 0) {
4830
- for (const file of wrongFiles) {
4831
- addToast(({ close }) => (jsxRuntime.jsx(Notification, { onClose: close, type: "error", message: `${props.messageBadFileFormat} - ${file.name}`, isPrimary: true })), { placement: "top" });
4832
- }
4833
- }
4834
- const mediaFiles = files.filter((file) => /^(image|video)\//.test(file.type));
4835
- if (mediaFiles.length === 0)
4836
- return false;
4837
- addThumbnails({ files: mediaFiles });
4838
- return false;
4782
+ handleEvent(event.dataTransfer);
4839
4783
  },
4840
4784
  handlePaste: (view, event, slice) => {
4841
- if (!event.clipboardData || !event.clipboardData.items)
4842
- return false;
4843
4785
  event.preventDefault();
4844
- const files = Array.from(event.clipboardData.files).map((file) => {
4845
- return Object.assign(file, {
4846
- isLoadingMedia: false,
4847
- internal_id: uuid.v4(),
4848
- });
4849
- });
4850
- const wrongFiles = files.filter((file) => !/^(image|video)\//.test(file.type));
4851
- if (wrongFiles.length > 0) {
4852
- for (const file of wrongFiles) {
4853
- addToast(({ close }) => (jsxRuntime.jsx(Notification, { onClose: close, type: "error", message: `${props.messageBadFileFormat} - ${file.name}`, isPrimary: true })), { placement: "top" });
4854
- }
4855
- }
4856
- const mediaFiles = files.filter((file) => /^(image|video)\//.test(file.type));
4857
- if (mediaFiles.length === 0)
4858
- return false;
4859
- addThumbnails({ files: mediaFiles });
4860
- return false;
4786
+ handleEvent(event.clipboardData);
4861
4787
  },
4862
4788
  } }, props));
4863
4789
  const onKeyDown = (event) => {
@@ -4870,14 +4796,32 @@ const CommentBox = (_a) => {
4870
4796
  return null;
4871
4797
  ed.on("create", ({ editor }) => setEditor(editor));
4872
4798
  ed.on("update", ({ editor }) => setEditor(editor));
4873
- const mediaFiles = thumbnails.map((file) => {
4874
- return Object.assign(file, { isLoadingMedia: file.isLoadingMedia });
4875
- });
4876
- return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [isOpen && selectedImage && (jsxRuntime.jsxs(Lightbox, Object.assign({ onClose: closeLightbox }, { children: [jsxRuntime.jsx(Lightbox.Header, { children: selectedImage.name }), jsxRuntime.jsx(Lightbox.Body, { children: jsxRuntime.jsx(Lightbox.Body.Main, Object.assign({ style: { flex: 3 } }, { children: jsxRuntime.jsx(Slider, Object.assign({ prevArrow: jsxRuntime.jsx(Slider.PrevButton, { isBright: true }), nextArrow: jsxRuntime.jsx(Slider.NextButton, { isBright: true }), onSlideChange: slideChange, initialSlide: selectedImageIndex }, { children: mediaFiles.map((item, index) => (jsxRuntime.jsxs(Slider.Slide, { children: [item.type.includes("image") && (jsxRuntime.jsx("img", { src: URL.createObjectURL(item), alt: `media ${item.name}` })), item.type.includes("video") && (jsxRuntime.jsx(Player, { ref: (ref) => {
4877
- videoRefs.current.push(ref);
4878
- }, url: URL.createObjectURL(item) }))] }))) })) })) }), jsxRuntime.jsx(Lightbox.Close, { "aria-label": "Close modal" })] }))), jsxRuntime.jsx(ChatBoxContainer, { children: jsxRuntime.jsxs(EditorContainer$1, Object.assign({ editable: true, style: { marginLeft: 0, paddingBottom: 12 } }, { children: [hasFloatingMenu && (jsxRuntime.jsx(FloatingMenu, { editor: ed, tippyOptions: Object.assign({}, bubbleOptions) })), jsxRuntime.jsx(react.EditorContent, { editor: ed, onKeyDown: onKeyDown }), jsxRuntime.jsx(ThumbnailContainer, { openLightbox: handleOpenLightbox })] })) }), hasButtonsMenu && jsxRuntime.jsx(CommentBar, { editor: ed, i18n: i18n })] }));
4799
+ return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(MediaLightBox, { isOpen: isOpen, header: (_b = thumbnails[selectedImageIndex]) === null || _b === void 0 ? void 0 : _b.name, onClose: closeLightbox, slideChange: slideChange, selectedImageIndex: selectedImageIndex, thumbnails: thumbnails, videoRefs: videoRefs }), jsxRuntime.jsx(ChatBoxContainer, { children: jsxRuntime.jsxs(EditorContainer$1, Object.assign({ editable: true, style: { marginLeft: 0, paddingBottom: 12 } }, { children: [hasFloatingMenu && (jsxRuntime.jsx(FloatingMenu, { editor: ed, tippyOptions: Object.assign({}, bubbleOptions) })), jsxRuntime.jsx(react.EditorContent, { editor: ed, onKeyDown: onKeyDown }), jsxRuntime.jsx(ThumbnailContainer, { openLightbox: handleOpenLightbox })] })) }), hasButtonsMenu && jsxRuntime.jsx(CommentBar, { editor: ed, i18n: i18n })] }));
4879
4800
  };
4880
4801
 
4802
+ const UgGrid = styled__default["default"](reactGrid.Grid) `
4803
+ padding-left: 0;
4804
+ padding-right: 0;
4805
+ `;
4806
+ /**
4807
+ * The Grid component is a framework for building modular layouts.
4808
+ * <hr>
4809
+ * Used for this:
4810
+ - To structure the layout of a page
4811
+ */
4812
+ const Grid = (props) => jsxRuntime.jsx(UgGrid, Object.assign({}, props));
4813
+
4814
+ const Row$1 = (props) => jsxRuntime.jsx(reactGrid.Row, Object.assign({}, props));
4815
+
4816
+ const StyledCol$1 = styled__default["default"](reactGrid.Col) `
4817
+ margin-bottom: ${theme.space.lg};
4818
+
4819
+ @media screen and (max-width: ${theme.breakpoints.sm}) {
4820
+ margin-bottom: ${theme.space.md};
4821
+ }
4822
+ `;
4823
+ const Col = (props) => jsxRuntime.jsx(StyledCol$1, Object.assign({}, props));
4824
+
4881
4825
  const CommentCard = styled.styled(Card) `
4882
4826
  padding: ${({ theme }) => `${theme.space.base * 3}px ${theme.space.sm}`};
4883
4827
  background-color: ${({ theme }) => theme.palette.grey[100]};
@@ -4921,13 +4865,9 @@ const Comment = ({ author, message, children, date, media = [], header, }) => {
4921
4865
  var _a, _b;
4922
4866
  const { mentionableUsers } = useChatContext();
4923
4867
  const [isOpen, setIsOpen] = React.useState(false);
4924
- const [selectedImage, setSelectedImage] = React.useState({});
4925
4868
  const [selectedImageIndex, setSelectedImageIndex] = React.useState(0);
4926
4869
  const ext = editorExtensions({ mentionableUsers });
4927
- const handleClickThumbnail = (file, index) => {
4928
- if (!file)
4929
- throw Error("Error with the image");
4930
- setSelectedImage(file);
4870
+ const handleClickThumbnail = (index) => {
4931
4871
  setSelectedImageIndex(index);
4932
4872
  setIsOpen(true);
4933
4873
  };
@@ -4936,7 +4876,6 @@ const Comment = ({ author, message, children, date, media = [], header, }) => {
4936
4876
  };
4937
4877
  const videoRefs = React.useRef([]);
4938
4878
  const slideChange = React.useCallback((index) => {
4939
- setSelectedImage(media[index]);
4940
4879
  setSelectedImageIndex(index);
4941
4880
  videoRefs.current.forEach((ref) => {
4942
4881
  if (ref) {
@@ -4953,23 +4892,12 @@ const Comment = ({ author, message, children, date, media = [], header, }) => {
4953
4892
  ed.setOptions({
4954
4893
  editable: false,
4955
4894
  });
4956
- return (jsxRuntime.jsxs(CommentCard, { children: [jsxRuntime.jsxs(AuthorContainer, { children: [jsxRuntime.jsx(Avatar, Object.assign({ avatarType: (_a = author.avatarType) !== null && _a !== void 0 ? _a : "text", style: { flexShrink: 0 } }, { children: author.avatar })), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsxs(CommentTitle, { children: [(_b = author.name) !== null && _b !== void 0 ? _b : "User", " ", jsxRuntime.jsx(CommentDate, { children: date })] }), jsxRuntime.jsx(ReadOnly, { children: jsxRuntime.jsx(EditorContainer$1, Object.assign({ editable: false }, { children: jsxRuntime.jsx(react.EditorContent, { editor: ed }) })) })] })] }), jsxRuntime.jsx(Grid, { children: jsxRuntime.jsx(Row$1, Object.assign({ className: "responsive-container" }, { children: media.map((file, index) => {
4957
- // Check if item is an image or a video
4958
- if (file.type.includes("image"))
4959
- return (jsxRuntime.jsx(Col, Object.assign({ xs: 12, sm: 4, className: "flex-3-sm" }, { children: jsxRuntime.jsx(ImageThumbnail, { src: file.url, index: index, showX: false, isLoadingMedia: false, clickThumbnail: () => {
4960
- handleClickThumbnail(file, index);
4961
- } }, index) })));
4962
- if (file.type.includes("video"))
4963
- return (jsxRuntime.jsx(Col, Object.assign({ xs: 12, sm: 4, className: "flex-3-sm" }, { children: jsxRuntime.jsx(VideoThumbnail, { src: file.url, index: index, showX: false, isLoadingMedia: false, clickThumbnail: () => {
4964
- handleClickThumbnail(file, index);
4965
- } }, index) })));
4966
- return null;
4967
- }) })) }), isOpen && selectedImage && (jsxRuntime.jsxs(Lightbox, Object.assign({ onClose: closeLightbox }, { children: [jsxRuntime.jsx(Lightbox.Header, { children: jsxRuntime.jsxs(reactTypography.MD, Object.assign({ isBold: true }, { children: [jsxRuntime.jsx(Grey600Span, { children: header && header.title }), header && header.message && (jsxRuntime.jsxs(Grey800Span, { children: [" | ", header.message] }))] })) }), jsxRuntime.jsxs(Lightbox.Body, { children: [jsxRuntime.jsx(Lightbox.Body.Main, Object.assign({ style: { flex: 2 } }, { children: jsxRuntime.jsx(Slider, Object.assign({ prevArrow: jsxRuntime.jsx(Slider.PrevButton, { isBright: true }), nextArrow: jsxRuntime.jsx(Slider.NextButton, { isBright: true }), onSlideChange: slideChange, initialSlide: selectedImageIndex }, { children: media.map((item, index) => (jsxRuntime.jsxs(Slider.Slide, { children: [item.type === "image" && (jsxRuntime.jsx("img", { src: item.url, alt: `{{${item.url}}}` })), item.type === "video" && (jsxRuntime.jsx(Player, { ref: (ref) => {
4968
- videoRefs.current.push(ref);
4969
- }, url: item.url }))] }))) })) })), jsxRuntime.jsx(Lightbox.Body.Details, Object.assign({ style: { flex: 1 } }, { children: jsxRuntime.jsx(Comment, Object.assign({ header: header, author: {
4970
- avatar: author.avatar,
4971
- name: author.name,
4972
- }, date: date, message: message }, { children: jsxRuntime.jsx(jsxRuntime.Fragment, { children: jsxRuntime.jsx("br", {}) }) })) }))] }), jsxRuntime.jsx(Lightbox.Footer, {}), jsxRuntime.jsx(Lightbox.Close, { "aria-label": "Close modal" })] }))), jsxRuntime.jsx(Footer$2, { children: children })] }));
4895
+ return (jsxRuntime.jsxs(CommentCard, { children: [jsxRuntime.jsxs(AuthorContainer, { children: [jsxRuntime.jsx(Avatar, Object.assign({ avatarType: (_a = author.avatarType) !== null && _a !== void 0 ? _a : "text", style: { flexShrink: 0 } }, { children: author.avatar })), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsxs(CommentTitle, { children: [(_b = author.name) !== null && _b !== void 0 ? _b : "User", " ", jsxRuntime.jsx(CommentDate, { children: date })] }), jsxRuntime.jsx(ReadOnly, { children: jsxRuntime.jsx(EditorContainer$1, Object.assign({ editable: false }, { children: jsxRuntime.jsx(react.EditorContent, { editor: ed }) })) })] })] }), jsxRuntime.jsx(Grid, { children: jsxRuntime.jsx(Row$1, Object.assign({ className: "responsive-container" }, { children: media.map((file, index) => (jsxRuntime.jsx(Col, Object.assign({ xs: 12, sm: 4, className: "flex-3-sm" }, { children: jsxRuntime.jsx(Thumbnail, { src: file.url, type: file.type, showX: false, isLoadingMedia: false, clickThumbnail: () => {
4896
+ handleClickThumbnail(index);
4897
+ } }) }), index))) })) }), jsxRuntime.jsx(MediaLightBox, { isOpen: isOpen, header: jsxRuntime.jsxs(reactTypography.MD, Object.assign({ isBold: true }, { children: [jsxRuntime.jsx(Grey600Span, { children: header && header.title }), header && header.message && (jsxRuntime.jsxs(Grey800Span, { children: [" | ", header.message] }))] })), onClose: closeLightbox, slideChange: slideChange, selectedImageIndex: selectedImageIndex, thumbnails: media, videoRefs: videoRefs, details: jsxRuntime.jsx(Comment, Object.assign({ header: header, author: {
4898
+ avatar: author.avatar,
4899
+ name: author.name,
4900
+ }, date: date, message: message }, { children: jsxRuntime.jsx(jsxRuntime.Fragment, { children: jsxRuntime.jsx("br", {}) }) })) }), jsxRuntime.jsx(Footer$2, { children: children })] }));
4973
4901
  };
4974
4902
 
4975
4903
  /**
@@ -9,7 +9,6 @@ export type SuggestedUser = {
9
9
  };
10
10
  export interface ChatEditorArgs extends Partial<EditorOptions> {
11
11
  author: Author;
12
- messageBadFileFormat: string;
13
12
  placeholderOptions?: Partial<PlaceholderOptions>;
14
13
  hasFloatingMenu?: boolean;
15
14
  hasButtonsMenu?: boolean;
@@ -19,7 +18,7 @@ export interface ChatEditorArgs extends Partial<EditorOptions> {
19
18
  bold?: string;
20
19
  italic?: string;
21
20
  mention?: string;
22
- attachment?: string | React.ReactNode;
21
+ attachment?: React.ReactNode;
23
22
  };
24
23
  mention?: {
25
24
  noResults?: string;
@@ -38,10 +37,13 @@ export interface EditorHeaderArgs {
38
37
  title?: string;
39
38
  validation?: validationStatus;
40
39
  }
41
- export interface FileItem extends File {
42
- isLoadingMedia: boolean;
40
+ export interface CommentMedia {
41
+ id: string;
42
+ type: string;
43
+ name?: string;
44
+ isLoadingMedia?: boolean;
43
45
  isError?: boolean;
44
- internal_id: string;
46
+ url?: string;
45
47
  }
46
48
  export interface FloatingMenuArgs extends Partial<BubbleMenuProps> {
47
49
  }
@@ -1,15 +1,15 @@
1
1
  import { Editor } from "@tiptap/react";
2
2
  import React from "react";
3
- import { FileItem, SuggestedUser } from "../_types";
3
+ import { CommentMedia, SuggestedUser } from "../_types";
4
4
  export type ChatContextType = {
5
5
  triggerSave: () => void;
6
6
  editor?: Editor;
7
7
  setEditor: React.Dispatch<React.SetStateAction<Editor | undefined>>;
8
8
  addThumbnails: (props: {
9
- files: FileItem[];
9
+ files: (File & CommentMedia)[];
10
10
  }) => void;
11
11
  removeThumbnail: (index: number) => void;
12
- thumbnails: FileItem[];
12
+ thumbnails: CommentMedia[];
13
13
  mentionableUsers: (props: {
14
14
  query: string;
15
15
  }) => SuggestedUser[];
@@ -29,7 +29,7 @@ export interface Data {
29
29
  }
30
30
  export declare const ChatContextProvider: ({ onSave, onFileUpload, onDeleteThumbnail, setMentionableUsers, children, }: {
31
31
  onSave?: ((editor: Editor, mentions: SuggestedUser[]) => void) | undefined;
32
- onFileUpload?: ((files: FileItem[]) => Promise<Data>) | undefined;
32
+ onFileUpload?: ((files: (File & CommentMedia)[]) => Promise<Data>) | undefined;
33
33
  onDeleteThumbnail: (id: string) => void;
34
34
  children: React.ReactNode;
35
35
  setMentionableUsers: (props: {
@@ -0,0 +1,8 @@
1
+ export declare const acceptedMediaTypes: RegExp;
2
+ export declare function useMedia(): {
3
+ getMedia: (data: FileList) => (File & {
4
+ url: string;
5
+ isLoadingMedia: boolean;
6
+ id: string;
7
+ })[];
8
+ };
@@ -1,7 +1,6 @@
1
1
  import { PlaceholderOptions } from "@tiptap/extension-placeholder";
2
2
  import { Editor as TipTapEditor } from "@tiptap/react";
3
- import { ChatEditorArgs, FileItem, SuggestedUser } from "./_types";
4
- import { MediaType } from "./parts/comment";
3
+ import { ChatEditorArgs, CommentMedia, SuggestedUser } from "./_types";
5
4
  import { Data } from "./context/chatContext";
6
5
  interface EditorStoryArgs extends ChatEditorArgs {
7
6
  children?: any;
@@ -13,12 +12,12 @@ interface EditorStoryArgs extends ChatEditorArgs {
13
12
  };
14
13
  message: string;
15
14
  date: string;
16
- media?: MediaType[];
15
+ media?: CommentMedia[];
17
16
  }[];
18
17
  editorText?: string;
19
18
  background?: string;
20
19
  onSave: (editor: TipTapEditor, mentions: SuggestedUser[]) => void;
21
- onFileUpload?: (files: FileItem[]) => Promise<Data>;
20
+ onFileUpload?: (files: (File & CommentMedia)[]) => Promise<Data>;
22
21
  placeholderOptions?: Partial<PlaceholderOptions>;
23
22
  }
24
23
  export declare const Default: import("@storybook/types").AnnotatedStoryFn<import("@storybook/react/dist/types-0a347bb9").R, EditorStoryArgs>;
@@ -0,0 +1,14 @@
1
+ /// <reference types="react" />
2
+ import { CommentMedia } from "../_types";
3
+ interface MediaLightBoxProps {
4
+ isOpen: boolean;
5
+ header: React.ReactNode;
6
+ onClose: () => void;
7
+ slideChange: (index: number) => void;
8
+ selectedImageIndex: number;
9
+ thumbnails: CommentMedia[];
10
+ videoRefs: React.MutableRefObject<Array<HTMLVideoElement | null>>;
11
+ details?: React.ReactNode;
12
+ }
13
+ declare const MediaLightBox: ({ header, onClose, slideChange, selectedImageIndex, thumbnails, videoRefs, isOpen, details }: MediaLightBoxProps) => import("react/jsx-runtime").JSX.Element | null;
14
+ export default MediaLightBox;
@@ -0,0 +1,11 @@
1
+ interface Props {
2
+ src?: string;
3
+ type: string;
4
+ clickThumbnail?: () => void;
5
+ isLoadingMedia?: boolean;
6
+ removeThumbnail?: () => void;
7
+ showX?: boolean;
8
+ isError?: boolean;
9
+ }
10
+ declare const Thumbnail: ({ src, type, removeThumbnail, clickThumbnail, showX, isLoadingMedia, isError, }: Props) => import("react/jsx-runtime").JSX.Element;
11
+ export default Thumbnail;
@@ -7,7 +7,7 @@ export interface FileElement {
7
7
  isLoadingMedia: boolean;
8
8
  }
9
9
  interface Props {
10
- openLightbox: (file: File, index: number) => void;
10
+ openLightbox: (index: number) => void;
11
11
  }
12
12
  declare const ThumbnailContainer: ({ openLightbox }: Props) => import("react/jsx-runtime").JSX.Element | null;
13
13
  export default ThumbnailContainer;
@@ -1,15 +1,10 @@
1
1
  import { PropsWithChildren } from "react";
2
- import { Author } from "../_types";
3
- export type MediaType = {
4
- url: string;
5
- id: number;
6
- type: "image" | "video";
7
- };
2
+ import { Author, CommentMedia } from "../_types";
8
3
  export declare const Comment: ({ author, message, children, date, media, header, }: PropsWithChildren<{
9
4
  author: Author;
10
5
  message: string;
11
6
  date: string;
12
- media?: MediaType[] | undefined;
7
+ media?: CommentMedia[] | undefined;
13
8
  header: {
14
9
  title: string;
15
10
  message?: string | undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@appquality/unguess-design-system",
3
- "version": "3.1.90",
3
+ "version": "3.1.91",
4
4
  "description": "",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -1,11 +0,0 @@
1
- interface Props {
2
- src: string;
3
- index?: number;
4
- removeThumbnail?: (index: number) => void;
5
- clickThumbnail: () => void;
6
- showX?: boolean;
7
- isLoadingMedia: boolean;
8
- isError?: boolean;
9
- }
10
- declare const ImageThumbnail: ({ src, index, removeThumbnail, clickThumbnail, showX, isLoadingMedia, isError, }: Props) => import("react/jsx-runtime").JSX.Element;
11
- export default ImageThumbnail;
@@ -1,11 +0,0 @@
1
- interface Props {
2
- src: string;
3
- index?: number;
4
- removeThumbnail?: (index: number) => void;
5
- clickThumbnail: () => void;
6
- showX?: boolean;
7
- isLoadingMedia: boolean;
8
- isError?: boolean;
9
- }
10
- declare const VideoThumbnail: ({ src, index, removeThumbnail, clickThumbnail, showX, isLoadingMedia, isError, }: Props) => import("react/jsx-runtime").JSX.Element;
11
- export default VideoThumbnail;