@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 +14 -0
- package/build/index.js +221 -293
- package/build/stories/chat/_types.d.ts +7 -5
- package/build/stories/chat/context/chatContext.d.ts +4 -4
- package/build/stories/chat/hooks/useMedia.d.ts +8 -0
- package/build/stories/chat/index.stories.d.ts +3 -4
- package/build/stories/chat/parts/MediaLightbox.d.ts +14 -0
- package/build/stories/chat/parts/ThumbnailContainer/Thumbnail.d.ts +11 -0
- package/build/stories/chat/parts/ThumbnailContainer/index.d.ts +1 -1
- package/build/stories/chat/parts/comment.d.ts +2 -7
- package/package.json +1 -1
- package/build/stories/chat/parts/ThumbnailContainer/ImageThumbnail.d.ts +0 -11
- package/build/stories/chat/parts/ThumbnailContainer/VideoThumbnail.d.ts +0 -11
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.
|
|
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.
|
|
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
|
|
3072
|
-
|
|
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
|
|
3086
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
3438
|
+
opacity: 0;
|
|
3439
|
+
transition: opacity 0.2s;
|
|
3478
3440
|
z-index: 1;
|
|
3479
3441
|
}
|
|
3480
3442
|
|
|
3481
|
-
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
|
|
3487
|
-
|
|
3488
|
-
|
|
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:
|
|
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
|
|
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(
|
|
3489
|
+
removeThumbnail();
|
|
3509
3490
|
};
|
|
3510
|
-
return (jsxRuntime.jsxs(
|
|
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" }) })),
|
|
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
|
|
3520
|
-
|
|
3521
|
-
|
|
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:
|
|
3549
|
-
|
|
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(
|
|
3557
|
-
|
|
3558
|
-
|
|
3559
|
-
|
|
3560
|
-
|
|
3561
|
-
|
|
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 = (
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 = (
|
|
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
|
-
|
|
4958
|
-
|
|
4959
|
-
|
|
4960
|
-
|
|
4961
|
-
|
|
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?:
|
|
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
|
|
42
|
-
|
|
40
|
+
export interface CommentMedia {
|
|
41
|
+
id: string;
|
|
42
|
+
type: string;
|
|
43
|
+
name?: string;
|
|
44
|
+
isLoadingMedia?: boolean;
|
|
43
45
|
isError?: boolean;
|
|
44
|
-
|
|
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 {
|
|
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:
|
|
9
|
+
files: (File & CommentMedia)[];
|
|
10
10
|
}) => void;
|
|
11
11
|
removeThumbnail: (index: number) => void;
|
|
12
|
-
thumbnails:
|
|
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:
|
|
32
|
+
onFileUpload?: ((files: (File & CommentMedia)[]) => Promise<Data>) | undefined;
|
|
33
33
|
onDeleteThumbnail: (id: string) => void;
|
|
34
34
|
children: React.ReactNode;
|
|
35
35
|
setMentionableUsers: (props: {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { PlaceholderOptions } from "@tiptap/extension-placeholder";
|
|
2
2
|
import { Editor as TipTapEditor } from "@tiptap/react";
|
|
3
|
-
import { ChatEditorArgs,
|
|
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?:
|
|
15
|
+
media?: CommentMedia[];
|
|
17
16
|
}[];
|
|
18
17
|
editorText?: string;
|
|
19
18
|
background?: string;
|
|
20
19
|
onSave: (editor: TipTapEditor, mentions: SuggestedUser[]) => void;
|
|
21
|
-
onFileUpload?: (files:
|
|
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: (
|
|
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?:
|
|
7
|
+
media?: CommentMedia[] | undefined;
|
|
13
8
|
header: {
|
|
14
9
|
title: string;
|
|
15
10
|
message?: string | undefined;
|
package/package.json
CHANGED
|
@@ -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;
|