UNPKG

@wordpress/editor

Version:
143 lines (142 loc) 4.64 kB
// packages/editor/src/components/upload-progress-snackbar/index.js import { useSelect, useDispatch } from "@wordpress/data"; import { useEffect, useMemo, useRef } from "@wordpress/element"; import { __, sprintf } from "@wordpress/i18n"; import { speak } from "@wordpress/a11y"; import { store as uploadStore } from "@wordpress/upload-media"; import { store as noticesStore } from "@wordpress/notices"; import { Icon as WCIcon, Spinner } from "@wordpress/components"; import { check } from "@wordpress/icons"; import { useTracker } from "./tracker.mjs"; import { jsx } from "react/jsx-runtime"; var NOTICE_ID = "upload-progress"; var COMPLETION_DISPLAY_MS = 3e3; var MAX_FILENAME_LENGTH = 40; function truncateFilename(filename) { if (filename.length <= MAX_FILENAME_LENGTH) { return filename; } const ellipsis = "…"; const visible = MAX_FILENAME_LENGTH - ellipsis.length; const front = Math.ceil(visible / 2); const back = Math.floor(visible / 2); return filename.slice(0, front) + ellipsis + filename.slice(filename.length - back); } var UPLOAD_SPINNER = /* @__PURE__ */ jsx( "span", { className: "editor-upload-progress-snackbar__spinner", "aria-hidden": "true", children: /* @__PURE__ */ jsx(Spinner, {}) } ); var UPLOAD_DONE = /* @__PURE__ */ jsx("span", { className: "editor-upload-progress-snackbar__check", "aria-hidden": "true", children: /* @__PURE__ */ jsx(WCIcon, { icon: check }) }); function UploadProgressSnackbar() { const items = useSelect( (select) => select(uploadStore).getItems(), [] ); const tracker = useTracker(); const csmOriginals = useMemo( () => items.filter((item) => !item.parentId), [items] ); const csmRemaining = csmOriginals.length; const trackedRemaining = tracker ? tracker.total - tracker.completed : 0; const remaining = csmRemaining + trackedRemaining; const sessionTotal = csmRemaining + (tracker ? tracker.total : 0); const peakRef = useRef(0); const { createNotice, removeNotice } = useDispatch(noticesStore); const dismissedRef = useRef(false); const wasUploadingRef = useRef(false); const completionTimeoutRef = useRef(null); useEffect(() => { return () => { if (completionTimeoutRef.current) { clearTimeout(completionTimeoutRef.current); } }; }, []); useEffect(() => { const isUploading = remaining > 0; if (isUploading && !wasUploadingRef.current) { dismissedRef.current = false; speak(__("Media upload started"), "polite"); if (completionTimeoutRef.current) { clearTimeout(completionTimeoutRef.current); completionTimeoutRef.current = null; peakRef.current = 0; } } else if (!isUploading && wasUploadingRef.current) { speak(__("Media upload complete"), "polite"); if (!dismissedRef.current) { createNotice("info", __("Upload complete"), { id: NOTICE_ID, type: "snackbar", isDismissible: false, explicitDismiss: false, speak: false, icon: UPLOAD_DONE, onDismiss: () => { dismissedRef.current = true; } }); completionTimeoutRef.current = setTimeout(() => { removeNotice(NOTICE_ID); completionTimeoutRef.current = null; peakRef.current = 0; }, COMPLETION_DISPLAY_MS); } else { peakRef.current = 0; } } wasUploadingRef.current = isUploading; if (!isUploading || dismissedRef.current) { return; } if (sessionTotal > peakRef.current) { peakRef.current = sessionTotal; } const total = peakRef.current; const current = total - remaining + 1; const filename = truncateFilename( csmOriginals[0]?.sourceFile?.name || tracker?.pending[0] || __("Uploading") ); const content = total === 1 ? sprintf( /* translators: %s: filename. */ __("Uploading — %s"), filename ) : sprintf( /* translators: 1: current upload number, 2: total uploads, 3: filename. */ __("Uploading %1$d of %2$d — %3$s"), current, total, filename ); createNotice("info", content, { id: NOTICE_ID, type: "snackbar", isDismissible: false, explicitDismiss: true, speak: false, icon: UPLOAD_SPINNER, onDismiss: () => { dismissedRef.current = true; } }); }, [ remaining, sessionTotal, csmOriginals, tracker, createNotice, removeNotice ]); return null; } export { UPLOAD_DONE, UPLOAD_SPINNER, UploadProgressSnackbar as default }; //# sourceMappingURL=index.mjs.map