@wordpress/editor
Version:
Enhanced block editor for WordPress posts.
169 lines (168 loc) • 6.14 kB
JavaScript
// packages/editor/src/components/sync-connection-error-modal/index.tsx
import { useSelect, select } from "@wordpress/data";
import { useCopyToClipboard } from "@wordpress/compose";
import { serialize } from "@wordpress/blocks";
import {
store as coreDataStore,
privateApis as coreDataPrivateApis
} from "@wordpress/core-data";
import { privateApis, store as blockEditorStore } from "@wordpress/block-editor";
import {
Button,
Modal,
__experimentalHStack as HStack,
__experimentalVStack as VStack
} from "@wordpress/components";
import { applyFilters } from "@wordpress/hooks";
import { useState, useEffect } from "@wordpress/element";
import { __, sprintf, _n } from "@wordpress/i18n";
import { getSyncErrorMessages } from "../../utils/sync-error-messages.mjs";
import { store as editorStore } from "../../store/index.mjs";
import { unlock } from "../../lock-unlock.mjs";
import { useRetryCountdown } from "./use-retry-countdown.mjs";
import { jsx, jsxs } from "react/jsx-runtime";
var { BlockCanvasCover } = unlock(privateApis);
var { retrySyncConnection } = unlock(coreDataPrivateApis);
var INITIAL_DISCONNECTED_DEBOUNCE_MS = 2e4;
function SyncConnectionErrorModal() {
const [hasInitialized, setHasInitialized] = useState(false);
const [showModal, setShowModal] = useState(false);
const [isManualRetryAvailable, setIsManualRetryAvailable] = useState(false);
const { connectionStatus, isCollaborationEnabled, postType } = useSelect(
(selectFn) => {
const currentPostType = selectFn(editorStore).getCurrentPostType();
return {
connectionStatus: selectFn(coreDataStore).getSyncConnectionStatus() || null,
isCollaborationEnabled: selectFn(
editorStore
).isCollaborationEnabledForCurrentPost(),
postType: currentPostType ? selectFn(coreDataStore).getPostType(currentPostType) : null
};
},
[]
);
const { onManualRetry, secondsRemaining } = useRetryCountdown(connectionStatus);
const copyButtonRef = useCopyToClipboard(() => {
const blocks = select(blockEditorStore).getBlocks();
return serialize(blocks);
});
useEffect(() => {
const timeout = setTimeout(() => {
setHasInitialized(true);
}, INITIAL_DISCONNECTED_DEBOUNCE_MS);
return () => clearTimeout(timeout);
}, []);
useEffect(() => {
if ("connecting" === connectionStatus?.status) {
return;
}
setIsManualRetryAvailable(
connectionStatus !== null && "canManuallyRetry" in connectionStatus && connectionStatus.canManuallyRetry === true
);
}, [connectionStatus]);
const canRetry = connectionStatus && "disconnected" === connectionStatus.status && (connectionStatus.canManuallyRetry || connectionStatus.willAutoRetryInMs);
useEffect(() => {
if ("connected" === connectionStatus?.status) {
setShowModal(false);
return;
}
if (connectionStatus?.status && "connecting" !== connectionStatus.status && (!canRetry || connectionStatus.backgroundRetriesFailed)) {
setShowModal(true);
}
}, [connectionStatus, canRetry]);
if (!isCollaborationEnabled || !hasInitialized || !showModal) {
return null;
}
const error = connectionStatus && "error" in connectionStatus ? connectionStatus?.error : void 0;
if (!canRetry && applyFilters(
"editor.isSyncConnectionErrorHandled",
false,
error?.code
) !== false) {
return null;
}
const manualRetry = isManualRetryAvailable ? () => {
onManualRetry();
retrySyncConnection();
} : void 0;
const messages = getSyncErrorMessages(error);
let retryCountdownText = "";
let isRetrying = false;
if (secondsRemaining && secondsRemaining > 0) {
retryCountdownText = sprintf(
/* translators: %d: number of seconds until retry */
_n(
"Retrying connection in %d second\u2026",
"Retrying connection in %d seconds\u2026",
secondsRemaining
),
secondsRemaining
);
} else if (0 === secondsRemaining) {
isRetrying = true;
retryCountdownText = __("Retrying\u2026");
}
let editPostHref = "edit.php";
if (postType?.slug) {
editPostHref = `edit.php?post_type=${postType.slug}`;
}
return /* @__PURE__ */ jsx(BlockCanvasCover.Fill, { children: /* @__PURE__ */ jsx(
Modal,
{
overlayClassName: "editor-sync-connection-error-modal",
isDismissible: false,
onRequestClose: () => {
},
shouldCloseOnClickOutside: false,
shouldCloseOnEsc: false,
size: "medium",
title: messages.title,
children: /* @__PURE__ */ jsxs(VStack, { spacing: 6, children: [
/* @__PURE__ */ jsx("p", { children: messages.description }),
retryCountdownText && /* @__PURE__ */ jsx("p", { className: "editor-sync-connection-error-modal__retry-countdown", children: retryCountdownText }),
/* @__PURE__ */ jsxs(HStack, { justify: "right", children: [
/* @__PURE__ */ jsx(
Button,
{
__next40pxDefaultSize: true,
href: editPostHref,
isDestructive: true,
variant: "tertiary",
children: sprintf(
/* translators: %s: Post type name (e.g., "Posts", "Pages"). */
__("Back to %s"),
postType?.labels?.name ?? __("Posts")
)
}
),
/* @__PURE__ */ jsx(
Button,
{
__next40pxDefaultSize: true,
ref: copyButtonRef,
variant: manualRetry ? "secondary" : "primary",
children: __("Copy Post Content")
}
),
manualRetry && /* @__PURE__ */ jsx(
Button,
{
__next40pxDefaultSize: true,
accessibleWhenDisabled: true,
"aria-disabled": isRetrying,
disabled: isRetrying,
isBusy: isRetrying,
variant: "primary",
onClick: manualRetry,
children: __("Retry")
}
)
] })
] })
}
) });
}
export {
SyncConnectionErrorModal
};
//# sourceMappingURL=index.mjs.map