@selfcommunity/react-ui
Version:
React UI Components to integrate a Community created with SelfCommunity Platform.
604 lines (598 loc) • 29.2 kB
JavaScript
import { __rest } from "tslib";
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { forwardRef, useCallback, useEffect, useMemo, useReducer, useRef, useState } from 'react';
import { SCContributionType, SCFeatureName, SCFeedTypologyType } from '@selfcommunity/types';
import { Endpoints, formatHttpErrorCode, http } from '@selfcommunity/api-services';
import { SCPreferences, UserUtils, useSCPreferences, useSCUser } from '@selfcommunity/react-core';
import { FormattedMessage } from 'react-intl';
import Icon from '@mui/material/Icon';
import { Alert, AlertTitle, Box, Dialog, DialogActions, DialogContent, DialogTitle, Fade, IconButton, Slide, useMediaQuery } from '@mui/material';
import { styled, useTheme } from '@mui/material/styles';
import { COMPOSER_POLL_MIN_CHOICES, COMPOSER_TITLE_MAX_LENGTH, COMPOSER_TYPE_POLL } from '../../constants/Composer';
import { MEDIA_TYPE_SHARE } from '../../constants/Media';
import LoadingButton from '@mui/lab/LoadingButton';
import AudienceLayer from './Layer/AudienceLayer';
import { iOS, isClientSideRendering, random, stripHtml } from '@selfcommunity/utils';
import classNames from 'classnames';
import ContentPoll from './Content/ContentPoll';
import { useSnackbar } from 'notistack';
import { useThemeProps } from '@mui/system';
import { extractHashtags } from '../../utils/editor';
import TypeSwitchButtonGroup from './TypeSwitchButtonGroup';
import ContentPost from './Content/ContentPost';
import CategoryLayer from './Layer/CategoryLayer';
import LocationLayer from './Layer/LocationLayer';
import ContentDiscussion from './Content/ContentDiscussion';
import { File, Link, Share } from '../../shared/Media';
import Attributes from './Attributes';
import { PREFIX } from './constants';
import ComposerSkeleton from './Skeleton';
import CloseLayer from './Layer/CloseLayer';
import BackdropScrollDisabled from '../../shared/BackdropScrollDisabled';
import { clearAllBodyScrollLocks } from 'body-scroll-lock';
const DialogTransition = forwardRef(function Transition(props, ref) {
return _jsx(Fade, Object.assign({ ref: ref }, props));
});
const classes = {
root: `${PREFIX}-root`,
ios: `${PREFIX}-ios`,
title: `${PREFIX}-title`,
types: `${PREFIX}-types`,
content: `${PREFIX}-content`,
attributes: `${PREFIX}-attributes`,
medias: `${PREFIX}-medias`,
actions: `${PREFIX}-actions`,
layerTransitionRoot: `${PREFIX}-layer-transition-root`
};
const Root = styled(Dialog, {
name: PREFIX,
slot: 'Root'
})(() => ({}));
const LayerTransitionRoot = styled(Slide, {
name: PREFIX,
slot: 'LayerTransitionRoot'
})(({ theme }) => ({}));
const COMPOSER_INITIAL_STATE = {
id: null,
type: null,
title: '',
titleError: null,
html: '',
htmlError: null,
categories: [],
group: null,
event: null,
categoriesError: null,
groupsError: null,
addressing: null,
addressingError: null,
medias: [],
poll: null,
location: null,
error: null
};
const reducer = (state, action) => {
switch (action.type) {
case 'reset':
return Object.assign(Object.assign({}, COMPOSER_INITIAL_STATE), { key: random() });
case 'resetEventFeed':
return Object.assign(Object.assign({}, COMPOSER_INITIAL_STATE), { event: state.event, key: random() });
case 'resetGroupFeed':
return Object.assign(Object.assign({}, COMPOSER_INITIAL_STATE), { group: state.group, key: random() });
case 'resetCategoryFeed':
return Object.assign(Object.assign({}, COMPOSER_INITIAL_STATE), { categories: state.categories, key: random() });
case 'multiple':
return Object.assign(Object.assign({}, state), action.value);
default:
return Object.assign(Object.assign({}, state), { [action.type]: action.value });
}
};
/**
* > API documentation for the Community-JS Composer component. Learn about the available props and the CSS API.
*
*
* The Composer component contains the logic around the creation of [Post](https://developers.selfcommunity.com/docs/apireference/v2/post/create_a_post) and [Discussion](https://developers.selfcommunity.com/docs/apireference/v2/discussion/create_a_discussion) objects.
*
*
:::info
To prevent the editor toolbar and action botton bar being hidden underneath the Virtual Keyboard you need to set the `interactive-widget=resizes-content` on meta viewport.
This works on chrome for android.
For iOS devices there is a lack of support of this meta so we force the blur event when the user start dragging.
[More information](https://bram.us/2021/09/13/prevent-items-from-being-hidden-underneath-the-virtual-keyboard-by-means-of-the-virtualkeyboard-api/)
:::
#### Import
```jsx
import {Composer} from '@selfcommunity/react-ui';
```
#### Component Name
The name `SCComposer` can be used when providing style overrides in the theme.
#### CSS
|Rule Name|Global class|Description|
|---|---|---|
|root|.SCComposer-root|Styles applied to the root element.|
|ios|.SCComposer-ios|Styles applied to the root element when the device is ios.|
|title|.SCComposer-title|Styles applied to the title element.|
|types|.SCComposer-types|Styles applied to the types element.|
|content|.SCComposer-content|Styles applied to the content.|
|attributes|.SCComposer-attributes|Styles applied to the attributes.|
|medias|.SCComposer-medias|Styles applied to the medias.|
|actions|.SCComposer-actions|Styles applied to the actions section.|
|layerTransitionRoot|.SCComposer-layer-transition-root|Styles applied to the overlay layers (eg. location).|
* @param inProps
*/
export default function Composer(inProps) {
// PROPS
const props = useThemeProps({
props: inProps,
name: PREFIX
});
const { feedObjectId = null, feedObjectType = null, feedObject = null, defaultValue = {}, mediaObjectTypes = [File, Link, Share], EditorProps = {}, onClose = null, onSuccess = null, feedType } = props, rest = __rest(props, ["feedObjectId", "feedObjectType", "feedObject", "defaultValue", "mediaObjectTypes", "EditorProps", "onClose", "onSuccess", "feedType"]);
// Context
const { preferences, features } = useSCPreferences();
const scUserContext = useSCUser();
const { enqueueSnackbar } = useSnackbar();
// HOOKS
const theme = useTheme();
const fullScreen = useMediaQuery(theme.breakpoints.down('md'), { noSsr: isClientSideRendering() });
// State variables
const [isSubmitting, setIsSubmitting] = useState(false);
const [layer, setLayer] = useState();
const [state, dispatch] = useReducer(reducer, Object.assign(Object.assign(Object.assign({}, COMPOSER_INITIAL_STATE), defaultValue), { key: random() }));
const { key, id, type, title, titleError, html, categories, event, group, addressing, audience, medias, poll, pollError, location, error } = state;
const destructureFeedObject = (_feedObject) => {
if (_feedObject.type === SCContributionType.POST) {
_feedObject = _feedObject;
}
else if (_feedObject.type === SCContributionType.DISCUSSION) {
_feedObject = _feedObject;
}
else {
_feedObject = _feedObject;
}
if (feedObject.author.id === scUserContext.user.id) {
dispatch({
type: 'multiple',
value: {
id: _feedObject.id,
type: _feedObject.poll ? COMPOSER_TYPE_POLL : feedObject.type,
title: _feedObject.title,
html: _feedObject.html,
categories: _feedObject.categories,
event: _feedObject.event,
group: _feedObject.group,
addressing: _feedObject.addressing,
medias: _feedObject.medias,
poll: _feedObject.poll,
location: _feedObject.location
}
});
setIsLoading(false);
}
else {
setLoadError(true);
}
};
// Edit state variables
const editMode = useMemo(() => Boolean((feedObjectId && feedObjectType) || feedObject), [feedObjectId, feedObjectType, feedObject]);
const [isLoading, setIsLoading] = useState(editMode);
const [loadError, setLoadError] = useState(false);
// REFS
const dialogRef = useRef();
const unloadRef = useRef(false);
const pointerStartY = useRef(null);
// Create a ref for medias because of state update error on chunk upload
const mediasRef = useRef({ medias });
mediasRef.current = { medias };
// MEMO
const hasPoll = useMemo(() => {
return poll && poll.title.length > 0 && poll.title.length < COMPOSER_TITLE_MAX_LENGTH && poll.choices.length >= COMPOSER_POLL_MIN_CHOICES;
}, [poll]);
const canSubmit = useMemo(() => {
return (!isLoading &&
((type === SCContributionType.DISCUSSION && title.length > 0 && title.length < COMPOSER_TITLE_MAX_LENGTH) ||
(type === SCContributionType.POST && (stripHtml(html).length > 0 || medias.length > 0 || hasPoll)) ||
(type === COMPOSER_TYPE_POLL && hasPoll)));
}, [isLoading, type, title, html, medias, hasPoll]);
const isIOS = useMemo(() => iOS(), []);
// Load feed object
useEffect(() => {
if (!editMode) {
return;
}
else if (feedObject !== null) {
destructureFeedObject(feedObject);
return;
}
setIsLoading(true);
http
.request({
url: Endpoints.FeedObject.url({ type: feedObjectType, id: feedObjectId }),
method: Endpoints.FeedObject.method
})
.then((res) => {
destructureFeedObject(res.data);
})
.catch(() => {
setLoadError(true);
})
.then(() => setIsLoading(false));
}, [editMode]);
// Prevent unload
useEffect(() => {
if (!unloadRef.current && canSubmit) {
unloadRef.current = true;
const onUnload = (e) => {
e.preventDefault();
return '';
};
window.onbeforeunload = onUnload;
}
else if (unloadRef.current && !canSubmit) {
unloadRef.current = false;
window.onbeforeunload = null;
}
}, [state, canSubmit]);
/**
* On iOS, since it is not possible to anchor meadiaObject actions
* to the bottom of the viewport, detect 'pan' gesture to close the
* soft keyboard on device and show actions
*/
useEffect(() => {
if (!dialogRef.current || !isIOS) {
return;
}
/**
* On touchStart event save the initial Y
* @param e
*/
const handleTouchStart = (e) => {
pointerStartY.current = e.touches[0].clientY;
};
/**
* Perform blur only if gesture is a pan (bottom direction)
* @param e
*/
const handleTouchmove = (e) => {
const currentY = e.touches[0].clientY;
const deltaY = currentY - pointerStartY.current;
pointerStartY.current = currentY;
if (deltaY > 0) {
dialogRef.current.focus();
}
};
/**
* Attach touchstart, touchmove necessary to detect the pan gesture
*/
dialogRef.current.addEventListener('touchstart', handleTouchStart);
dialogRef.current.addEventListener('touchmove', handleTouchmove);
/**
* To disable scroll on iOS
*/
// dialogRef.current &&
// disableBodyScroll(dialogRef.current, {
// allowTouchMove: (el) => {
// while (el && el !== document.body) {
// if (el.getAttribute('class') !== null && el.getAttribute('class').includes('SCComposer-content')) {
// return true;
// }
// el = el.parentElement;
// }
// }
// });
return () => {
var _a, _b;
(_a = dialogRef.current) === null || _a === void 0 ? void 0 : _a.removeEventListener('touchstart', handleTouchStart);
(_b = dialogRef.current) === null || _b === void 0 ? void 0 : _b.removeEventListener('touchmove', handleTouchmove);
/**
* To re-enable scroll on iOS
*/
// dialogRef.current && enableBodyScroll(dialogRef.current);
};
}, [dialogRef.current, isIOS]);
/* Handlers */
const handleAddLayer = useCallback((layer) => setLayer(layer), []);
const handleRemoveLayer = useCallback(() => setLayer(null), []);
const handleChangeType = useCallback((value) => {
dispatch({ type: 'type', value });
}, []);
const handleChangePoll = useCallback((content) => {
dispatch({
type: 'multiple',
value: Object.assign(Object.assign({}, content), { pollError: content.poll.title.length > COMPOSER_TITLE_MAX_LENGTH
? { titleError: _jsx(FormattedMessage, { id: "ui.composer.title.error.maxlength", defaultMessage: "ui.composer.title.error.maxlength" }) }
: null })
});
}, []);
const handleChangeDiscussion = useCallback((content) => {
dispatch({
type: 'multiple',
value: Object.assign(Object.assign({}, content), { titleError: content.title.length > COMPOSER_TITLE_MAX_LENGTH ? (_jsx(FormattedMessage, { id: "ui.composer.title.error.maxlength", defaultMessage: "ui.composer.title.error.maxlength" })) : null })
});
}, []);
const handleChangePost = useCallback((content) => {
dispatch({
type: 'multiple',
value: Object.assign({}, content)
});
}, []);
const handleChangeCategories = useCallback((value) => {
dispatch({ type: 'categories', value });
setLayer(null);
}, []);
const handleAddCategoryLayer = useCallback(() => handleAddLayer({
name: 'category',
Component: CategoryLayer,
ComponentProps: {
onClose: handleRemoveLayer,
onSave: handleChangeCategories,
defaultValue: categories
}
}), [handleAddLayer, handleRemoveLayer, handleChangeCategories, categories]);
const handleChangeAudience = useCallback((value) => {
if (group || (value && Object.prototype.hasOwnProperty.call(value, 'emotional_image_position'))) {
dispatch({ type: 'group', value });
}
else if (event || (value && Object.prototype.hasOwnProperty.call(value, 'recurring'))) {
dispatch({ type: 'event', value });
}
else {
dispatch({ type: 'addressing', value });
}
setLayer(null);
}, [group]);
const handleAddAudienceLayer = useCallback(() => handleAddLayer({
name: 'audience',
Component: AudienceLayer,
ComponentProps: {
onClose: handleRemoveLayer,
onSave: handleChangeAudience,
defaultValue: group || (addressing && Object.prototype.hasOwnProperty.call(addressing, 'emotional_image_position'))
? group
: event || (addressing && Object.prototype.hasOwnProperty.call(addressing, 'recurring'))
? event
: addressing
}
}), [handleAddLayer, handleRemoveLayer, handleChangeAudience, addressing, event, group]);
const handleChangeLocation = useCallback((value) => {
dispatch({ type: 'location', value });
setLayer(null);
}, []);
const handleAddLocationLayer = useCallback(() => handleAddLayer({
name: 'location',
Component: LocationLayer,
ComponentProps: {
onClose: handleRemoveLayer,
onSave: handleChangeLocation,
defaultValue: location
}
}), [handleAddLayer, handleRemoveLayer, handleChangeLocation, location]);
const handleChangeMedias = useCallback((value) => {
const _medias = [...value];
dispatch({
type: 'medias',
value: [...value]
});
mediasRef.current.medias = _medias;
setLayer(null);
}, []);
const handleAddMedia = useCallback((media) => {
const _medias = [...mediasRef.current.medias, media];
dispatch({
type: 'medias',
value: _medias
});
mediasRef.current.medias = _medias;
}, []);
const handleMediaTriggerClick = useCallback((mediaObjectType) => (e) => {
if (mediaObjectType.layerComponent) {
handleAddLayer({
name: mediaObjectType.name,
Component: mediaObjectType.layerComponent,
ComponentProps: {
onClose: handleRemoveLayer,
onSave: handleChangeMedias,
defaultValue: medias
}
});
}
}, [handleAddLayer, handleRemoveLayer, handleChangeMedias, medias]);
const handleChangeAttributes = useCallback((content) => {
dispatch({
type: 'multiple',
value: Object.assign({}, content)
});
}, []);
const handleClickAttributes = useCallback((attr) => {
switch (attr) {
case 'categories':
handleAddCategoryLayer();
break;
case 'addressing':
handleAddAudienceLayer();
break;
case 'location':
handleAddLocationLayer();
break;
}
}, [handleAddCategoryLayer, handleAddAudienceLayer, handleAddLocationLayer]);
const handleSubmit = useCallback((e) => {
e.preventDefault();
e.stopPropagation();
if (UserUtils.isBlocked(scUserContext.user)) {
// deny submit action if authenticated user is blocked
enqueueSnackbar(_jsx(FormattedMessage, { id: "ui.common.userBlocked", defaultMessage: "ui.common.userBlocked" }), {
variant: 'warning',
autoHideDuration: 3000
});
return;
}
// Extract hashtags and add to categories
const _categories = [...categories.map((c) => c.id), ...extractHashtags(html)];
const data = {
title,
text: html,
medias: medias.map((m) => m.id),
categories: _categories.filter((item, index) => _categories.indexOf(item) === index)
};
if ((preferences[SCPreferences.ADDONS_POLLS_ENABLED].value || UserUtils.isStaff(scUserContext.user)) && hasPoll) {
data.poll = poll;
}
if (preferences[SCPreferences.ADDONS_POST_GEOLOCATION_ENABLED].value && location) {
data.location = location;
}
if (features.includes(SCFeatureName.TAGGING) && addressing !== null) {
data.addressing = addressing.map((t) => t.id);
}
if (features.includes(SCFeatureName.TAGGING) &&
features.includes(SCFeatureName.GROUPING) &&
preferences[SCPreferences.CONFIGURATIONS_GROUPS_ENABLED].value &&
group !== null) {
data.group = group.id;
}
if (features.includes(SCFeatureName.TAGGING) &&
features.includes(SCFeatureName.EVENT) &&
preferences[SCPreferences.CONFIGURATIONS_EVENTS_ENABLED].value &&
event !== null) {
data.event = event.id;
}
setIsSubmitting(true);
// Finding right url
const _type = type === COMPOSER_TYPE_POLL ? SCContributionType.POST : type;
let url = Endpoints.Composer.url({ type: _type });
let method = Endpoints.Composer.method;
if (editMode) {
url = Endpoints.ComposerEdit.url({ type: feedObjectType ? feedObjectType : _type, id });
method = Endpoints.ComposerEdit.method;
}
// Perform request
http
.request({
url,
method,
data
})
.then((res) => {
onSuccess(res.data);
if (unloadRef.current) {
window.onbeforeunload = null;
}
feedType && feedType === SCFeedTypologyType.CATEGORY
? dispatch({ type: 'resetCategoryFeed' })
: feedType === SCFeedTypologyType.EVENT
? dispatch({ type: 'resetEventFeed' })
: feedType === SCFeedTypologyType.GROUP
? dispatch({ type: 'resetGroupFeed' })
: dispatch({ type: 'reset' });
})
.catch((error) => {
dispatch({ type: 'multiple', value: formatHttpErrorCode(error) });
})
.then(() => setIsSubmitting(false));
}, [scUserContext.user, feedObjectType, id, type, title, html, categories, event, group, addressing, audience, medias, poll, location, hasPoll]);
//edited here
const handleClose = useCallback((e, reason) => {
if (unloadRef.current) {
window.onbeforeunload = null;
}
if (reason && canSubmit) {
handleAddLayer({
name: 'close',
Component: CloseLayer,
ComponentProps: {
onClose: handleRemoveLayer,
onSave: () => {
onClose && onClose(e);
setLayer(null);
feedType && feedType === SCFeedTypologyType.CATEGORY
? dispatch({ type: 'resetCategoryFeed' })
: feedType === SCFeedTypologyType.EVENT
? dispatch({ type: 'resetEventFeed' })
: feedType === SCFeedTypologyType.GROUP
? dispatch({ type: 'resetGroupFeed' })
: dispatch({ type: 'reset' });
}
}
});
}
else {
clearAllBodyScrollLocks();
onClose && onClose(e);
setLayer(null);
dispatch({ type: 'reset' });
/*setLayer(null);
feedType && feedType === SCFeedTypologyType.CATEGORY
? dispatch({type: 'resetCategoryFeed'})
: feedType === SCFeedTypologyType.GROUP
? dispatch({type: 'resetGroupFeed'})
: dispatch({type: 'reset'}); */
}
}, [onClose, canSubmit, handleRemoveLayer]);
const handleClosePrompt = useCallback((e) => {
if (canSubmit) {
handleAddLayer({
name: 'close',
Component: CloseLayer,
ComponentProps: {
onClose: handleRemoveLayer,
onSave: handleClose
}
});
}
else {
handleClose(e);
}
}, [canSubmit, handleAddLayer, handleRemoveLayer, handleClose]);
// RENDER
const hasMediaShare = useMemo(() => medias.findIndex((m) => m.type === MEDIA_TYPE_SHARE) !== -1, [medias]);
const content = useMemo(() => {
if (editMode && isLoading) {
return _jsx(ComposerSkeleton, {});
}
else if (editMode && loadError) {
return (_jsxs(Alert, Object.assign({ severity: "error", onClose: handleClose }, { children: [_jsx(AlertTitle, { children: _jsx(FormattedMessage, { id: "ui.composer.edit.error.title", defaultMessage: "ui.composer.edit.error.title" }) }), _jsx(FormattedMessage, { id: "ui.composer.edit.error.content", defaultMessage: "ui.composer.edit.error.content" })] })));
}
switch (type) {
case COMPOSER_TYPE_POLL:
return (_jsx(ContentPoll, { onChange: handleChangePoll, value: { html, event, group, addressing, medias, poll, location }, error: pollError, disabled: isSubmitting }, key));
case SCContributionType.DISCUSSION:
return (_jsx(ContentDiscussion, { value: { title, html, categories, event, group, addressing, medias, poll, location }, error: { titleError, error }, onChange: handleChangeDiscussion, disabled: isSubmitting, isContentSwitchButtonVisible: !canSubmit && !editMode, EditorProps: Object.assign({ toolbar: true, uploadImage: true }, EditorProps) }, key));
default:
return (_jsx(ContentPost, { value: { html, categories, event, group, addressing, medias, poll, location }, error: { error }, onChange: handleChangePost, disabled: isSubmitting, EditorProps: Object.assign({ toolbar: false, uploadImage: false }, EditorProps) }, key));
}
}, [
key,
type,
title,
html,
categories,
event,
group,
addressing,
medias,
poll,
pollError,
location,
error,
handleChangePoll,
handleChangePost,
isSubmitting,
canSubmit,
editMode
]);
if (!scUserContext.user && !(scUserContext.loading && open)) {
return null;
}
return (_jsxs(Root, Object.assign({ ref: dialogRef, TransitionComponent: DialogTransition, slots: { backdrop: BackdropScrollDisabled }, onClose: handleClose }, rest, { disableEscapeKeyDown: true, className: classNames(classes.root, { [classes.ios]: isIOS }), scroll: "body", fullScreen: fullScreen, tabIndex: -1 }, { children: [_jsxs("form", Object.assign({ onSubmit: handleSubmit, method: "post" }, { children: [_jsxs(DialogTitle, Object.assign({ className: classes.title }, { children: [_jsx(IconButton, Object.assign({ onClick: handleClosePrompt }, { children: _jsx(Icon, { children: "close" }) })), _jsx(LoadingButton, Object.assign({ size: "small", type: "submit", color: "secondary", variant: "contained", disabled: !canSubmit, loading: isSubmitting }, { children: _jsx(FormattedMessage, { id: "ui.composer.submit", defaultMessage: "ui.composer.submit" }) }))] })), _jsxs(DialogContent, Object.assign({ className: classes.content }, { children: [_jsx(Attributes, { value: { categories, event, group, addressing, location }, className: classes.attributes, onChange: handleChangeAttributes, onClick: handleClickAttributes }), content, medias && medias.length > 0 && (_jsx(Box, Object.assign({ className: classes.medias }, { children: mediaObjectTypes.map((mediaObjectType) => {
if (mediaObjectType.previewComponent) {
return _jsx(mediaObjectType.previewComponent, { value: medias, onChange: handleChangeMedias }, mediaObjectType.name);
}
else if (mediaObjectType.displayComponent) {
return _jsx(mediaObjectType.displayComponent, { medias: medias }, mediaObjectType.name);
}
}) })))] })), !canSubmit && !editMode && _jsx(TypeSwitchButtonGroup, { className: classes.types, onChange: handleChangeType, size: "small", value: type }), _jsxs(DialogActions, Object.assign({ className: classes.actions }, { children: [mediaObjectTypes
.filter((mediaObjectType) => mediaObjectType.triggerButton !== null)
.map((mediaObjectType) => {
const props = mediaObjectType.layerComponent ? { onClick: handleMediaTriggerClick(mediaObjectType) } : { onAdd: handleAddMedia };
return (_jsx(mediaObjectType.triggerButton, Object.assign({ disabled: isSubmitting || hasMediaShare, color: medias.filter(mediaObjectType.filter).length > 0 ? 'primary' : 'default' }, props), mediaObjectType.name));
}), _jsx(IconButton, Object.assign({ disabled: isSubmitting, onClick: handleAddCategoryLayer }, { children: _jsx(Icon, { children: "category" }) })), _jsx(IconButton, Object.assign({ disabled: isSubmitting || !features.includes(SCFeatureName.TAGGING) || Boolean(feedObject === null || feedObject === void 0 ? void 0 : feedObject.group) || Boolean(feedObject === null || feedObject === void 0 ? void 0 : feedObject.event), onClick: handleAddAudienceLayer }, { children: (!group && addressing === null) || (!event && addressing === null) || (addressing === null || addressing === void 0 ? void 0 : addressing.length) === 0 ? (_jsx(Icon, { children: "public" })) : group ? (_jsx(Icon, { children: "groups" })) : event ? (_jsx(Icon, { children: "CalendarIcon" })) : (_jsx(Icon, { children: "label" })) })), preferences[SCPreferences.ADDONS_POST_GEOLOCATION_ENABLED].value && (_jsx(IconButton, Object.assign({ disabled: isSubmitting, onClick: handleAddLocationLayer, color: location !== null ? 'primary' : 'default' }, { children: _jsx(Icon, { children: "add_location_alt" }) })))] }))] })), layer && (_jsx(LayerTransitionRoot, Object.assign({ className: classes.layerTransitionRoot, in: true, container: dialogRef.current, direction: "left" }, { children: _jsx(layer.Component, Object.assign({}, layer.ComponentProps)) })))] })));
}