@selfcommunity/react-ui
Version:
React UI Components to integrate a Community created with SelfCommunity Platform.
450 lines (441 loc) • 36.3 kB
JavaScript
import { __rest } from "tslib";
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { styled } from '@mui/material/styles';
import CardContent from '@mui/material/CardContent';
import { Avatar, Box, Button, CardActions, CardHeader, Chip, Collapse, Stack, Tooltip, Typography } from '@mui/material';
import FeedObjectSkeleton from './Skeleton';
import DateTimeAgo from '../../shared/DateTimeAgo';
import Bullet from '../../shared/Bullet';
import Tags from '../../shared/Tags';
import Actions from './Actions';
import Icon from '@mui/material/Icon';
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
import PollObject from './Poll';
import ContributorsFeedObject from './Contributors';
import { SCFeedObjectActivitiesType, SCFeedObjectTemplateType } from '../../types/feedObject';
import MarkRead from '../../shared/MarkRead';
import classNames from 'classnames';
import ContributionActionsMenu from '../../shared/ContributionActionsMenu';
import { getContributionHtml, getContributionRouteName, getContributionSnippet, getRouteData } from '../../utils/contribution';
import Follow from './Actions/Follow';
import Widget from '../Widget';
import { useThemeProps } from '@mui/system';
import BaseItem from '../../shared/BaseItem';
import Activities from './Activities';
import CommentObjectReply from '../CommentObjectReply';
import { SCOPE_SC_UI } from '../../constants/Errors';
import { useSnackbar } from 'notistack';
import { SCContributionType } from '@selfcommunity/types';
import { Endpoints, http } from '@selfcommunity/api-services';
import { CacheStrategies, Logger, LRUCache } from '@selfcommunity/utils';
import { catchUnauthorizedActionByBlockedUser } from '../../utils/errors';
import { Link, SCCache, SCRoutes, UserUtils, useSCContext, useSCFetchFeedObject, useSCRouting, useSCUser } from '@selfcommunity/react-core';
import UserDeletedSnackBar from '../../shared/UserDeletedSnackBar';
import UserAvatar from '../../shared/UserAvatar';
import { MAX_SUMMARY_LENGTH } from '../../constants/Feed';
import Composer from '../Composer';
import FeedObjectMediaPreview from '../FeedObjectMediaPreview';
import { PREFIX } from './constants';
import { MEDIA_EMBED_SC_SHARED_EVENT } from '../../constants/Media';
const messages = defineMessages({
visibleToAll: {
id: 'ui.feedObject.visibleToAll',
defaultMessage: 'ui.feedObject.visibleToAll'
},
visibleToGroup: {
id: 'ui.feedObject.visibleToGroup',
defaultMessage: 'ui.feedObject.visibleToGroup'
}
});
const classes = {
root: `${PREFIX}-root`,
deleted: `${PREFIX}-deleted`,
header: `${PREFIX}-header`,
category: `${PREFIX}-category`,
event: `${PREFIX}-event`,
group: `${PREFIX}-group`,
avatar: `${PREFIX}-avatar`,
username: `${PREFIX}-username`,
activityAt: `${PREFIX}-activity-at`,
tag: `${PREFIX}-tag`,
location: `${PREFIX}-location`,
content: `${PREFIX}-content`,
showMore: `${PREFIX}-show-more`,
error: `${PREFIX}-error`,
titleSection: `${PREFIX}-title-section`,
title: `${PREFIX}-title`,
textSection: `${PREFIX}-text-section`,
text: `${PREFIX}-text`,
snippet: `${PREFIX}-snippet`,
snippetContent: `${PREFIX}-snippet-content`,
mediasSection: `${PREFIX}-medias-section`,
pollsSection: `${PREFIX}-polls-section`,
infoSection: `${PREFIX}-info-section`,
actionsSection: `${PREFIX}-actions-section`,
replyContent: `${PREFIX}-reply-content`,
activitiesSection: `${PREFIX}-activities-section`,
activitiesContent: `${PREFIX}-activities-content`,
followButton: `${PREFIX}-follow-button`
};
const Root = styled(Widget, {
name: PREFIX,
slot: 'Root'
})(() => ({}));
/**
* > API documentation for the Community-JS Feed Object component. Learn about the available props and the CSS API.
*
*
* This component renders a feed object item (post, discussion or status).
* Take a look at our <strong>demo</strong> component [here](/docs/sdk/community-js/react-ui/Components/FeedObject)
#### Import
```jsx
import {FeedObject} from '@selfcommunity/react-ui';
```
#### Component Name
The name `SCFeedObject` can be used when providing style overrides in the theme.
#### CSS
|Rule Name|Global class|Description|
|---|---|---|
|root|.SCFeedObject-root|Styles applied to the root element.|
|deleted|.SCFeedObject-deleted|Styles applied to the feed obj when is deleted (visible only for admin and moderator).|
|header|.SCFeedObject-header|Styles applied to the header of the card.|
|category|.SCFeedObject-category|Styles applied to the category element.|
|event|.SCFeedObject-event|Styles applied to the event element.|
|group|.SCFeedObject-group|Styles applied to the group element.|
|avatar|.SCFeedObject-avatar|Styles applied to the avatar element.|
|username|.SCFeedObject-username|Styles applied to the username element.|
|activityAt|.SCFeedObject-activity-at|Styles applied to the activity at section.|
|tag|.SCFeedObject-tag|Styles applied to the tag element.|
|location|.SCFeedObject-location|Styles applied to the location element.|
|content|.SCFeedObject-content|Styles applied to the content section. Content section include: title-section, text-section, snippetContent, subContent, medias-section, polls-section, info-section.|
|error|.SCFeedObject-error|Styles applied to the error element.|
|title-section|.SCFeedObject-title-section|Styles applied to the title section.|
|title|.SCFeedObject-title|Styles applied to the title element.|
|text-section|.SCFeedObject-text-section|Styles applied to the text section.|
|text|.SCFeedObject-text|Styles applied to the text element.|
|snippet|.SCFeedObject-snippet|Styles applied to snippet element.|
|snippet-content|.SCFeedObject-snippet-content|Styles applied to snippet content element.|
|medias-section|.SCFeedObject-medias-section|Styles applied to the medias section.|
|polls-section|.SCFeedObject-polls-section|Styles applied to the polls section.|
|info-section|.SCFeedObject-info-section|Styles applied to the info section.|
|actions-section|.SCFeedObject-actions-section|Styles applied to the actions container.|
|reply-content|.SCFeedObject-reply-content|Styles applied to the reply box.|
|activitiesSection|.SCFeedObject-activities-section|Styles applied to the activities section element.|
|activitiesContent|.SCFeedObject-activities-content|Styles applied to the activities content element.|
|followButton|.SCFeedObject-follow-button|Styles applied to the follow button element.|
* @param inProps
*/
export default function FeedObject(inProps) {
var _a, _b, _c, _d, _f, _g, _h;
// PROPS
const props = useThemeProps({
props: inProps,
name: PREFIX
});
const { id = `feed_object_${props.feedObjectId ? props.feedObjectId : props.feedObject ? props.feedObject.id : ''}`, className = null, feedObjectId = null, feedObject = null, feedObjectType = null, feedObjectActivities = null, cacheStrategy = CacheStrategies.CACHE_FIRST, markRead = false, template = SCFeedObjectTemplateType.PREVIEW, hideFollowAction = false, summaryExpanded = false, activitiesExpanded = true, activitiesExpandedType, hideParticipantsPreview = false, pollVisible = true, FollowButtonProps = {}, FeedObjectSkeletonProps = { elevation: 0 }, ActionsProps = {}, CommentObjectReplyComponent = CommentObjectReply, CommentObjectReplyComponentProps = { WidgetProps: { variant: 'outlined' } }, CommentComponentProps = { variant: 'outlined' }, CommentObjectSkeletonProps = { elevation: 0, WidgetProps: { variant: 'outlined' } }, ContributionActionsMenuProps = {}, FeedObjectMediaPreviewProps = {}, ActivitiesProps = { cacheStrategy }, PollObjectProps = { elevation: 0 }, ContributorsFeedObjectProps = {}, onReply, onHeightChange, onStateChange } = props, rest = __rest(props, ["id", "className", "feedObjectId", "feedObject", "feedObjectType", "feedObjectActivities", "cacheStrategy", "markRead", "template", "hideFollowAction", "summaryExpanded", "activitiesExpanded", "activitiesExpandedType", "hideParticipantsPreview", "pollVisible", "FollowButtonProps", "FeedObjectSkeletonProps", "ActionsProps", "CommentObjectReplyComponent", "CommentObjectReplyComponentProps", "CommentComponentProps", "CommentObjectSkeletonProps", "ContributionActionsMenuProps", "FeedObjectMediaPreviewProps", "ActivitiesProps", "PollObjectProps", "ContributorsFeedObjectProps", "onReply", "onHeightChange", "onStateChange"]);
// CONTEXT
const scContext = useSCContext();
const scRoutingContext = useSCRouting();
const scUserContext = useSCUser();
const { enqueueSnackbar } = useSnackbar();
// OBJECTS
const { obj, setObj, error } = useSCFetchFeedObject({ id: feedObjectId, feedObject, feedObjectType, cacheStrategy });
const objId = obj ? obj.id : null;
const [openAlert, setOpenAlert] = useState(false);
/**
* Get initial expanded activities type
*/
const geExpandedActivities = () => {
return obj && activitiesExpanded && (obj.comment_count > 0 || (feedObjectActivities && feedObjectActivities.length > 0));
};
// STATE
const [composerOpen, setComposerOpen] = useState(false);
const [expandedActivities, setExpandedActivities] = useState(geExpandedActivities());
const [comments, setComments] = useState([]);
const [isReplying, setIsReplying] = useState(false);
const [selectedActivities, setSelectedActivities] = useState(getInitialSelectedActivitiesType());
const [expanded, setExpanded] = useState(summaryExpanded);
const hasEvent = useMemo(() => { var _a; return (obj === null || obj === void 0 ? void 0 : obj.medias.length) > 0 && ((_a = obj.medias[0].embed) === null || _a === void 0 ? void 0 : _a.embed_type) === MEDIA_EMBED_SC_SHARED_EVENT; }, [obj === null || obj === void 0 ? void 0 : obj.medias]);
const _hideFollowAction = useMemo(() => { var _a, _b, _c, _d; return hideFollowAction || (hasEvent && ((_d = (_c = (_b = (_a = obj === null || obj === void 0 ? void 0 : obj.medias) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.embed) === null || _c === void 0 ? void 0 : _c.metadata) === null || _d === void 0 ? void 0 : _d.active) === false); }, [hideFollowAction, hasEvent, obj]);
// INTL
const intl = useIntl();
/**
* Notify changes to Feed if the FeedObject is contained in the feed
*/
const notifyFeedChanges = useMemo(() => (state) => {
if (onStateChange && state) {
onStateChange(state);
}
onHeightChange && onHeightChange();
}, [onStateChange, onHeightChange]);
/**
* Update state object
* @param newObj
*/
const updateObject = (newObj) => {
setObj(newObj);
notifyFeedChanges();
};
/**
* Get initial selected activities section
*/
function getInitialSelectedActivitiesType() {
if (activitiesExpandedType) {
return activitiesExpandedType;
}
if (feedObjectActivities && feedObjectActivities.length > 0) {
return SCFeedObjectActivitiesType.RELEVANCE_ACTIVITIES;
}
return SCFeedObjectActivitiesType.RECENT_COMMENTS;
}
/**
* Open expanded activities
*/
useEffect(() => {
const _e = geExpandedActivities();
setExpandedActivities(_e);
notifyFeedChanges({ activitiesExpanded: _e, activitiesExpandedType: selectedActivities, cacheStrategy: CacheStrategies.CACHE_FIRST });
}, [objId, selectedActivities]);
/**
* Handle change/update poll: votes
*/
const handleChangePoll = useCallback((pollChoices) => {
if ('poll' in obj) {
updateObject(Object.assign({}, obj, { poll: Object.assign(Object.assign({}, obj.poll), { choices: pollChoices }) }));
}
}, [obj]);
/**
* Handle change poll visibility
*/
const handleTogglePollVisibility = useCallback((visible) => {
notifyFeedChanges({ pollVisible: visible });
}, [pollVisible, notifyFeedChanges]);
/**
* Handle toggle summary
*/
const handleToggleSummary = useCallback(() => {
setExpanded(!expanded);
notifyFeedChanges({ summaryExpanded: !expanded });
}, [expanded, notifyFeedChanges]);
/**
* Render header action
* if author = authenticated user -> render edit action
* else render ContributionActionsMenu
*/
const renderHeaderAction = () => {
return (_jsx(ContributionActionsMenu, Object.assign({ feedObject: obj, feedObjectType: feedObjectType, onEditContribution: handleToggleEdit, onHideContribution: handleHide, onDeleteContribution: handleDelete, onRestoreContribution: handleRestore, onSuspendNotificationContribution: handleSuspendNotification, onFlagContribution: handleFlag }, ContributionActionsMenuProps)));
};
/**
* Handle flag obj
*/
const handleFlag = useCallback((obj, type, flagged) => {
enqueueSnackbar(flagged ? (_jsx(FormattedMessage, { id: "ui.feedObject.flagSent", defaultMessage: "ui.feedObject.flagSent" })) : (_jsx(FormattedMessage, { id: "ui.feedObject.flagRemoved", defaultMessage: "ui.feedObject.flagRemoved" })), {
autoHideDuration: 3000
});
}, []);
/**
* Handle restore obj
*/
const handleRestore = useCallback(() => {
updateObject(Object.assign({}, obj, { deleted: false }));
}, [obj]);
/**
* Handle restore obj
*/
const handleHide = useCallback(() => {
updateObject(Object.assign({}, obj, { collapsed: !obj.collapsed }));
}, [obj]);
/**
* Handle delete obj
*/
const handleDelete = useCallback(() => {
updateObject(Object.assign({}, obj, { deleted: !obj.deleted }));
}, [obj]);
/**
* Handle suspend notification obj
*/
const handleSuspendNotification = useCallback(() => {
updateObject(Object.assign({}, obj, { suspended: !obj.suspended }));
enqueueSnackbar(obj.suspended ? (_jsx(FormattedMessage, { id: "ui.feedObject.notificationsEnabled", defaultMessage: "ui.feedObject.notificationsEnabled" })) : (_jsx(FormattedMessage, { id: "ui.feedObject.notificationsDisabled", defaultMessage: "ui.feedObject.notificationsDisabled" })), {
autoHideDuration: 3000
});
}, [obj]);
/**
* Handle initial edit
* Open composer
*/
const handleToggleEdit = useCallback(() => {
setComposerOpen((prev) => !prev);
}, [composerOpen]);
/**
* handle edit success
*/
const handleEditSuccess = useCallback((data) => {
updateObject(data);
setComposerOpen(false);
}, [obj, composerOpen]);
/**
* handle vote
*/
const handleVoteSuccess = useCallback((data) => {
updateObject(Object.assign({}, obj, { voted: data.voted, vote_count: data.vote_count, reactions_count: data.reactions_count, reaction: data.reaction }));
}, [obj]);
/**
* Expand activities if the user is logged
*/
const handleExpandActivities = useCallback(() => {
if (scUserContext.user) {
const _e = !expandedActivities;
setExpandedActivities(_e);
notifyFeedChanges({ activitiesExpanded: _e });
}
else {
scContext.settings.handleAnonymousAction();
}
}, [expandedActivities, scUserContext.user, notifyFeedChanges, selectedActivities]);
/**
* Handle follow obj
*/
const handleFollow = useCallback((isFollow) => {
updateObject(Object.assign(Object.assign({}, obj), { followed: isFollow }));
}, [obj]);
/**
* Handle delete comment callback
*/
const handleDeleteComment = useCallback(() => {
updateObject(Object.assign(Object.assign({}, obj), { comment_count: Math.max(obj.comment_count - 1, 0) }));
}, [obj]);
/**
* Handle select activities
*/
const handleSelectedActivities = useCallback((type) => {
setSelectedActivities(type);
setComments([]);
notifyFeedChanges({ activitiesExpandedType: type });
}, [obj, expandedActivities]);
/**
* Perform reply
* Comment of first level
*/
const performReply = useMemo(() => (comment) => {
return http
.request({
url: Endpoints.NewComment.url({}),
method: Endpoints.NewComment.method,
data: {
[`${obj.type}`]: obj.id,
text: comment
}
})
.then((res) => {
if (res.status >= 300) {
return Promise.reject(res);
}
return Promise.resolve(res.data);
});
}, [objId]);
/**
* Handle comment
*/
const handleReply = (comment) => {
if (!scUserContext.user) {
scContext.settings.handleAnonymousAction();
}
else if (UserUtils.isBlocked(scUserContext.user)) {
enqueueSnackbar(_jsx(FormattedMessage, { id: "ui.common.userBlocked", defaultMessage: "ui.common.userBlocked" }), {
variant: 'warning',
autoHideDuration: 3000
});
}
else {
setIsReplying(true);
performReply(comment)
.then((data) => {
// if add a comment -> the comment must be untruncated
const _data = data;
_data.summary_truncated = false;
if (selectedActivities !== SCFeedObjectActivitiesType.RECENT_COMMENTS) {
setComments([]);
setSelectedActivities(SCFeedObjectActivitiesType.RECENT_COMMENTS);
}
else {
setComments([...[_data], ...comments]);
}
setIsReplying(false);
const newObj = Object.assign({}, obj, { comment_count: obj.comment_count + 1 });
updateObject(newObj);
LRUCache.deleteKeysWithPrefix(SCCache.getCommentObjectsCachePrefixKeys(obj.id, obj.type));
onReply && onReply(data);
notifyFeedChanges({
activitiesExpanded: expandedActivities,
activitiesExpandedType: SCFeedObjectActivitiesType.RECENT_COMMENTS
});
})
.catch((error) => {
Logger.error(SCOPE_SC_UI, error);
if (!catchUnauthorizedActionByBlockedUser(error, scUserContext.managers.blockedUsers.isBlocked(obj.author), enqueueSnackbar)) {
enqueueSnackbar(_jsx(FormattedMessage, { id: "ui.common.error.action", defaultMessage: "ui.common.error.action" }), {
variant: 'error',
autoHideDuration: 3000
});
}
});
}
};
/**
* Get contribution summary
*/
const getContributionSummary = useCallback((obj, template) => {
const contributionHtml = 'summary_html' in obj ? obj.summary_html : obj.summary;
const summaryHtmlTruncated = 'summary_truncated' in obj ? obj.summary_truncated : obj.html.length >= MAX_SUMMARY_LENGTH;
const summaryHtml = expanded || template === SCFeedObjectTemplateType.DETAIL
? getContributionHtml(obj.html, scRoutingContext.url)
: getContributionHtml(contributionHtml, scRoutingContext.url);
if (template === SCFeedObjectTemplateType.SHARE) {
return (_jsxs(Link, Object.assign({ to: scRoutingContext.url(getContributionRouteName(obj), getRouteData(obj)), className: classes.text }, { children: [_jsx(Typography, { component: "span", className: classes.text, variant: "body2", gutterBottom: true, dangerouslySetInnerHTML: {
__html: summaryHtml
} }), !expanded && summaryHtmlTruncated && (_jsx(Button, Object.assign({ size: "small", variant: "text", color: "inherit", className: classes.showMore, onClick: handleToggleSummary }, { children: _jsx(FormattedMessage, { id: "ui.feedObject.content.showMore", defaultMessage: "ui.feedObject.content.showMore" }) })))] })));
}
else if (template === SCFeedObjectTemplateType.DETAIL) {
return (_jsx(Typography, { component: "div", gutterBottom: true, className: classes.text, dangerouslySetInnerHTML: {
__html: summaryHtml
} }));
}
else {
return (_jsxs(Typography, Object.assign({ component: "div", gutterBottom: true, className: classes.text }, { children: [_jsx(Typography, { component: "span", dangerouslySetInnerHTML: {
__html: summaryHtml
} }), !expanded && summaryHtmlTruncated && (_jsx(Button, Object.assign({ size: "small", variant: "text", color: "inherit", className: classes.showMore, onClick: handleToggleSummary }, { children: _jsx(FormattedMessage, { id: "ui.feedObject.content.showMore", defaultMessage: "ui.feedObject.content.showMore" }) })))] })));
}
}, [obj, template, expanded]);
/**
* Render the obj object
* Manage variants:
* SNIPPET, PREVIEW, DETAIL, SEARCH, SHARE
*/
let objElement;
if ((!obj && error) ||
((obj === null || obj === void 0 ? void 0 : obj.deleted) && !scUserContext.user && !(UserUtils.isAdmin(scUserContext.user) || UserUtils.isModerator(scUserContext.user)))) {
objElement = (_jsx(CardContent, Object.assign({ className: classNames(classes.error, classes.content) }, { children: _jsx(FormattedMessage, { id: "ui.feedObject.error", defaultMessage: "ui.feedObject.error" }) })));
}
else if (template === SCFeedObjectTemplateType.PREVIEW ||
template === SCFeedObjectTemplateType.DETAIL ||
template === SCFeedObjectTemplateType.SEARCH) {
objElement = (_jsx(React.Fragment, { children: obj ? (_jsxs(Box, Object.assign({ className: classNames({ [classes.deleted]: obj && obj.deleted }) }, { children: [obj.categories.length > 0 && (_jsxs("div", Object.assign({ className: classes.category }, { children: [_jsxs(_Fragment, { children: [obj.group && (_jsx(Chip, { className: classes.group, color: "secondary", size: "small", icon: _jsx(Icon, { children: "groups" }), component: Link, to: scRoutingContext.url(SCRoutes.GROUP_ROUTE_NAME, obj.group), clickable: true }, obj.group.id)), obj.event && (_jsx(Chip, { className: classes.event, color: "secondary", size: "small", label: obj.event.name, icon: _jsx(Icon, { children: "CalendarIcon" }), component: Link, to: scRoutingContext.url(SCRoutes.EVENT_ROUTE_NAME, obj.event), clickable: true }, obj.event.id))] }), obj.categories.map((c) => (_jsx(Link, Object.assign({ to: scRoutingContext.url(SCRoutes.CATEGORY_ROUTE_NAME, c) }, { children: _jsx(Typography, Object.assign({ variant: "overline" }, { children: c.name })) }), c.id)))] }))), obj.group && !obj.categories.length && (_jsx("div", Object.assign({ className: classes.group }, { children: _jsx(Chip, { color: "secondary", size: "small", icon: _jsx(Icon, { children: "groups" }), label: obj.group.name, component: Link, to: scRoutingContext.url(SCRoutes.GROUP_ROUTE_NAME, obj.group), clickable: true }, obj.group.id) }))), obj.event && !obj.categories.length && (_jsx(Chip, { className: classes.event, color: "secondary", size: "small", icon: _jsx(Icon, { children: "CalendarIcon" }), label: obj.event.name, component: Link, to: scRoutingContext.url(SCRoutes.EVENT_ROUTE_NAME, obj.event), clickable: true }, obj.event.id)), _jsx(CardHeader, { className: classes.header, avatar: _jsx(Link, Object.assign({}, (!obj.author.deleted && { to: scRoutingContext.url(SCRoutes.USER_PROFILE_ROUTE_NAME, obj.author) }), { onClick: obj.author.deleted ? () => setOpenAlert(true) : null }, { children: _jsx(UserAvatar, Object.assign({ hide: !obj.author.community_badge }, { children: _jsx(Avatar, Object.assign({ "aria-label": "recipe", src: obj.author.avatar, className: classes.avatar }, { children: obj.author.username })) })) })), title: _jsx(Link, Object.assign({}, (!obj.author.deleted && { to: scRoutingContext.url(SCRoutes.USER_PROFILE_ROUTE_NAME, obj.author) }), { onClick: obj.author.deleted ? () => setOpenAlert(true) : null, className: classes.username }, { children: obj.author.username })), subheader: _jsxs(_Fragment, { children: [_jsx(Link, Object.assign({ to: scRoutingContext.url(getContributionRouteName(obj), getRouteData(obj)), className: classes.activityAt }, { children: _jsx(DateTimeAgo, { component: 'span', date: obj.added_at }) })), obj.location && (_jsxs(_Fragment, { children: [_jsx(Bullet, {}), _jsxs(Box, Object.assign({ className: classes.location }, { children: [_jsx(Icon, { children: "add_location_alt" }), (_a = obj.location) === null || _a === void 0 ? void 0 : _a.location] }))] })), _jsx(Bullet, {}), _jsx(Box, Object.assign({ className: classes.tag }, { children: obj.addressing.length > 0 ? (_jsx(Tags, { tags: obj.addressing, TagChipProps: { disposable: false, clickable: false } })) : obj.group ? (_jsx(Tooltip, Object.assign({ title: `${intl.formatMessage(messages.visibleToGroup, { group: obj.group.name })}` }, { children: _jsx(Icon, Object.assign({ color: "disabled", fontSize: "small" }, { children: "groups" })) }))) : (_jsx(Tooltip, Object.assign({ title: `${intl.formatMessage(messages.visibleToAll)}` }, { children: _jsx(Icon, Object.assign({ color: "disabled", fontSize: "small" }, { children: "public" })) }))) }))] }), action: renderHeaderAction() }), _jsxs(CardContent, Object.assign({ classes: { root: classes.content } }, { children: [_jsx(Box, Object.assign({ className: classes.titleSection }, { children: 'title' in obj && (_jsx(_Fragment, { children: template === SCFeedObjectTemplateType.DETAIL ? (_jsx(Typography, Object.assign({ variant: "body1", gutterBottom: true, className: classes.title }, { children: obj.title }))) : (_jsx(Link, Object.assign({ to: scRoutingContext.url(getContributionRouteName(obj), getRouteData(obj)) }, { children: _jsx(Typography, Object.assign({ variant: "body1", gutterBottom: true, className: classes.title }, { children: obj.title })) }))) })) })), _jsx(Box, Object.assign({ className: classes.textSection }, { children: getContributionSummary(obj, template) })), _jsx(Box, Object.assign({ className: classes.mediasSection }, { children: _jsx(FeedObjectMediaPreview, Object.assign({ medias: obj.medias }, FeedObjectMediaPreviewProps)) })), _jsx(Box, Object.assign({ className: classes.pollsSection }, { children: obj['poll'] && (_jsx(PollObject, Object.assign({ visible: pollVisible ||
template === SCFeedObjectTemplateType.DETAIL ||
Boolean(obj.type !== SCContributionType.DISCUSSION && !obj.html && !obj.medias.length), feedObject: obj, pollObject: obj['poll'], onChange: handleChangePoll, onToggleVisibility: handleTogglePollVisibility }, PollObjectProps))) })), _jsx(Box, Object.assign({ className: classes.infoSection }, { children: _jsxs(Stack, Object.assign({ direction: "row", justifyContent: "space-between", alignItems: "center", spacing: 2 }, { children: [!hideParticipantsPreview && (_jsx(ContributorsFeedObject, Object.assign({ feedObject: obj, feedObjectType: obj.type }, ContributorsFeedObjectProps, { cacheStrategy: cacheStrategy }))), !_hideFollowAction && _jsx(Follow, Object.assign({ feedObject: obj, feedObjectType: obj.type, handleFollow: handleFollow }, FollowButtonProps))] })) }))] })), _jsxs(CardActions, Object.assign({ className: classes.actionsSection }, { children: [_jsx(Actions, Object.assign({ feedObjectId: feedObjectId, feedObjectType: feedObjectType, feedObject: obj, hideCommentAction: template === SCFeedObjectTemplateType.DETAIL || (hasEvent && !((_c = (_b = obj === null || obj === void 0 ? void 0 : obj.medias[0].embed) === null || _b === void 0 ? void 0 : _b.metadata) === null || _c === void 0 ? void 0 : _c.active)), handleExpandActivities: template === SCFeedObjectTemplateType.PREVIEW ? handleExpandActivities : null, VoteActionProps: { onVoteAction: handleVoteSuccess } }, ActionsProps)), ((template === SCFeedObjectTemplateType.DETAIL && (!hasEvent || ((_h = (_g = (_f = (_d = obj === null || obj === void 0 ? void 0 : obj.medias) === null || _d === void 0 ? void 0 : _d[0]) === null || _f === void 0 ? void 0 : _f.embed) === null || _g === void 0 ? void 0 : _g.metadata) === null || _h === void 0 ? void 0 : _h.active))) || expandedActivities) && (_jsx(Box, Object.assign({ className: classes.replyContent }, { children: _jsx(CommentObjectReplyComponent, Object.assign({ id: `reply-feedObject-${obj.id}`, onReply: handleReply, editable: !isReplying || Boolean(obj) }, CommentObjectReplyComponentProps), Number(isReplying)) })))] })), template === SCFeedObjectTemplateType.PREVIEW && (obj.comment_count > 0 || (feedObjectActivities && feedObjectActivities.length > 0)) && (_jsx(Collapse, Object.assign({ in: expandedActivities, timeout: "auto", classes: { root: classes.activitiesSection } }, { children: _jsx(CardContent, Object.assign({ className: classes.activitiesContent }, { children: _jsx(Activities, Object.assign({ feedObject: obj, feedObjectActivities: feedObjectActivities, activitiesType: selectedActivities, onSetSelectedActivities: handleSelectedActivities, comments: comments, CommentsObjectProps: {
CommentComponentProps: Object.assign({ onDelete: handleDeleteComment, truncateContent: true, CommentsObjectComponentProps: { inPlaceLoadMoreContents: false } }, CommentComponentProps),
CommentObjectSkeletonProps: CommentObjectSkeletonProps
}, cacheStrategy: cacheStrategy }, ActivitiesProps), selectedActivities) })) }))), composerOpen && (_jsx(Composer, { open: composerOpen, feedObject: obj, onClose: handleToggleEdit, onSuccess: handleEditSuccess, maxWidth: "sm", fullWidth: true }))] }))) : (_jsx(FeedObjectSkeleton, Object.assign({ template: template }, FeedObjectSkeletonProps))) }));
}
else if (template === SCFeedObjectTemplateType.SHARE) {
objElement = (_jsx(React.Fragment, { children: obj ? (_jsxs(React.Fragment, { children: [obj.categories.length > 0 && (_jsxs("div", Object.assign({ className: classes.category }, { children: [_jsxs(_Fragment, { children: [obj.group && (_jsx("div", Object.assign({ className: classes.group }, { children: _jsx(Chip, { color: "secondary", size: "small", icon: _jsx(Icon, { children: "groups" }), component: Link, to: scRoutingContext.url(SCRoutes.GROUP_ROUTE_NAME, obj.group), clickable: true }, obj.group.id) }))), obj.event && (_jsx(Chip, { className: classes.event, color: "secondary", size: "small", icon: _jsx(Icon, { children: "CalendarIcon" }), component: Link, to: scRoutingContext.url(SCRoutes.EVENT_ROUTE_NAME, obj.event), clickable: true }, obj.event.id))] }), obj.categories.map((c) => (_jsx(Link, Object.assign({ to: scRoutingContext.url(SCRoutes.CATEGORY_ROUTE_NAME, c) }, { children: _jsx(Typography, Object.assign({ variant: "overline" }, { children: c.name })) }), c.id)))] }))), obj.group && !obj.categories.length && (_jsx("div", Object.assign({ className: classes.group }, { children: _jsx(Chip, { color: "secondary", size: "small", icon: _jsx(Icon, { children: "groups" }), label: obj.group.name, component: Link, to: scRoutingContext.url(SCRoutes.GROUP_ROUTE_NAME, obj.group), clickable: true }, obj.group.id) }))), obj.event && !obj.categories.length && (_jsx("div", Object.assign({ className: classes.event }, { children: _jsx(Chip, { color: "secondary", size: "small", icon: _jsx(Icon, { children: "groups" }), label: obj.event.name, component: Link, to: scRoutingContext.url(SCRoutes.EVENT_ROUTE_NAME, obj.event), clickable: true }, obj.event.id) }))), _jsx(CardHeader, { classes: { root: classes.header }, avatar: _jsx(Link, Object.assign({}, (!obj.author.deleted && { to: scRoutingContext.url(SCRoutes.USER_PROFILE_ROUTE_NAME, obj.author) }), { onClick: obj.author.deleted ? () => setOpenAlert(true) : null, className: classes.username }, { children: _jsx(UserAvatar, Object.assign({ hide: !obj.author.community_badge }, { children: _jsx(Avatar, Object.assign({ "aria-label": "recipe", src: obj.author.avatar, className: classes.avatar }, { children: obj.author.username })) })) })), title: _jsx(Link, Object.assign({}, (!obj.author.deleted && { to: scRoutingContext.url(SCRoutes.USER_PROFILE_ROUTE_NAME, obj.author) }), { onClick: obj.author.deleted ? () => setOpenAlert(true) : null, className: classes.username }, { children: obj.author.username })), subheader: _jsx(Link, Object.assign({ to: scRoutingContext.url(getContributionRouteName(obj), getRouteData(obj)), className: classes.activityAt }, { children: _jsx(DateTimeAgo, { date: obj.added_at }) })) }), _jsxs(CardContent, Object.assign({ classes: { root: classes.content } }, { children: [_jsx(Box, Object.assign({ className: classes.titleSection }, { children: 'title' in obj && (_jsx(Link, Object.assign({ to: scRoutingContext.url(getContributionRouteName(obj), getRouteData(obj)) }, { children: _jsx(Typography, Object.assign({ variant: "body1", gutterBottom: true, className: classes.title }, { children: obj.title })) }))) })), _jsx(Box, Object.assign({ className: classes.textSection }, { children: getContributionSummary(obj, template) })), _jsx(Box, Object.assign({ className: classes.mediasSection }, { children: _jsx(FeedObjectMediaPreview, Object.assign({ medias: obj.medias }, FeedObjectMediaPreviewProps)) })), _jsx(Box, Object.assign({ className: classes.pollsSection }, { children: obj['poll'] && (_jsx(PollObject, Object.assign({ feedObject: obj, pollObject: obj['poll'], onChange: handleChangePoll, visible: Boolean(obj.type !== SCContributionType.DISCUSSION && !obj.html && !obj.medias.length) }, PollObjectProps))) }))] }))] })) : (_jsx(FeedObjectSkeleton, Object.assign({ template: template }, FeedObjectSkeletonProps))) }));
}
else {
objElement = (_jsx(React.Fragment, { children: obj ? (_jsx(BaseItem, { elevation: 0, className: classes.snippet, image: _jsx(Link, Object.assign({}, (!obj.author.deleted && { to: scRoutingContext.url(SCRoutes.USER_PROFILE_ROUTE_NAME, obj.author) }), { onClick: obj.author.deleted ? () => setOpenAlert(true) : null }, { children: _jsx(UserAvatar, Object.assign({ hide: !obj.author.community_badge }, { children: _jsx(Avatar, { alt: obj.author.username, variant: "circular", src: obj.author.avatar, className: classes.avatar }) })) })), primary: _jsxs(Box, { children: [_jsx(Link, Object.assign({}, (!obj.author.deleted && { to: scRoutingContext.url(SCRoutes.USER_PROFILE_ROUTE_NAME, obj.author) }), { onClick: obj.author.deleted ? () => setOpenAlert(true) : null, className: classes.username }, { children: obj.author.username })), _jsx(Typography, Object.assign({ variant: "body2", className: classes.snippetContent }, { children: _jsx(Link, Object.assign({ to: scRoutingContext.url(getContributionRouteName(obj), getRouteData(obj)) }, { children: getContributionSnippet(obj) })) }))] }), disableTypography: true, secondary: _jsxs(Stack, Object.assign({ direction: "row", justifyContent: "space-between", spacing: 2, alignItems: "center" }, { children: [_jsx(Link, Object.assign({ to: scRoutingContext.url(getContributionRouteName(obj), getRouteData(obj)), className: classes.activityAt }, { children: _jsx(DateTimeAgo, { component: "span", date: obj.added_at }) })), _jsx(Button, Object.assign({ component: Link, to: scRoutingContext.url(getContributionRouteName(obj), getRouteData(obj)), variant: "text", color: "secondary", size: "small" }, { children: _jsx(FormattedMessage, { id: "ui.feedObject.comment", defaultMessage: "ui.feedObject.comment" }) }))] })) })) : (_jsx(FeedObjectSkeleton, Object.assign({}, FeedObjectSkeletonProps))) }));
}
/**
* Renders root object
*/
return (_jsxs(_Fragment, { children: [_jsxs(Root, Object.assign({ id: id, className: classNames(classes.root, className, `${PREFIX}-${template}`) }, rest, { children: [obj && markRead && _jsx(MarkRead, { endpoint: Endpoints.FeedObjectMarkRead, data: { object: [obj.id] } }), objElement] })), openAlert && _jsx(UserDeletedSnackBar, { open: openAlert, handleClose: () => setOpenAlert(false) })] }));
}