| 1 |
import { useState, useEffect, useRef } from "@wordpress/element"; |
| 2 |
import { select, subscribe } from "@wordpress/data"; |
| 3 |
|
| 4 |
/** |
| 5 |
* useEditorSaveStatus |
| 6 |
* |
| 7 |
* Detects if *any* entity (post, page, template, widget, etc.) |
| 8 |
* is currently being saved — works in Site Editor, Post Editor, and Widgets. |
| 9 |
* |
| 10 |
* @return {Object} { isSaving, isAutosaving } |
| 11 |
*/ |
| 12 |
export const useEditorSaveStatus = () => { |
| 13 |
const [isSaving, setIsSaving] = useState(false); |
| 14 |
const [isAutosaving, setIsAutosaving] = useState(false); |
| 15 |
const prevSavingRef = useRef(false); |
| 16 |
|
| 17 |
useEffect(() => { |
| 18 |
const unsubscribe = subscribe(() => { |
| 19 |
const core = select("core"); |
| 20 |
if (!core) { |
| 21 |
return; |
| 22 |
} |
| 23 |
|
| 24 |
const { __experimentalGetDirtyEntityRecords, isSavingEntityRecord } = core; |
| 25 |
|
| 26 |
if (typeof __experimentalGetDirtyEntityRecords !== "function") { |
| 27 |
return; |
| 28 |
} |
| 29 |
|
| 30 |
const dirtyEntities = __experimentalGetDirtyEntityRecords(); |
| 31 |
|
| 32 |
// Check if any entity is saving |
| 33 |
const isNowSaving = dirtyEntities.some((record) => |
| 34 |
isSavingEntityRecord(record.kind, record.name, record.key) |
| 35 |
); |
| 36 |
|
| 37 |
// Detect autosaving from post editor if available |
| 38 |
const coreEditor = select("core/editor"); |
| 39 |
const isNowAutosaving = |
| 40 |
typeof coreEditor?.isAutosavingPost === "function" ? coreEditor.isAutosavingPost() : false; |
| 41 |
|
| 42 |
// Update only when changed |
| 43 |
if (prevSavingRef.current !== isNowSaving) { |
| 44 |
setIsSaving(isNowSaving); |
| 45 |
prevSavingRef.current = isNowSaving; |
| 46 |
} |
| 47 |
setIsAutosaving(isNowAutosaving); |
| 48 |
}); |
| 49 |
|
| 50 |
return () => { |
| 51 |
unsubscribe(); |
| 52 |
}; |
| 53 |
}, []); |
| 54 |
|
| 55 |
return { isSaving, isAutosaving }; |
| 56 |
}; |
| 57 |
|