/** * WordPress dependencies */ import { useSelect } from '@safe-wordpress/data'; /** * External dependencies */ import { flatten, filter, find, keyBy, keys, map, mapValues, omit, values, } from 'lodash'; import { store as NC_DATA } from '@nelio-content/data'; import { isAutoSelectedUuid } from '@nelio-content/utils'; import type { AutoSelectedUuid, Maybe, Post, SocialTemplate, Uuid, } from '@nelio-content/types'; /** * Internal dependencies */ import { store as NC_SOCIAL_EDITOR } from '../store'; export type PostTemplates = { readonly recommendedTemplates: ReadonlyArray< SocialTemplate >; readonly otherTemplates: ReadonlyArray< SocialTemplate >; }; export const usePostTemplates = ( post: Maybe< Post > ): PostTemplates => { const templates = useSelect( ( select ) => select( NC_DATA ).getSocialTemplates( post ), [ post ] ); const recommendedTemplates = useSelect( ( select ) => { const selectedProfiles = select( NC_SOCIAL_EDITOR ).getSelectedSocialProfiles(); const selectedNetworks = select( NC_SOCIAL_EDITOR ).getSelectedSocialNetworks(); const profiles = map( selectedProfiles, ( id: Uuid | AutoSelectedUuid ) => isAutoSelectedUuid( id ) ? id.value : id ); const targets = flatten( map( profiles, select( NC_SOCIAL_EDITOR ).getSelectedTargetsInProfile ) ); return keyBy( filter( templates, ( t ) => { if ( ! post && hasPlaceholders( t.text ) ) { return false; } if ( ! impliesIn( t.profileId, profiles ) ) { return false; } if ( ! impliesIn( t.network, selectedNetworks ) ) { return false; } if ( ! impliesIn( t.targetName, targets ) ) { return false; } if ( ! post ) { return true; } if ( t.author && t.author !== post.author ) { return false; } const taxOk = values( mapValues( post.taxonomies, ( terms, tax ) => { const required = t.taxonomies?.[ tax ]; if ( ! required ) { return true; } return !! find( terms, { id: required } ); } ) ).every( Boolean ); return taxOk; } ), 'text' ); }, [ post, templates ] ); return { recommendedTemplates: values( recommendedTemplates ), otherTemplates: values( omit( keyBy( templates, 'text' ), keys( recommendedTemplates ) ) ), }; }; // ======= // HELPERS // ======= const hasPlaceholders = ( text: string ) => text.includes( '{permalink}' ); const impliesIn = ( el: Maybe< string >, list: ReadonlyArray< string > ) => ! el || ! list.length || list.includes( el );