UNPKG

@wordpress/block-library

Version:
8 lines (7 loc) 7.34 kB
{ "version": 3, "sources": ["../../src/comment-template/hooks.js"], "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { useState, useEffect, useMemo } from '@wordpress/element';\nimport { useSelect } from '@wordpress/data';\nimport { store as blockEditorStore } from '@wordpress/block-editor';\nimport { addQueryArgs } from '@wordpress/url';\nimport apiFetch from '@wordpress/api-fetch';\n\n// This is limited by WP REST API\nconst MAX_COMMENTS_PER_PAGE = 100;\n\n/**\n * Return an object with the query args needed to fetch the default page of\n * comments.\n *\n * @param {Object} props Hook props.\n * @param {number} props.postId ID of the post that contains the comments.\n * discussion settings.\n *\n * @return {Object} Query args to retrieve the comments.\n */\nexport const useCommentQueryArgs = ( { postId } ) => {\n\t// Initialize the query args that are not going to change.\n\tconst queryArgs = {\n\t\tstatus: 'approve',\n\t\torder: 'asc',\n\t\tcontext: 'embed',\n\t\tparent: 0,\n\t\t_embed: 'children',\n\t};\n\n\t// Get the Discussion settings that may be needed to query the comments.\n\tconst {\n\t\tpageComments,\n\t\tcommentsPerPage,\n\t\tdefaultCommentsPage: defaultPage,\n\t} = useSelect( ( select ) => {\n\t\tconst { getSettings } = select( blockEditorStore );\n\t\tconst { __experimentalDiscussionSettings } = getSettings();\n\t\treturn __experimentalDiscussionSettings ?? {};\n\t}, [] );\n\n\t// WP REST API doesn't allow fetching more than max items limit set per single page of data.\n\t// As for the editor performance is more important than completeness of data and fetching only the\n\t// max allowed for single page should be enough for the purpose of design and laying out the page.\n\t// Fetching over the limit would return an error here but would work with backend query.\n\tconst perPage = pageComments\n\t\t? Math.min( commentsPerPage, MAX_COMMENTS_PER_PAGE )\n\t\t: MAX_COMMENTS_PER_PAGE;\n\n\t// Get the number of the default page.\n\tconst page = useDefaultPageIndex( {\n\t\tdefaultPage,\n\t\tpostId,\n\t\tperPage,\n\t\tqueryArgs,\n\t} );\n\n\t// Merge, memoize and return all query arguments, unless the default page's\n\t// number is not known yet.\n\treturn useMemo( () => {\n\t\treturn page\n\t\t\t? {\n\t\t\t\t\t...queryArgs,\n\t\t\t\t\tpost: postId,\n\t\t\t\t\tper_page: perPage,\n\t\t\t\t\tpage,\n\t\t\t }\n\t\t\t: null;\n\t}, [ postId, perPage, page ] );\n};\n\n/**\n * Return the index of the default page, depending on whether `defaultPage` is\n * `newest` or `oldest`. In the first case, the only way to know the page's\n * index is by using the `X-WP-TotalPages` header, which forces to make an\n * additional request.\n *\n * @param {Object} props Hook props.\n * @param {string} props.defaultPage Page shown by default (newest/oldest).\n * @param {number} props.postId ID of the post that contains the comments.\n * @param {number} props.perPage The number of comments included per page.\n * @param {Object} props.queryArgs Other query args.\n *\n * @return {number} Index of the default comments page.\n */\nconst useDefaultPageIndex = ( { defaultPage, postId, perPage, queryArgs } ) => {\n\t// Store the default page indices.\n\tconst [ defaultPages, setDefaultPages ] = useState( {} );\n\tconst key = `${ postId }_${ perPage }`;\n\tconst page = defaultPages[ key ] || 0;\n\n\tuseEffect( () => {\n\t\t// Do nothing if the page is already known or not the newest page.\n\t\tif ( page || defaultPage !== 'newest' ) {\n\t\t\treturn;\n\t\t}\n\t\t// We need to fetch comments to know the index. Use HEAD and limit\n\t\t// fields just to ID, to make this call as light as possible.\n\t\tapiFetch( {\n\t\t\tpath: addQueryArgs( '/wp/v2/comments', {\n\t\t\t\t...queryArgs,\n\t\t\t\tpost: postId,\n\t\t\t\tper_page: perPage,\n\t\t\t\t_fields: 'id',\n\t\t\t} ),\n\t\t\tmethod: 'HEAD',\n\t\t\tparse: false,\n\t\t} )\n\t\t\t.then( ( res ) => {\n\t\t\t\tconst pages = parseInt( res.headers.get( 'X-WP-TotalPages' ) );\n\t\t\t\tsetDefaultPages( {\n\t\t\t\t\t...defaultPages,\n\t\t\t\t\t[ key ]: pages <= 1 ? 1 : pages, // If there are 0 pages, it means that there are no comments, but there is no 0th page.\n\t\t\t\t} );\n\t\t\t} )\n\t\t\t.catch( () => {\n\t\t\t\t// There's no 0th page, but we can't know the number of pages, fallback to 1.\n\t\t\t\tsetDefaultPages( {\n\t\t\t\t\t...defaultPages,\n\t\t\t\t\t[ key ]: 1,\n\t\t\t\t} );\n\t\t\t} );\n\t}, [ defaultPage, postId, perPage, setDefaultPages ] );\n\n\t// The oldest one is always the first one.\n\treturn defaultPage === 'newest' ? page : 1;\n};\n\n/**\n * Generate a tree structure of comment IDs from a list of comment entities. The\n * children of each comment are obtained from `_embedded`.\n *\n * @typedef {{ commentId: number, children: CommentNode }} CommentNode\n *\n * @param {Object[]} topLevelComments List of comment entities.\n * @return {{ commentTree: CommentNode[]}} Tree of comment IDs.\n */\nexport const useCommentTree = ( topLevelComments ) => {\n\tconst commentTree = useMemo(\n\t\t() =>\n\t\t\ttopLevelComments?.map( ( { id, _embedded } ) => {\n\t\t\t\tconst [ children ] = _embedded?.children || [ [] ];\n\t\t\t\treturn {\n\t\t\t\t\tcommentId: id,\n\t\t\t\t\tchildren: children.map( ( child ) => ( {\n\t\t\t\t\t\tcommentId: child.id,\n\t\t\t\t\t} ) ),\n\t\t\t\t};\n\t\t\t} ),\n\t\t[ topLevelComments ]\n\t);\n\n\treturn commentTree;\n};\n"], "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,qBAA6C;AAC7C,kBAA0B;AAC1B,0BAA0C;AAC1C,iBAA6B;AAC7B,uBAAqB;AAGrB,IAAM,wBAAwB;AAYvB,IAAM,sBAAsB,CAAE,EAAE,OAAO,MAAO;AAEpD,QAAM,YAAY;AAAA,IACjB,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,QAAQ;AAAA,EACT;AAGA,QAAM;AAAA,IACL;AAAA,IACA;AAAA,IACA,qBAAqB;AAAA,EACtB,QAAI,uBAAW,CAAE,WAAY;AAC5B,UAAM,EAAE,YAAY,IAAI,OAAQ,oBAAAA,KAAiB;AACjD,UAAM,EAAE,iCAAiC,IAAI,YAAY;AACzD,WAAO,oCAAoC,CAAC;AAAA,EAC7C,GAAG,CAAC,CAAE;AAMN,QAAM,UAAU,eACb,KAAK,IAAK,iBAAiB,qBAAsB,IACjD;AAGH,QAAM,OAAO,oBAAqB;AAAA,IACjC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD,CAAE;AAIF,aAAO,wBAAS,MAAM;AACrB,WAAO,OACJ;AAAA,MACA,GAAG;AAAA,MACH,MAAM;AAAA,MACN,UAAU;AAAA,MACV;AAAA,IACA,IACA;AAAA,EACJ,GAAG,CAAE,QAAQ,SAAS,IAAK,CAAE;AAC9B;AAgBA,IAAM,sBAAsB,CAAE,EAAE,aAAa,QAAQ,SAAS,UAAU,MAAO;AAE9E,QAAM,CAAE,cAAc,eAAgB,QAAI,yBAAU,CAAC,CAAE;AACvD,QAAM,MAAM,GAAI,MAAO,IAAK,OAAQ;AACpC,QAAM,OAAO,aAAc,GAAI,KAAK;AAEpC,gCAAW,MAAM;AAEhB,QAAK,QAAQ,gBAAgB,UAAW;AACvC;AAAA,IACD;AAGA,yBAAAC,SAAU;AAAA,MACT,UAAM,yBAAc,mBAAmB;AAAA,QACtC,GAAG;AAAA,QACH,MAAM;AAAA,QACN,UAAU;AAAA,QACV,SAAS;AAAA,MACV,CAAE;AAAA,MACF,QAAQ;AAAA,MACR,OAAO;AAAA,IACR,CAAE,EACA,KAAM,CAAE,QAAS;AACjB,YAAM,QAAQ,SAAU,IAAI,QAAQ,IAAK,iBAAkB,CAAE;AAC7D,sBAAiB;AAAA,QAChB,GAAG;AAAA,QACH,CAAE,GAAI,GAAG,SAAS,IAAI,IAAI;AAAA;AAAA,MAC3B,CAAE;AAAA,IACH,CAAE,EACD,MAAO,MAAM;AAEb,sBAAiB;AAAA,QAChB,GAAG;AAAA,QACH,CAAE,GAAI,GAAG;AAAA,MACV,CAAE;AAAA,IACH,CAAE;AAAA,EACJ,GAAG,CAAE,aAAa,QAAQ,SAAS,eAAgB,CAAE;AAGrD,SAAO,gBAAgB,WAAW,OAAO;AAC1C;AAWO,IAAM,iBAAiB,CAAE,qBAAsB;AACrD,QAAM,kBAAc;AAAA,IACnB,MACC,kBAAkB,IAAK,CAAE,EAAE,IAAI,UAAU,MAAO;AAC/C,YAAM,CAAE,QAAS,IAAI,WAAW,YAAY,CAAE,CAAC,CAAE;AACjD,aAAO;AAAA,QACN,WAAW;AAAA,QACX,UAAU,SAAS,IAAK,CAAE,WAAa;AAAA,UACtC,WAAW,MAAM;AAAA,QAClB,EAAI;AAAA,MACL;AAAA,IACD,CAAE;AAAA,IACH,CAAE,gBAAiB;AAAA,EACpB;AAEA,SAAO;AACR;", "names": ["blockEditorStore", "apiFetch"] }