ThreadItem: Add display names to getAuthorsBelow

Change-Id: I4195f982d7071fea0d0334908535639a11cdcae9
This commit is contained in:
Ed Sanders 2022-09-06 14:16:10 +01:00
parent b82af45735
commit 79a62f539d
6 changed files with 66 additions and 17 deletions

View file

@ -65,9 +65,17 @@ abstract class ContentThreadItem implements JsonSerializable, ThreadItem {
) {
if ( $comment instanceof ContentCommentItem ) {
$author = $comment->getAuthor();
if ( $author ) {
$authors[ $author ] = true;
if ( !isset( $authors[ $author] ) ) {
$authors[ $author ] = [
'username' => $author,
'displayNames' => [],
];
}
$displayName = $comment->getDisplayName();
if ( $displayName && !in_array( $displayName, $authors[ $author ][ 'displayNames' ], true ) ) {
$authors[ $author ][ 'displayNames' ][] = $displayName;
}
if (
!$oldestReply ||
( $comment->getTimestamp() < $oldestReply->getTimestamp() )
@ -91,7 +99,7 @@ abstract class ContentThreadItem implements JsonSerializable, ThreadItem {
ksort( $authors );
$this->authors = array_keys( $authors );
$this->authors = array_values( $authors );
$this->commentCount = $commentCount;
$this->oldestReply = $oldestReply;
$this->latestReply = $latestReply;
@ -102,7 +110,7 @@ abstract class ContentThreadItem implements JsonSerializable, ThreadItem {
*
* Usually called on a HeadingItem to find all authors in a thread.
*
* @return string[] Author usernames
* @return array[] Authors, with `username` and `displayNames` (list of display names) properties.
*/
public function getAuthorsBelow(): array {
$this->calculateThreadSummary();

View file

@ -130,7 +130,17 @@ ThreadItem.prototype.calculateThreadSummary = function () {
var latestReply = null;
function threadScan( comment ) {
if ( comment.type === 'comment' ) {
authors[ comment.author ] = true;
authors[ comment.author ] = authors[ comment.author ] || {
username: comment.author,
displayNames: []
};
if (
comment.displayName &&
authors[ comment.author ].displayNames.indexOf( comment.displayName ) === -1
) {
authors[ comment.author ].displayNames.push( comment.displayName );
}
if (
!oldestReply ||
( comment.timestamp < oldestReply.timestamp )
@ -149,7 +159,9 @@ ThreadItem.prototype.calculateThreadSummary = function () {
}
this.replies.forEach( threadScan );
this.authors = Object.keys( authors ).sort();
this.authors = Object.keys( authors ).sort().map( function ( author ) {
return authors[ author ];
} );
this.commentCount = commentCount;
this.oldestReply = oldestReply;
this.latestReply = latestReply;
@ -160,7 +172,7 @@ ThreadItem.prototype.calculateThreadSummary = function () {
*
* Usually called on a HeadingItem to find all authors in a thread.
*
* @return {string[]} Author usernames
* @return {Object[]} Authors, with `username` and `displayNames` (list of display names) properties.
*/
ThreadItem.prototype.getAuthorsBelow = function () {
this.calculateThreadSummary();

View file

@ -29,11 +29,12 @@ function MWUsernameCompletionAction( surface ) {
this.searchedPrefixes = {};
this.localUsers = [];
this.ipUsers = [];
this.surface.authors.forEach( function ( user ) {
if ( mw.util.isIPAddress( user ) ) {
action.ipUsers.push( user );
} else if ( user !== mw.user.getName() ) {
action.localUsers.push( user );
this.surface.authors.forEach( function ( author ) {
var username = author.username;
if ( mw.util.isIPAddress( username ) ) {
action.ipUsers.push( username );
} else if ( username !== mw.user.getName() ) {
action.localUsers.push( username );
}
} );
if (

View file

@ -13,6 +13,7 @@
"type": "comment",
"id": "Bob1",
"author": "Bob",
"displayName": "Bobby",
"replies": []
}
]
@ -20,13 +21,22 @@
{
"type": "comment",
"author": "Bob",
"displayName": "Robert",
"id": "Bob2",
"replies": [
{
"type": "comment",
"id": "Alice1",
"author": "Alice",
"replies": []
"replies": [
{
"type": "comment",
"id": "Bob3",
"author": "Bob",
"displayName": "Bobby",
"replies": []
}
]
},
{
"type": "comment",
@ -39,15 +49,28 @@
]
},
"expectedAuthorsBelow": [
"Alice",
"Bob",
"Eve"
{
"username": "Alice",
"displayNames": []
},
{
"username": "Bob",
"displayNames": [
"Bobby",
"Robert"
]
},
{
"username": "Eve",
"displayNames": []
}
],
"expectedThreadItemIdsBelow": [
"Eve1",
"Bob1",
"Bob2",
"Alice1",
"Bob3",
"Eve2"
]
}

View file

@ -31,7 +31,11 @@ class ContentThreadItemTest extends IntegrationTestCase {
$makeThreadItem = static function ( array $arr ) use ( &$makeThreadItem, $range ): ContentThreadItem {
if ( $arr['type'] === 'comment' ) {
$item = new ContentCommentItem( 1, $range, [], new DateTimeImmutable(), $arr['author'] );
$item = new ContentCommentItem(
1, $range, [], new DateTimeImmutable(),
$arr['author'],
$arr['displayName'] ?? null
);
} else {
$item = new ContentHeadingItem( $range, 2 );
}

View file

@ -14,6 +14,7 @@ QUnit.test( '#getAuthorsBelow/#getThreadItemsBelow', function ( assert ) {
} else {
item = new CommentItem();
item.author = json.author;
item.displayName = json.displayName;
}
item.id = json.id;
item.replies = json.replies.map( newFromJSON );