@selfcommunity/react-ui 0.7.0-alpha.316 → 0.7.0-alpha.317
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/lib/cjs/components/CategoriesPopularWidget/CategoriesPopularWidget.d.ts +1 -1
- package/lib/cjs/components/CategoriesPopularWidget/CategoriesPopularWidget.js +1 -1
- package/lib/cjs/components/CommentObject/CommentObject.js +7 -1
- package/lib/cjs/components/FeedObject/FeedObject.js +36 -13
- package/lib/cjs/constants/Feed.d.ts +1 -0
- package/lib/cjs/constants/Feed.js +2 -1
- package/lib/cjs/utils/contribution.d.ts +2 -2
- package/lib/cjs/utils/contribution.js +3 -3
- package/lib/esm/components/CategoriesPopularWidget/CategoriesPopularWidget.d.ts +1 -1
- package/lib/esm/components/CategoriesPopularWidget/CategoriesPopularWidget.js +1 -1
- package/lib/esm/components/CommentObject/CommentObject.js +7 -1
- package/lib/esm/components/FeedObject/FeedObject.js +36 -13
- package/lib/esm/constants/Feed.d.ts +1 -0
- package/lib/esm/constants/Feed.js +1 -0
- package/lib/esm/utils/contribution.d.ts +2 -2
- package/lib/esm/utils/contribution.js +3 -3
- package/lib/umd/react-ui.js +1 -1
- package/package.json +6 -6
|
@@ -40,7 +40,7 @@ export interface CategoriesPopularWidgetProps extends VirtualScrollerItemProps,
|
|
|
40
40
|
*
|
|
41
41
|
* This component renders a list of popular categories.
|
|
42
42
|
* Take a look at our <strong>demo</strong> component [here](/docs/sdk/community-js/react-ui/Components/CategoriesPopular)
|
|
43
|
-
|
|
43
|
+
|
|
44
44
|
#### Import
|
|
45
45
|
```jsx
|
|
46
46
|
import {CategoriesPopular} from '@selfcommunity/react-ui';
|
|
@@ -43,7 +43,7 @@ const DialogRoot = (0, styles_1.styled)(BaseDialog_1.default, {
|
|
|
43
43
|
*
|
|
44
44
|
* This component renders a list of popular categories.
|
|
45
45
|
* Take a look at our <strong>demo</strong> component [here](/docs/sdk/community-js/react-ui/Components/CategoriesPopular)
|
|
46
|
-
|
|
46
|
+
|
|
47
47
|
#### Import
|
|
48
48
|
```jsx
|
|
49
49
|
import {CategoriesPopular} from '@selfcommunity/react-ui';
|
|
@@ -34,6 +34,7 @@ const classes = {
|
|
|
34
34
|
nestedComments: `${PREFIX}-nested-comments`,
|
|
35
35
|
avatar: `${PREFIX}-avatar`,
|
|
36
36
|
content: `${PREFIX}-content`,
|
|
37
|
+
showMoreContent: `${PREFIX}-show-more-content`,
|
|
37
38
|
author: `${PREFIX}-author`,
|
|
38
39
|
textContent: `${PREFIX}-text-content`,
|
|
39
40
|
commentActionsMenu: `${PREFIX}-comment-actions-menu`,
|
|
@@ -328,6 +329,9 @@ function CommentObject(inProps) {
|
|
|
328
329
|
// or the comment author is the logged user
|
|
329
330
|
return null;
|
|
330
331
|
}
|
|
332
|
+
const commentHtml = comment.summary_html ? comment.summary_html : comment.html;
|
|
333
|
+
const summaryHtmlTruncated = comment.summary_truncated ? comment.summary_truncated : false;
|
|
334
|
+
const summaryHtml = (0, contribution_1.getContributionHtml)(commentHtml, scRoutingContext.url);
|
|
331
335
|
return (react_1.default.createElement(react_1.default.Fragment, { key: comment.id },
|
|
332
336
|
editComment && editComment.id === comment.id ? (react_1.default.createElement(material_1.Box, { className: classes.comment },
|
|
333
337
|
react_1.default.createElement(CommentObjectReply_1.default, Object.assign({ text: comment.html, autoFocus: true, id: `edit-${comment.id}`, onSave: handleSave, onCancel: handleCancel, editable: !isReplying || !isSavingComment }, CommentObjectReplyProps)))) : (react_1.default.createElement(BaseItem_1.default, { elevation: 0, className: classes.comment, image: react_1.default.createElement(react_core_1.Link, Object.assign({}, (!comment.author.deleted && { to: scRoutingContext.url(react_core_1.SCRoutes.USER_PROFILE_ROUTE_NAME, comment.author) }), { onClick: comment.author.deleted ? () => setOpenAlert(true) : null }),
|
|
@@ -337,7 +341,9 @@ function CommentObject(inProps) {
|
|
|
337
341
|
react_1.default.createElement(material_1.CardContent, { className: (0, classnames_1.default)({ [classes.deleted]: obj && obj.deleted }) },
|
|
338
342
|
react_1.default.createElement(react_core_1.Link, Object.assign({ className: classes.author }, (!comment.author.deleted && { to: scRoutingContext.url(react_core_1.SCRoutes.USER_PROFILE_ROUTE_NAME, comment.author) }), { onClick: comment.author.deleted ? () => setOpenAlert(true) : null }),
|
|
339
343
|
react_1.default.createElement(material_1.Typography, { component: "span" }, comment.author.username)),
|
|
340
|
-
react_1.default.createElement(material_1.Typography, { className: classes.textContent, variant: "body2", gutterBottom: true, dangerouslySetInnerHTML: { __html:
|
|
344
|
+
react_1.default.createElement(material_1.Typography, { className: classes.textContent, variant: "body2", gutterBottom: true, dangerouslySetInnerHTML: { __html: summaryHtml } }),
|
|
345
|
+
summaryHtmlTruncated && (react_1.default.createElement(react_core_1.Link, { to: scRoutingContext.url(react_core_1.SCRoutes.COMMENT_ROUTE_NAME, (0, contribution_1.getRouteData)(comment)), className: classes.showMoreContent },
|
|
346
|
+
react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.commentObject.showMore", defaultMessage: "ui.commentObject.showMore" })))),
|
|
341
347
|
scUserContext.user && (react_1.default.createElement(material_1.Box, { className: classes.commentActionsMenu },
|
|
342
348
|
react_1.default.createElement(ContributionActionsMenu_1.default, { commentObject: comment, onRestoreContribution: handleRestore, onHideContribution: handleHide, onDeleteContribution: handleDelete, onEditContribution: handleEdit })))),
|
|
343
349
|
react_1.default.createElement(material_1.Box, { component: "span", className: classes.contentSubSection },
|
|
@@ -15,7 +15,6 @@ const Icon_1 = tslib_1.__importDefault(require("@mui/material/Icon"));
|
|
|
15
15
|
const react_intl_1 = require("react-intl");
|
|
16
16
|
const Poll_1 = tslib_1.__importDefault(require("./Poll"));
|
|
17
17
|
const Contributors_1 = tslib_1.__importDefault(require("./Contributors"));
|
|
18
|
-
const Composer_1 = tslib_1.__importDefault(require("../Composer"));
|
|
19
18
|
const feedObject_1 = require("../../types/feedObject");
|
|
20
19
|
const MarkRead_1 = tslib_1.__importDefault(require("../../shared/MarkRead"));
|
|
21
20
|
const classnames_1 = tslib_1.__importDefault(require("classnames"));
|
|
@@ -36,7 +35,8 @@ const errors_1 = require("../../utils/errors");
|
|
|
36
35
|
const react_core_1 = require("@selfcommunity/react-core");
|
|
37
36
|
const UserDeletedSnackBar_1 = tslib_1.__importDefault(require("../../shared/UserDeletedSnackBar"));
|
|
38
37
|
const UserAvatar_1 = tslib_1.__importDefault(require("../../shared/UserAvatar"));
|
|
39
|
-
const
|
|
38
|
+
const Feed_1 = require("../../constants/Feed");
|
|
39
|
+
const Composer_1 = tslib_1.__importDefault(require("../Composer"));
|
|
40
40
|
const messages = (0, react_intl_1.defineMessages)({
|
|
41
41
|
visibleToAll: {
|
|
42
42
|
id: 'ui.feedObject.visibleToAll',
|
|
@@ -369,6 +369,38 @@ function FeedObject(inProps) {
|
|
|
369
369
|
});
|
|
370
370
|
}
|
|
371
371
|
};
|
|
372
|
+
/**
|
|
373
|
+
* Get contribution summary
|
|
374
|
+
*/
|
|
375
|
+
const getContributionSummary = (0, react_1.useCallback)((obj, template) => {
|
|
376
|
+
const contributionHtml = obj.summary_html ? obj.summary_html : obj.summary;
|
|
377
|
+
const summaryHtmlTruncated = obj.summary_truncated ? obj.summary_truncated : obj.html.length >= Feed_1.MAX_SUMMARY_LENGTH;
|
|
378
|
+
const summaryHtml = expanded || template === feedObject_1.SCFeedObjectTemplateType.DETAIL
|
|
379
|
+
? (0, contribution_1.getContributionHtml)(obj.html, scRoutingContext.url)
|
|
380
|
+
: (0, contribution_1.getContributionHtml)(contributionHtml, scRoutingContext.url);
|
|
381
|
+
if (template === feedObject_1.SCFeedObjectTemplateType.SHARE) {
|
|
382
|
+
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
383
|
+
react_1.default.createElement(react_core_1.Link, { to: scRoutingContext.url((0, contribution_1.getContributionRouteName)(obj), (0, contribution_1.getRouteData)(obj)), className: classes.text },
|
|
384
|
+
react_1.default.createElement(material_1.Typography, { component: "div", className: classes.text, variant: "body2", gutterBottom: true, dangerouslySetInnerHTML: {
|
|
385
|
+
__html: summaryHtml
|
|
386
|
+
} })),
|
|
387
|
+
!expanded && summaryHtmlTruncated && (react_1.default.createElement(material_1.Button, { size: "small", variant: "text", color: "inherit", onClick: () => setExpanded(!expanded) },
|
|
388
|
+
react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.feedObject.content.showMore", defaultMessage: "ui.feedObject.content.showMore" })))));
|
|
389
|
+
}
|
|
390
|
+
else if (template === feedObject_1.SCFeedObjectTemplateType.DETAIL) {
|
|
391
|
+
return (react_1.default.createElement(material_1.Typography, { component: "div", gutterBottom: true, className: classes.text, dangerouslySetInnerHTML: {
|
|
392
|
+
__html: summaryHtml
|
|
393
|
+
} }));
|
|
394
|
+
}
|
|
395
|
+
else {
|
|
396
|
+
return (react_1.default.createElement(material_1.Typography, { component: "div", gutterBottom: true, className: classes.text },
|
|
397
|
+
react_1.default.createElement(material_1.Typography, { component: "span", dangerouslySetInnerHTML: {
|
|
398
|
+
__html: summaryHtml
|
|
399
|
+
} }),
|
|
400
|
+
!expanded && summaryHtmlTruncated && (react_1.default.createElement(material_1.Button, { size: "small", variant: "text", color: "inherit", onClick: () => setExpanded(!expanded) },
|
|
401
|
+
react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.feedObject.content.showMore", defaultMessage: "ui.feedObject.content.showMore" })))));
|
|
402
|
+
}
|
|
403
|
+
}, [obj, template, expanded]);
|
|
372
404
|
/**
|
|
373
405
|
* Render the obj object
|
|
374
406
|
* Manage variants:
|
|
@@ -402,12 +434,7 @@ function FeedObject(inProps) {
|
|
|
402
434
|
react_1.default.createElement(CardContent_1.default, { classes: { root: classes.content } },
|
|
403
435
|
react_1.default.createElement(material_1.Box, { className: classes.titleSection }, 'title' in obj && (react_1.default.createElement(react_1.default.Fragment, null, template === feedObject_1.SCFeedObjectTemplateType.DETAIL ? (react_1.default.createElement(material_1.Typography, { variant: "body1", gutterBottom: true, className: classes.title }, obj.title)) : (react_1.default.createElement(react_core_1.Link, { to: scRoutingContext.url((0, contribution_1.getContributionRouteName)(obj), (0, contribution_1.getRouteData)(obj)) },
|
|
404
436
|
react_1.default.createElement(material_1.Typography, { variant: "body1", gutterBottom: true, className: classes.title }, obj.title)))))),
|
|
405
|
-
react_1.default.createElement(material_1.Box, { className: classes.textSection },
|
|
406
|
-
__html: (0, contribution_1.getContributionHtml)(obj, scRoutingContext.url)
|
|
407
|
-
} })) : (react_1.default.createElement(material_1.Typography, { component: "div", gutterBottom: true, className: classes.text },
|
|
408
|
-
react_1.default.createElement(material_1.Typography, { component: "span", dangerouslySetInnerHTML: { __html: expanded ? (0, contribution_1.getContributionHtml)(obj, scRoutingContext.url) : obj.summary } }),
|
|
409
|
-
!expanded && obj.html.length >= MAX_SUMMARY_LENGTH && (react_1.default.createElement(material_1.Button, { size: "small", variant: "text", color: "inherit", onClick: () => setExpanded(!expanded) },
|
|
410
|
-
react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.feedObject.content.showMore", defaultMessage: "ui.feedObject.content.showMore" })))))),
|
|
437
|
+
react_1.default.createElement(material_1.Box, { className: classes.textSection }, getContributionSummary(obj, template)),
|
|
411
438
|
react_1.default.createElement(material_1.Box, { className: classes.mediasSection },
|
|
412
439
|
react_1.default.createElement(MediasPreview_1.default, Object.assign({ medias: obj.medias }, MediasPreviewProps))),
|
|
413
440
|
react_1.default.createElement(material_1.Box, { className: classes.pollsSection }, obj['poll'] && (react_1.default.createElement(Poll_1.default, Object.assign({ visible: pollVisible ||
|
|
@@ -440,11 +467,7 @@ function FeedObject(inProps) {
|
|
|
440
467
|
react_1.default.createElement(CardContent_1.default, { classes: { root: classes.content } },
|
|
441
468
|
react_1.default.createElement(material_1.Box, { className: classes.titleSection }, 'title' in obj && (react_1.default.createElement(react_core_1.Link, { to: scRoutingContext.url((0, contribution_1.getContributionRouteName)(obj), (0, contribution_1.getRouteData)(obj)) },
|
|
442
469
|
react_1.default.createElement(material_1.Typography, { variant: "body1", gutterBottom: true, className: classes.title }, obj.title)))),
|
|
443
|
-
react_1.default.createElement(material_1.Box, { className: classes.textSection },
|
|
444
|
-
react_1.default.createElement(react_core_1.Link, { to: scRoutingContext.url((0, contribution_1.getContributionRouteName)(obj), (0, contribution_1.getRouteData)(obj)), className: classes.text },
|
|
445
|
-
react_1.default.createElement(material_1.Typography, { component: "div", className: classes.text, variant: "body2", gutterBottom: true, dangerouslySetInnerHTML: { __html: expanded ? (0, contribution_1.getContributionHtml)(obj, scRoutingContext.url) : obj.summary } })),
|
|
446
|
-
!expanded && obj.html.length >= MAX_SUMMARY_LENGTH && (react_1.default.createElement(material_1.Button, { size: "small", variant: "text", color: "inherit", onClick: () => setExpanded(!expanded) },
|
|
447
|
-
react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.feedObject.content.showMore", defaultMessage: "ui.feedObject.content.showMore" })))),
|
|
470
|
+
react_1.default.createElement(material_1.Box, { className: classes.textSection }, getContributionSummary(obj, template)),
|
|
448
471
|
react_1.default.createElement(material_1.Box, { className: classes.mediasSection },
|
|
449
472
|
react_1.default.createElement(MediasPreview_1.default, Object.assign({ medias: obj.medias }, MediasPreviewProps))),
|
|
450
473
|
react_1.default.createElement(material_1.Box, { className: classes.pollsSection }, obj['poll'] && (react_1.default.createElement(Poll_1.default, Object.assign({ feedObject: obj, pollObject: obj['poll'], onChange: handleChangePoll, visible: Boolean(obj.type !== types_1.SCContributionType.DISCUSSION && !obj.html && !obj.medias.length) }, PollObjectProps))))))) : (react_1.default.createElement(Skeleton_1.default, Object.assign({ template: template }, FeedObjectSkeletonProps)))));
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DEFAULT_WIDGETS_NUMBER = exports.WIDGET_PREFIX_KEY = void 0;
|
|
3
|
+
exports.MAX_SUMMARY_LENGTH = exports.DEFAULT_WIDGETS_NUMBER = exports.WIDGET_PREFIX_KEY = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Feed constants
|
|
6
6
|
*/
|
|
7
7
|
exports.WIDGET_PREFIX_KEY = 'widget_';
|
|
8
8
|
exports.DEFAULT_WIDGETS_NUMBER = 10; // every how many elements insert a widget
|
|
9
|
+
exports.MAX_SUMMARY_LENGTH = 150; // maximum number of characters for the summary before being truncated
|
|
@@ -17,10 +17,10 @@ export declare function getContributionSnippet(obj: any): any;
|
|
|
17
17
|
/**
|
|
18
18
|
* Get the contribution text
|
|
19
19
|
* Hydrate text with mention, etc.
|
|
20
|
-
* @param
|
|
20
|
+
* @param html Html of the contribution
|
|
21
21
|
* @param handleUrl Func that handle urls
|
|
22
22
|
*/
|
|
23
|
-
export declare function getContributionHtml(
|
|
23
|
+
export declare function getContributionHtml(html: any, handleUrl: any): any;
|
|
24
24
|
/**
|
|
25
25
|
* Get route name for a contribution
|
|
26
26
|
* @param obj
|
|
@@ -54,11 +54,11 @@ exports.getContributionSnippet = getContributionSnippet;
|
|
|
54
54
|
/**
|
|
55
55
|
* Get the contribution text
|
|
56
56
|
* Hydrate text with mention, etc.
|
|
57
|
-
* @param
|
|
57
|
+
* @param html Html of the contribution
|
|
58
58
|
* @param handleUrl Func that handle urls
|
|
59
59
|
*/
|
|
60
|
-
function getContributionHtml(
|
|
61
|
-
return
|
|
60
|
+
function getContributionHtml(html, handleUrl) {
|
|
61
|
+
return html.replace(/<mention.*? id="([0-9]+)"{1}.*?>@([a-z\d_]+)<\/mention>/gi, (match, id, username) => {
|
|
62
62
|
return `<a href='${handleUrl(react_core_1.SCRoutes.USER_PROFILE_ROUTE_NAME, { id, username })}'>@${username}</a>`;
|
|
63
63
|
});
|
|
64
64
|
}
|
|
@@ -40,7 +40,7 @@ export interface CategoriesPopularWidgetProps extends VirtualScrollerItemProps,
|
|
|
40
40
|
*
|
|
41
41
|
* This component renders a list of popular categories.
|
|
42
42
|
* Take a look at our <strong>demo</strong> component [here](/docs/sdk/community-js/react-ui/Components/CategoriesPopular)
|
|
43
|
-
|
|
43
|
+
|
|
44
44
|
#### Import
|
|
45
45
|
```jsx
|
|
46
46
|
import {CategoriesPopular} from '@selfcommunity/react-ui';
|
|
@@ -41,7 +41,7 @@ const DialogRoot = styled(BaseDialog, {
|
|
|
41
41
|
*
|
|
42
42
|
* This component renders a list of popular categories.
|
|
43
43
|
* Take a look at our <strong>demo</strong> component [here](/docs/sdk/community-js/react-ui/Components/CategoriesPopular)
|
|
44
|
-
|
|
44
|
+
|
|
45
45
|
#### Import
|
|
46
46
|
```jsx
|
|
47
47
|
import {CategoriesPopular} from '@selfcommunity/react-ui';
|
|
@@ -32,6 +32,7 @@ const classes = {
|
|
|
32
32
|
nestedComments: `${PREFIX}-nested-comments`,
|
|
33
33
|
avatar: `${PREFIX}-avatar`,
|
|
34
34
|
content: `${PREFIX}-content`,
|
|
35
|
+
showMoreContent: `${PREFIX}-show-more-content`,
|
|
35
36
|
author: `${PREFIX}-author`,
|
|
36
37
|
textContent: `${PREFIX}-text-content`,
|
|
37
38
|
commentActionsMenu: `${PREFIX}-comment-actions-menu`,
|
|
@@ -326,6 +327,9 @@ export default function CommentObject(inProps) {
|
|
|
326
327
|
// or the comment author is the logged user
|
|
327
328
|
return null;
|
|
328
329
|
}
|
|
330
|
+
const commentHtml = comment.summary_html ? comment.summary_html : comment.html;
|
|
331
|
+
const summaryHtmlTruncated = comment.summary_truncated ? comment.summary_truncated : false;
|
|
332
|
+
const summaryHtml = getContributionHtml(commentHtml, scRoutingContext.url);
|
|
329
333
|
return (React.createElement(React.Fragment, { key: comment.id },
|
|
330
334
|
editComment && editComment.id === comment.id ? (React.createElement(Box, { className: classes.comment },
|
|
331
335
|
React.createElement(CommentObjectReply, Object.assign({ text: comment.html, autoFocus: true, id: `edit-${comment.id}`, onSave: handleSave, onCancel: handleCancel, editable: !isReplying || !isSavingComment }, CommentObjectReplyProps)))) : (React.createElement(BaseItem, { elevation: 0, className: classes.comment, image: React.createElement(Link, Object.assign({}, (!comment.author.deleted && { to: scRoutingContext.url(SCRoutes.USER_PROFILE_ROUTE_NAME, comment.author) }), { onClick: comment.author.deleted ? () => setOpenAlert(true) : null }),
|
|
@@ -335,7 +339,9 @@ export default function CommentObject(inProps) {
|
|
|
335
339
|
React.createElement(CardContent, { className: classNames({ [classes.deleted]: obj && obj.deleted }) },
|
|
336
340
|
React.createElement(Link, Object.assign({ className: classes.author }, (!comment.author.deleted && { to: scRoutingContext.url(SCRoutes.USER_PROFILE_ROUTE_NAME, comment.author) }), { onClick: comment.author.deleted ? () => setOpenAlert(true) : null }),
|
|
337
341
|
React.createElement(Typography, { component: "span" }, comment.author.username)),
|
|
338
|
-
React.createElement(Typography, { className: classes.textContent, variant: "body2", gutterBottom: true, dangerouslySetInnerHTML: { __html:
|
|
342
|
+
React.createElement(Typography, { className: classes.textContent, variant: "body2", gutterBottom: true, dangerouslySetInnerHTML: { __html: summaryHtml } }),
|
|
343
|
+
summaryHtmlTruncated && (React.createElement(Link, { to: scRoutingContext.url(SCRoutes.COMMENT_ROUTE_NAME, getRouteData(comment)), className: classes.showMoreContent },
|
|
344
|
+
React.createElement(FormattedMessage, { id: "ui.commentObject.showMore", defaultMessage: "ui.commentObject.showMore" })))),
|
|
339
345
|
scUserContext.user && (React.createElement(Box, { className: classes.commentActionsMenu },
|
|
340
346
|
React.createElement(ContributionActionsMenu, { commentObject: comment, onRestoreContribution: handleRestore, onHideContribution: handleHide, onDeleteContribution: handleDelete, onEditContribution: handleEdit })))),
|
|
341
347
|
React.createElement(Box, { component: "span", className: classes.contentSubSection },
|
|
@@ -13,7 +13,6 @@ import Icon from '@mui/material/Icon';
|
|
|
13
13
|
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
|
14
14
|
import PollObject from './Poll';
|
|
15
15
|
import ContributorsFeedObject from './Contributors';
|
|
16
|
-
import Composer from '../Composer';
|
|
17
16
|
import { SCFeedObjectActivitiesType, SCFeedObjectTemplateType } from '../../types/feedObject';
|
|
18
17
|
import MarkRead from '../../shared/MarkRead';
|
|
19
18
|
import classNames from 'classnames';
|
|
@@ -34,7 +33,8 @@ import { catchUnauthorizedActionByBlockedUser } from '../../utils/errors';
|
|
|
34
33
|
import { Link, SCCache, SCRoutes, UserUtils, useSCContext, useSCFetchFeedObject, useSCRouting, useSCUser } from '@selfcommunity/react-core';
|
|
35
34
|
import UserDeletedSnackBar from '../../shared/UserDeletedSnackBar';
|
|
36
35
|
import UserAvatar from '../../shared/UserAvatar';
|
|
37
|
-
|
|
36
|
+
import { MAX_SUMMARY_LENGTH } from '../../constants/Feed';
|
|
37
|
+
import Composer from '../Composer';
|
|
38
38
|
const messages = defineMessages({
|
|
39
39
|
visibleToAll: {
|
|
40
40
|
id: 'ui.feedObject.visibleToAll',
|
|
@@ -367,6 +367,38 @@ export default function FeedObject(inProps) {
|
|
|
367
367
|
});
|
|
368
368
|
}
|
|
369
369
|
};
|
|
370
|
+
/**
|
|
371
|
+
* Get contribution summary
|
|
372
|
+
*/
|
|
373
|
+
const getContributionSummary = useCallback((obj, template) => {
|
|
374
|
+
const contributionHtml = obj.summary_html ? obj.summary_html : obj.summary;
|
|
375
|
+
const summaryHtmlTruncated = obj.summary_truncated ? obj.summary_truncated : obj.html.length >= MAX_SUMMARY_LENGTH;
|
|
376
|
+
const summaryHtml = expanded || template === SCFeedObjectTemplateType.DETAIL
|
|
377
|
+
? getContributionHtml(obj.html, scRoutingContext.url)
|
|
378
|
+
: getContributionHtml(contributionHtml, scRoutingContext.url);
|
|
379
|
+
if (template === SCFeedObjectTemplateType.SHARE) {
|
|
380
|
+
return (React.createElement(React.Fragment, null,
|
|
381
|
+
React.createElement(Link, { to: scRoutingContext.url(getContributionRouteName(obj), getRouteData(obj)), className: classes.text },
|
|
382
|
+
React.createElement(Typography, { component: "div", className: classes.text, variant: "body2", gutterBottom: true, dangerouslySetInnerHTML: {
|
|
383
|
+
__html: summaryHtml
|
|
384
|
+
} })),
|
|
385
|
+
!expanded && summaryHtmlTruncated && (React.createElement(Button, { size: "small", variant: "text", color: "inherit", onClick: () => setExpanded(!expanded) },
|
|
386
|
+
React.createElement(FormattedMessage, { id: "ui.feedObject.content.showMore", defaultMessage: "ui.feedObject.content.showMore" })))));
|
|
387
|
+
}
|
|
388
|
+
else if (template === SCFeedObjectTemplateType.DETAIL) {
|
|
389
|
+
return (React.createElement(Typography, { component: "div", gutterBottom: true, className: classes.text, dangerouslySetInnerHTML: {
|
|
390
|
+
__html: summaryHtml
|
|
391
|
+
} }));
|
|
392
|
+
}
|
|
393
|
+
else {
|
|
394
|
+
return (React.createElement(Typography, { component: "div", gutterBottom: true, className: classes.text },
|
|
395
|
+
React.createElement(Typography, { component: "span", dangerouslySetInnerHTML: {
|
|
396
|
+
__html: summaryHtml
|
|
397
|
+
} }),
|
|
398
|
+
!expanded && summaryHtmlTruncated && (React.createElement(Button, { size: "small", variant: "text", color: "inherit", onClick: () => setExpanded(!expanded) },
|
|
399
|
+
React.createElement(FormattedMessage, { id: "ui.feedObject.content.showMore", defaultMessage: "ui.feedObject.content.showMore" })))));
|
|
400
|
+
}
|
|
401
|
+
}, [obj, template, expanded]);
|
|
370
402
|
/**
|
|
371
403
|
* Render the obj object
|
|
372
404
|
* Manage variants:
|
|
@@ -400,12 +432,7 @@ export default function FeedObject(inProps) {
|
|
|
400
432
|
React.createElement(CardContent, { classes: { root: classes.content } },
|
|
401
433
|
React.createElement(Box, { className: classes.titleSection }, 'title' in obj && (React.createElement(React.Fragment, null, template === SCFeedObjectTemplateType.DETAIL ? (React.createElement(Typography, { variant: "body1", gutterBottom: true, className: classes.title }, obj.title)) : (React.createElement(Link, { to: scRoutingContext.url(getContributionRouteName(obj), getRouteData(obj)) },
|
|
402
434
|
React.createElement(Typography, { variant: "body1", gutterBottom: true, className: classes.title }, obj.title)))))),
|
|
403
|
-
React.createElement(Box, { className: classes.textSection },
|
|
404
|
-
__html: getContributionHtml(obj, scRoutingContext.url)
|
|
405
|
-
} })) : (React.createElement(Typography, { component: "div", gutterBottom: true, className: classes.text },
|
|
406
|
-
React.createElement(Typography, { component: "span", dangerouslySetInnerHTML: { __html: expanded ? getContributionHtml(obj, scRoutingContext.url) : obj.summary } }),
|
|
407
|
-
!expanded && obj.html.length >= MAX_SUMMARY_LENGTH && (React.createElement(Button, { size: "small", variant: "text", color: "inherit", onClick: () => setExpanded(!expanded) },
|
|
408
|
-
React.createElement(FormattedMessage, { id: "ui.feedObject.content.showMore", defaultMessage: "ui.feedObject.content.showMore" })))))),
|
|
435
|
+
React.createElement(Box, { className: classes.textSection }, getContributionSummary(obj, template)),
|
|
409
436
|
React.createElement(Box, { className: classes.mediasSection },
|
|
410
437
|
React.createElement(MediasPreview, Object.assign({ medias: obj.medias }, MediasPreviewProps))),
|
|
411
438
|
React.createElement(Box, { className: classes.pollsSection }, obj['poll'] && (React.createElement(PollObject, Object.assign({ visible: pollVisible ||
|
|
@@ -438,11 +465,7 @@ export default function FeedObject(inProps) {
|
|
|
438
465
|
React.createElement(CardContent, { classes: { root: classes.content } },
|
|
439
466
|
React.createElement(Box, { className: classes.titleSection }, 'title' in obj && (React.createElement(Link, { to: scRoutingContext.url(getContributionRouteName(obj), getRouteData(obj)) },
|
|
440
467
|
React.createElement(Typography, { variant: "body1", gutterBottom: true, className: classes.title }, obj.title)))),
|
|
441
|
-
React.createElement(Box, { className: classes.textSection },
|
|
442
|
-
React.createElement(Link, { to: scRoutingContext.url(getContributionRouteName(obj), getRouteData(obj)), className: classes.text },
|
|
443
|
-
React.createElement(Typography, { component: "div", className: classes.text, variant: "body2", gutterBottom: true, dangerouslySetInnerHTML: { __html: expanded ? getContributionHtml(obj, scRoutingContext.url) : obj.summary } })),
|
|
444
|
-
!expanded && obj.html.length >= MAX_SUMMARY_LENGTH && (React.createElement(Button, { size: "small", variant: "text", color: "inherit", onClick: () => setExpanded(!expanded) },
|
|
445
|
-
React.createElement(FormattedMessage, { id: "ui.feedObject.content.showMore", defaultMessage: "ui.feedObject.content.showMore" })))),
|
|
468
|
+
React.createElement(Box, { className: classes.textSection }, getContributionSummary(obj, template)),
|
|
446
469
|
React.createElement(Box, { className: classes.mediasSection },
|
|
447
470
|
React.createElement(MediasPreview, Object.assign({ medias: obj.medias }, MediasPreviewProps))),
|
|
448
471
|
React.createElement(Box, { className: classes.pollsSection }, obj['poll'] && (React.createElement(PollObject, Object.assign({ feedObject: obj, pollObject: obj['poll'], onChange: handleChangePoll, visible: Boolean(obj.type !== SCContributionType.DISCUSSION && !obj.html && !obj.medias.length) }, PollObjectProps))))))) : (React.createElement(FeedObjectSkeleton, Object.assign({ template: template }, FeedObjectSkeletonProps)))));
|
|
@@ -17,10 +17,10 @@ export declare function getContributionSnippet(obj: any): any;
|
|
|
17
17
|
/**
|
|
18
18
|
* Get the contribution text
|
|
19
19
|
* Hydrate text with mention, etc.
|
|
20
|
-
* @param
|
|
20
|
+
* @param html Html of the contribution
|
|
21
21
|
* @param handleUrl Func that handle urls
|
|
22
22
|
*/
|
|
23
|
-
export declare function getContributionHtml(
|
|
23
|
+
export declare function getContributionHtml(html: any, handleUrl: any): any;
|
|
24
24
|
/**
|
|
25
25
|
* Get route name for a contribution
|
|
26
26
|
* @param obj
|
|
@@ -47,11 +47,11 @@ export function getContributionSnippet(obj) {
|
|
|
47
47
|
/**
|
|
48
48
|
* Get the contribution text
|
|
49
49
|
* Hydrate text with mention, etc.
|
|
50
|
-
* @param
|
|
50
|
+
* @param html Html of the contribution
|
|
51
51
|
* @param handleUrl Func that handle urls
|
|
52
52
|
*/
|
|
53
|
-
export function getContributionHtml(
|
|
54
|
-
return
|
|
53
|
+
export function getContributionHtml(html, handleUrl) {
|
|
54
|
+
return html.replace(/<mention.*? id="([0-9]+)"{1}.*?>@([a-z\d_]+)<\/mention>/gi, (match, id, username) => {
|
|
55
55
|
return `<a href='${handleUrl(SCRoutes.USER_PROFILE_ROUTE_NAME, { id, username })}'>@${username}</a>`;
|
|
56
56
|
});
|
|
57
57
|
}
|