UNPKG

@selfcommunity/react-ui

Version:

React UI Components to integrate a Community created with SelfCommunity Platform.

715 lines (709 loc) • 40.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const jsx_runtime_1 = require("react/jsx-runtime"); const react_1 = require("react"); const types_1 = require("@selfcommunity/types"); const api_services_1 = require("@selfcommunity/api-services"); const react_core_1 = require("@selfcommunity/react-core"); const react_intl_1 = require("react-intl"); const material_1 = require("@mui/material"); const Composer_1 = require("../../constants/Composer"); const Media_1 = require("../../constants/Media"); const LoadingButton_1 = tslib_1.__importDefault(require("@mui/lab/LoadingButton")); const AudienceLayer_1 = tslib_1.__importDefault(require("./Layer/AudienceLayer")); const utils_1 = require("@selfcommunity/utils"); const classnames_1 = tslib_1.__importDefault(require("classnames")); const ContentPoll_1 = tslib_1.__importDefault(require("./Content/ContentPoll")); const notistack_1 = require("notistack"); const system_1 = require("@mui/system"); const editor_1 = require("../../utils/editor"); const TypeSwitchButtonGroup_1 = tslib_1.__importDefault(require("./TypeSwitchButtonGroup")); const ContentPost_1 = tslib_1.__importDefault(require("./Content/ContentPost")); const CategoryLayer_1 = tslib_1.__importDefault(require("./Layer/CategoryLayer")); const LocationLayer_1 = tslib_1.__importDefault(require("./Layer/LocationLayer")); const ContentDiscussion_1 = tslib_1.__importDefault(require("./Content/ContentDiscussion")); const Media_2 = require("../../shared/Media"); const Attributes_1 = tslib_1.__importDefault(require("./Attributes")); const constants_1 = require("./constants"); const Skeleton_1 = tslib_1.__importDefault(require("./Skeleton")); const CloseLayer_1 = tslib_1.__importDefault(require("./Layer/CloseLayer")); const BackdropScrollDisabled_1 = tslib_1.__importDefault(require("../../shared/BackdropScrollDisabled")); const body_scroll_lock_1 = require("body-scroll-lock"); const ScheduledLayer_1 = tslib_1.__importDefault(require("./Layer/ScheduledLayer")); const DialogTransition = (0, react_1.forwardRef)(function Transition(props, ref) { return (0, jsx_runtime_1.jsx)(material_1.Fade, Object.assign({ ref: ref }, props)); }); const classes = { root: `${constants_1.PREFIX}-root`, ios: `${constants_1.PREFIX}-ios`, title: `${constants_1.PREFIX}-title`, types: `${constants_1.PREFIX}-types`, content: `${constants_1.PREFIX}-content`, attributes: `${constants_1.PREFIX}-attributes`, medias: `${constants_1.PREFIX}-medias`, actions: `${constants_1.PREFIX}-actions`, selectedAction: `${constants_1.PREFIX}-selected-action`, actionSelectedIcon: `${constants_1.PREFIX}-action-selected-icon`, layerTransitionRoot: `${constants_1.PREFIX}-layer-transition-root` }; const Root = (0, material_1.styled)(material_1.Dialog, { name: constants_1.PREFIX, slot: 'Root' })(() => ({})); const LayerTransitionRoot = (0, material_1.styled)(material_1.Slide, { name: constants_1.PREFIX, slot: 'LayerTransitionRoot' })(() => ({})); const COMPOSER_INITIAL_STATE = { id: null, type: null, title: '', titleError: null, html: '', htmlError: null, categories: [], categoriesError: null, group: null, event: null, groupsError: null, addressing: null, addressingError: null, recipients: [], medias: [], poll: null, location: null, scheduled_at: null, error: null }; const reducer = (state, action) => { switch (action.type) { case 'reset': return Object.assign(Object.assign({}, COMPOSER_INITIAL_STATE), { key: (0, utils_1.random)() }); case 'resetEventFeed': return Object.assign(Object.assign({}, COMPOSER_INITIAL_STATE), { event: state.event, key: (0, utils_1.random)() }); case 'resetGroupFeed': return Object.assign(Object.assign({}, COMPOSER_INITIAL_STATE), { group: state.group, key: (0, utils_1.random)() }); case 'resetCategoryFeed': return Object.assign(Object.assign({}, COMPOSER_INITIAL_STATE), { categories: state.categories, key: (0, utils_1.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 */ function Composer(inProps) { // PROPS const props = (0, system_1.useThemeProps)({ props: inProps, name: constants_1.PREFIX }); const { feedObjectId = null, feedObjectType = null, feedObject = null, defaultValue = {}, mediaObjectTypes = [Media_2.File, Media_2.Link, Media_2.Share], EditorProps = {}, onClose = null, onSuccess = null, feedType } = props, rest = tslib_1.__rest(props, ["feedObjectId", "feedObjectType", "feedObject", "defaultValue", "mediaObjectTypes", "EditorProps", "onClose", "onSuccess", "feedType"]); // Context const { preferences, features } = (0, react_core_1.useSCPreferences)(); const scUserContext = (0, react_core_1.useSCUser)(); const { enqueueSnackbar } = (0, notistack_1.useSnackbar)(); // HOOKS const theme = (0, material_1.useTheme)(); const fullScreen = (0, material_1.useMediaQuery)(theme.breakpoints.down('md'), { noSsr: (0, utils_1.isClientSideRendering)() }); // State variables const [isSubmitting, setIsSubmitting] = (0, react_1.useState)(false); const [layer, setLayer] = (0, react_1.useState)(); const [state, dispatch] = (0, react_1.useReducer)(reducer, Object.assign(Object.assign(Object.assign({}, COMPOSER_INITIAL_STATE), defaultValue), { key: (0, utils_1.random)() })); const { key, id, type, title, titleError, html, categories, categoriesError, event, group, addressing, addressingError, recipients, audience, medias, poll, pollError, location, scheduled_at, error } = state; //MEMO const scheduledPostsEnabled = (0, react_1.useMemo)(() => preferences && react_core_1.SCPreferences.CONFIGURATIONS_SCHEDULED_POSTS_ENABLED in preferences && preferences[react_core_1.SCPreferences.CONFIGURATIONS_SCHEDULED_POSTS_ENABLED].value, [preferences]); const addressingRequiredEnabled = (0, react_1.useMemo)(() => preferences && react_core_1.SCPreferences.CONFIGURATIONS_POST_ADDRESSING_REQUIRED_ENABLED in preferences && preferences[react_core_1.SCPreferences.CONFIGURATIONS_POST_ADDRESSING_REQUIRED_ENABLED].value, [preferences]); const categoryRequiredEnabled = (0, react_1.useMemo)(() => preferences && react_core_1.SCPreferences.CONFIGURATIONS_POST_CATEGORY_REQUIRED_ENABLED in preferences && preferences[react_core_1.SCPreferences.CONFIGURATIONS_POST_CATEGORY_REQUIRED_ENABLED].value, [preferences]); const usersTaggingEnabled = (0, react_1.useMemo)(() => preferences && features && features.includes(types_1.SCFeatureName.TAGGING) && react_core_1.SCPreferences.CONFIGURATIONS_POST_USER_ADDRESSING_ENABLED in preferences && preferences[react_core_1.SCPreferences.CONFIGURATIONS_POST_USER_ADDRESSING_ENABLED].value, [preferences, features]); const destructureFeedObject = (_feedObject) => { if (_feedObject.type === types_1.SCContributionType.POST) { _feedObject = _feedObject; } else if (_feedObject.type === types_1.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_1.COMPOSER_TYPE_POLL : feedObject.type, title: _feedObject.title, html: _feedObject.html, categories: _feedObject.categories, event: _feedObject.event, group: _feedObject.group, addressing: _feedObject.addressing, recipients: _feedObject.recipients, medias: _feedObject.medias, poll: _feedObject.poll, location: _feedObject.location, scheduled_at: _feedObject.scheduled_at } }); setIsLoading(false); } else { setLoadError(true); } }; // Edit state variables const editMode = (0, react_1.useMemo)(() => Boolean((feedObjectId && feedObjectType) || feedObject), [feedObjectId, feedObjectType, feedObject]); const [isLoading, setIsLoading] = (0, react_1.useState)(editMode); const [loadError, setLoadError] = (0, react_1.useState)(false); // REFS const dialogRef = (0, react_1.useRef)(); const unloadRef = (0, react_1.useRef)(false); const pointerStartY = (0, react_1.useRef)(null); // Create a ref for medias because of state update error on chunk upload const mediasRef = (0, react_1.useRef)({ medias }); mediasRef.current = { medias }; // MEMO const hasPoll = (0, react_1.useMemo)(() => { return poll && poll.title.length > 0 && poll.title.length < Composer_1.COMPOSER_TITLE_MAX_LENGTH && poll.choices.length >= Composer_1.COMPOSER_POLL_MIN_CHOICES; }, [poll]); const canSubmit = (0, react_1.useMemo)(() => { return (!isLoading && ((type === types_1.SCContributionType.DISCUSSION && title.length > 0 && title.length < Composer_1.COMPOSER_TITLE_MAX_LENGTH) || (type === types_1.SCContributionType.POST && ((0, utils_1.stripHtml)(html).length > 0 || medias.length > 0 || hasPoll)) || (type === Composer_1.COMPOSER_TYPE_POLL && hasPoll)) && (!addressingRequiredEnabled || (addressing && addressing.length > 0) || (recipients && recipients.length > 0)) && (!categoryRequiredEnabled || (categories && categories.length > 0))); }, [isLoading, type, title, html, medias, hasPoll, addressing, recipients, addressingRequiredEnabled, categories, categoryRequiredEnabled]); const isIOS = (0, react_1.useMemo)(() => (0, utils_1.iOS)(), []); // Load feed object (0, react_1.useEffect)(() => { if (!editMode) { return; } else if (feedObject !== null) { destructureFeedObject(feedObject); return; } setIsLoading(true); api_services_1.http .request({ url: api_services_1.Endpoints.FeedObject.url({ type: feedObjectType, id: feedObjectId }), method: api_services_1.Endpoints.FeedObject.method }) .then((res) => { destructureFeedObject(res.data); }) .catch(() => { setLoadError(true); }) .then(() => setIsLoading(false)); }, [editMode]); // Prevent unload (0, react_1.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 */ (0, react_1.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 = (0, react_1.useCallback)((layer) => setLayer(layer), []); const handleRemoveLayer = (0, react_1.useCallback)(() => setLayer(null), []); const handleChangeType = (0, react_1.useCallback)((value) => { dispatch({ type: 'type', value }); }, []); const getAddressingError = (content) => { var _a, _b; const isMissing = addressingRequiredEnabled && !((_a = content.addressing) === null || _a === void 0 ? void 0 : _a.length) && !((_b = content.recipients) === null || _b === void 0 ? void 0 : _b.length); if (!isMissing) return null; return usersTaggingEnabled ? ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.composer.addressingRecipients.error.missing", defaultMessage: "ui.composer.addressingRecipients.error.missing" })) : ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.composer.addressing.error.missing", defaultMessage: "ui.composer.addressing.error.missing" })); }; const handleChangePoll = (0, react_1.useCallback)((content) => { dispatch({ type: 'multiple', value: Object.assign(Object.assign({}, content), { pollError: content.poll.title.length > Composer_1.COMPOSER_TITLE_MAX_LENGTH ? { titleError: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.composer.title.error.maxlength", defaultMessage: "ui.composer.title.error.maxlength" }) } : null, addressingError: getAddressingError(content) }) }); }, []); const handleChangeDiscussion = (0, react_1.useCallback)((content) => { dispatch({ type: 'multiple', value: Object.assign(Object.assign({}, content), { titleError: content.title.length > Composer_1.COMPOSER_TITLE_MAX_LENGTH ? ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.composer.title.error.maxlength", defaultMessage: "ui.composer.title.error.maxlength" })) : null, addressingError: getAddressingError(content), categoriesError: categoryRequiredEnabled && content.categories.length === 0 ? ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.composer.categories.error.missing", defaultMessage: "ui.composer.categories.error.missing" })) : null }) }); }, []); const handleChangePost = (0, react_1.useCallback)((content) => { dispatch({ type: 'multiple', value: Object.assign(Object.assign({}, content), { addressingError: getAddressingError(content), categoriesError: categoryRequiredEnabled && content.categories.length === 0 ? ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.composer.categories.error.missing", defaultMessage: "ui.composer.categories.error.missing" })) : null }) }); }, []); const handleChangeCategories = (0, react_1.useCallback)((value) => { dispatch({ type: 'multiple', value: { categories: value, categoriesError: categoryRequiredEnabled && (!value || value.length === 0) ? ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.composer.categories.error.missing", defaultMessage: "ui.composer.categories.error.missing" })) : null } }); setLayer(null); }, []); const handleAddCategoryLayer = (0, react_1.useCallback)(() => handleAddLayer({ name: 'category', Component: CategoryLayer_1.default, ComponentProps: { onClose: handleRemoveLayer, onSave: handleChangeCategories, defaultValue: categories } }), [handleAddLayer, handleRemoveLayer, handleChangeCategories, categories]); const handleChangeAudience = (0, react_1.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 if ((value && Array.isArray(value) && value.some((item) => typeof item === 'object' && !('color' in item))) || (value === null && Array.isArray(recipients) && recipients.length > 0)) { dispatch({ type: 'multiple', value: { recipients: value, addressing: [], addressingError: addressingRequiredEnabled && !value ? ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.composer.addressing.error.missing", defaultMessage: "ui.composer.addressing.error.missing" })) : null } }); } else { dispatch({ type: 'multiple', value: { addressing: value, recipients: [], addressingError: addressingRequiredEnabled && !value ? ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.composer.addressing.error.missing", defaultMessage: "ui.composer.addressing.error.missing" })) : null } }); } setLayer(null); }, [group, event, recipients]); const handleAddAudienceLayer = (0, react_1.useCallback)(() => { const defaultValue = group || (addressing && Object.prototype.hasOwnProperty.call(addressing, 'emotional_image_position')) ? group : event || (addressing && Object.prototype.hasOwnProperty.call(addressing, 'recurring')) ? event : Array.isArray(recipients) && recipients.some((item) => typeof item === 'object' && item !== null && !('color' in item)) ? recipients : addressing; handleAddLayer({ name: 'audience', Component: AudienceLayer_1.default, ComponentProps: { onClose: handleRemoveLayer, onSave: handleChangeAudience, defaultValue: defaultValue } }); }, [handleAddLayer, handleRemoveLayer, handleChangeAudience, addressing, event, group, recipients]); const handleChangeLocation = (0, react_1.useCallback)((value) => { dispatch({ type: 'location', value }); setLayer(null); }, []); const handleAddLocationLayer = (0, react_1.useCallback)(() => handleAddLayer({ name: 'location', Component: LocationLayer_1.default, ComponentProps: { onClose: handleRemoveLayer, onSave: handleChangeLocation, defaultValue: location } }), [handleAddLayer, handleRemoveLayer, handleChangeLocation, location]); const handleChangeScheduled = (0, react_1.useCallback)((value) => { dispatch({ type: 'scheduled_at', value }); setLayer(null); }, []); const handleAddScheduledLayer = (0, react_1.useCallback)(() => handleAddLayer({ name: 'scheduled_at', Component: ScheduledLayer_1.default, ComponentProps: { onClose: handleRemoveLayer, onSave: handleChangeScheduled, defaultValue: scheduled_at } }), [handleAddLayer, handleRemoveLayer, handleChangeScheduled, scheduled_at]); const handleChangeMedias = (0, react_1.useCallback)((value) => { const _medias = [...value]; dispatch({ type: 'medias', value: [...value] }); mediasRef.current.medias = _medias; setLayer(null); }, []); const handleAddMedia = (0, react_1.useCallback)((media) => { const _medias = [...mediasRef.current.medias, media]; dispatch({ type: 'medias', value: _medias }); mediasRef.current.medias = _medias; }, []); const handleMediaTriggerClick = (0, react_1.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 = (0, react_1.useCallback)((content) => { dispatch({ type: 'multiple', value: Object.assign(Object.assign({}, content), { addressingError: getAddressingError(content), categoriesError: categoryRequiredEnabled && content.categories.length === 0 ? ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.composer.categories.error.missing", defaultMessage: "ui.composer.categories.error.missing" })) : null }) }); }, []); const handleClickAttributes = (0, react_1.useCallback)((attr) => { switch (attr) { case 'categories': handleAddCategoryLayer(); break; case 'addressing': handleAddAudienceLayer(); break; case 'recipients': handleAddAudienceLayer(); break; case 'location': handleAddLocationLayer(); break; case 'scheduled_at': handleAddScheduledLayer(); break; } }, [handleAddCategoryLayer, handleAddAudienceLayer, handleAddLocationLayer, handleAddScheduledLayer]); const handleSubmit = (0, react_1.useCallback)((e) => { e.preventDefault(); e.stopPropagation(); if (react_core_1.UserUtils.isBlocked(scUserContext.user)) { // deny submit action if authenticated user is blocked enqueueSnackbar((0, jsx_runtime_1.jsx)(react_intl_1.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), ...(0, editor_1.extractHashtags)(html)]; const data = { title, text: html, medias: medias.map((m) => m.id), categories: _categories.filter((item, index) => _categories.indexOf(item) === index) }; if ((preferences[react_core_1.SCPreferences.ADDONS_POLLS_ENABLED].value || react_core_1.UserUtils.isStaff(scUserContext.user) || react_core_1.UserUtils.isPublisher(scUserContext.user)) && hasPoll) { data.poll = poll; } if (preferences[react_core_1.SCPreferences.ADDONS_POST_GEOLOCATION_ENABLED].value && location) { data.location = location; } if (preferences[react_core_1.SCPreferences.CONFIGURATIONS_SCHEDULED_POSTS_ENABLED].value && scheduled_at) { data.scheduled_at = scheduled_at; } if (features.includes(types_1.SCFeatureName.TAGGING) && addressing !== null) { data.addressing = addressing.map((t) => t.id); } if (features.includes(types_1.SCFeatureName.TAGGING) && recipients !== null) { data.recipients = recipients.map((r) => (typeof r === 'string' ? r : r.username)); } if (features.includes(types_1.SCFeatureName.TAGGING) && features.includes(types_1.SCFeatureName.GROUPING) && preferences[react_core_1.SCPreferences.CONFIGURATIONS_GROUPS_ENABLED].value && group !== null) { data.group = group.id; } if (features.includes(types_1.SCFeatureName.TAGGING) && features.includes(types_1.SCFeatureName.EVENT) && preferences[react_core_1.SCPreferences.CONFIGURATIONS_EVENTS_ENABLED].value && event !== null) { data.event = event.id; } setIsSubmitting(true); // Finding right url const _type = type === Composer_1.COMPOSER_TYPE_POLL ? types_1.SCContributionType.POST : type; let url = api_services_1.Endpoints.Composer.url({ type: _type }); let method = api_services_1.Endpoints.Composer.method; if (editMode) { url = api_services_1.Endpoints.ComposerEdit.url({ type: feedObjectType ? feedObjectType : _type, id }); method = api_services_1.Endpoints.ComposerEdit.method; } // Perform request api_services_1.http .request({ url, method, data }) .then((res) => { onSuccess(res.data); if (unloadRef.current) { window.onbeforeunload = null; } feedType && feedType === types_1.SCFeedTypologyType.CATEGORY ? dispatch({ type: 'resetCategoryFeed' }) : feedType === types_1.SCFeedTypologyType.EVENT ? dispatch({ type: 'resetEventFeed' }) : feedType === types_1.SCFeedTypologyType.GROUP ? dispatch({ type: 'resetGroupFeed' }) : dispatch({ type: 'reset' }); }) .catch((error) => { dispatch({ type: 'multiple', value: (0, api_services_1.formatHttpErrorCode)(error) }); }) .then(() => setIsSubmitting(false)); }, [ scUserContext.user, feedObjectType, id, type, title, html, categories, event, group, addressing, recipients, audience, medias, poll, location, scheduled_at, hasPoll ]); //edited here const handleClose = (0, react_1.useCallback)((e, reason) => { if (unloadRef.current) { window.onbeforeunload = null; } if (reason && canSubmit) { handleAddLayer({ name: 'close', Component: CloseLayer_1.default, ComponentProps: { onClose: handleRemoveLayer, onSave: () => { onClose && onClose(e); setLayer(null); feedType && feedType === types_1.SCFeedTypologyType.CATEGORY ? dispatch({ type: 'resetCategoryFeed' }) : feedType === types_1.SCFeedTypologyType.EVENT ? dispatch({ type: 'resetEventFeed' }) : feedType === types_1.SCFeedTypologyType.GROUP ? dispatch({ type: 'resetGroupFeed' }) : dispatch({ type: 'reset' }); } } }); } else { (0, body_scroll_lock_1.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 = (0, react_1.useCallback)((e) => { if (canSubmit) { handleAddLayer({ name: 'close', Component: CloseLayer_1.default, ComponentProps: { onClose: handleRemoveLayer, onSave: handleClose } }); } else { handleClose(e); } }, [canSubmit, handleAddLayer, handleRemoveLayer, handleClose]); // RENDER const hasMediaShare = (0, react_1.useMemo)(() => medias.findIndex((m) => m.type === Media_1.MEDIA_TYPE_SHARE) !== -1, [medias]); const content = (0, react_1.useMemo)(() => { if (editMode && isLoading) { return (0, jsx_runtime_1.jsx)(Skeleton_1.default, {}); } else if (editMode && loadError) { return ((0, jsx_runtime_1.jsxs)(material_1.Alert, Object.assign({ severity: "error", onClose: handleClose }, { children: [(0, jsx_runtime_1.jsx)(material_1.AlertTitle, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.composer.edit.error.title", defaultMessage: "ui.composer.edit.error.title" }) }), (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.composer.edit.error.content", defaultMessage: "ui.composer.edit.error.content" })] }))); } switch (type) { case Composer_1.COMPOSER_TYPE_POLL: return ((0, jsx_runtime_1.jsx)(ContentPoll_1.default, { onChange: handleChangePoll, value: { html, event, group, addressing, recipients, medias, poll, location, scheduled_at }, error: { pollError, categoriesError, addressingError }, disabled: isSubmitting }, key)); case types_1.SCContributionType.DISCUSSION: return ((0, jsx_runtime_1.jsx)(ContentDiscussion_1.default, { value: { title, html, categories, event, group, addressing, recipients, medias, poll, location, scheduled_at }, error: { titleError, categoriesError, addressingError, error }, onChange: handleChangeDiscussion, disabled: isSubmitting, isContentSwitchButtonVisible: !canSubmit && !editMode, EditorProps: Object.assign({ toolbar: true, uploadImage: true }, EditorProps) }, key)); default: return ((0, jsx_runtime_1.jsx)(ContentPost_1.default, { value: { html, categories, event, group, addressing, recipients, medias, poll, location, scheduled_at }, error: { error, categoriesError, addressingError }, onChange: handleChangePost, disabled: isSubmitting, EditorProps: Object.assign({ toolbar: false, uploadImage: false }, EditorProps) }, key)); } }, [ key, type, title, html, categories, event, group, addressing, recipients, medias, poll, pollError, location, scheduled_at, error, handleChangePoll, handleChangePost, isSubmitting, canSubmit, editMode ]); if (!scUserContext.user && !(scUserContext.loading && open)) { return null; } return ((0, jsx_runtime_1.jsxs)(Root, Object.assign({ ref: dialogRef, TransitionComponent: DialogTransition, slots: { backdrop: BackdropScrollDisabled_1.default }, onClose: handleClose }, rest, { disableEscapeKeyDown: true, className: (0, classnames_1.default)(classes.root, { [classes.ios]: isIOS }), scroll: "body", fullScreen: fullScreen, tabIndex: -1 }, { children: [(0, jsx_runtime_1.jsxs)("form", Object.assign({ onSubmit: handleSubmit, method: "post" }, { children: [(0, jsx_runtime_1.jsxs)(material_1.DialogTitle, Object.assign({ className: classes.title }, { children: [(0, jsx_runtime_1.jsx)(material_1.IconButton, Object.assign({ onClick: handleClosePrompt }, { children: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "close" }) })), (0, jsx_runtime_1.jsx)(LoadingButton_1.default, Object.assign({ size: "small", type: "submit", color: "secondary", variant: "contained", disabled: !canSubmit, loading: isSubmitting }, { children: scheduledPostsEnabled && !scheduled_at ? ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.composer.submit.now", defaultMessage: "ui.composer.submit.now" })) : ((0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.composer.submit", defaultMessage: "ui.composer.submit" })) }))] })), (0, jsx_runtime_1.jsxs)(material_1.DialogContent, Object.assign({ className: classes.content }, { children: [(0, jsx_runtime_1.jsx)(Attributes_1.default, { value: { categories, event, group, addressing, recipients, location }, className: classes.attributes, onChange: handleChangeAttributes, onClick: handleClickAttributes }), content, medias && medias.length > 0 && ((0, jsx_runtime_1.jsx)(material_1.Box, Object.assign({ className: classes.medias }, { children: mediaObjectTypes.map((mediaObjectType) => { if (mediaObjectType.previewComponent) { return (0, jsx_runtime_1.jsx)(mediaObjectType.previewComponent, { value: medias, onChange: handleChangeMedias }, mediaObjectType.name); } else if (mediaObjectType.displayComponent) { return (0, jsx_runtime_1.jsx)(mediaObjectType.displayComponent, { medias: medias }, mediaObjectType.name); } }) })))] })), !canSubmit && !editMode && (0, jsx_runtime_1.jsx)(TypeSwitchButtonGroup_1.default, { className: classes.types, onChange: handleChangeType, size: "small", value: type }), (0, jsx_runtime_1.jsxs)(material_1.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 ((0, jsx_runtime_1.jsx)(mediaObjectType.triggerButton, Object.assign({ disabled: isSubmitting || hasMediaShare, color: medias.filter(mediaObjectType.filter).length > 0 ? 'primary' : 'default' }, props), mediaObjectType.name)); }), (0, jsx_runtime_1.jsx)(material_1.IconButton, Object.assign({ disabled: isSubmitting, onClick: handleAddCategoryLayer, color: (categories === null || categories === void 0 ? void 0 : categories.length) !== 0 ? 'primary' : 'default' }, { children: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "category" }) })), (0, jsx_runtime_1.jsx)(material_1.IconButton, Object.assign({ color: group || event || (addressing !== null && (addressing === null || addressing === void 0 ? void 0 : addressing.length) > 0) || (recipients !== null && (recipients === null || recipients === void 0 ? void 0 : recipients.length) > 0) ? 'primary' : 'default', disabled: isSubmitting || !features.includes(types_1.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 ? ((0, jsx_runtime_1.jsx)(material_1.Icon, { children: "groups" })) : event ? ((0, jsx_runtime_1.jsx)(material_1.Icon, { children: "CalendarIcon" })) : addressing === null || (addressing === null || addressing === void 0 ? void 0 : addressing.length) === 0 ? (addressingRequiredEnabled ? ((0, jsx_runtime_1.jsx)(material_1.Icon, { children: "label" })) : ((0, jsx_runtime_1.jsx)(material_1.Icon, { children: "public" }))) : ((0, jsx_runtime_1.jsx)(material_1.Icon, { children: "label" })) })), preferences[react_core_1.SCPreferences.ADDONS_POST_GEOLOCATION_ENABLED].value && ((0, jsx_runtime_1.jsx)(material_1.IconButton, Object.assign({ disabled: isSubmitting, onClick: handleAddLocationLayer, color: location !== null ? 'primary' : 'default' }, { children: (0, jsx_runtime_1.jsx)(material_1.Icon, { children: "add_location_alt" }) }))), preferences[react_core_1.SCPreferences.CONFIGURATIONS_SCHEDULED_POSTS_ENABLED].value && ((0, jsx_runtime_1.jsx)(material_1.IconButton, Object.assign({ disabled: isSubmitting || (Boolean(feedObject === null || feedObject === void 0 ? void 0 : feedObject.scheduled_at) && Boolean(!(feedObject === null || feedObject === void 0 ? void 0 : feedObject.draft))), onClick: handleAddScheduledLayer, color: scheduled_at !== null ? 'primary' : 'default' }, { children: (0, jsx_runtime_1.jsxs)(material_1.Box, Object.assign({ className: classes.selectedAction }, { children: [(0, jsx_runtime_1.jsx)(material_1.Icon, { children: "access_time" }), scheduled_at !== null && ((0, jsx_runtime_1.jsx)(material_1.Icon, Object.assign({ color: "primary", className: classes.actionSelectedIcon }, { children: "fiber_manual_record" })))] })) })))] }))] })), layer && ((0, jsx_runtime_1.jsx)(LayerTransitionRoot, Object.assign({ className: classes.layerTransitionRoot, in: true, container: dialogRef.current, direction: "left" }, { children: (0, jsx_runtime_1.jsx)(layer.Component, Object.assign({}, layer.ComponentProps)) })))] }))); } exports.default = Composer;