@wordpress/block-library 7.0.0 → 7.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (230) hide show
  1. package/README.md +16 -0
  2. package/build/button/edit.native.js +2 -2
  3. package/build/button/edit.native.js.map +1 -1
  4. package/build/columns/index.js +12 -0
  5. package/build/columns/index.js.map +1 -1
  6. package/build/comment-author-avatar/edit.js +17 -4
  7. package/build/comment-author-avatar/edit.js.map +1 -1
  8. package/build/comment-template/edit.js +94 -36
  9. package/build/comment-template/edit.js.map +1 -1
  10. package/build/comment-template/hooks.js +175 -0
  11. package/build/comment-template/hooks.js.map +1 -0
  12. package/build/comment-template/index.js +1 -1
  13. package/build/comment-template/util.js.map +1 -1
  14. package/build/comments-pagination-next/index.js +1 -1
  15. package/build/comments-pagination-numbers/index.js +1 -1
  16. package/build/comments-query-loop/edit/comments-inspector-controls.js +20 -9
  17. package/build/comments-query-loop/edit/comments-inspector-controls.js.map +1 -1
  18. package/build/comments-query-loop/edit.js +1 -19
  19. package/build/comments-query-loop/edit.js.map +1 -1
  20. package/build/comments-query-loop/index.js +5 -0
  21. package/build/comments-query-loop/index.js.map +1 -1
  22. package/build/cover/edit.js +21 -22
  23. package/build/cover/edit.js.map +1 -1
  24. package/build/cover/edit.native.js +7 -5
  25. package/build/cover/edit.native.js.map +1 -1
  26. package/build/cover/overlay-color-settings.native.js +4 -3
  27. package/build/cover/overlay-color-settings.native.js.map +1 -1
  28. package/build/cover/transforms.js +4 -2
  29. package/build/cover/transforms.js.map +1 -1
  30. package/build/group/index.js +1 -0
  31. package/build/group/index.js.map +1 -1
  32. package/build/heading/edit.js +14 -2
  33. package/build/heading/edit.js.map +1 -1
  34. package/build/image/deprecated.js +89 -5
  35. package/build/image/deprecated.js.map +1 -1
  36. package/build/image/save.js +0 -7
  37. package/build/image/save.js.map +1 -1
  38. package/build/latest-posts/edit.js +1 -0
  39. package/build/latest-posts/edit.js.map +1 -1
  40. package/build/navigation/edit/index.js +17 -15
  41. package/build/navigation/edit/index.js.map +1 -1
  42. package/build/navigation/edit/navigation-menu-selector.js +44 -27
  43. package/build/navigation/edit/navigation-menu-selector.js.map +1 -1
  44. package/build/navigation/edit/placeholder/index.js +8 -22
  45. package/build/navigation/edit/placeholder/index.js.map +1 -1
  46. package/build/navigation/use-navigation-menu.js +6 -6
  47. package/build/navigation/use-navigation-menu.js.map +1 -1
  48. package/build/navigation-submenu/edit.js +41 -9
  49. package/build/navigation-submenu/edit.js.map +1 -1
  50. package/build/page-list/edit.js +11 -17
  51. package/build/page-list/edit.js.map +1 -1
  52. package/build/social-links/deprecated.js +1 -62
  53. package/build/social-links/deprecated.js.map +1 -1
  54. package/build/template-part/edit/index.js +36 -64
  55. package/build/template-part/edit/index.js.map +1 -1
  56. package/build/template-part/edit/placeholder.js +64 -0
  57. package/build/template-part/edit/placeholder.js.map +1 -0
  58. package/build/template-part/edit/selection-modal.js +103 -0
  59. package/build/template-part/edit/selection-modal.js.map +1 -0
  60. package/build/template-part/edit/title-modal.js +54 -0
  61. package/build/template-part/edit/title-modal.js.map +1 -0
  62. package/build/template-part/edit/utils/hooks.js +156 -0
  63. package/build/template-part/edit/utils/hooks.js.map +1 -0
  64. package/build/template-part/index.js +3 -1
  65. package/build/template-part/index.js.map +1 -1
  66. package/build-module/button/edit.native.js +4 -4
  67. package/build-module/button/edit.native.js.map +1 -1
  68. package/build-module/columns/index.js +12 -0
  69. package/build-module/columns/index.js.map +1 -1
  70. package/build-module/comment-author-avatar/edit.js +18 -6
  71. package/build-module/comment-author-avatar/edit.js.map +1 -1
  72. package/build-module/comment-template/edit.js +95 -37
  73. package/build-module/comment-template/edit.js.map +1 -1
  74. package/build-module/comment-template/hooks.js +156 -0
  75. package/build-module/comment-template/hooks.js.map +1 -0
  76. package/build-module/comment-template/index.js +1 -1
  77. package/build-module/comment-template/util.js.map +1 -1
  78. package/build-module/comments-pagination-next/index.js +1 -1
  79. package/build-module/comments-pagination-numbers/index.js +1 -1
  80. package/build-module/comments-query-loop/edit/comments-inspector-controls.js +20 -9
  81. package/build-module/comments-query-loop/edit/comments-inspector-controls.js.map +1 -1
  82. package/build-module/comments-query-loop/edit.js +2 -19
  83. package/build-module/comments-query-loop/edit.js.map +1 -1
  84. package/build-module/comments-query-loop/index.js +5 -0
  85. package/build-module/comments-query-loop/index.js.map +1 -1
  86. package/build-module/cover/edit.js +23 -24
  87. package/build-module/cover/edit.js.map +1 -1
  88. package/build-module/cover/edit.native.js +10 -8
  89. package/build-module/cover/edit.native.js.map +1 -1
  90. package/build-module/cover/overlay-color-settings.native.js +4 -4
  91. package/build-module/cover/overlay-color-settings.native.js.map +1 -1
  92. package/build-module/cover/transforms.js +4 -2
  93. package/build-module/cover/transforms.js.map +1 -1
  94. package/build-module/group/index.js +1 -0
  95. package/build-module/group/index.js.map +1 -1
  96. package/build-module/heading/edit.js +15 -3
  97. package/build-module/heading/edit.js.map +1 -1
  98. package/build-module/image/deprecated.js +90 -7
  99. package/build-module/image/deprecated.js.map +1 -1
  100. package/build-module/image/save.js +0 -7
  101. package/build-module/image/save.js.map +1 -1
  102. package/build-module/latest-posts/edit.js +1 -0
  103. package/build-module/latest-posts/edit.js.map +1 -1
  104. package/build-module/navigation/edit/index.js +17 -15
  105. package/build-module/navigation/edit/index.js.map +1 -1
  106. package/build-module/navigation/edit/navigation-menu-selector.js +45 -27
  107. package/build-module/navigation/edit/navigation-menu-selector.js.map +1 -1
  108. package/build-module/navigation/edit/placeholder/index.js +8 -21
  109. package/build-module/navigation/edit/placeholder/index.js.map +1 -1
  110. package/build-module/navigation/use-navigation-menu.js +6 -6
  111. package/build-module/navigation/use-navigation-menu.js.map +1 -1
  112. package/build-module/navigation-submenu/edit.js +41 -10
  113. package/build-module/navigation-submenu/edit.js.map +1 -1
  114. package/build-module/page-list/edit.js +12 -18
  115. package/build-module/page-list/edit.js.map +1 -1
  116. package/build-module/social-links/deprecated.js +1 -62
  117. package/build-module/social-links/deprecated.js.map +1 -1
  118. package/build-module/template-part/edit/index.js +37 -65
  119. package/build-module/template-part/edit/index.js.map +1 -1
  120. package/build-module/template-part/edit/placeholder.js +52 -0
  121. package/build-module/template-part/edit/placeholder.js.map +1 -0
  122. package/build-module/template-part/edit/selection-modal.js +89 -0
  123. package/build-module/template-part/edit/selection-modal.js.map +1 -0
  124. package/build-module/template-part/edit/title-modal.js +46 -0
  125. package/build-module/template-part/edit/title-modal.js.map +1 -0
  126. package/build-module/template-part/edit/utils/hooks.js +135 -0
  127. package/build-module/template-part/edit/utils/hooks.js.map +1 -0
  128. package/build-module/template-part/index.js +2 -1
  129. package/build-module/template-part/index.js.map +1 -1
  130. package/build-style/comment-author-avatar/editor-rtl.css +83 -0
  131. package/build-style/comment-author-avatar/editor.css +83 -0
  132. package/build-style/cover/style-rtl.css +4 -0
  133. package/build-style/cover/style.css +4 -0
  134. package/build-style/editor-rtl.css +27 -81
  135. package/build-style/editor.css +27 -81
  136. package/build-style/image/editor-rtl.css +0 -16
  137. package/build-style/image/editor.css +0 -16
  138. package/build-style/image/style-rtl.css +2 -0
  139. package/build-style/image/style.css +2 -0
  140. package/build-style/navigation/style-rtl.css +14 -3
  141. package/build-style/navigation/style.css +14 -3
  142. package/build-style/page-list/editor-rtl.css +0 -9
  143. package/build-style/page-list/editor.css +0 -9
  144. package/build-style/style-rtl.css +20 -3
  145. package/build-style/style.css +20 -3
  146. package/build-style/template-part/editor-rtl.css +19 -56
  147. package/build-style/template-part/editor.css +19 -56
  148. package/package.json +15 -15
  149. package/src/archives/index.php +1 -1
  150. package/src/button/edit.native.js +3 -3
  151. package/src/columns/block.json +12 -0
  152. package/src/comment-author-avatar/edit.js +13 -8
  153. package/src/comment-author-avatar/editor.scss +7 -0
  154. package/src/comment-template/block.json +7 -1
  155. package/src/comment-template/edit.js +102 -40
  156. package/src/comment-template/hooks.js +151 -0
  157. package/src/comment-template/index.php +8 -0
  158. package/src/comment-template/util.js +1 -0
  159. package/src/comments-pagination-next/block.json +8 -1
  160. package/src/comments-pagination-next/index.php +6 -8
  161. package/src/comments-pagination-numbers/block.json +7 -1
  162. package/src/comments-pagination-numbers/index.php +3 -10
  163. package/src/comments-query-loop/block.json +5 -0
  164. package/src/comments-query-loop/edit/comments-inspector-controls.js +22 -4
  165. package/src/comments-query-loop/edit.js +1 -16
  166. package/src/cover/edit.js +15 -28
  167. package/src/cover/edit.native.js +15 -7
  168. package/src/cover/overlay-color-settings.native.js +3 -4
  169. package/src/cover/style.scss +4 -0
  170. package/src/cover/transforms.js +2 -0
  171. package/src/editor.scss +1 -0
  172. package/src/gallery/index.php +1 -8
  173. package/src/group/block.json +1 -0
  174. package/src/heading/edit.js +18 -5
  175. package/src/home-link/index.php +1 -19
  176. package/src/image/deprecated.js +105 -1
  177. package/src/image/editor.scss +0 -18
  178. package/src/image/save.js +0 -8
  179. package/src/image/style.scss +3 -0
  180. package/src/image/test/edit.native.js +0 -10
  181. package/src/latest-posts/edit.js +1 -0
  182. package/src/latest-posts/index.php +1 -1
  183. package/src/navigation/edit/index.js +25 -26
  184. package/src/navigation/edit/navigation-menu-selector.js +73 -28
  185. package/src/navigation/edit/placeholder/index.js +8 -32
  186. package/src/navigation/index.php +4 -4
  187. package/src/navigation/style.scss +22 -3
  188. package/src/navigation/use-navigation-menu.js +6 -6
  189. package/src/navigation-link/index.php +3 -22
  190. package/src/navigation-submenu/edit.js +50 -12
  191. package/src/navigation-submenu/index.php +3 -21
  192. package/src/page-list/edit.js +21 -25
  193. package/src/page-list/editor.scss +0 -10
  194. package/src/page-list/index.php +4 -4
  195. package/src/post-navigation-link/index.php +3 -3
  196. package/src/search/index.php +6 -3
  197. package/src/site-logo/index.php +1 -1
  198. package/src/social-links/deprecated.js +0 -59
  199. package/src/template-part/edit/index.js +61 -71
  200. package/src/template-part/edit/placeholder.js +78 -0
  201. package/src/template-part/edit/selection-modal.js +115 -0
  202. package/src/template-part/edit/title-modal.js +59 -0
  203. package/src/template-part/edit/utils/hooks.js +158 -0
  204. package/src/template-part/editor.scss +16 -74
  205. package/src/template-part/index.js +4 -1
  206. package/build/navigation/edit/existing-menus-options.js +0 -62
  207. package/build/navigation/edit/existing-menus-options.js.map +0 -1
  208. package/build/template-part/edit/placeholder/index.js +0 -141
  209. package/build/template-part/edit/placeholder/index.js.map +0 -1
  210. package/build/template-part/edit/placeholder/patterns-setup.js +0 -100
  211. package/build/template-part/edit/placeholder/patterns-setup.js.map +0 -1
  212. package/build/template-part/edit/selection/index.js +0 -45
  213. package/build/template-part/edit/selection/index.js.map +0 -1
  214. package/build/template-part/edit/selection/template-part-previews.js +0 -317
  215. package/build/template-part/edit/selection/template-part-previews.js.map +0 -1
  216. package/build-module/navigation/edit/existing-menus-options.js +0 -53
  217. package/build-module/navigation/edit/existing-menus-options.js.map +0 -1
  218. package/build-module/template-part/edit/placeholder/index.js +0 -124
  219. package/build-module/template-part/edit/placeholder/index.js.map +0 -1
  220. package/build-module/template-part/edit/placeholder/patterns-setup.js +0 -91
  221. package/build-module/template-part/edit/placeholder/patterns-setup.js.map +0 -1
  222. package/build-module/template-part/edit/selection/index.js +0 -35
  223. package/build-module/template-part/edit/selection/index.js.map +0 -1
  224. package/build-module/template-part/edit/selection/template-part-previews.js +0 -298
  225. package/build-module/template-part/edit/selection/template-part-previews.js.map +0 -1
  226. package/src/navigation/edit/existing-menus-options.js +0 -70
  227. package/src/template-part/edit/placeholder/index.js +0 -172
  228. package/src/template-part/edit/placeholder/patterns-setup.js +0 -124
  229. package/src/template-part/edit/selection/index.js +0 -37
  230. package/src/template-part/edit/selection/template-part-previews.js +0 -372
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * WordPress dependencies
3
3
  */
