@wordpress/editor 14.33.3-next.36001005c.0 → 14.33.3
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.
- package/build/bindings/post-data.js +10 -17
- package/build/bindings/post-data.js.map +2 -2
- package/build/bindings/post-meta.js +7 -14
- package/build/bindings/post-meta.js.map +2 -2
- package/build/bindings/term-data.js +6 -16
- package/build/bindings/term-data.js.map +2 -2
- package/build/components/block-settings-menu/content-only-settings-menu.js +186 -0
- package/build/components/block-settings-menu/content-only-settings-menu.js.map +7 -0
- package/build/components/collab-sidebar/add-comment.js +26 -3
- package/build/components/collab-sidebar/add-comment.js.map +3 -3
- package/build/components/collab-sidebar/comment-indicator-toolbar.js +6 -22
- package/build/components/collab-sidebar/comment-indicator-toolbar.js.map +3 -3
- package/build/components/collab-sidebar/comments.js +105 -28
- package/build/components/collab-sidebar/comments.js.map +3 -3
- package/build/components/collab-sidebar/hooks.js +3 -4
- package/build/components/collab-sidebar/hooks.js.map +2 -2
- package/build/components/collab-sidebar/index.js +42 -57
- package/build/components/collab-sidebar/index.js.map +3 -3
- package/build/components/editor/index.js +2 -0
- package/build/components/editor/index.js.map +3 -3
- package/build/components/header/index.js +0 -3
- package/build/components/header/index.js.map +3 -3
- package/build/components/post-template/hooks.js +7 -38
- package/build/components/post-template/hooks.js.map +2 -2
- package/build/components/provider/index.js +3 -1
- package/build/components/provider/index.js.map +3 -3
- package/build/store/actions.js +1 -1
- package/build/store/actions.js.map +2 -2
- package/build-module/bindings/post-data.js +10 -17
- package/build-module/bindings/post-data.js.map +2 -2
- package/build-module/bindings/post-meta.js +7 -14
- package/build-module/bindings/post-meta.js.map +2 -2
- package/build-module/bindings/term-data.js +6 -16
- package/build-module/bindings/term-data.js.map +2 -2
- package/build-module/components/block-settings-menu/content-only-settings-menu.js +161 -0
- package/build-module/components/block-settings-menu/content-only-settings-menu.js.map +7 -0
- package/build-module/components/collab-sidebar/add-comment.js +27 -4
- package/build-module/components/collab-sidebar/add-comment.js.map +2 -2
- package/build-module/components/collab-sidebar/comment-indicator-toolbar.js +6 -12
- package/build-module/components/collab-sidebar/comment-indicator-toolbar.js.map +2 -2
- package/build-module/components/collab-sidebar/comments.js +114 -31
- package/build-module/components/collab-sidebar/comments.js.map +2 -2
- package/build-module/components/collab-sidebar/hooks.js +3 -4
- package/build-module/components/collab-sidebar/hooks.js.map +2 -2
- package/build-module/components/collab-sidebar/index.js +42 -57
- package/build-module/components/collab-sidebar/index.js.map +2 -2
- package/build-module/components/editor/index.js +2 -0
- package/build-module/components/editor/index.js.map +2 -2
- package/build-module/components/header/index.js +0 -3
- package/build-module/components/header/index.js.map +2 -2
- package/build-module/components/post-template/hooks.js +7 -38
- package/build-module/components/post-template/hooks.js.map +2 -2
- package/build-module/components/provider/index.js +3 -1
- package/build-module/components/provider/index.js.map +2 -2
- package/build-module/store/actions.js +1 -1
- package/build-module/store/actions.js.map +2 -2
- package/build-style/style-rtl.css +12 -23
- package/build-style/style.css +12 -23
- package/build-types/bindings/post-data.d.ts +6 -16
- package/build-types/bindings/post-meta.d.ts +6 -13
- package/build-types/bindings/term-data.d.ts +6 -16
- package/build-types/components/block-settings-menu/content-only-settings-menu.d.ts +2 -0
- package/build-types/components/block-settings-menu/content-only-settings-menu.d.ts.map +1 -0
- package/build-types/components/collab-sidebar/add-comment.d.ts +6 -1
- package/build-types/components/collab-sidebar/add-comment.d.ts.map +1 -1
- package/build-types/components/collab-sidebar/comment-indicator-toolbar.d.ts +1 -2
- package/build-types/components/collab-sidebar/comment-indicator-toolbar.d.ts.map +1 -1
- package/build-types/components/collab-sidebar/comments.d.ts +12 -26
- package/build-types/components/collab-sidebar/comments.d.ts.map +1 -1
- package/build-types/components/collab-sidebar/hooks.d.ts +0 -1
- package/build-types/components/collab-sidebar/hooks.d.ts.map +1 -1
- package/build-types/components/collab-sidebar/index.d.ts +1 -4
- package/build-types/components/collab-sidebar/index.d.ts.map +1 -1
- package/build-types/components/editor/index.d.ts.map +1 -1
- package/build-types/components/header/index.d.ts.map +1 -1
- package/build-types/components/post-template/hooks.d.ts +1 -1
- package/build-types/components/post-template/hooks.d.ts.map +1 -1
- package/build-types/components/provider/index.d.ts.map +1 -1
- package/build-types/store/actions.d.ts.map +1 -1
- package/package.json +38 -38
- package/src/bindings/post-data.js +9 -20
- package/src/bindings/post-meta.js +6 -17
- package/src/bindings/term-data.js +6 -21
- package/src/components/block-settings-menu/content-only-settings-menu.js +185 -0
- package/src/components/block-settings-menu/content-only-settings-menu.native.js +4 -0
- package/src/components/block-settings-menu/style.scss +6 -0
- package/src/components/collab-sidebar/add-comment.js +31 -3
- package/src/components/collab-sidebar/comment-indicator-toolbar.js +6 -22
- package/src/components/collab-sidebar/comments.js +108 -35
- package/src/components/collab-sidebar/hooks.js +3 -4
- package/src/components/collab-sidebar/index.js +34 -42
- package/src/components/collab-sidebar/style.scss +2 -23
- package/src/components/editor/index.js +2 -0
- package/src/components/editor-help/style.scss +1 -1
- package/src/components/header/index.js +0 -7
- package/src/components/post-last-revision/style.scss +1 -1
- package/src/components/post-panel-row/style.scss +0 -1
- package/src/components/post-publish-panel/style.scss +1 -1
- package/src/components/post-publish-panel/test/__snapshots__/index.js.snap +2 -2
- package/src/components/post-template/hooks.js +10 -51
- package/src/components/provider/index.js +3 -4
- package/src/store/actions.js +4 -1
- package/src/style.scss +1 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -195,30 +195,15 @@ export default {
|
|
|
195
195
|
return false;
|
|
196
196
|
},
|
|
197
197
|
getFieldsList( { select, context } ) {
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
const selectedBlock = select( blockEditorStore ).getSelectedBlock();
|
|
203
|
-
// Exit early for navigation blocks (read-only)
|
|
204
|
-
if ( NAVIGATION_BLOCK_TYPES.includes( selectedBlock?.name ) ) {
|
|
205
|
-
return {};
|
|
198
|
+
const clientId = select( blockEditorStore ).getSelectedBlockClientId();
|
|
199
|
+
const termDataFields = getTermDataFields( select, context, clientId );
|
|
200
|
+
if ( ! termDataFields ) {
|
|
201
|
+
return [];
|
|
206
202
|
}
|
|
207
|
-
|
|
208
|
-
getTermDataFields( select, context ) || {}
|
|
209
|
-
).map( ( [ key, field ] ) => ( {
|
|
203
|
+
return Object.entries( termDataFields ).map( ( [ key, field ] ) => ( {
|
|
210
204
|
label: field.label,
|
|
211
205
|
type: field.type,
|
|
212
|
-
args: {
|
|
213
|
-
field: key,
|
|
214
|
-
},
|
|
206
|
+
args: { field: key },
|
|
215
207
|
} ) );
|
|
216
|
-
/*
|
|
217
|
-
* We need to define the data as [{ label: string, value: any, type: https://developer.wordpress.org/block-editor/reference-guides/block-api/block-attributes/#type-validation }]
|
|
218
|
-
*/
|
|
219
|
-
return {
|
|
220
|
-
mode: 'dropdown',
|
|
221
|
-
data: termDataFields,
|
|
222
|
-
};
|
|
223
208
|
},
|
|
224
209
|
};
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import {
|
|
5
|
+
BlockSettingsMenuControls,
|
|
6
|
+
__unstableBlockSettingsMenuFirstItem as BlockSettingsMenuFirstItem,
|
|
7
|
+
store as blockEditorStore,
|
|
8
|
+
useBlockDisplayInformation,
|
|
9
|
+
} from '@wordpress/block-editor';
|
|
10
|
+
import { store as coreStore } from '@wordpress/core-data';
|
|
11
|
+
import { __experimentalText as Text, MenuItem } from '@wordpress/components';
|
|
12
|
+
import { useSelect, useDispatch } from '@wordpress/data';
|
|
13
|
+
import { __, _x } from '@wordpress/i18n';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Internal dependencies
|
|
17
|
+
*/
|
|
18
|
+
import { store as editorStore } from '../../store';
|
|
19
|
+
import { unlock } from '../../lock-unlock';
|
|
20
|
+
import usePostContentBlocks from '../provider/use-post-content-blocks';
|
|
21
|
+
|
|
22
|
+
function ContentOnlySettingsMenuItems( { clientId, onClose } ) {
|
|
23
|
+
const postContentBlocks = usePostContentBlocks();
|
|
24
|
+
const { entity, onNavigateToEntityRecord, canEditTemplates } = useSelect(
|
|
25
|
+
( select ) => {
|
|
26
|
+
const {
|
|
27
|
+
getBlockParentsByBlockName,
|
|
28
|
+
getSettings,
|
|
29
|
+
getBlockAttributes,
|
|
30
|
+
getBlockParents,
|
|
31
|
+
} = select( blockEditorStore );
|
|
32
|
+
const { getCurrentTemplateId, getRenderingMode } =
|
|
33
|
+
select( editorStore );
|
|
34
|
+
const patternParent = getBlockParentsByBlockName(
|
|
35
|
+
clientId,
|
|
36
|
+
'core/block',
|
|
37
|
+
true
|
|
38
|
+
)[ 0 ];
|
|
39
|
+
|
|
40
|
+
let record;
|
|
41
|
+
if ( patternParent ) {
|
|
42
|
+
record = select( coreStore ).getEntityRecord(
|
|
43
|
+
'postType',
|
|
44
|
+
'wp_block',
|
|
45
|
+
getBlockAttributes( patternParent ).ref
|
|
46
|
+
);
|
|
47
|
+
} else if (
|
|
48
|
+
getRenderingMode() === 'template-locked' &&
|
|
49
|
+
! getBlockParents( clientId ).some( ( parent ) =>
|
|
50
|
+
postContentBlocks.includes( parent )
|
|
51
|
+
)
|
|
52
|
+
) {
|
|
53
|
+
record = select( coreStore ).getEntityRecord(
|
|
54
|
+
'postType',
|
|
55
|
+
'wp_template',
|
|
56
|
+
getCurrentTemplateId()
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
if ( ! record ) {
|
|
60
|
+
return {};
|
|
61
|
+
}
|
|
62
|
+
const _canEditTemplates = select( coreStore ).canUser( 'create', {
|
|
63
|
+
kind: 'postType',
|
|
64
|
+
name: 'wp_template',
|
|
65
|
+
} );
|
|
66
|
+
return {
|
|
67
|
+
canEditTemplates: _canEditTemplates,
|
|
68
|
+
entity: record,
|
|
69
|
+
onNavigateToEntityRecord:
|
|
70
|
+
getSettings().onNavigateToEntityRecord,
|
|
71
|
+
};
|
|
72
|
+
},
|
|
73
|
+
[ clientId, postContentBlocks ]
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
if ( ! entity ) {
|
|
77
|
+
return (
|
|
78
|
+
<TemplateLockContentOnlyMenuItems
|
|
79
|
+
clientId={ clientId }
|
|
80
|
+
onClose={ onClose }
|
|
81
|
+
/>
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const isPattern = entity.type === 'wp_block';
|
|
86
|
+
let helpText = isPattern
|
|
87
|
+
? __(
|
|
88
|
+
'Edit the pattern to move, delete, or make further changes to this block.'
|
|
89
|
+
)
|
|
90
|
+
: __(
|
|
91
|
+
'Edit the template to move, delete, or make further changes to this block.'
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
if ( ! canEditTemplates ) {
|
|
95
|
+
helpText = __(
|
|
96
|
+
'Only users with permissions to edit the template can move or delete this block'
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return (
|
|
101
|
+
<>
|
|
102
|
+
<BlockSettingsMenuFirstItem>
|
|
103
|
+
<MenuItem
|
|
104
|
+
onClick={ () => {
|
|
105
|
+
onNavigateToEntityRecord( {
|
|
106
|
+
postId: entity.id,
|
|
107
|
+
postType: entity.type,
|
|
108
|
+
} );
|
|
109
|
+
} }
|
|
110
|
+
disabled={ ! canEditTemplates }
|
|
111
|
+
>
|
|
112
|
+
{ isPattern ? __( 'Edit pattern' ) : __( 'Edit template' ) }
|
|
113
|
+
</MenuItem>
|
|
114
|
+
</BlockSettingsMenuFirstItem>
|
|
115
|
+
<Text
|
|
116
|
+
variant="muted"
|
|
117
|
+
as="p"
|
|
118
|
+
className="editor-content-only-settings-menu__description"
|
|
119
|
+
>
|
|
120
|
+
{ helpText }
|
|
121
|
+
</Text>
|
|
122
|
+
</>
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function TemplateLockContentOnlyMenuItems( { clientId, onClose } ) {
|
|
127
|
+
const { contentLockingParent } = useSelect(
|
|
128
|
+
( select ) => {
|
|
129
|
+
const { getContentLockingParent } = unlock(
|
|
130
|
+
select( blockEditorStore )
|
|
131
|
+
);
|
|
132
|
+
return {
|
|
133
|
+
contentLockingParent: getContentLockingParent( clientId ),
|
|
134
|
+
};
|
|
135
|
+
},
|
|
136
|
+
[ clientId ]
|
|
137
|
+
);
|
|
138
|
+
const blockDisplayInformation =
|
|
139
|
+
useBlockDisplayInformation( contentLockingParent );
|
|
140
|
+
const blockEditorActions = useDispatch( blockEditorStore );
|
|
141
|
+
if ( ! blockDisplayInformation?.title ) {
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const { modifyContentLockBlock } = unlock( blockEditorActions );
|
|
146
|
+
|
|
147
|
+
return (
|
|
148
|
+
<>
|
|
149
|
+
<BlockSettingsMenuFirstItem>
|
|
150
|
+
<MenuItem
|
|
151
|
+
onClick={ () => {
|
|
152
|
+
modifyContentLockBlock( contentLockingParent );
|
|
153
|
+
onClose();
|
|
154
|
+
} }
|
|
155
|
+
>
|
|
156
|
+
{ _x( 'Unlock', 'Unlock content locked blocks' ) }
|
|
157
|
+
</MenuItem>
|
|
158
|
+
</BlockSettingsMenuFirstItem>
|
|
159
|
+
<Text
|
|
160
|
+
variant="muted"
|
|
161
|
+
as="p"
|
|
162
|
+
className="editor-content-only-settings-menu__description"
|
|
163
|
+
>
|
|
164
|
+
{ __(
|
|
165
|
+
'Temporarily unlock the parent block to edit, delete or make further changes to this block.'
|
|
166
|
+
) }
|
|
167
|
+
</Text>
|
|
168
|
+
</>
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export default function ContentOnlySettingsMenu() {
|
|
173
|
+
return (
|
|
174
|
+
<BlockSettingsMenuControls>
|
|
175
|
+
{ ( { selectedClientIds, onClose } ) =>
|
|
176
|
+
selectedClientIds.length === 1 && (
|
|
177
|
+
<ContentOnlySettingsMenuItems
|
|
178
|
+
clientId={ selectedClientIds[ 0 ] }
|
|
179
|
+
onClose={ onClose }
|
|
180
|
+
/>
|
|
181
|
+
)
|
|
182
|
+
}
|
|
183
|
+
</BlockSettingsMenuControls>
|
|
184
|
+
);
|
|
185
|
+
}
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import clsx from 'clsx';
|
|
1
5
|
/**
|
|
2
6
|
* WordPress dependencies
|
|
3
7
|
*/
|
|
@@ -18,7 +22,7 @@ import {
|
|
|
18
22
|
import { unlock } from '../../lock-unlock';
|
|
19
23
|
import CommentAuthorInfo from './comment-author-info';
|
|
20
24
|
import CommentForm from './comment-form';
|
|
21
|
-
import { focusCommentThread } from './utils';
|
|
25
|
+
import { focusCommentThread, noop } from './utils';
|
|
22
26
|
|
|
23
27
|
const { useBlockElement } = unlock( blockEditorPrivateApis );
|
|
24
28
|
|
|
@@ -27,6 +31,10 @@ export function AddComment( {
|
|
|
27
31
|
showCommentBoard,
|
|
28
32
|
setShowCommentBoard,
|
|
29
33
|
commentSidebarRef,
|
|
34
|
+
reflowComments = noop,
|
|
35
|
+
isFloating = false,
|
|
36
|
+
y,
|
|
37
|
+
refs,
|
|
30
38
|
} ) {
|
|
31
39
|
const { clientId, blockCommentId } = useSelect( ( select ) => {
|
|
32
40
|
const { getSelectedBlock } = select( blockEditorStore );
|
|
@@ -44,10 +52,29 @@ export function AddComment( {
|
|
|
44
52
|
|
|
45
53
|
return (
|
|
46
54
|
<VStack
|
|
47
|
-
className=
|
|
55
|
+
className={ clsx(
|
|
56
|
+
'editor-collab-sidebar-panel__thread is-selected',
|
|
57
|
+
{
|
|
58
|
+
'is-floating': isFloating,
|
|
59
|
+
}
|
|
60
|
+
) }
|
|
48
61
|
spacing="3"
|
|
49
62
|
tabIndex={ 0 }
|
|
63
|
+
aria-label={ __( 'New note' ) }
|
|
50
64
|
role="listitem"
|
|
65
|
+
ref={ isFloating ? refs.setFloating : undefined }
|
|
66
|
+
style={
|
|
67
|
+
isFloating
|
|
68
|
+
? // Delay showing the floating note box until a Y position is known to prevent blink.
|
|
69
|
+
{ top: y, opacity: ! y ? 0 : undefined }
|
|
70
|
+
: undefined
|
|
71
|
+
}
|
|
72
|
+
onBlur={ ( event ) => {
|
|
73
|
+
if ( event.currentTarget.contains( event.relatedTarget ) ) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
setShowCommentBoard( false );
|
|
77
|
+
} }
|
|
51
78
|
>
|
|
52
79
|
<HStack alignment="left" spacing="3">
|
|
53
80
|
<CommentAuthorInfo />
|
|
@@ -62,8 +89,9 @@ export function AddComment( {
|
|
|
62
89
|
setShowCommentBoard( false );
|
|
63
90
|
blockElement?.focus();
|
|
64
91
|
} }
|
|
92
|
+
reflowComments={ reflowComments }
|
|
65
93
|
submitButtonText={ __( 'Add note' ) }
|
|
66
|
-
labelText={ __( 'New
|
|
94
|
+
labelText={ __( 'New note' ) }
|
|
67
95
|
/>
|
|
68
96
|
</VStack>
|
|
69
97
|
);
|
|
@@ -6,11 +6,6 @@ import { __, _n, sprintf } from '@wordpress/i18n';
|
|
|
6
6
|
import { useMemo } from '@wordpress/element';
|
|
7
7
|
import { privateApis as blockEditorPrivateApis } from '@wordpress/block-editor';
|
|
8
8
|
|
|
9
|
-
/**
|
|
10
|
-
* External dependencies
|
|
11
|
-
*/
|
|
12
|
-
import clsx from 'clsx';
|
|
13
|
-
|
|
14
9
|
/**
|
|
15
10
|
* Internal dependencies
|
|
16
11
|
*/
|
|
@@ -19,7 +14,7 @@ import { getAvatarBorderColor } from './utils';
|
|
|
19
14
|
|
|
20
15
|
const { CommentIconToolbarSlotFill } = unlock( blockEditorPrivateApis );
|
|
21
16
|
|
|
22
|
-
const CommentAvatarIndicator = ( { onClick, thread
|
|
17
|
+
const CommentAvatarIndicator = ( { onClick, thread } ) => {
|
|
23
18
|
const threadParticipants = useMemo( () => {
|
|
24
19
|
if ( ! thread ) {
|
|
25
20
|
return [];
|
|
@@ -34,15 +29,13 @@ const CommentAvatarIndicator = ( { onClick, thread, hasMoreComments } ) => {
|
|
|
34
29
|
allComments.forEach( ( comment ) => {
|
|
35
30
|
// Track thread participants (original commenter + repliers).
|
|
36
31
|
if ( comment.author_name && comment.author_avatar_urls ) {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
participantsMap.set( authorKey, {
|
|
32
|
+
if ( ! participantsMap.has( comment.author ) ) {
|
|
33
|
+
participantsMap.set( comment.author, {
|
|
40
34
|
name: comment.author_name,
|
|
41
35
|
avatar:
|
|
42
36
|
comment.author_avatar_urls?.[ '48' ] ||
|
|
43
37
|
comment.author_avatar_urls?.[ '96' ],
|
|
44
38
|
id: comment.author,
|
|
45
|
-
isOriginalCommenter: comment.id === thread.id,
|
|
46
39
|
date: comment.date,
|
|
47
40
|
} );
|
|
48
41
|
}
|
|
@@ -52,14 +45,6 @@ const CommentAvatarIndicator = ( { onClick, thread, hasMoreComments } ) => {
|
|
|
52
45
|
return Array.from( participantsMap.values() );
|
|
53
46
|
}, [ thread ] );
|
|
54
47
|
|
|
55
|
-
const hasUnresolved = thread?.status !== 'approved';
|
|
56
|
-
|
|
57
|
-
// Check if this specific thread has more participants due to pagination.
|
|
58
|
-
// If we have pagination AND this thread + its replies equals or exceeds the API limit,
|
|
59
|
-
// then this thread likely has more participants that weren't loaded.
|
|
60
|
-
const threadHasMoreParticipants =
|
|
61
|
-
hasMoreComments && thread?.reply && 1 + thread.reply.length >= 100;
|
|
62
|
-
|
|
63
48
|
if ( ! threadParticipants.length ) {
|
|
64
49
|
return null;
|
|
65
50
|
}
|
|
@@ -68,6 +53,7 @@ const CommentAvatarIndicator = ( { onClick, thread, hasMoreComments } ) => {
|
|
|
68
53
|
const maxAvatars = 3;
|
|
69
54
|
const visibleParticipants = threadParticipants.slice( 0, maxAvatars );
|
|
70
55
|
const overflowCount = Math.max( 0, threadParticipants.length - maxAvatars );
|
|
56
|
+
const threadHasMoreParticipants = threadParticipants.length > 100;
|
|
71
57
|
|
|
72
58
|
// If we hit the comment limit, show "100+" instead of exact overflow count.
|
|
73
59
|
const overflowText =
|
|
@@ -95,9 +81,7 @@ const CommentAvatarIndicator = ( { onClick, thread, hasMoreComments } ) => {
|
|
|
95
81
|
return (
|
|
96
82
|
<CommentIconToolbarSlotFill.Fill>
|
|
97
83
|
<ToolbarButton
|
|
98
|
-
className=
|
|
99
|
-
'has-unresolved': hasUnresolved,
|
|
100
|
-
} ) }
|
|
84
|
+
className="comment-avatar-indicator"
|
|
101
85
|
label={ __( 'View notes' ) }
|
|
102
86
|
onClick={ onClick }
|
|
103
87
|
showTooltip
|
|
@@ -105,7 +89,7 @@ const CommentAvatarIndicator = ( { onClick, thread, hasMoreComments } ) => {
|
|
|
105
89
|
<div className="comment-avatar-stack">
|
|
106
90
|
{ visibleParticipants.map( ( participant, index ) => (
|
|
107
91
|
<img
|
|
108
|
-
key={ participant.
|
|
92
|
+
key={ participant.id }
|
|
109
93
|
src={ participant.avatar }
|
|
110
94
|
alt={ participant.name }
|
|
111
95
|
className="comment-avatar"
|
|
@@ -6,7 +6,13 @@ import clsx from 'clsx';
|
|
|
6
6
|
/**
|
|
7
7
|
* WordPress dependencies
|
|
8
8
|
*/
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
useState,
|
|
11
|
+
RawHTML,
|
|
12
|
+
useEffect,
|
|
13
|
+
useCallback,
|
|
14
|
+
useMemo,
|
|
15
|
+
} from '@wordpress/element';
|
|
10
16
|
import {
|
|
11
17
|
__experimentalText as Text,
|
|
12
18
|
__experimentalHStack as HStack,
|
|
@@ -33,32 +39,19 @@ import {
|
|
|
33
39
|
import { unlock } from '../../lock-unlock';
|
|
34
40
|
import CommentAuthorInfo from './comment-author-info';
|
|
35
41
|
import CommentForm from './comment-form';
|
|
36
|
-
import {
|
|
42
|
+
import { focusCommentThread, getCommentExcerpt } from './utils';
|
|
37
43
|
import { useFloatingThread } from './hooks';
|
|
44
|
+
import { AddComment } from './add-comment';
|
|
38
45
|
|
|
39
46
|
const { useBlockElement } = unlock( blockEditorPrivateApis );
|
|
40
47
|
const { Menu } = unlock( componentsPrivateApis );
|
|
41
48
|
|
|
42
|
-
/**
|
|
43
|
-
* Renders the Comments component.
|
|
44
|
-
*
|
|
45
|
-
* @param {Object} props - The component props.
|
|
46
|
-
* @param {Array} props.threads - The array of comment threads.
|
|
47
|
-
* @param {Function} props.onEditComment - The function to handle comment editing.
|
|
48
|
-
* @param {Function} props.onAddReply - The function to add a reply to a comment.
|
|
49
|
-
* @param {Function} props.onCommentDelete - The function to delete a comment.
|
|
50
|
-
* @param {Function} props.setShowCommentBoard - The function to set the comment board visibility.
|
|
51
|
-
* @param {Ref} props.commentSidebarRef - The ref to the comment sidebar.
|
|
52
|
-
* @param {Function} props.reflowComments - The function to call indicating a comment is updated.
|
|
53
|
-
* @param {boolean} props.isFloating - Whether the comment thread is floating.
|
|
54
|
-
* @param {number} props.commentLastUpdated - Timestamp of the last comment update.
|
|
55
|
-
* @return {React.ReactNode} The rendered Comments component.
|
|
56
|
-
*/
|
|
57
49
|
export function Comments( {
|
|
58
|
-
threads,
|
|
50
|
+
threads: noteThreads,
|
|
59
51
|
onEditComment,
|
|
60
52
|
onAddReply,
|
|
61
53
|
onCommentDelete,
|
|
54
|
+
showCommentBoard,
|
|
62
55
|
setShowCommentBoard,
|
|
63
56
|
commentSidebarRef,
|
|
64
57
|
reflowComments,
|
|
@@ -70,20 +63,62 @@ export function Comments( {
|
|
|
70
63
|
const [ boardOffsets, setBoardOffsets ] = useState( {} );
|
|
71
64
|
const [ blockRefs, setBlockRefs ] = useState( {} );
|
|
72
65
|
|
|
73
|
-
const { blockCommentId, selectedBlockClientId } =
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
66
|
+
const { blockCommentId, selectedBlockClientId, orderedBlockIds } =
|
|
67
|
+
useSelect( ( select ) => {
|
|
68
|
+
const { getBlockAttributes, getSelectedBlockClientId } =
|
|
69
|
+
select( blockEditorStore );
|
|
70
|
+
const clientId = getSelectedBlockClientId();
|
|
71
|
+
return {
|
|
72
|
+
blockCommentId: clientId
|
|
73
|
+
? getBlockAttributes( clientId )?.metadata?.noteId
|
|
74
|
+
: null,
|
|
75
|
+
selectedBlockClientId: clientId,
|
|
76
|
+
orderedBlockIds: select( blockEditorStore ).getBlockOrder(),
|
|
77
|
+
};
|
|
78
|
+
}, [] );
|
|
84
79
|
|
|
85
80
|
const relatedBlockElement = useBlockElement( selectedBlockClientId );
|
|
86
81
|
|
|
82
|
+
const threads = useMemo( () => {
|
|
83
|
+
const t = [ ...noteThreads ];
|
|
84
|
+
const orderedThreads = [];
|
|
85
|
+
// In floating mode, when the note board is shown, and as long
|
|
86
|
+
// as the selected block doesn't have an existing note attached -
|
|
87
|
+
// add a "new note" entry to the threads. This special thread type
|
|
88
|
+
// gets sorted and floated like regular threads, but shows an AddComment
|
|
89
|
+
// component instead of a regular comment thread.
|
|
90
|
+
if ( isFloating && showCommentBoard && undefined === blockCommentId ) {
|
|
91
|
+
// Insert the new note entry at the correct location for its blockId.
|
|
92
|
+
const newNoteThread = {
|
|
93
|
+
id: 'new-note-thread',
|
|
94
|
+
blockClientId: selectedBlockClientId,
|
|
95
|
+
content: { rendered: '' },
|
|
96
|
+
};
|
|
97
|
+
// Insert the new comment block at the right order within the threads.
|
|
98
|
+
orderedBlockIds.forEach( ( blockId ) => {
|
|
99
|
+
if ( blockId === selectedBlockClientId ) {
|
|
100
|
+
orderedThreads.push( newNoteThread );
|
|
101
|
+
} else {
|
|
102
|
+
const threadForBlock = t.find(
|
|
103
|
+
( thread ) => thread.blockClientId === blockId
|
|
104
|
+
);
|
|
105
|
+
if ( threadForBlock ) {
|
|
106
|
+
orderedThreads.push( threadForBlock );
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
} );
|
|
110
|
+
return orderedThreads;
|
|
111
|
+
}
|
|
112
|
+
return t;
|
|
113
|
+
}, [
|
|
114
|
+
noteThreads,
|
|
115
|
+
isFloating,
|
|
116
|
+
showCommentBoard,
|
|
117
|
+
blockCommentId,
|
|
118
|
+
selectedBlockClientId,
|
|
119
|
+
orderedBlockIds,
|
|
120
|
+
] );
|
|
121
|
+
|
|
87
122
|
const handleDelete = async ( comment ) => {
|
|
88
123
|
const currentIndex = threads.findIndex( ( t ) => t.id === comment.id );
|
|
89
124
|
const nextThread = threads[ currentIndex + 1 ];
|
|
@@ -247,17 +282,33 @@ export function Comments( {
|
|
|
247
282
|
const hasThreads = Array.isArray( threads ) && threads.length > 0;
|
|
248
283
|
if ( ! hasThreads && ! isFloating ) {
|
|
249
284
|
return (
|
|
250
|
-
|
|
285
|
+
<>
|
|
286
|
+
<AddComment
|
|
287
|
+
onSubmit={ onAddReply }
|
|
288
|
+
showCommentBoard={ showCommentBoard }
|
|
289
|
+
setShowCommentBoard={ setShowCommentBoard }
|
|
290
|
+
commentSidebarRef={ commentSidebarRef }
|
|
291
|
+
/>
|
|
251
292
|
<Text as="p">{ __( 'No notes available.' ) }</Text>
|
|
252
293
|
<Text as="p" variant="muted">
|
|
253
294
|
{ __( 'Only logged in users can see Notes.' ) }
|
|
254
295
|
</Text>
|
|
255
|
-
|
|
296
|
+
</>
|
|
256
297
|
);
|
|
257
298
|
}
|
|
258
299
|
|
|
259
300
|
return (
|
|
260
|
-
|
|
301
|
+
<>
|
|
302
|
+
{ ! isFloating &&
|
|
303
|
+
showCommentBoard &&
|
|
304
|
+
undefined === blockCommentId && (
|
|
305
|
+
<AddComment
|
|
306
|
+
onSubmit={ onAddReply }
|
|
307
|
+
showCommentBoard={ showCommentBoard }
|
|
308
|
+
setShowCommentBoard={ setShowCommentBoard }
|
|
309
|
+
commentSidebarRef={ commentSidebarRef }
|
|
310
|
+
/>
|
|
311
|
+
) }
|
|
261
312
|
{ threads.map( ( thread ) => (
|
|
262
313
|
<Thread
|
|
263
314
|
key={ thread.id }
|
|
@@ -276,9 +327,10 @@ export function Comments( {
|
|
|
276
327
|
setBlockRef={ setBlockRef }
|
|
277
328
|
selectedThread={ selectedThread }
|
|
278
329
|
commentLastUpdated={ commentLastUpdated }
|
|
330
|
+
showCommentBoard={ showCommentBoard }
|
|
279
331
|
/>
|
|
280
332
|
) ) }
|
|
281
|
-
|
|
333
|
+
</>
|
|
282
334
|
);
|
|
283
335
|
}
|
|
284
336
|
|
|
@@ -298,6 +350,7 @@ function Thread( {
|
|
|
298
350
|
setSelectedThread,
|
|
299
351
|
selectedThread,
|
|
300
352
|
commentLastUpdated,
|
|
353
|
+
showCommentBoard,
|
|
301
354
|
} ) {
|
|
302
355
|
const { toggleBlockHighlight, selectBlock, toggleBlockSpotlight } = unlock(
|
|
303
356
|
useDispatch( blockEditorStore )
|
|
@@ -347,7 +400,7 @@ function Thread( {
|
|
|
347
400
|
const restReplies = allReplies.length > 0 ? allReplies.slice( 0, -1 ) : [];
|
|
348
401
|
|
|
349
402
|
const commentExcerpt = getCommentExcerpt(
|
|
350
|
-
stripHTML( thread.content
|
|
403
|
+
stripHTML( thread.content?.rendered ),
|
|
351
404
|
10
|
|
352
405
|
);
|
|
353
406
|
const ariaLabel = !! thread.blockClientId
|
|
@@ -362,6 +415,21 @@ function Thread( {
|
|
|
362
415
|
commentExcerpt
|
|
363
416
|
);
|
|
364
417
|
|
|
418
|
+
if ( 'new-note-thread' === thread.id && showCommentBoard && isFloating ) {
|
|
419
|
+
return (
|
|
420
|
+
<AddComment
|
|
421
|
+
onSubmit={ onAddReply }
|
|
422
|
+
showCommentBoard={ showCommentBoard }
|
|
423
|
+
setShowCommentBoard={ setShowCommentBoard }
|
|
424
|
+
commentSidebarRef={ commentSidebarRef }
|
|
425
|
+
reflowComments={ reflowComments }
|
|
426
|
+
isFloating={ isFloating }
|
|
427
|
+
y={ y }
|
|
428
|
+
refs={ refs }
|
|
429
|
+
/>
|
|
430
|
+
);
|
|
431
|
+
}
|
|
432
|
+
|
|
365
433
|
return (
|
|
366
434
|
// Disable reason: role="listitem" does in fact support aria-expanded.
|
|
367
435
|
// eslint-disable-next-line jsx-a11y/role-supports-aria-props
|
|
@@ -378,6 +446,9 @@ function Thread( {
|
|
|
378
446
|
onFocus={ onMouseEnter }
|
|
379
447
|
onBlur={ onMouseLeave }
|
|
380
448
|
onKeyDown={ ( event ) => {
|
|
449
|
+
if ( event.defaultPrevented ) {
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
381
452
|
// Expand or Collapse thread.
|
|
382
453
|
if (
|
|
383
454
|
event.key === 'Enter' &&
|
|
@@ -745,7 +816,9 @@ const CommentBoard = ( {
|
|
|
745
816
|
onCancel={ handleCancel }
|
|
746
817
|
confirmButtonText={ __( 'Delete' ) }
|
|
747
818
|
>
|
|
748
|
-
{ __(
|
|
819
|
+
{ __(
|
|
820
|
+
"Are you sure you want to delete this note? This will also delete all of this note's replies."
|
|
821
|
+
) }
|
|
749
822
|
</ConfirmDialog>
|
|
750
823
|
) }
|
|
751
824
|
</VStack>
|
|
@@ -50,10 +50,10 @@ export function useBlockComments( postId ) {
|
|
|
50
50
|
post: postId,
|
|
51
51
|
type: 'note',
|
|
52
52
|
status: 'all',
|
|
53
|
-
per_page:
|
|
53
|
+
per_page: -1,
|
|
54
54
|
};
|
|
55
55
|
|
|
56
|
-
const { records: threads
|
|
56
|
+
const { records: threads } = useEntityRecords(
|
|
57
57
|
'root',
|
|
58
58
|
'comment',
|
|
59
59
|
queryArgs,
|
|
@@ -160,7 +160,6 @@ export function useBlockComments( postId ) {
|
|
|
160
160
|
return {
|
|
161
161
|
resultComments,
|
|
162
162
|
unresolvedSortedThreads,
|
|
163
|
-
totalPages,
|
|
164
163
|
reflowComments,
|
|
165
164
|
commentLastUpdated,
|
|
166
165
|
};
|
|
@@ -399,7 +398,7 @@ export function useFloatingThread( {
|
|
|
399
398
|
if ( blockRef.current ) {
|
|
400
399
|
refs.setReference( blockRef.current );
|
|
401
400
|
}
|
|
402
|
-
}, [ blockRef, refs ] );
|
|
401
|
+
}, [ blockRef, refs, commentLastUpdated ] );
|
|
403
402
|
|
|
404
403
|
// Track thread heights.
|
|
405
404
|
useEffect( () => {
|