@wordpress/editor
Version:
Enhanced block editor for WordPress posts.
198 lines (180 loc) • 6.24 kB
JavaScript
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