4
- import { useState, useMemo, memo } from '@wordpress/element';
4
+ import { useState, memo } from '@wordpress/element';
5
5
  import { useSelect } from '@wordpress/data';
6
6
  import { __ } from '@wordpress/i18n';
7
7
  import {
@@ -17,7 +17,7 @@ import { store as coreStore } from '@wordpress/core-data';
17
17
  /**
18
18
  * Internal dependencies
19
19
  */
20
- import { convertToTree } from './util';
20
+ import { useCommentQueryArgs, useCommentTree } from './hooks';
21
21
 
22
22
  const TEMPLATE = [
23
23
  [ 'core/comment-author-avatar' ],
@@ -28,6 +28,56 @@ const TEMPLATE = [
28
28
  [ 'core/comment-edit-link' ],
29
29
  ];
30
30
 
31
+ /**
32
+ * Function that returns a comment structure that will be rendered with default placehoders.
33
+ *
34
+ * @param {Object} settings Discussion Settings.
35
+ * @param {number} [settings.perPage] - Comments per page setting or block attribute.
36
+ * @param {boolean} [settings.threadComments] - Enable threaded (nested) comments setting.
37
+ * @param {number} [settings.threadCommentsDepth] - Level deep of threaded comments.
38
+ *
39
+ * @typedef {{id: null, children: EmptyComment[]}} EmptyComment
40
+ * @return {EmptyComment[]} Inner blocks of the Comment Template
41
+ */
42
+ const getCommentsPlaceholder = ( {
43
+ perPage,
44
+ threadComments,
45
+ threadCommentsDepth,
46
+ } ) => {
47
+ // In case that `threadCommentsDepth` is falsy, we default to a somewhat
48
+ // arbitrary value of 3.
49
+ // In case that the value is set but larger than 3 we truncate it to 3.
50
+ const commentsDepth = Math.min( threadCommentsDepth || 3, 3 );
51
+
52
+ // We set a limit in order not to overload the editor of empty comments.
53
+ const defaultCommentsToShow =
54
+ perPage <= commentsDepth ? perPage : commentsDepth;
55
+ if ( ! threadComments || defaultCommentsToShow === 1 ) {
56
+ // If displaying threaded comments is disabled, we only show one comment
57
+ return [ { commentId: null, children: [] } ];
58
+ } else if ( defaultCommentsToShow === 2 ) {
59
+ return [
60
+ {
61
+ commentId: null,
62
+ children: [ { commentId: null, children: [] } ],
63
+ },
64
+ ];
65
+ }
66
+
67
+ // In case that the value is set but larger than 3 we truncate it to 3.
68
+ return [
69
+ {
70
+ commentId: null,
71
+ children: [
72
+ {
73
+ commentId: null,
74
+ children: [ { commentId: null, children: [] } ],
75
+ },
76
+ ],
77
+ },
78
+ ];
79
+ };
80
+
31
81
  /**
32
82
  * Component which renders the inner blocks of the Comment Template.
33
83
  *
@@ -56,10 +106,10 @@ function CommentTemplateInnerBlocks( {
56
106
  { comment === ( activeComment || firstComment ) ? children : null }
57
107
 
58
108
  { /* To avoid flicker when switching active block contexts, a preview
59
- is ALWAYS rendered and the preview for the active block is hidden.
60
- This ensures that when switching the active block, the component is not
109
+ is ALWAYS rendered and the preview for the active block is hidden.
110
+ This ensures that when switching the active block, the component is not
61
111
  mounted again but rather it only toggles the `isHidden` prop.
62
-
112
+
63
113
  The same strategy is used for preventing the flicker in the Post Template
64
114
  block. */ }
65
115
  <MemoizedCommentTemplatePreview
@@ -140,9 +190,9 @@ const CommentsList = ( {
140
190
  } ) => (
141
191
  <ol { ...blockProps }>
142
192
  { comments &&
143
- comments.map( ( comment ) => (
193
+ comments.map( ( comment, index ) => (
144
194
  <BlockContextProvider
145
- key={ comment.commentId }
195
+ key={ comment.commentId || index }
146
196
  value={ comment }
147
197
  >
148
198
  <CommentTemplateInnerBlocks
@@ -159,54 +209,58 @@ const CommentsList = ( {
159
209
 
160
210
  export default function CommentTemplateEdit( {
161
211
  clientId,
162
- context: { postId, 'comments/perPage': perPage, 'comments/order': order },
212
+ context: {
213
+ postId,
214
+ 'comments/perPage': perPage,
215
+ 'comments/order': order,
216
+ 'comments/defaultPage': defaultPage,
217
+ 'comments/inherit': inherit,
218
+ },
163
219
  } ) {
164
220
  const blockProps = useBlockProps();
165
221
 
166
222
  const [ activeComment, setActiveComment ] = useState();
167
- const { commentOrder, commentsPerPage } = useSelect( ( select ) => {
168
- const { getSettings } = select( blockEditorStore );
169
- return getSettings().__experimentalDiscussionSettings;
223
+ const { commentOrder, threadCommentsDepth, threadComments } = useSelect(
224
+ ( select ) => {
225
+ const { getSettings } = select( blockEditorStore );
226
+ return getSettings().__experimentalDiscussionSettings;
227
+ }
228
+ );
229
+
230
+ const commentQuery = useCommentQueryArgs( {
231
+ postId,
232
+ perPage,
233
+ defaultPage,
234
+ inherit,
170
235
  } );
171
- const { rawComments, blocks } = useSelect(
236
+
237
+ const { topLevelComments, blocks } = useSelect(
172
238
  ( select ) => {
173
239
  const { getEntityRecords } = select( coreStore );
174
240
  const { getBlocks } = select( blockEditorStore );
175
241
 
176
- const commentQuery = {
177
- post: postId,
178
- status: 'approve',
179
- context: 'embed',
180
- order: order || commentOrder,
181
- };
182
-
183
- if ( order ) {
184
- commentQuery.order = order;
185
- }
186
242
  return {
187
- rawComments: getEntityRecords(
188
- 'root',
189
- 'comment',
190
- commentQuery
191
- ),
243
+ // Request only top-level comments. Replies are embedded.
244
+ topLevelComments: commentQuery
245
+ ? getEntityRecords( 'root', 'comment', commentQuery )
246
+ : null,
192
247
  blocks: getBlocks( clientId ),
193
248
  };
194
249
  },
195
- [ postId, clientId, order ]
250
+ [ clientId, commentQuery ]
196
251
  );
197
252
 
198
- // TODO: Replicate the logic used on the server.
199
- perPage = perPage || commentsPerPage;
200
- // We convert the flat list of comments to tree.
201
- // Then, we show only a maximum of `perPage` number of comments.
202
- // This is because passing `per_page` to `getEntityRecords()` does not
203
- // take into account nested comments.
204
- const comments = useMemo(
205
- () => convertToTree( rawComments ).slice( 0, perPage ),
206
- [ rawComments, perPage ]
253
+ order = inherit || ! order ? commentOrder : order;
254
+
255
+ // Generate a tree structure of comment IDs.
256
+ let commentTree = useCommentTree(
257
+ // Reverse the order of top comments if needed.
258
+ order === 'desc' && topLevelComments
259
+ ? [ ...topLevelComments ].reverse()
260
+ : topLevelComments
207
261
  );
208
262
 
209
- if ( ! rawComments ) {
263
+ if ( ! topLevelComments ) {
210
264
  return (
211
265
  <p { ...blockProps }>
212
266
  <Spinner />
@@ -214,13 +268,21 @@ export default function CommentTemplateEdit( {
214
268
  );
215
269
  }
216
270
 
217
- if ( ! comments.length ) {
271
+ if ( ! postId ) {
272
+ commentTree = getCommentsPlaceholder( {
273
+ perPage,
274
+ threadComments,
275
+ threadCommentsDepth,
276
+ } );
277
+ }
278
+
279
+ if ( ! commentTree.length ) {
218
280
  return <p { ...blockProps }> { __( 'No results found.' ) }</p>;
219
281
  }
220
282
 
221
283
  return (
222
284
  <CommentsList
223
- comments={ comments }
285
+ comments={ commentTree }
224
286
  blockProps={ blockProps }
225
287
  blocks={ blocks }
226
288
  activeComment={ activeComment }
@@ -0,0 +1,151 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { useState, useEffect, useMemo } from '@wordpress/element';
5
+ import { useSelect } from '@wordpress/data';
6
+ import { store as blockEditorStore } from '@wordpress/block-editor';
7
+ import { addQueryArgs } from '@wordpress/url';
8
+ import apiFetch from '@wordpress/api-fetch';
9
+
10
+ /**
11
+ * Return an object with the query args needed to fetch the default page of
12
+ * comments.
13
+ *
14
+ * @param {Object} props Hook props.
15
+ * @param {number} props.postId ID of the post that contains the comments.
16
+ * @param {number} props.perPage The number of comments included per page.
17
+ * @param {string} props.defaultPage Page shown by default (newest/oldest).
18
+ * @param {boolean} props.inherit Overwrite props with values from WP
19
+ * discussion settings.
20
+ *
21
+ * @return {Object} Query args to retrieve the comments.
22
+ */
23
+ export const useCommentQueryArgs = ( {
24
+ postId,
25
+ perPage,
26
+ defaultPage,
27
+ inherit,
28
+ } ) => {
29
+ // Initialize the query args that are not going to change.
30
+ const queryArgs = {
31
+ status: 'approve',
32
+ order: 'asc',
33
+ context: 'embed',
34
+ parent: 0,
35
+ _embed: 'children',
36
+ };
37
+
38
+ // Get the Discussion settings that may be needed to query the comments.
39
+ const { commentsPerPage, defaultCommentsPage } = useSelect( ( select ) => {
40
+ const { getSettings } = select( blockEditorStore );
41
+ const { __experimentalDiscussionSettings } = getSettings();
42
+ return __experimentalDiscussionSettings;
43
+ } );
44
+
45
+ // Overwrite the received attributes if `inherit` is true.
46
+ if ( inherit ) {
47
+ perPage = commentsPerPage;
48
+ defaultPage = defaultCommentsPage;
49
+ }
50
+
51
+ // If a block props is not set, use the settings value to generate the
52
+ // appropriate query arg.
53
+ perPage = perPage || commentsPerPage;
54
+ defaultPage = defaultPage || defaultCommentsPage;
55
+
56
+ // Get the number of the default page.
57
+ const page = useDefaultPageIndex( {
58
+ defaultPage,
59
+ postId,
60
+ perPage,
61
+ queryArgs,
62
+ } );
63
+
64
+ // Merge, memoize and return all query arguments, unless the default page's
65
+ // number is not known yet.
66
+ return useMemo( () => {
67
+ return page
68
+ ? {
69
+ ...queryArgs,
70
+ post: postId,
71
+ per_page: perPage,
72
+ page,
73
+ }
74
+ : null;
75
+ }, [ postId, perPage, page ] );
76
+ };
77
+
78
+ /**
79
+ * Return the index of the default page, depending on whether `defaultPage` is
80
+ * `newest` or `oldest`. In the first case, the only way to know the page's
81
+ * index is by using the `X-WP-TotalPages` header, which forces to make an
82
+ * additional request.
83
+ *
84
+ * @param {Object} props Hook props.
85
+ * @param {string} props.defaultPage Page shown by default (newest/oldest).
86
+ * @param {number} props.postId ID of the post that contains the comments.
87
+ * @param {number} props.perPage The number of comments included per page.
88
+ * @param {Object} props.queryArgs Other query args.
89
+ *
90
+ * @return {number} Index of the default comments page.
91
+ */
92
+ const useDefaultPageIndex = ( { defaultPage, postId, perPage, queryArgs } ) => {
93
+ // Store the default page indices.
94
+ const [ defaultPages, setDefaultPages ] = useState( {} );
95
+ const key = `${ postId }_${ perPage }`;
96
+ const page = defaultPages[ key ] || 0;
97
+
98
+ useEffect( () => {
99
+ // Do nothing if the page is already known or not the newest page.
100
+ if ( page || defaultPage !== 'newest' ) {
101
+ return;
102
+ }
103
+ // We need to fetch comments to know the index. Use HEAD and limit
104
+ // fields just to ID, to make this call as light as possible.
105
+ apiFetch( {
106
+ path: addQueryArgs( '/wp/v2/comments', {
107
+ ...queryArgs,
108
+ post: postId,
109
+ per_page: perPage,
110
+ _fields: 'id',
111
+ } ),
112
+ method: 'HEAD',
113
+ parse: false,
114
+ } ).then( ( res ) => {
115
+ setDefaultPages( {
116
+ ...defaultPages,
117
+ [ key ]: parseInt( res.headers.get( 'X-WP-TotalPages' ) ),
118
+ } );
119
+ } );
120
+ }, [ defaultPage, postId, perPage, setDefaultPages ] );
121
+
122
+ // The oldest one is always the first one.
123
+ return defaultPage === 'newest' ? page : 1;
124
+ };
125
+
126
+ /**
127
+ * Generate a tree structure of comment IDs from a list of comment entities. The
128
+ * children of each comment are obtained from `_embedded`.
129
+ *
130
+ * @typedef {{ commentId: number, children: CommentNode }} CommentNode
131
+ *
132
+ * @param {Object[]} topLevelComments List of comment entities.
133
+ * @return {{ commentTree: CommentNode[]}} Tree of comment IDs.
134
+ */
135
+ export const useCommentTree = ( topLevelComments ) => {
136
+ const commentTree = useMemo(
137
+ () =>
138
+ topLevelComments?.map( ( { id, _embedded } ) => {
139
+ const [ children ] = _embedded?.children || [ [] ];
140
+ return {
141
+ commentId: id,
142
+ children: children.map( ( child ) => ( {
143
+ commentId: child.id,
144
+ } ) ),
145
+ };
146
+ } ),
147
+ [ topLevelComments ]
148
+ );
149
+
150
+ return commentTree;
151
+ };
@@ -68,6 +68,14 @@ function render_block_core_comment_template( $attributes, $content, $block ) {
68
68
  return '';
69
69
  }
70
70
 
71
+ $comment_order = empty( $block->context['comments/inherit'] ) && ! empty( $block->context['comments/order'] )
72
+ ? $block->context['comments/order']
73
+ : get_option( 'comment_order' );
74
+
75
+ if ( 'desc' === $comment_order ) {
76
+ $comments = array_reverse( $comments );
77
+ }
78
+
71
79
  $wrapper_attributes = get_block_wrapper_attributes();
72
80
 
73
81
  return sprintf(
@@ -29,6 +29,7 @@
29
29
  */
30
30
  export const convertToTree = ( data ) => {
31
31
  const table = {};
32
+
32
33
  if ( ! data ) return [];
33
34
 
34
35
  // First create a hash table of { [id]: { ...comment, children: [] }}
@@ -12,7 +12,14 @@
12
12
  "type": "string"
13
13
  }
14
14
  },
15
- "usesContext": [ "postId", "comments/perPage", "comments/paginationArrow" ],
15
+ "usesContext": [
16
+ "postId",
17
+ "comments/perPage",
18
+ "comments/order",
19
+ "comments/inherit",
20
+ "comments/defaultPage",
21
+ "comments/paginationArrow"
22
+ ],
16
23
  "supports": {
17
24
  "reusable": false,
18
25
  "html": false,
@@ -15,15 +15,13 @@
15
15
  * @return string Returns the next comments link for the query pagination.
16
16
  */
17
17
  function render_block_core_comments_pagination_next( $attributes, $content, $block ) {
18
- $per_page = ! empty( $block->context['comments/perPage'] ) ? (int) $block->context['comments/perPage'] : 0;
19
- if ( 0 === $per_page && get_option( 'page_comments' ) ) {
20
- $per_page = (int) get_query_var( 'comments_per_page' );
21
- if ( 0 === $per_page ) {
22
- $per_page = (int) get_option( 'comments_per_page' );
23
- }
18
+ // Bail out early if the post ID is not set for some reason.
19
+ if ( empty( $block->context['postId'] ) ) {
20
+ return '';
24
21
  }
25
- $comments_number = (int) get_comments_number();
26
- $max_page = 0 !== $per_page ? (int) floor( $comments_number / $per_page ) : 0;
22
+
23
+ $comment_vars = build_comment_query_vars_from_block( $block );
24
+ $max_page = ( new WP_Comment_Query( $comment_vars ) )->max_num_pages;
27
25
  $default_label = __( 'Newer Comments' );
28
26
  $label = isset( $attributes['label'] ) && ! empty( $attributes['label'] ) ? $attributes['label'] : $default_label;
29
27
  $pagination_arrow = get_comments_pagination_arrow( $block, 'next' );
@@ -7,7 +7,13 @@
7
7
  "parent": [ "core/comments-pagination" ],
8
8
  "description": "Displays a list of page numbers for comments pagination.",
9
9
  "textdomain": "default",
10
- "usesContext": [ "comments/perPage", "postId", "comments/order" ],
10
+ "usesContext": [
11
+ "postId",
12
+ "comments/perPage",
13
+ "comments/order",
14
+ "comments/inherit",
15
+ "comments/defaultPage"
16
+ ],
11
17
  "supports": {
12
18
  "reusable": false,
13
19
  "html": false
@@ -20,17 +20,10 @@ function render_block_core_comments_pagination_numbers( $attributes, $content, $
20
20
  return '';
21
21
  }
22
22
 
23
- $comments_query = new WP_Comment_Query(
24
- build_comment_query_vars_from_block( $block )
25
- );
26
- $total = $comments_query->max_num_pages;
23
+ $comment_vars = build_comment_query_vars_from_block( $block );
27
24
 
28
- // Get the current comment page from the URL.
29
- $current = get_query_var( 'cpage' );
30
- if ( ! $current ) {
31
- // Get the number of the default page.
32
- $current = 'newest' === get_option( 'default_comments_page' ) ? $total : 1;
33
- }
25
+ $total = ( new WP_Comment_Query( $comment_vars ) )->max_num_pages;
26
+ $current = $comment_vars['paged'];
34
27
 
35
28
  // Render links.
36
29
  $content = paginate_comments_links(
@@ -22,11 +22,16 @@
22
22
  "tagName": {
23
23
  "type": "string",
24
24
  "default": "div"
25
+ },
26
+ "defaultPage": {
27
+ "type": "string",
28
+ "default": "oldest"
25
29
  }
26
30
  },
27
31
  "providesContext": {
28
32
  "comments/perPage": "perPage",
29
33
  "comments/order": "order",
34
+ "comments/defaultPage": "defaultPage",
30
35
  "comments/inherit": "inherit"
31
36
  },
32
37
  "supports": {
@@ -21,10 +21,20 @@ const orderOptions = [
21
21
  },
22
22
  ];
23
23
 
24
+ const defaultPageOptions = [
25
+ {
26
+ label: __( 'Newest' ),
27
+ value: 'newest',
28
+ },
29
+ {
30
+ label: __( 'Oldest' ),
31
+ value: 'oldest',
32
+ },
33
+ ];
34
+
24
35
  export default function CommentsInspectorControls( {
25
- attributes: { TagName, perPage, order, inherit },
36
+ attributes: { TagName, perPage, order, inherit, defaultPage },
26
37
  setAttributes,
27
- defaultSettings: { defaultPerPage, defaultOrder },
28
38
  } ) {
29
39
  return (
30
40
  <InspectorControls>
@@ -35,8 +45,6 @@ export default function CommentsInspectorControls( {
35
45
  onChange={ () => {
36
46
  setAttributes( {
37
47
  inherit: ! inherit,
38
- order: inherit ? defaultOrder : null,
39
- perPage: inherit ? defaultPerPage : null,
40
48
  } );
41
49
  } }
42
50
  />
@@ -52,6 +60,16 @@ export default function CommentsInspectorControls( {
52
60
  } );
53
61
  } }
54
62
  />
63
+ <SelectControl
64
+ label={ __( 'Default page' ) }
65
+ value={ defaultPage }
66
+ options={ defaultPageOptions }
67
+ onChange={ ( value ) => {
68
+ setAttributes( {
69
+ defaultPage: value,
70
+ } );
71
+ } }
72
+ />
55
73
  <NumberControl
56
74
  __unstableInputWidth="60px"
57
75
  label={ __( 'Items per Page' ) }
@@ -1,17 +1,12 @@
1
1
  /**
2
2
  * WordPress dependencies
3
3
  */
4
- import {
5
- useBlockProps,
6
- useInnerBlocksProps,
7
- store as blockEditorStore,
8
- } from '@wordpress/block-editor';
4
+ import { useBlockProps, useInnerBlocksProps } from '@wordpress/block-editor';
9
5
 
10
6
  /**
11
7
  * Internal dependencies
12
8
  */
13
9
  import CommentsInspectorControls from './edit/comments-inspector-controls';
14
- import { useSelect } from '@wordpress/data';
15
10
 
16
11
  const TEMPLATE = [
17
12
  [ 'core/comment-template' ],
@@ -26,21 +21,11 @@ export default function CommentsQueryLoopEdit( { attributes, setAttributes } ) {
26
21
  template: TEMPLATE,
27
22
  } );
28
23
 
29
- const { commentOrder, commentsPerPage } = useSelect( ( select ) => {
30
- const { getSettings } = select( blockEditorStore );
31
- const { __experimentalDiscussionSettings } = getSettings();
32
- return __experimentalDiscussionSettings;
33
- } );
34
-
35
24
  return (
36
25
  <>
37
26
  <CommentsInspectorControls
38
27
  attributes={ attributes }
39
28
  setAttributes={ setAttributes }
40
- defaultSettings={ {
41
- defaultOrder: commentOrder,
42
- defaultPerPage: commentsPerPage,
43
- } }
44
29
  />
45
30
  <TagName { ...innerBlocksProps } />
46
31
  </>