/** * WordPress dependencies */ import { store as CORE } from '@safe-wordpress/core-data'; import { useDispatch, useSelect, select as doSelect, } from '@safe-wordpress/data'; import { useCallback, useMemo } from '@safe-wordpress/element'; import type { Type as PostType } from '@safe-wordpress/core-data'; /** * External dependencies */ import { filter, map, uniq } from 'lodash'; import { EMPTY_ARRAY } from '@nelio-content/constants'; import { store as NC_DATA } from '@nelio-content/data'; import type { Maybe, Post, PostId, PostTypeName, Taxonomy, } from '@nelio-content/types'; /** * Internal dependencies */ import { store as NC_SOCIAL_EDITOR } from '../store'; import type { RelatedPostStatus } from '../store/types'; export const useIsLoadingRelatedPost = (): boolean => useSelect( ( select ) => 'loading' === select( NC_SOCIAL_EDITOR ).getRelatedPostStatus().type, [] ); export const useRelatedPost = (): [ Maybe< Post >, ( post: PostId ) => void, ] => { const post = useSelect( ( select ) => select( NC_SOCIAL_EDITOR ).getPost(), [] ); const { setPost: doSetPost } = useDispatch( NC_SOCIAL_EDITOR ); const setPost = useCallback( ( postId: PostId ) => { const newPost = doSelect( NC_DATA ).getPost( postId ); if ( ! newPost ) { return; } void doSetPost( newPost ); }, [ doSetPost ] ); return [ post, setPost ]; }; export const useRelatedPostId = (): Maybe< PostId > => useSelect( ( select ) => select( NC_SOCIAL_EDITOR ).getPostId(), [] ); export const useRelatedPostType = (): Maybe< PostTypeName > => useSelect( ( select ) => select( NC_SOCIAL_EDITOR ).getPostType(), [] ); export const useIsRelatedPostHidden = (): boolean => useSelect( ( select ) => { const editor = select( NC_SOCIAL_EDITOR ); const context = editor.getEditorContext(); const isExistingMessage = ! editor.isNewMessage(); const hasRelatedPost = editor.getRelatedPostStatus().type !== 'none'; return ( context !== 'calendar' || ( isExistingMessage && ! hasRelatedPost ) ); }, [] ); export const useRelatedPostStatus = (): RelatedPostStatus => useSelect( ( select ) => select( NC_SOCIAL_EDITOR ).getRelatedPostStatus(), [] ); const EMPTY_RESULT = { published: EMPTY_ARRAY, pending: EMPTY_ARRAY, } as const; export const useExistingMessages = (): { readonly published: ReadonlyArray< string >; readonly pending: ReadonlyArray< string >; } => { const postId = useSelect( ( select ) => select( NC_SOCIAL_EDITOR ).getPostId(), [] ); const messages = useSelect( ( select ) => postId ? select( NC_DATA ).getSocialMessagesRelatedToPost( postId ) : EMPTY_ARRAY, [ postId ] ); return useMemo( () => { if ( ! postId ) { return EMPTY_RESULT; } const published = filter( messages, ( m ) => m.status === 'publish' ); const pending = filter( messages, ( m ) => m.status !== 'publish' ); return { published: uniq( map( published, 'text' ) ), pending: uniq( map( pending, 'text' ) ), }; }, [ postId, messages ] ); }; export const useIsLoadingPreviousMessages = (): boolean => useSelect( ( select ) => { const postId = select( NC_SOCIAL_EDITOR ).getPostId(); const isLoading = select( NC_DATA ).isResolving( 'getPostRelatedItems', [ postId ] ); return !! postId && isLoading; }, [] ); export const usePostSupports = ( feat: 'author' | 'excerpt', post: Maybe< Post > ): boolean => { const typeName = post?.type; const type = useSelect( ( select ) => typeName ? select( CORE ).getEntityRecord< PostType >( 'root', 'postType', typeName ) : undefined, [ typeName ] ); return useMemo( () => { if ( ! type ) { return false; } switch ( feat ) { case 'author': return !! type.supports?.author; case 'excerpt': return !! type.supports?.excerpt; default: return false; } }, [ type, feat ] ); }; const TAX_QUERY = { per_page: -1 } as const; export const useSupportedTaxonomies = ( post: Maybe< Post > ): ReadonlyArray< Taxonomy > => { const type = post?.type ?? ''; const taxonomies = useSelect( ( select ) => select( CORE ).getEntityRecords< Taxonomy >( 'root', 'taxonomy', TAX_QUERY ) ?? EMPTY_ARRAY, [] ); return useMemo( () => filter( filter( taxonomies, ( t ): t is Taxonomy => !! t ), ( tax ) => tax.visibility.public && tax.types.includes( type ) ), [ taxonomies, type ] ); };