@selfcommunity/react-ui 0.7.0-alpha.323 → 0.7.0-alpha.325

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
+ CommentsObjectProps?: 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, CommentsObjectProps = {} } = props, rest = tslib_1.__rest(props, ["id", "className", "commentObjectId", "commentObject", "feedObjectId", "feedObject", "feedObjectType", "commentReply", "onOpenReply", "onDelete", "onVote", "elevation", "truncateContent", "CommentObjectSkeletonProps", "CommentObjectReplyProps", "linkableCommentDateTime", "cacheStrategy", "CommentsObjectProps"]);
99
99
  // CONTEXT
100
100
  const scContext = (0, react_core_1.useSCContext)();
101
101
  const scUserContext = (0, react_1.useContext)(react_core_1.SCUserContext);
@@ -192,7 +192,10 @@ function CommentObject(inProps) {
192
192
  setIsReplying(true);
193
193
  performReply(comment)
194
194
  .then((data) => {
195
- updateObject(Object.assign(Object.assign({}, obj), { comment_count: obj.comment_count + 1, latest_comments: [...obj.latest_comments, data] }));
195
+ // if add a comment -> the comment must be untruncated
196
+ const _data = data;
197
+ _data.summary_truncated = false;
198
+ updateObject(Object.assign(Object.assign({}, obj), { comment_count: obj.comment_count + 1, latest_comments: [...obj.latest_comments, _data] }));
196
199
  setReplyComment(null);
197
200
  setIsReplying(false);
198
201
  })
@@ -329,8 +332,8 @@ function CommentObject(inProps) {
329
332
  // or the comment author is the logged user
330
333
  return null;
331
334
  }
332
- const commentHtml = comment.summary_html && truncateContent ? comment.summary_html : comment.html;
333
- const summaryHtmlTruncated = comment.summary_truncated ? comment.summary_truncated : false;
335
+ const summaryHtmlTruncated = 'summary_truncated' in comment ? comment.summary_truncated : false;
336
+ const commentHtml = 'summary_html' in comment && truncateContent && summaryHtmlTruncated ? comment.summary_html : comment.html;
334
337
  const summaryHtml = (0, contribution_1.getContributionHtml)(commentHtml, scRoutingContext.url);
335
338
  return (react_1.default.createElement(react_1.default.Fragment, { key: comment.id },
336
339
  editComment && editComment.id === comment.id ? (react_1.default.createElement(material_1.Box, { className: classes.comment },
@@ -362,7 +365,8 @@ function CommentObject(inProps) {
362
365
  * @param comment
363
366
  */
364
367
  function renderLatestComment(comment) {
365
- 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 }), 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 }, CommentsObjectProps, { cacheStrategy: cacheStrategy })));
366
370
  }
367
371
  /**
368
372
  * Render comments
@@ -112,7 +112,7 @@ export interface CommentsObjectProps {
112
112
  hidePaginationLinks?: boolean;
113
113
  /**
114
114
  * Load more contents in place
115
- * rather than opening a new page
115
+ * rather than opening a new page
116
116
  */
117
117
  inPlaceLoadMoreContents?: boolean;
118
118
  /**
@@ -199,9 +199,9 @@ function CommentsObject(inProps) {
199
199
  /**
200
200
  * Render comments and load others with load more button
201
201
  */
202
- function renderComments(comments, truncateContent = null) {
202
+ function renderComments(comments) {
203
203
  return (react_1.default.createElement(react_1.default.Fragment, null, comments.map((comment, index) => (react_1.default.createElement(react_1.default.Fragment, { key: index },
204
- react_1.default.createElement(CommentComponent, Object.assign({ key: comment.id, commentObject: comment, onOpenReply: openReplyBox, feedObject: obj }, CommentComponentProps, { CommentObjectSkeletonProps: CommentObjectSkeletonProps }, (truncateContent !== null ? { truncateContent } : {}))),
204
+ react_1.default.createElement(CommentComponent, Object.assign({ key: comment.id, commentObject: comment, onOpenReply: openReplyBox, feedObject: obj }, CommentComponentProps, { CommentObjectSkeletonProps: CommentObjectSkeletonProps })),
205
205
  advPosition === index && renderAdvertising())))));
206
206
  }
207
207
  /**
@@ -233,8 +233,8 @@ function CommentsObject(inProps) {
233
233
  * Renders root object
234
234
  */
235
235
  return (react_1.default.createElement(Root, Object.assign({ id: id, className: (0, classnames_1.default)(classes.root, className) }, rest),
236
- renderComments(getFilteredComments(startComments), false),
236
+ renderComments(getFilteredComments(startComments)),
237
237
  commentsRendered,
238
- renderComments(getFilteredComments(endComments), false)));
238
+ renderComments(getFilteredComments(endComments))));
239
239
  }
