@selfcommunity/react-ui 0.7.0-alpha.324 → 0.7.0-alpha.326

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.
@@ -1,5 +1,6 @@
1
1
  import { CardProps } from '@mui/material';
2
2
  import { SCCommentsOrderBy } from '../../types/comments';
3
+ import { CommentsObjectProps } from '../CommentsObject';
3
4
  import { SCCommentType, SCContributionType, SCFeedObjectType } from '@selfcommunity/types';
4
5
  import { CacheStrategies } from '@selfcommunity/utils';
5
6
  export interface CommentObjectProps {
@@ -79,6 +80,11 @@ export interface CommentObjectProps {
79
80
  * @default {elevation: 0}
80
81
  */
81
82
  CommentObjectReplyProps?: CardProps;
83
+ /**
84
+ * Props to spread to sub comments object
85
+ * @default {elevation: 0, WidgetProps: {variant: 'outlined'} as WidgetProps}
86
+ */
87
+ CommentsObjectComponentProps?: CommentsObjectProps;
82
88
  /**
83
89
  * If datetime is linkable or not
84
90
  * @default true
@@ -11,13 +11,13 @@ const classnames_1 = tslib_1.__importDefault(require("classnames"));
11
11
  const Errors_1 = require("../../constants/Errors");
12
12
  const Skeleton_1 = tslib_1.__importDefault(require("./Skeleton"));
13
13
  const comments_1 = require("../../types/comments");
14
+ const CommentsObject_1 = tslib_1.__importDefault(require("../CommentsObject"));
14
15
  const CommentObjectReply_1 = tslib_1.__importDefault(require("../CommentObjectReply"));
15
16
  const ContributionActionsMenu_1 = tslib_1.__importDefault(require("../../shared/ContributionActionsMenu"));
16
17
  const DateTimeAgo_1 = tslib_1.__importDefault(require("../../shared/DateTimeAgo"));
17
18
  const contribution_1 = require("../../utils/contribution");
18
19
  const notistack_1 = require("notistack");
19
20
  const system_1 = require("@mui/system");
20
- const CommentsObject_1 = tslib_1.__importDefault(require("../CommentsObject"));
21
21
  const BaseItem_1 = tslib_1.__importDefault(require("../../shared/BaseItem"));
22
22
  const types_1 = require("@selfcommunity/types");
23
23
  const api_services_1 = require("@selfcommunity/api-services");
@@ -95,7 +95,7 @@ function CommentObject(inProps) {
95
95
  props: inProps,
96
96
  name: PREFIX
97
97
  });
98
- const { id = `comment_object_${props.commentObjectId ? props.commentObjectId : props.commentObject ? props.commentObject.id : ''}`, className, commentObjectId, commentObject, feedObjectId, feedObject, feedObjectType = types_1.SCContributionType.POST, commentReply, onOpenReply, onDelete, onVote, elevation = 0, truncateContent = false, CommentObjectSkeletonProps = { elevation, WidgetProps: { variant: 'outlined' } }, CommentObjectReplyProps = { elevation, WidgetProps: { variant: 'outlined' } }, linkableCommentDateTime = true, cacheStrategy = utils_1.CacheStrategies.NETWORK_ONLY } = props, rest = tslib_1.__rest(props, ["id", "className", "commentObjectId", "commentObject", "feedObjectId", "feedObject", "feedObjectType", "commentReply", "onOpenReply", "onDelete", "onVote", "elevation", "truncateContent", "CommentObjectSkeletonProps", "CommentObjectReplyProps", "linkableCommentDateTime", "cacheStrategy"]);
98
+ const { id = `comment_object_${props.commentObjectId ? props.commentObjectId : props.commentObject ? props.commentObject.id : ''}`, className, commentObjectId, commentObject, feedObjectId, feedObject, feedObjectType = types_1.SCContributionType.POST, commentReply, onOpenReply, onDelete, onVote, elevation = 0, truncateContent = false, CommentObjectSkeletonProps = { elevation, WidgetProps: { variant: 'outlined' } }, CommentObjectReplyProps = { elevation, WidgetProps: { variant: 'outlined' } }, linkableCommentDateTime = true, cacheStrategy = utils_1.CacheStrategies.NETWORK_ONLY, CommentsObjectComponentProps = {} } = props, rest = tslib_1.__rest(props, ["id", "className", "commentObjectId", "commentObject", "feedObjectId", "feedObject", "feedObjectType", "commentReply", "onOpenReply", "onDelete", "onVote", "elevation", "truncateContent", "CommentObjectSkeletonProps", "CommentObjectReplyProps", "linkableCommentDateTime", "cacheStrategy", "CommentsObjectComponentProps"]);
99
99
  // CONTEXT
100
100
  const scContext = (0, react_core_1.useSCContext)();
101
101
  const scUserContext = (0, react_1.useContext)(react_core_1.SCUserContext);
@@ -365,8 +365,8 @@ function CommentObject(inProps) {
365
365
  * @param comment
366
366
  */
367
367
  function renderLatestComment(comment) {
368
- return (react_1.default.createElement(CommentsObject_1.default, { feedObject: commentsObject.feedObject, feedObjectType: commentsObject.feedObject ? commentsObject.feedObject.type : feedObjectType, hideAdvertising: true, comments: [].concat(commentsObject.comments).reverse(), endComments: comment.latest_comments, previous: comment.comment_count > comment.latest_comments.length ? commentsObject.next : null, isLoadingPrevious: commentsObject.isLoadingNext, handlePrevious: commentsObject.getNextPage, CommentComponentProps: Object.assign(Object.assign({ onOpenReply: reply, CommentObjectSkeletonProps, elevation: elevation, linkableCommentDateTime: linkableCommentDateTime }, rest), { cacheStrategy,
369
- truncateContent }), CommentsObjectSkeletonProps: { count: 1, CommentObjectSkeletonProps: CommentObjectSkeletonProps }, cacheStrategy: cacheStrategy, inPlaceLoadMoreContents: true }));
368
+ return (react_1.default.createElement(CommentsObject_1.default, Object.assign({ feedObject: commentsObject.feedObject, feedObjectType: commentsObject.feedObject ? commentsObject.feedObject.type : feedObjectType, hideAdvertising: true, comments: [].concat(commentsObject.comments).reverse(), endComments: comment.latest_comments, previous: comment.comment_count > comment.latest_comments.length ? commentsObject.next : null, isLoadingPrevious: commentsObject.isLoadingNext, handlePrevious: commentsObject.getNextPage, CommentComponentProps: Object.assign(Object.assign({ onOpenReply: reply, CommentObjectSkeletonProps, elevation: elevation, linkableCommentDateTime: linkableCommentDateTime }, rest), { cacheStrategy,
369
+ truncateContent }), CommentsObjectSkeletonProps: { count: 1, CommentObjectSkeletonProps: CommentObjectSkeletonProps }, inPlaceLoadMoreContents: true }, CommentsObjectComponentProps, { cacheStrategy: cacheStrategy })));
370
370
  }
371
371
  /**
372
372
  * Render comments
@@ -14,22 +14,18 @@ declare function convertImageElement(domNode: any): {
14
14
  };
15
15
  export declare type SerializedImageNode = Spread<{
16
16
  altText: string;
17
- height?: number;
18
17
  maxWidth: number | string;
19
18
  src: string;
20
- width?: number;
21
19
  type: 'image';
22
20
  version: 1;
23
21
  }, SerializedLexicalNode>;
24
22
  export declare class ImageNode extends DecoratorNode<JSX.Element> {
25
23
  __src: string;
26
24
  __altText: string;
27
- __width: 'inherit' | number;
28
- __height: 'inherit' | number;
29
25
  __maxWidth: number | string;
30
26
  static getType(): string;
31
27
  static clone(node: ImageNode): ImageNode;
32
- constructor(src: string, altText: string, maxWidth: number | string, width?: 'inherit' | number, height?: 'inherit' | number, key?: NodeKey);
28
+ constructor(src: string, altText: string, maxWidth: number | string, key?: NodeKey);
33
29
  setWidthAndHeight(width: 'inherit' | number, height: 'inherit' | number): void;
34
30
  createDOM(config: EditorConfig): HTMLElement;
35
31
  updateDOM(): false;
@@ -44,6 +40,6 @@ export declare class ImageNode extends DecoratorNode<JSX.Element> {
44
40
  static importJSON(serializedNode: SerializedImageNode): ImageNode;
45
41
  exportJSON(): SerializedImageNode;
46
42
  }
47
- export declare function $createImageNode({ src, altText, maxWidth, width, height }: ImagePayload): ImageNode;
43
+ export declare function $createImageNode({ src, altText, maxWidth }: ImagePayload): ImageNode;
48
44
  export declare function $isImageNode(node?: LexicalNode): boolean;
49
45
  export {};
@@ -28,7 +28,7 @@ function LazyImage({ altText, className, imageRef, src, width, height, maxWidth
28
28
  width: `${width}${width === 'inherit' ? '' : 'px'}`
29
29
  } }));
30
30
  }
31
- function ImageComponent({ src, altText, nodeKey, width, height, maxWidth }) {
31
+ function ImageComponent({ src, altText, nodeKey, maxWidth }) {
32
32
  const imageRef = (0, react_1.useRef)(null);
33
33
  const buttonRef = (0, react_1.useRef)(null);
34
34
  const [isSelected, setSelected, clearSelection] = (0, useLexicalNodeSelection_1.useLexicalNodeSelection)(nodeKey);
@@ -94,32 +94,29 @@ function ImageComponent({ src, altText, nodeKey, width, height, maxWidth }) {
94
94
  unregister();
95
95
  };
96
96
  }, [clearSelection, editor, isSelected, nodeKey, onDelete, onEnter, onEscape, setSelected]);
97
- const isFocused = isSelected;
98
97
  return (react_1.default.createElement(react_1.Suspense, { fallback: null },
99
- react_1.default.createElement(LazyImage, { className: isFocused ? `focused` : null, src: src, altText: altText, imageRef: imageRef, width: width, height: height, maxWidth: maxWidth })));
98
+ react_1.default.createElement(LazyImage, { className: isSelected ? `selected` : null, src: src, altText: altText, imageRef: imageRef, maxWidth: maxWidth })));
100
99
  }
101
100
  function convertImageElement(domNode) {
102
101
  if (domNode instanceof HTMLImageElement) {
103
- const { alt: altText, src, dataset: { width, height } } = domNode;
104
- const node = $createImageNode({ altText, height: Number(height), src, width: Number(width), maxWidth: '100%' });
102
+ const { alt: altText, src } = domNode;
103
+ const node = $createImageNode({ altText, src, maxWidth: '100%' });
105
104
  return { node };
106
105
  }
107
106
  return null;
108
107
  }
109
108
  class ImageNode extends lexical_1.DecoratorNode {
110
- constructor(src, altText, maxWidth, width, height, key) {
109
+ constructor(src, altText, maxWidth, key) {
111
110
  super(key);
112
111
  this.__src = src;
113
112
  this.__altText = altText;
114
- this.__width = width || 'inherit';
115
113
  this.__maxWidth = maxWidth;
116
- this.__height = height || 'inherit';
117
114
  }
118
115
  static getType() {
119
116
  return 'image';
120
117
  }
121
118
  static clone(node) {
122
- return new ImageNode(node.__src, node.__altText, node.__maxWidth, node.__width, node.__height, node.__key);
119
+ return new ImageNode(node.__src, node.__altText, node.__maxWidth, node.__key);
123
120
  }
124
121
  setWidthAndHeight(width, height) {
125
122
  const writable = this.getWritable();
@@ -132,13 +129,13 @@ class ImageNode extends lexical_1.DecoratorNode {
132
129
  }
133
130
  // View
134
131
  createDOM(config) {
135
- const span = document.createElement('span');
132
+ const div = document.createElement('div');
136
133
  const theme = config.theme;
137
134
  const className = theme.image;
138
135
  if (className !== undefined) {
139
- span.className = className;
136
+ div.className = className;
140
137
  }
141
- return span;
138
+ return div;
142
139
  }
143
140
  updateDOM() {
144
141
  return false;
@@ -156,21 +153,17 @@ class ImageNode extends lexical_1.DecoratorNode {
156
153
  const element = document.createElement('img');
157
154
  element.setAttribute('src', this.__src);
158
155
  element.setAttribute('alt', this.__altText);
159
- element.setAttribute('width', `${this.__width}`);
160
- element.setAttribute('height', `${this.__height}`);
161
156
  element.setAttribute('style', `max-width: ${this.__maxWidth}px;`);
162
157
  return { element };
163
158
  }
164
159
  decorate() {
165
- return (react_1.default.createElement(ImageComponent, { src: this.__src, altText: this.__altText, width: this.__width, height: this.__height, maxWidth: this.__maxWidth, nodeKey: this.getKey() }));
160
+ return react_1.default.createElement(ImageComponent, { src: this.__src, altText: this.__altText, maxWidth: this.__maxWidth, nodeKey: this.getKey() });
166
161
  }
167
162
  static importJSON(serializedNode) {
168
- const { altText, height, width, maxWidth, src } = serializedNode;
163
+ const { altText, maxWidth, src } = serializedNode;
169
164
  const node = $createImageNode({
170
165
  altText,
171
- height,
172
166
  src,
173
- width,
174
167
  maxWidth
175
168
  });
176
169
  return node;
@@ -178,18 +171,16 @@ class ImageNode extends lexical_1.DecoratorNode {
178
171
  exportJSON() {
179
172
  return {
180
173
  altText: this.getAltText(),
181
- height: this.__height === 'inherit' ? 0 : this.__height,
182
174
  maxWidth: this.__maxWidth,
183
175
  src: this.getSrc(),
184
176
  type: 'image',
185
- version: 1,
186
- width: this.__width === 'inherit' ? 0 : this.__width
177
+ version: 1
187
178
  };
188
179
  }
189
180
  }
190
181
  exports.ImageNode = ImageNode;
191
- function $createImageNode({ src, altText, maxWidth, width = null, height = null }) {
192
- return new ImageNode(src, altText, maxWidth, width, height);
182
+ function $createImageNode({ src, altText, maxWidth }) {
183
+ return new ImageNode(src, altText, maxWidth);
193
184
  }
194
185
  exports.$createImageNode = $createImageNode;
195
186
  function $isImageNode(node) {
@@ -4,6 +4,7 @@ exports.INSERT_IMAGE_COMMAND = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const react_1 = tslib_1.__importStar(require("react"));
6
6
  const lexical_1 = require("lexical");
7
+ const utils_1 = require("@lexical/utils");
7
8
  const LexicalComposerContext_1 = require("@lexical/react/LexicalComposerContext");
8
9
  const material_1 = require("@mui/material");
9
10
  const styles_1 = require("@mui/material/styles");
@@ -40,7 +41,6 @@ function Image({ editor, className = '' }) {
40
41
  };
41
42
  editor.focus();
42
43
  editor.dispatchCommand(exports.INSERT_IMAGE_COMMAND, data);
43
- editor.dispatchCommand(lexical_1.INSERT_PARAGRAPH_COMMAND, undefined);
44
44
  };
45
45
  const handleUploadProgress = (chunks) => {
46
46
  setUploading(Object.assign({}, chunks));
@@ -84,20 +84,15 @@ function ImagePlugin() {
84
84
  return;
85
85
  }
86
86
  return editor.registerCommand(exports.INSERT_IMAGE_COMMAND, (payload) => {
87
- const selection = (0, lexical_1.$getSelection)();
88
- if ((0, lexical_1.$isRangeSelection)(selection)) {
89
- if ((0, lexical_1.$isRootNode)(selection.anchor.getNode())) {
90
- selection.insertParagraph();
91
- }
92
- const imageNode = (0, ImageNode_1.$createImageNode)({
93
- src: payload.src,
94
- altText: payload.altText,
95
- maxWidth: '100%',
96
- width: payload.width,
97
- height: payload.height
98
- });
99
- selection.insertNodes([imageNode]);
100
- }
87
+ const imageNode = (0, ImageNode_1.$createImageNode)({
88
+ src: payload.src,
89
+ altText: payload.altText,
90
+ maxWidth: '100%',
91
+ width: payload.width,
92
+ height: payload.height
93
+ });
94
+ // The image is not editable so it is better to position it near the root element
95
+ (0, utils_1.$insertNodeToNearestRoot)(imageNode);
101
96
  return true;
102
97
  }, lexical_1.COMMAND_PRIORITY_EDITOR);
103
98
  }, [editor]);
@@ -3,61 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  const react_1 = tslib_1.__importDefault(require("react"));
5
5
  const LexicalOnChangePlugin_1 = require("@lexical/react/LexicalOnChangePlugin");
6
- const ImageNode_1 = require("../nodes/ImageNode");
7
- const MentionNode_1 = require("../nodes/MentionNode");
8
- const rich_text_1 = require("@lexical/rich-text");
9
- const link_1 = require("@lexical/link");
10
- const code_1 = require("@lexical/code");
11
6
  const html_1 = require("@lexical/html");
12
- const IS_BOLD = 1;
13
- const IS_ITALIC = 2;
14
- const convertText = (node) => {
15
- if (node.getFormat() === IS_BOLD) {
16
- return `<strong>${node.__text}</strong>`;
17
- }
18
- else if (node.getFormat() === IS_ITALIC) {
19
- return `<em>${node.__text}</em>`;
20
- }
21
- return `<span>${node.__text}</span>`;
22
- };
23
- const convertNode = (node, children) => {
24
- switch (node.getType()) {
25
- case ImageNode_1.ImageNode.getType():
26
- return `<img src="${node.__src}" alt="${node.__altText}" width="${node.__width}" height="${node.__height}" style="max-width: ${node.__maxWidth}px;" />`;
27
- case MentionNode_1.MentionNode.getType():
28
- return `<mention id="${node.__user.id}" ext-id="${node.__user.ext_id}">@${node.__user.username}</mention>`;
29
- case link_1.AutoLinkNode.getType():
30
- case link_1.LinkNode.getType():
31
- return `<a href="${node.__url}">${node.__url}</a>`;
32
- case 'list':
33
- return `<${node.__tag}>${children}</${node.__tag}>`;
34
- case 'listitem':
35
- return `<li>${node.__value}</li>`;
36
- case rich_text_1.QuoteNode.getType():
37
- return `<blockquote>${children}</blockquote>`;
38
- case code_1.CodeNode.getType():
39
- return `<pre>${children}</pre>`;
40
- case 'linebreak':
41
- return `<br/>`;
42
- case 'text':
43
- return convertText(node);
44
- case rich_text_1.HeadingNode.getType():
45
- return `<${node.__tag}>${children}</${node.__tag}>`;
46
- case 'paragraph':
47
- return `<p>${children ? children : '<br/>'}</p>`;
48
- case 'root':
49
- return children;
50
- default:
51
- return '';
52
- }
53
- };
54
- const $toHtml = (node) => {
55
- let html = '';
56
- // Create html for child nodes
57
- node.getChildren && node.getChildren().map((child) => (html += $toHtml(child)));
58
- // Return new html
59
- return convertNode(node, html);
60
- };
61
7
  const OnChangePlugin = (props) => {
62
8
  // PROPS
63
9
  const { onChange } = props;
@@ -90,7 +90,7 @@ function Activities(inProps) {
90
90
  * Render comments of feedObject
91
91
  */
92
92
  function renderComments() {
93
- return (react_1.default.createElement(react_1.default.Fragment, null, (commentsObject.feedObject.comment_count > 0 || comments.length > 0) && (react_1.default.createElement(CommentsObject_1.default, Object.assign({ feedObject: commentsObject.feedObject, comments: commentsObject.comments, startComments: comments, next: commentsObject.next, isLoadingNext: commentsObject.isLoadingNext, handleNext: handleNext, totalLoadedComments: commentsObject.comments.length + comments.length, totalComments: commentsObject.feedObject.comment_count, hideAdvertising: true }, CommentsObjectProps, { cacheStrategy: cacheStrategy, CommentsObjectSkeletonProps: { count: skeletonsCount }, CommentComponentProps: Object.assign(Object.assign(Object.assign({ truncateContent: true }, CommentComponentProps), { cacheStrategy }), (CommentsObjectProps.CommentComponentProps ? CommentsObjectProps.CommentComponentProps : {})), inPlaceLoadMoreContents: false })))));
93
+ return (react_1.default.createElement(react_1.default.Fragment, null, (commentsObject.feedObject.comment_count > 0 || comments.length > 0) && (react_1.default.createElement(CommentsObject_1.default, Object.assign({ feedObject: commentsObject.feedObject, comments: commentsObject.comments, startComments: comments, next: commentsObject.next, isLoadingNext: commentsObject.isLoadingNext, handleNext: handleNext, totalLoadedComments: commentsObject.comments.length + comments.length, totalComments: commentsObject.feedObject.comment_count, hideAdvertising: true }, CommentsObjectProps, { cacheStrategy: cacheStrategy, CommentsObjectSkeletonProps: { count: skeletonsCount }, CommentComponentProps: Object.assign(Object.assign(Object.assign(Object.assign({}, (CommentsObjectProps.CommentComponentProps ? CommentsObjectProps.CommentComponentProps : {})), { truncateContent: true }), CommentComponentProps), { cacheStrategy }), inPlaceLoadMoreContents: false })))));
94
94
  }
95
95
  /**
96
96
  * Renders root object
@@ -11,6 +11,8 @@ const classnames_1 = tslib_1.__importDefault(require("classnames"));
11
11
  const system_1 = require("@mui/system");
12
12
  const BaseItem_1 = tslib_1.__importDefault(require("../../../../../shared/BaseItem"));
13
13
  const UserDeletedSnackBar_1 = tslib_1.__importDefault(require("../../../../../shared/UserDeletedSnackBar"));
14
+ const contribution_1 = require("../../../../../utils/contribution");
15
+ const Feed_1 = require("../../../../../constants/Feed");
14
16
  const messages = (0, react_intl_1.defineMessages)({
15
17
  comment: {
16
18
  id: 'ui.feedObject.relevantActivities.comment',
@@ -21,7 +23,8 @@ const PREFIX = 'SCCommentRelevantActivity';
21
23
  const classes = {
22
24
  root: `${PREFIX}-root`,
23
25
  avatar: `${PREFIX}-avatar`,
24
- username: `${PREFIX}-username`
26
+ username: `${PREFIX}-username`,
27
+ showMoreContent: `${PREFIX}-show-more-content`
25
28
  };
26
29
  const Root = (0, styles_1.styled)(BaseItem_1.default, {
27
30
  name: PREFIX,
@@ -55,11 +58,19 @@ function CommentRelevantActivity(inProps) {
55
58
  // INTL
56
59
  const intl = (0, react_intl_1.useIntl)();
57
60
  // RENDER
61
+ const summaryHtmlTruncated = 'summary_truncated' in activityObject.comment
62
+ ? activityObject.comment.summary_truncated
63
+ : activityObject.comment.html.length >= Feed_1.MAX_SUMMARY_LENGTH;
64
+ const commentHtml = 'summary_html' in activityObject.comment ? activityObject.comment.summary_html : activityObject.comment.summary;
65
+ const summaryHtml = (0, contribution_1.getContributionHtml)(commentHtml, scRoutingContext.url);
58
66
  return (react_1.default.createElement(react_1.default.Fragment, null,
59
67
  react_1.default.createElement(Root, Object.assign({}, rest, { className: (0, classnames_1.default)(classes.root, className), image: react_1.default.createElement(react_core_1.Link, Object.assign({}, (!activityObject.author.deleted && { to: scRoutingContext.url(react_core_1.SCRoutes.USER_PROFILE_ROUTE_NAME, activityObject.author) }), { onClick: activityObject.author.deleted ? () => setOpenAlert(true) : null }),
60
68
  react_1.default.createElement(material_1.Avatar, { alt: activityObject.author.username, variant: "circular", src: activityObject.author.avatar, className: classes.avatar })), primary: react_1.default.createElement(react_1.default.Fragment, null, intl.formatMessage(messages.comment, {
61
69
  username: (react_1.default.createElement(react_core_1.Link, Object.assign({}, (!activityObject.author.deleted && { to: scRoutingContext.url(react_core_1.SCRoutes.USER_PROFILE_ROUTE_NAME, activityObject.author) }), { onClick: activityObject.author.deleted ? () => setOpenAlert(true) : null, className: classes.username }), activityObject.author.username)),
62
- comment: activityObject.comment.summary
70
+ comment: (react_1.default.createElement(react_1.default.Fragment, null,
71
+ summaryHtml,
72
+ react_1.default.createElement(react_core_1.Link, { to: scRoutingContext.url(react_core_1.SCRoutes.COMMENT_ROUTE_NAME, (0, contribution_1.getRouteData)(activityObject.comment)), className: classes.showMoreContent },
73
+ react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.commentObject.showMore", defaultMessage: "ui.commentObject.showMore" }))))
63
74
  })), secondary: react_1.default.createElement(DateTimeAgo_1.default, { date: activityObject.active_at }) })),
64
75
  openAlert && react_1.default.createElement(UserDeletedSnackBar_1.default, { open: openAlert, handleClose: () => setOpenAlert(false) })));
65
76
  }
@@ -461,7 +461,7 @@ function FeedObject(inProps) {
461
461
  template === feedObject_1.SCFeedObjectTemplateType.PREVIEW && (obj.comment_count > 0 || (feedObjectActivities && feedObjectActivities.length > 0)) && (react_1.default.createElement(material_1.Collapse, { in: expandedActivities, timeout: "auto", classes: { root: classes.activitiesSection } },
462
462
  react_1.default.createElement(CardContent_1.default, { className: classes.activitiesContent },
463
463
  react_1.default.createElement(Activities_1.default, Object.assign({ feedObject: obj, key: selectedActivities, feedObjectActivities: feedObjectActivities, activitiesType: selectedActivities, onSetSelectedActivities: handleSelectedActivities, comments: comments, CommentsObjectProps: {
464
- CommentComponentProps: Object.assign({ onDelete: handleDeleteComment, truncateContent: true }, CommentComponentProps),
464
+ CommentComponentProps: Object.assign({ onDelete: handleDeleteComment, truncateContent: true, CommentsObjectComponentProps: { inPlaceLoadMoreContents: false } }, CommentComponentProps),
465
465
  CommentObjectSkeletonProps: CommentObjectSkeletonProps
466
466
  }, cacheStrategy: cacheStrategy }, ActivitiesProps))))),
467
467
  composerOpen && (react_1.default.createElement(Composer_1.default, { open: composerOpen, feedObject: obj, onClose: handleToggleEdit, onSuccess: handleEditSuccess, maxWidth: "sm", fullWidth: true, scroll: "body" })))) : (react_1.default.createElement(Skeleton_1.default, Object.assign({ template: template }, FeedObjectSkeletonProps)))));
@@ -1,5 +1,6 @@
1
1
  import { CardProps } from '@mui/material';
2
2
  import { SCCommentsOrderBy } from '../../types/comments';
3
+ import { CommentsObjectProps } from '../CommentsObject';
3
4
  import { SCCommentType, SCContributionType, SCFeedObjectType } from '@selfcommunity/types';
4
5
  import { CacheStrategies } from '@selfcommunity/utils';
5
6
  export interface CommentObjectProps {
@@ -79,6 +80,11 @@ export interface CommentObjectProps {
79
80
  * @default {elevation: 0}
80
81
  */
81
82
  CommentObjectReplyProps?: CardProps;
83
+ /**
84
+ * Props to spread to sub comments object
85
+ * @default {elevation: 0, WidgetProps: {variant: 'outlined'} as WidgetProps}
86
+ */
87
+ CommentsObjectComponentProps?: CommentsObjectProps;
82
88
  /**
83
89
  * If datetime is linkable or not
84
90
  * @default true
@@ -9,13 +9,13 @@ import classNames from 'classnames';
9
9
  import { SCOPE_SC_UI } from '../../constants/Errors';
10
10
  import CommentObjectSkeleton from './Skeleton';
11
11
  import { SCCommentsOrderBy } from '../../types/comments';
12
+ import CommentsObject from '../CommentsObject';
12
13
  import CommentObjectReply from '../CommentObjectReply';
13
14
  import ContributionActionsMenu from '../../shared/ContributionActionsMenu';
14
15
  import DateTimeAgo from '../../shared/DateTimeAgo';
15
16
  import { getContributionHtml, getContributionType, getRouteData } from '../../utils/contribution';
16
17
  import { useSnackbar } from 'notistack';
17
18
  import { useThemeProps } from '@mui/system';
18
- import CommentsObject from '../CommentsObject';
19
19
  import BaseItem from '../../shared/BaseItem';
20
20
  import { SCContributionType } from '@selfcommunity/types';
21
21
  import { Endpoints, http } from '@selfcommunity/api-services';
@@ -93,7 +93,7 @@ export default function CommentObject(inProps) {
93
93
  props: inProps,
94
94
  name: PREFIX
95
95
  });
96
- const { id = `comment_object_${props.commentObjectId ? props.commentObjectId : props.commentObject ? props.commentObject.id : ''}`, className, commentObjectId, commentObject, feedObjectId, feedObject, feedObjectType = SCContributionType.POST, commentReply, onOpenReply, onDelete, onVote, elevation = 0, truncateContent = false, CommentObjectSkeletonProps = { elevation, WidgetProps: { variant: 'outlined' } }, CommentObjectReplyProps = { elevation, WidgetProps: { variant: 'outlined' } }, linkableCommentDateTime = true, cacheStrategy = CacheStrategies.NETWORK_ONLY } = props, rest = __rest(props, ["id", "className", "commentObjectId", "commentObject", "feedObjectId", "feedObject", "feedObjectType", "commentReply", "onOpenReply", "onDelete", "onVote", "elevation", "truncateContent", "CommentObjectSkeletonProps", "CommentObjectReplyProps", "linkableCommentDateTime", "cacheStrategy"]);
96
+ const { id = `comment_object_${props.commentObjectId ? props.commentObjectId : props.commentObject ? props.commentObject.id : ''}`, className, commentObjectId, commentObject, feedObjectId, feedObject, feedObjectType = SCContributionType.POST, commentReply, onOpenReply, onDelete, onVote, elevation = 0, truncateContent = false, CommentObjectSkeletonProps = { elevation, WidgetProps: { variant: 'outlined' } }, CommentObjectReplyProps = { elevation, WidgetProps: { variant: 'outlined' } }, linkableCommentDateTime = true, cacheStrategy = CacheStrategies.NETWORK_ONLY, CommentsObjectComponentProps = {} } = props, rest = __rest(props, ["id", "className", "commentObjectId", "commentObject", "feedObjectId", "feedObject", "feedObjectType", "commentReply", "onOpenReply", "onDelete", "onVote", "elevation", "truncateContent", "CommentObjectSkeletonProps", "CommentObjectReplyProps", "linkableCommentDateTime", "cacheStrategy", "CommentsObjectComponentProps"]);
97
97
  // CONTEXT
98
98
  const scContext = useSCContext();
99
99
  const scUserContext = useContext(SCUserContext);
@@ -363,8 +363,8 @@ export default function CommentObject(inProps) {
363
363
  * @param comment
364
364
  */
365
365
  function renderLatestComment(comment) {
366
- return (React.createElement(CommentsObject, { feedObject: commentsObject.feedObject, feedObjectType: commentsObject.feedObject ? commentsObject.feedObject.type : feedObjectType, hideAdvertising: true, comments: [].concat(commentsObject.comments).reverse(), endComments: comment.latest_comments, previous: comment.comment_count > comment.latest_comments.length ? commentsObject.next : null, isLoadingPrevious: commentsObject.isLoadingNext, handlePrevious: commentsObject.getNextPage, CommentComponentProps: Object.assign(Object.assign({ onOpenReply: reply, CommentObjectSkeletonProps, elevation: elevation, linkableCommentDateTime: linkableCommentDateTime }, rest), { cacheStrategy,
367
- truncateContent }), CommentsObjectSkeletonProps: { count: 1, CommentObjectSkeletonProps: CommentObjectSkeletonProps }, cacheStrategy: cacheStrategy, inPlaceLoadMoreContents: true }));
366
+ return (React.createElement(CommentsObject, Object.assign({ feedObject: commentsObject.feedObject, feedObjectType: commentsObject.feedObject ? commentsObject.feedObject.type : feedObjectType, hideAdvertising: true, comments: [].concat(commentsObject.comments).reverse(), endComments: comment.latest_comments, previous: comment.comment_count > comment.latest_comments.length ? commentsObject.next : null, isLoadingPrevious: commentsObject.isLoadingNext, handlePrevious: commentsObject.getNextPage, CommentComponentProps: Object.assign(Object.assign({ onOpenReply: reply, CommentObjectSkeletonProps, elevation: elevation, linkableCommentDateTime: linkableCommentDateTime }, rest), { cacheStrategy,
367
+ truncateContent }), CommentsObjectSkeletonProps: { count: 1, CommentObjectSkeletonProps: CommentObjectSkeletonProps }, inPlaceLoadMoreContents: true }, CommentsObjectComponentProps, { cacheStrategy: cacheStrategy })));
368
368
  }
369
369
  /**
370
370
  * Render comments
@@ -14,22 +14,18 @@ declare function convertImageElement(domNode: any): {
14
14
  };
15
15
  export declare type SerializedImageNode = Spread<{
16
16
  altText: string;
17
- height?: number;
18
17
  maxWidth: number | string;
19
18
  src: string;
20
- width?: number;
21
19
  type: 'image';
22
20
  version: 1;
23
21
  }, SerializedLexicalNode>;
24
22
  export declare class ImageNode extends DecoratorNode<JSX.Element> {
25
23
  __src: string;
26
24
  __altText: string;
27
- __width: 'inherit' | number;
28
- __height: 'inherit' | number;
29
25
  __maxWidth: number | string;
30
26
  static getType(): string;
31
27
  static clone(node: ImageNode): ImageNode;
32
- constructor(src: string, altText: string, maxWidth: number | string, width?: 'inherit' | number, height?: 'inherit' | number, key?: NodeKey);
28
+ constructor(src: string, altText: string, maxWidth: number | string, key?: NodeKey);
33
29
  setWidthAndHeight(width: 'inherit' | number, height: 'inherit' | number): void;
34
30
  createDOM(config: EditorConfig): HTMLElement;
35
31
  updateDOM(): false;
@@ -44,6 +40,6 @@ export declare class ImageNode extends DecoratorNode<JSX.Element> {
44
40
  static importJSON(serializedNode: SerializedImageNode): ImageNode;
45
41
  exportJSON(): SerializedImageNode;
46
42
  }
47
- export declare function $createImageNode({ src, altText, maxWidth, width, height }: ImagePayload): ImageNode;
43
+ export declare function $createImageNode({ src, altText, maxWidth }: ImagePayload): ImageNode;
48
44
  export declare function $isImageNode(node?: LexicalNode): boolean;
49
45
  export {};
@@ -24,7 +24,7 @@ function LazyImage({ altText, className, imageRef, src, width, height, maxWidth
24
24
  width: `${width}${width === 'inherit' ? '' : 'px'}`
25
25
  } }));
26
26
  }
27
- function ImageComponent({ src, altText, nodeKey, width, height, maxWidth }) {
27
+ function ImageComponent({ src, altText, nodeKey, maxWidth }) {
28
28
  const imageRef = useRef(null);
29
29
  const buttonRef = useRef(null);
30
30
  const [isSelected, setSelected, clearSelection] = useLexicalNodeSelection(nodeKey);
@@ -90,32 +90,29 @@ function ImageComponent({ src, altText, nodeKey, width, height, maxWidth }) {
90
90
  unregister();
91
91
  };
92
92
  }, [clearSelection, editor, isSelected, nodeKey, onDelete, onEnter, onEscape, setSelected]);
93
- const isFocused = isSelected;
94
93
  return (React.createElement(Suspense, { fallback: null },
95
- React.createElement(LazyImage, { className: isFocused ? `focused` : null, src: src, altText: altText, imageRef: imageRef, width: width, height: height, maxWidth: maxWidth })));
94
+ React.createElement(LazyImage, { className: isSelected ? `selected` : null, src: src, altText: altText, imageRef: imageRef, maxWidth: maxWidth })));
96
95
  }
97
96
  function convertImageElement(domNode) {
98
97
  if (domNode instanceof HTMLImageElement) {
99
- const { alt: altText, src, dataset: { width, height } } = domNode;
100
- const node = $createImageNode({ altText, height: Number(height), src, width: Number(width), maxWidth: '100%' });
98
+ const { alt: altText, src } = domNode;
99
+ const node = $createImageNode({ altText, src, maxWidth: '100%' });
101
100
  return { node };
102
101
  }
103
102
  return null;
104
103
  }
105
104
  export class ImageNode extends DecoratorNode {
106
- constructor(src, altText, maxWidth, width, height, key) {
105
+ constructor(src, altText, maxWidth, key) {
107
106
  super(key);
108
107
  this.__src = src;
109
108
  this.__altText = altText;
110
- this.__width = width || 'inherit';
111
109
  this.__maxWidth = maxWidth;
112
- this.__height = height || 'inherit';
113
110
  }
114
111
  static getType() {
115
112
  return 'image';
116
113
  }
117
114
  static clone(node) {
118
- return new ImageNode(node.__src, node.__altText, node.__maxWidth, node.__width, node.__height, node.__key);
115
+ return new ImageNode(node.__src, node.__altText, node.__maxWidth, node.__key);
119
116
  }
120
117
  setWidthAndHeight(width, height) {
121
118
  const writable = this.getWritable();
@@ -128,13 +125,13 @@ export class ImageNode extends DecoratorNode {
128
125
  }
129
126
  // View
130
127
  createDOM(config) {
131
- const span = document.createElement('span');
128
+ const div = document.createElement('div');
132
129
  const theme = config.theme;
133
130
  const className = theme.image;
134
131
  if (className !== undefined) {
135
- span.className = className;
132
+ div.className = className;
136
133
  }
137
- return span;
134
+ return div;
138
135
  }
139
136
  updateDOM() {
140
137
  return false;
@@ -152,21 +149,17 @@ export class ImageNode extends DecoratorNode {
152
149
  const element = document.createElement('img');
153
150
  element.setAttribute('src', this.__src);
154
151
  element.setAttribute('alt', this.__altText);
155
- element.setAttribute('width', `${this.__width}`);
156
- element.setAttribute('height', `${this.__height}`);
157
152
  element.setAttribute('style', `max-width: ${this.__maxWidth}px;`);
158
153
  return { element };
159
154
  }
160
155
  decorate() {
161
- return (React.createElement(ImageComponent, { src: this.__src, altText: this.__altText, width: this.__width, height: this.__height, maxWidth: this.__maxWidth, nodeKey: this.getKey() }));
156
+ return React.createElement(ImageComponent, { src: this.__src, altText: this.__altText, maxWidth: this.__maxWidth, nodeKey: this.getKey() });
162
157
  }
163
158
  static importJSON(serializedNode) {
164
- const { altText, height, width, maxWidth, src } = serializedNode;
159
+ const { altText, maxWidth, src } = serializedNode;
165
160
  const node = $createImageNode({
166
161
  altText,
167
- height,
168
162
  src,
169
- width,
170
163
  maxWidth
171
164
  });
172
165
  return node;
@@ -174,17 +167,15 @@ export class ImageNode extends DecoratorNode {
174
167
  exportJSON() {
175
168
  return {
176
169
  altText: this.getAltText(),
177
- height: this.__height === 'inherit' ? 0 : this.__height,
178
170
  maxWidth: this.__maxWidth,
179
171
  src: this.getSrc(),
180
172
  type: 'image',
181
- version: 1,
182
- width: this.__width === 'inherit' ? 0 : this.__width
173
+ version: 1
183
174
  };
184
175
  }
185
176
  }
186
- export function $createImageNode({ src, altText, maxWidth, width = null, height = null }) {
187
- return new ImageNode(src, altText, maxWidth, width, height);
177
+ export function $createImageNode({ src, altText, maxWidth }) {
178
+ return new ImageNode(src, altText, maxWidth);
188
179
  }
189
180
  export function $isImageNode(node) {
190
181
  return node.getType() === 'image';
@@ -1,6 +1,7 @@
1
1
  import { __rest } from "tslib";
2
2
  import React, { forwardRef, useEffect, useState } from 'react';
3
- import { $getSelection, $isRangeSelection, $isRootNode, COMMAND_PRIORITY_EDITOR, createCommand, INSERT_PARAGRAPH_COMMAND } from 'lexical';
3
+ import { COMMAND_PRIORITY_EDITOR, createCommand, } from 'lexical';
4
+ import { $insertNodeToNearestRoot } from '@lexical/utils';
4
5
  import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
5
6
  import { CircularProgress, Icon, IconButton } from '@mui/material';
6
7
  import { styled } from '@mui/material/styles';
@@ -37,7 +38,6 @@ function Image({ editor, className = '' }) {
37
38
  };
38
39
  editor.focus();
39
40
  editor.dispatchCommand(INSERT_IMAGE_COMMAND, data);
40
- editor.dispatchCommand(INSERT_PARAGRAPH_COMMAND, undefined);
41
41
  };
42
42
  const handleUploadProgress = (chunks) => {
43
43
  setUploading(Object.assign({}, chunks));
@@ -81,20 +81,15 @@ export default function ImagePlugin() {
81
81
  return;
82
82
  }
83
83
  return editor.registerCommand(INSERT_IMAGE_COMMAND, (payload) => {
84
- const selection = $getSelection();
85
- if ($isRangeSelection(selection)) {
86
- if ($isRootNode(selection.anchor.getNode())) {
87
- selection.insertParagraph();
88
- }
89
- const imageNode = $createImageNode({
90
- src: payload.src,
91
- altText: payload.altText,
92
- maxWidth: '100%',
93
- width: payload.width,
94
- height: payload.height
95
- });
96
- selection.insertNodes([imageNode]);
97
- }
84
+ const imageNode = $createImageNode({
85
+ src: payload.src,
86
+ altText: payload.altText,
87
+ maxWidth: '100%',
88
+ width: payload.width,
89
+ height: payload.height
90
+ });
91
+ // The image is not editable so it is better to position it near the root element
92
+ $insertNodeToNearestRoot(imageNode);
98
93
  return true;
99
94
  }, COMMAND_PRIORITY_EDITOR);
100
95
  }, [editor]);