UNPKG

@wordpress/editor

Version:
198 lines (180 loc) 6.24 kB
import { createElement } from "@wordpress/element"; /** * External dependencies */ import { get } from 'lodash'; /** * WordPress dependencies */ import { __, sprintf } from '@wordpress/i18n'; import { Modal, Button } from '@wordpress/components'; import { useSelect, useDispatch } from '@wordpress/data'; import { addQueryArgs } from '@wordpress/url'; import { useEffect } from '@wordpress/element'; import { addAction, removeAction } from '@wordpress/hooks'; import { useInstanceId } from '@wordpress/compose'; /** * Internal dependencies */ import { getWPAdminURL } from '../../utils/url'; import PostPreviewButton from '../post-preview-button'; export default function PostLockedModal() { const instanceId = useInstanceId(PostLockedModal); const hookName = 'core/editor/post-locked-modal-' + instanceId; const { autosave, updatePostLock } = useDispatch('core/editor'); const { isLocked, isTakeover, user, postId, postLockUtils, activePostLock, postType } = useSelect(select => { const { isPostLocked, isPostLockTakeover, getPostLockUser, getCurrentPostId, getActivePostLock, getEditedPostAttribute, getEditorSettings } = select('core/editor'); const { getPostType } = select('core'); return { isLocked: isPostLocked(), isTakeover: isPostLockTakeover(), user: getPostLockUser(), postId: getCurrentPostId(), postLockUtils: getEditorSettings().postLockUtils, activePostLock: getActivePostLock(), postType: getPostType(getEditedPostAttribute('type')) }; }); useEffect(() => { /** * Keep the lock refreshed. * * When the user does not send a heartbeat in a heartbeat-tick * the user is no longer editing and another user can start editing. * * @param {Object} data Data to send in the heartbeat request. */ function sendPostLock(data) { if (isLocked) { return; } data['wp-refresh-post-lock'] = { lock: activePostLock, post_id: postId }; } /** * Refresh post locks: update the lock string or show the dialog if somebody has taken over editing. * * @param {Object} data Data received in the heartbeat request */ function receivePostLock(data) { if (!data['wp-refresh-post-lock']) { return; } const received = data['wp-refresh-post-lock']; if (received.lock_error) { // Auto save and display the takeover modal. autosave(); updatePostLock({ isLocked: true, isTakeover: true, user: { avatar: received.lock_error.avatar_src } }); } else if (received.new_lock) { updatePostLock({ isLocked: false, activePostLock: received.new_lock }); } } /** * Unlock the post before the window is exited. */ function releasePostLock() { if (isLocked || !activePostLock) { return; } const data = new window.FormData(); data.append('action', 'wp-remove-post-lock'); data.append('_wpnonce', postLockUtils.unlockNonce); data.append('post_ID', postId); data.append('active_post_lock', activePostLock); if (window.navigator.sendBeacon) { window.navigator.sendBeacon(postLockUtils.ajaxUrl, data); } else { const xhr = new window.XMLHttpRequest(); xhr.open('POST', postLockUtils.ajaxUrl, false); xhr.send(data); } } // Details on these events on the Heartbeat API docs // https://developer.wordpress.org/plugins/javascript/heartbeat-api/ addAction('heartbeat.send', hookName, sendPostLock); addAction('heartbeat.tick', hookName, receivePostLock); window.addEventListener('beforeunload', releasePostLock); return () => { removeAction('heartbeat.send', hookName); removeAction('heartbeat.tick', hookName); window.removeEventListener('beforeunload', releasePostLock); }; }, []); if (!isLocked) { return null; } const userDisplayName = user.name; const userAvatar = user.avatar; const unlockUrl = addQueryArgs('post.php', { 'get-post-lock': '1', lockKey: true, post: postId, action: 'edit', _wpnonce: postLockUtils.nonce }); const allPostsUrl = getWPAdminURL('edit.php', { post_type: get(postType, ['slug']) }); const allPostsLabel = __('Exit the Editor'); return createElement(Modal, { title: isTakeover ? __('Someone else has taken over this post.') : __('This post is already being edited.'), focusOnMount: true, shouldCloseOnClickOutside: false, shouldCloseOnEsc: false, isDismissible: false, className: "editor-post-locked-modal" }, !!userAvatar && createElement("img", { src: userAvatar, alt: __('Avatar'), className: "editor-post-locked-modal__avatar" }), !!isTakeover && createElement("div", null, createElement("div", null, userDisplayName ? sprintf( /* translators: %s: user's display name */ __('%s now has editing control of this post. Don’t worry, your changes up to this moment have been saved.'), userDisplayName) : __('Another user now has editing control of this post. Don’t worry, your changes up to this moment have been saved.')), createElement("div", { className: "editor-post-locked-modal__buttons" }, createElement(Button, { isPrimary: true, href: allPostsUrl }, allPostsLabel))), !isTakeover && createElement("div", null, createElement("div", null, userDisplayName ? sprintf( /* translators: %s: user's display name */ __('%s is currently working on this post, which means you cannot make changes, unless you take over.'), userDisplayName) : __('Another user is currently working on this post, which means you cannot make changes, unless you take over.')), createElement("div", { className: "editor-post-locked-modal__buttons" }, createElement(Button, { isSecondary: true, href: allPostsUrl }, allPostsLabel), createElement(PostPreviewButton, null), createElement(Button, { isPrimary: true, href: unlockUrl }, __('Take Over'))))); } //# sourceMappingURL=index.js.map