240
240
  exports.default = CommentsObject;
@@ -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);
@@ -96,30 +96,28 @@ function ImageComponent({ src, altText, nodeKey, width, height, maxWidth }) {
96
96
  }, [clearSelection, editor, isSelected, nodeKey, onDelete, onEnter, onEscape, setSelected]);
97
97
  const isFocused = isSelected;
98
98
  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 })));
99
+ react_1.default.createElement(LazyImage, { className: isFocused ? `focused` : null, src: src, altText: altText, imageRef: imageRef, maxWidth: maxWidth })));
100
100
  }
101
101
  function convertImageElement(domNode) {
102
102
  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%' });
103
+ const { alt: altText, src } = domNode;
104
+ const node = $createImageNode({ altText, src, maxWidth: '100%' });
105
105
  return { node };
106
106
  }
107
107
  return null;
108
108
  }
109
109
  class ImageNode extends lexical_1.DecoratorNode {
110
- constructor(src, altText, maxWidth, width, height, key) {
110
+ constructor(src, altText, maxWidth, key) {
111
111
  super(key);
112
112
  this.__src = src;
113
113
  this.__altText = altText;
114
- this.__width = width || 'inherit';
115
114
  this.__maxWidth = maxWidth;
116
- this.__height = height || 'inherit';
117
115
  }
118
116
  static getType() {
119
117
  return 'image';
120
118
  }
121
119
  static clone(node) {
122
- return new ImageNode(node.__src, node.__altText, node.__maxWidth, node.__width, node.__height, node.__key);
120
+ return new ImageNode(node.__src, node.__altText, node.__maxWidth, node.__key);
123
121
  }
124
122
  setWidthAndHeight(width, height) {
125
123
  const writable = this.getWritable();
@@ -156,21 +154,17 @@ class ImageNode extends lexical_1.DecoratorNode {
156
154
  const element = document.createElement('img');
157
155
  element.setAttribute('src', this.__src);
158
156
  element.setAttribute('alt', this.__altText);
159
- element.setAttribute('width', `${this.__width}`);
160
- element.setAttribute('height', `${this.__height}`);
161
157
  element.setAttribute('style', `max-width: ${this.__maxWidth}px;`);
162
158
  return { element };
163
159
  }
164
160
  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() }));
161
+ return react_1.default.createElement(ImageComponent, { src: this.__src, altText: this.__altText, maxWidth: this.__maxWidth, nodeKey: this.getKey() });
166
162
  }
