@wordpress/block-editor
Version:
125 lines (121 loc) • 4.52 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.useMediaCategories = useMediaCategories;
exports.useMediaResults = useMediaResults;
var _element = require("@wordpress/element");
var _data = require("@wordpress/data");
var _store = require("../../../store");
var _lockUnlock = require("../../../lock-unlock");
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
/** @typedef {import('../../../store/actions').InserterMediaRequest} InserterMediaRequest */
/** @typedef {import('../../../store/actions').InserterMediaItem} InserterMediaItem */
/**
* Fetches media items based on the provided category.
* Each media category is responsible for providing a `fetch` function.
*
* @param {Object} category The media category to fetch results for.
* @param {InserterMediaRequest} query The query args to use for the request.
* @return {InserterMediaItem[]} The media results.
*/
function useMediaResults(category, query = {}) {
const [mediaList, setMediaList] = (0, _element.useState)();
const [isLoading, setIsLoading] = (0, _element.useState)(false);
// We need to keep track of the last request made because
// multiple request can be fired without knowing the order
// of resolution, and we need to ensure we are showing
// the results of the last request.
// In the future we could use AbortController to cancel previous
// requests, but we don't for now as it involves adding support
// for this to `core-data` package.
const lastRequestRef = (0, _element.useRef)();
(0, _element.useEffect)(() => {
(async () => {
const key = JSON.stringify({
category: category.name,
...query
});
lastRequestRef.current = key;
setIsLoading(true);
setMediaList([]); // Empty the previous results.
const _media = await category.fetch?.(query);
if (key === lastRequestRef.current) {
setMediaList(_media);
setIsLoading(false);
}
})();
}, [category.name, ...Object.values(query)]);
return {
mediaList,
isLoading
};
}
function useMediaCategories(rootClientId) {
const [categories, setCategories] = (0, _element.useState)([]);
const inserterMediaCategories = (0, _data.useSelect)(select => (0, _lockUnlock.unlock)(select(_store.store)).getInserterMediaCategories(), []);
const {
canInsertImage,
canInsertVideo,
canInsertAudio
} = (0, _data.useSelect)(select => {
const {
canInsertBlockType
} = select(_store.store);
return {
canInsertImage: canInsertBlockType('core/image', rootClientId),
canInsertVideo: canInsertBlockType('core/video', rootClientId),
canInsertAudio: canInsertBlockType('core/audio', rootClientId)
};
}, [rootClientId]);
(0, _element.useEffect)(() => {
(async () => {
const _categories = [];
// If `inserterMediaCategories` is not defined in
// block editor settings, do not show any media categories.
if (!inserterMediaCategories) {
return;
}
// Loop through categories to check if they have at least one media item.
const categoriesHaveMedia = new Map(await Promise.all(inserterMediaCategories.map(async category => {
// Some sources are external and we don't need to make a request.
if (category.isExternalResource) {
return [category.name, true];
}
let results = [];
try {
results = await category.fetch({
per_page: 1
});
} catch (e) {
// If the request fails, we shallow the error and just don't show
// the category, in order to not break the media tab.
}
return [category.name, !!results.length];
})));
// We need to filter out categories that don't have any media items or
// whose corresponding block type is not allowed to be inserted, based
// on the category's `mediaType`.
const canInsertMediaType = {
image: canInsertImage,
video: canInsertVideo,
audio: canInsertAudio
};
inserterMediaCategories.forEach(category => {
if (canInsertMediaType[category.mediaType] && categoriesHaveMedia.get(category.name)) {
_categories.push(category);
}
});
if (!!_categories.length) {
setCategories(_categories);
}
})();
}, [canInsertImage, canInsertVideo, canInsertAudio, inserterMediaCategories]);
return categories;
}
//# sourceMappingURL=hooks.js.map