167
163
  static importJSON(serializedNode) {
168
- const { altText, height, width, maxWidth, src } = serializedNode;
164
+ const { altText, maxWidth, src } = serializedNode;
169
165
  const node = $createImageNode({
170
166
  altText,
171
- height,
172
167
  src,
173
- width,
174
168
  maxWidth
175
169
  });
176
170
  return node;
@@ -178,18 +172,16 @@ class ImageNode extends lexical_1.DecoratorNode {
178
172
  exportJSON() {
179
173
  return {
180
174
  altText: this.getAltText(),
181
- height: this.__height === 'inherit' ? 0 : this.__height,
182
175
  maxWidth: this.__maxWidth,
183
176
  src: this.getSrc(),
184
177
  type: 'image',
185
- version: 1,
186
- width: this.__width === 'inherit' ? 0 : this.__width
178
+ version: 1
187
179
  };
188
180
  }
189
181
  }
190
182
  exports.ImageNode = ImageNode;
191
- function $createImageNode({ src, altText, maxWidth, width = null, height = null }) {
192
- return new ImageNode(src, altText, maxWidth, width, height);
183
+ function $createImageNode({ src, altText, maxWidth }) {
184
+ return new ImageNode(src, altText, maxWidth);
193
185
  }
194
186
  exports.$createImageNode = $createImageNode;
195
187
  function $isImageNode(node) {
@@ -415,7 +415,7 @@ const Feed = (inProps, ref) => {
415
415
  react_1.default.createElement(CustomAdv_1.default, Object.assign({ position: types_1.SCCustomAdvPosition.POSITION_BELOW_TOPBAR }, CustomAdvProps)))) : null,
416
416
  react_1.default.createElement(material_1.Grid, { item: true, xs: 12, md: 7 },
417
417
  react_1.default.createElement("div", { style: { overflow: 'visible' } },
418
- react_1.default.createElement(InfiniteScroll_1.default, { className: classes.left, dataLength: feedDataLeft.length, next: getNextPage, previous: getPreviousPage, hasMoreNext: Boolean(feedDataObject.next), hasMorePrevious: Boolean(feedDataObject.previous), header: PreviousPageLink, footer: NextPageLink, loaderNext: react_1.default.createElement(ItemSkeleton, Object.assign({}, ItemSkeletonProps)), loaderPrevious: react_1.default.createElement(ItemSkeleton, Object.assign({}, ItemSkeletonProps)), scrollThreshold: 1, endMessage: react_1.default.createElement(material_1.Box, { className: classes.end },
418
+ react_1.default.createElement(InfiniteScroll_1.default, { className: classes.left, dataLength: feedDataLeft.length, next: getNextPage, previous: getPreviousPage, hasMoreNext: Boolean(feedDataObject.next), hasMorePrevious: Boolean(feedDataObject.previous), header: PreviousPageLink, footer: NextPageLink, loaderNext: react_1.default.createElement(ItemSkeleton, Object.assign({}, ItemSkeletonProps)), loaderPrevious: react_1.default.createElement(ItemSkeleton, Object.assign({}, ItemSkeletonProps)), scrollThreshold: '90%', endMessage: react_1.default.createElement(material_1.Box, { className: classes.end },
419
419
  react_1.default.createElement(Widget_1.default, { className: classes.endMessage },
420
420
  react_1.default.createElement(material_1.CardContent, null, endMessage)),
421
421
  advEnabled && !hideAdvs && enabledCustomAdvPositions.includes(types_1.SCCustomAdvPosition.POSITION_ABOVE_FOOTER_BAR) ? (react_1.default.createElement(CustomAdv_1.default, Object.assign({ position: types_1.SCCustomAdvPosition.POSITION_ABOVE_FOOTER_BAR }, CustomAdvProps))) : null,
@@ -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({}, 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({ truncateContent: true }, CommentComponentProps), { cacheStrategy }), { CommentsObjectProps: Object.assign({ inPlaceLoadMoreContents: false }, CommentsObjectProps) }), 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
  }
@@ -348,12 +348,15 @@ function FeedObject(inProps) {
348
348
  setIsReplying(true);
349
349
  performReply(comment)
350
350
  .then((data) => {
351
+ // if add a comment -> the comment must be untruncated
352
+ const _data = data;
353
+ _data.summary_truncated = false;
351
354
  if (selectedActivities !== feedObject_1.SCFeedObjectActivitiesType.RECENT_COMMENTS) {
352
355
  setComments([]);
353
356
  setSelectedActivities(feedObject_1.SCFeedObjectActivitiesType.RECENT_COMMENTS);
354
357
  }
355
358
  else {
356
- setComments([...[data], ...comments]);
359
+ setComments([...[_data], ...comments]);
357
360
  }
358
361
  setIsReplying(false);
359
362
  const newObj = Object.assign({}, obj, { comment_count: obj.comment_count + 1 });
@@ -380,8 +383,8 @@ function FeedObject(inProps) {
380
383
  * Get contribution summary
381
384
  */
382
385
  const getContributionSummary = (0, react_1.useCallback)((obj, template) => {
383
- const contributionHtml = obj.summary_html ? obj.summary_html : obj.summary;
384
- const summaryHtmlTruncated = obj.summary_truncated ? obj.summary_truncated : obj.html.length >= Feed_1.MAX_SUMMARY_LENGTH;
386
+ const contributionHtml = 'summary_html' in obj ? obj.summary_html : obj.summary;
387
+ const summaryHtmlTruncated = 'summary_truncated' in obj ? obj.summary_truncated : obj.html.length >= Feed_1.MAX_SUMMARY_LENGTH;
385
388
  const summaryHtml = expanded || template === feedObject_1.SCFeedObjectTemplateType.DETAIL
386
389
  ? (0, contribution_1.getContributionHtml)(obj.html, scRoutingContext.url)
387
390
  : (0, contribution_1.getContributionHtml)(contributionHtml, scRoutingContext.url);
@@ -458,7 +461,7 @@ function FeedObject(inProps) {
458
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 } },
459
462
  react_1.default.createElement(CardContent_1.default, { className: classes.activitiesContent },
460
463
  react_1.default.createElement(Activities_1.default, Object.assign({ feedObject: obj, key: selectedActivities, feedObjectActivities: feedObjectActivities, activitiesType: selectedActivities, onSetSelectedActivities: handleSelectedActivities, comments: comments, CommentsObjectProps: {
461
- CommentComponentProps: Object.assign({ onDelete: handleDeleteComment, truncateContent: true }, CommentComponentProps),
464
+ CommentComponentProps: Object.assign({ onDelete: handleDeleteComment, truncateContent: true, CommentsObjectProps: { inPlaceLoadMoreContents: false } }, CommentComponentProps),
462
465
  CommentObjectSkeletonProps: CommentObjectSkeletonProps
463
466
  }, cacheStrategy: cacheStrategy }, ActivitiesProps))))),
464
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
+ CommentsObjectProps?: 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, CommentsObjectProps = {} } = props, rest = __rest(props, ["id", "className", "commentObjectId", "commentObject", "feedObjectId", "feedObject", "feedObjectType", "commentReply", "onOpenReply", "onDelete", "onVote", "elevation", "truncateContent", "CommentObjectSkeletonProps", "CommentObjectReplyProps", "linkableCommentDateTime", "cacheStrategy", "CommentsObjectProps"]);
97
97
  // CONTEXT
98
98
  const scContext = useSCContext();
99
99
  const scUserContext = useContext(SCUserContext);
@@ -190,7 +190,10 @@ export default function CommentObject(inProps) {
190
190
  setIsReplying(true);
191
191
  performReply(comment)
192
192
  .then((data) => {
193
- updateObject(Object.assign(Object.assign({}, obj), { comment_count: obj.comment_count + 1, latest_comments: [...obj.latest_comments, data] }));
193
+ // if add a comment -> the comment must be untruncated
194
+ const _data = data;
195
+ _data.summary_truncated = false;
196
+ updateObject(Object.assign(Object.assign({}, obj), { comment_count: obj.comment_count + 1, latest_comments: [...obj.latest_comments, _data] }));
194
197
  setReplyComment(null);
195
198
  setIsReplying(false);
196
199
  })
@@ -327,8 +330,8 @@ export default function CommentObject(inProps) {
327
330
  // or the comment author is the logged user
328
331
  return null;
329
332
  }
330
- const commentHtml = comment.summary_html && truncateContent ? comment.summary_html : comment.html;
331
- const summaryHtmlTruncated = comment.summary_truncated ? comment.summary_truncated : false;
333
+ const summaryHtmlTruncated = 'summary_truncated' in comment ? comment.summary_truncated : false;
334
+ const commentHtml = 'summary_html' in comment && truncateContent && summaryHtmlTruncated ? comment.summary_html : comment.html;
332
335
  const summaryHtml = getContributionHtml(commentHtml, scRoutingContext.url);
333
336
  return (React.createElement(React.Fragment, { key: comment.id },
334
337
  editComment && editComment.id === comment.id ? (React.createElement(Box, { className: classes.comment },
@@ -360,7 +363,8 @@ export default function CommentObject(inProps) {
360
363
  * @param comment
361
364
  */
362
365
  function renderLatestComment(comment) {
363
- 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 }), 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 }, CommentsObjectProps, { cacheStrategy: cacheStrategy })));
364
368
  }
365
369
  /**
366
370
  * Render comments
@@ -112,7 +112,7 @@ export interface CommentsObjectProps {
112
112
  hidePaginationLinks?: boolean;
113
113
  /**
114
114
  * Load more contents in place
115
- * rather than opening a new page
115
+ * rather than opening a new page
116
116
  */
117
117
  inPlaceLoadMoreContents?: boolean;
118
118
  /**
@@ -197,9 +197,9 @@ export default function CommentsObject(inProps) {
197
197
  /**
198
198
  * Render comments and load others with load more button
199
199
  */
200
- function renderComments(comments, truncateContent = null) {
200
+ function renderComments(comments) {
201
201
  return (React.createElement(React.Fragment, null, comments.map((comment, index) => (React.createElement(React.Fragment, { key: index },
202
- React.createElement(CommentComponent, Object.assign({ key: comment.id, commentObject: comment, onOpenReply: openReplyBox, feedObject: obj }, CommentComponentProps, { CommentObjectSkeletonProps: CommentObjectSkeletonProps }, (truncateContent !== null ? { truncateContent } : {}))),
202
+ React.createElement(CommentComponent, Object.assign({ key: comment.id, commentObject: comment, onOpenReply: openReplyBox, feedObject: obj }, CommentComponentProps, { CommentObjectSkeletonProps: CommentObjectSkeletonProps })),
203
203
  advPosition === index && renderAdvertising())))));
204
204
  }
205
205
  /**
@@ -231,7 +231,7 @@ export default function CommentsObject(inProps) {
231
231
  * Renders root object
232
232
  */
233
233
  return (React.createElement(Root, Object.assign({ id: id, className: classNames(classes.root, className) }, rest),
234
- renderComments(getFilteredComments(startComments), false),
234
+ renderComments(getFilteredComments(startComments)),
235
235
  commentsRendered,
236
- renderComments(getFilteredComments(endComments), false)));
236
+ renderComments(getFilteredComments(endComments))));
237
237
  }
@@ -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);
@@ -92,30 +92,28 @@ function ImageComponent({ src, altText, nodeKey, width, height, maxWidth }) {
92
92
  }, [clearSelection, editor, isSelected, nodeKey, onDelete, onEnter, onEscape, setSelected]);
93
93
  const isFocused = isSelected;
94
94
  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 })));
95
+ React.createElement(LazyImage, { className: isFocused ? `focused` : null, src: src, altText: altText, imageRef: imageRef, maxWidth: maxWidth })));
96
96
  }
97
97
  function convertImageElement(domNode) {
98
98
  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%' });
99
+ const { alt: altText, src } = domNode;
100
+ const node = $createImageNode({ altText, src, maxWidth: '100%' });
101
101
  return { node };
102
102
  }
103
103
  return null;
104
104
  }
105
105
  export class ImageNode extends DecoratorNode {
106
- constructor(src, altText, maxWidth, width, height, key) {
106
+ constructor(src, altText, maxWidth, key) {
107
107
  super(key);
108
108
  this.__src = src;
109
109
  this.__altText = altText;
110
- this.__width = width || 'inherit';
111
110
  this.__maxWidth = maxWidth;
112
- this.__height = height || 'inherit';
113
111
  }
114
112
  static getType() {
115
113
  return 'image';
116
114
  }
117
115
  static clone(node) {
118
- return new ImageNode(node.__src, node.__altText, node.__maxWidth, node.__width, node.__height, node.__key);
116
+ return new ImageNode(node.__src, node.__altText, node.__maxWidth, node.__key);
119
117
  }
120
118
  setWidthAndHeight(width, height) {
121
119
  const writable = this.getWritable();
@@ -152,21 +150,17 @@ export class ImageNode extends DecoratorNode {
152
150
  const element = document.createElement('img');
153
151
  element.setAttribute('src', this.__src);
154
152
  element.setAttribute('alt', this.__altText);
155
- element.setAttribute('width', `${this.__width}`);
156
- element.setAttribute('height', `${this.__height}`);
157
153
  element.setAttribute('style', `max-width: ${this.__maxWidth}px;`);
158
154
  return { element };
159
155
  }
160
156
  decorate() {
161
- return (React.createElement(ImageComponent, { src: this.__src, altText: this.__altText, width: this.__width, height: this.__height, maxWidth: this.__maxWidth, nodeKey: this.getKey() }));
157
+ return React.createElement(ImageComponent, { src: this.__src, altText: this.__altText, maxWidth: this.__maxWidth, nodeKey: this.getKey() });
162
158
  }
163
159
  static importJSON(serializedNode) {
164
- const { altText, height, width, maxWidth, src } = serializedNode;
160
+ const { altText, maxWidth, src } = serializedNode;
165
161
  const node = $createImageNode({
166
162
  altText,
167
- height,
168
163
  src,
169
- width,
170
164
  maxWidth
171
165
  });
172
166
  return node;
@@ -174,17 +168,15 @@ export class ImageNode extends DecoratorNode {
174
168
  exportJSON() {
175
169
  return {
176
170
  altText: this.getAltText(),
177
- height: this.__height === 'inherit' ? 0 : this.__height,
178
171
  maxWidth: this.__maxWidth,
179
172
  src: this.getSrc(),
180
173
  type: 'image',
181
- version: 1,
182
- width: this.__width === 'inherit' ? 0 : this.__width
174
+ version: 1
183
175
  };
184
176
  }
185
177
  }
186
- export function $createImageNode({ src, altText, maxWidth, width = null, height = null }) {
187
- return new ImageNode(src, altText, maxWidth, width, height);
178
+ export function $createImageNode({ src, altText, maxWidth }) {
179
+ return new ImageNode(src, altText, maxWidth);
188
180
  }
189
181
  export function $isImageNode(node) {
190
182
  return node.getType() === 'image';
@@ -412,7 +412,7 @@ const Feed = (inProps, ref) => {
412
412
  React.createElement(CustomAdv, Object.assign({ position: SCCustomAdvPosition.POSITION_BELOW_TOPBAR }, CustomAdvProps)))) : null,
413
413
  React.createElement(Grid, { item: true, xs: 12, md: 7 },
414
414
  React.createElement("div", { style: { overflow: 'visible' } },
415
- React.createElement(InfiniteScroll, { className: classes.left, dataLength: feedDataLeft.length, next: getNextPage, previous: getPreviousPage, hasMoreNext: Boolean(feedDataObject.next), hasMorePrevious: Boolean(feedDataObject.previous), header: PreviousPageLink, footer: NextPageLink, loaderNext: React.createElement(ItemSkeleton, Object.assign({}, ItemSkeletonProps)), loaderPrevious: React.createElement(ItemSkeleton, Object.assign({}, ItemSkeletonProps)), scrollThreshold: 1, endMessage: React.createElement(Box, { className: classes.end },
415
+ React.createElement(InfiniteScroll, { className: classes.left, dataLength: feedDataLeft.length, next: getNextPage, previous: getPreviousPage, hasMoreNext: Boolean(feedDataObject.next), hasMorePrevious: Boolean(feedDataObject.previous), header: PreviousPageLink, footer: NextPageLink, loaderNext: React.createElement(ItemSkeleton, Object.assign({}, ItemSkeletonProps)), loaderPrevious: React.createElement(ItemSkeleton, Object.assign({}, ItemSkeletonProps)), scrollThreshold: '90%', endMessage: React.createElement(Box, { className: classes.end },
416
416
  React.createElement(Widget, { className: classes.endMessage },
417
417
  React.createElement(CardContent, null, endMessage)),
418
418
  advEnabled && !hideAdvs && enabledCustomAdvPositions.includes(SCCustomAdvPosition.POSITION_ABOVE_FOOTER_BAR) ? (React.createElement(CustomAdv, Object.assign({ position: SCCustomAdvPosition.POSITION_ABOVE_FOOTER_BAR }, CustomAdvProps))) : null,
@@ -88,7 +88,7 @@ export default function Activities(inProps) {
88
88
  * Render comments of feedObject
89
89
  */
90
90
  function renderComments() {
91
- return (React.createElement(React.Fragment, null, (commentsObject.feedObject.comment_count > 0 || comments.length > 0) && (React.createElement(CommentsObject, 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({}, CommentComponentProps), { cacheStrategy }), (CommentsObjectProps.CommentComponentProps ? CommentsObjectProps.CommentComponentProps : {})), inPlaceLoadMoreContents: false })))));
91
+ return (React.createElement(React.Fragment, null, (commentsObject.feedObject.comment_count > 0 || comments.length > 0) && (React.createElement(CommentsObject, 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: Object.assign({ inPlaceLoadMoreContents: false }, CommentsObjectProps) }), inPlaceLoadMoreContents: false })))));
92
92
  }
93
93
  /**
94
94
  * Renders root object