Index: trunk/extensions/CodeReview/CodeRevision.php |
— | — | @@ -102,8 +102,8 @@ |
103 | 103 | // We construct a threaded sort key by concatenating the timestamps |
104 | 104 | // of all our parent comments |
105 | 105 | $dbw = wfGetDB( DB_SLAVE ); |
106 | | - $parentKey = $dbw->selectRow( 'code_comment', |
107 | | - array( 'cc_sortkey' ), |
| 106 | + $parentKey = $dbw->selectField( 'code_comment', |
| 107 | + 'cc_sortkey', |
108 | 108 | array( 'cc_id' => $parent ), |
109 | 109 | __METHOD__ ); |
110 | 110 | if( $parentKey ) { |
— | — | @@ -127,7 +127,8 @@ |
128 | 128 | 'cc_user', |
129 | 129 | 'cc_user_text', |
130 | 130 | 'cc_timestamp', |
131 | | - 'cc_review' ), |
| 131 | + 'cc_review', |
| 132 | + 'cc_sortkey' ), |
132 | 133 | array( |
133 | 134 | 'cc_repo_id' => $this->mRepo, |
134 | 135 | 'cc_rev_id' => $this->mId ), |
Index: trunk/extensions/CodeReview/CodeReview.i18n.php |
— | — | @@ -30,6 +30,8 @@ |
31 | 31 | 'code-rev-comment-submit' => 'Submit comment', |
32 | 32 | 'code-rev-comment-preview' => 'Preview', |
33 | 33 | 'code-rev-diff' => 'Diff', |
| 34 | + |
| 35 | + 'codereview-reply-link' => 'reply', |
34 | 36 | |
35 | 37 | 'repoadmin' => 'Repository Administration', |
36 | 38 | 'repoadmin-new-legend' => 'Create a new repository', |
Index: trunk/extensions/CodeReview/SpecialCode.php |
— | — | @@ -25,6 +25,11 @@ |
26 | 26 | case 2: |
27 | 27 | $view = new CodeRevisionView( $params[0], $params[1] ); |
28 | 28 | break; |
| 29 | + case 4: |
| 30 | + if( $params[2] == 'reply' ) { |
| 31 | + $view = new CodeRevisionView( $params[0], $params[1], $params[3] ); |
| 32 | + break; |
| 33 | + } |
29 | 34 | default: |
30 | 35 | throw new MWException( "Unexpected number of parameters" ); |
31 | 36 | } |
— | — | @@ -237,10 +242,11 @@ |
238 | 243 | // Special:Code/MediaWiki/40696 |
239 | 244 | class CodeRevisionView extends CodeView { |
240 | 245 | |
241 | | - function __construct( $repoName, $rev ){ |
| 246 | + function __construct( $repoName, $rev, $replyTarget=null ){ |
242 | 247 | parent::__construct(); |
243 | 248 | $this->mRepo = CodeRepository::newFromName( $repoName ); |
244 | 249 | $this->mRev = $this->mRepo ? $this->mRepo->getRevision( intval( $rev ) ) : null; |
| 250 | + $this->mReplyTarget = $replyTarget; |
245 | 251 | } |
246 | 252 | |
247 | 253 | function execute(){ |
— | — | @@ -333,29 +339,61 @@ |
334 | 340 | return "<div class='mw-codereview-comments'>" . |
335 | 341 | implode( "\n", |
336 | 342 | array_map( |
337 | | - array( $this, 'formatComment' ), |
| 343 | + array( $this, 'formatCommentInline' ), |
338 | 344 | $this->mRev->getComments() ) ) . |
339 | 345 | $this->postCommentForm() . |
340 | 346 | "</div>"; |
341 | 347 | } |
342 | 348 | |
343 | | - function formatComment( $comment ) { |
| 349 | + function formatCommentInline( $comment ) { |
| 350 | + if( $comment->id == $this->mReplyTarget ) { |
| 351 | + return $this->formatComment( $comment, |
| 352 | + $this->postCommentForm( $comment->id ) ); |
| 353 | + } else { |
| 354 | + return $this->formatComment( $comment ); |
| 355 | + } |
| 356 | + } |
| 357 | + |
| 358 | + function formatComment( $comment, $replyForm='' ) { |
344 | 359 | global $wgOut, $wgLang; |
345 | 360 | $linker = new CodeCommentLinkerWiki( $this->mRepo ); |
346 | | - return '<div class="mw-codereview-comment">' . |
| 361 | + return Xml::openElement( 'div', |
| 362 | + array( |
| 363 | + 'class' => 'mw-codereview-comment', |
| 364 | + 'id' => 'c' . intval( $comment->id ), |
| 365 | + 'style' => $this->commentStyle( $comment ) ) ) . |
347 | 366 | '<div class="mw-codereview-comment-meta">' . |
348 | 367 | wfMsgHtml( 'code-rev-comment-by' ) . ' ' . |
349 | 368 | $this->mSkin->userLink( $comment->user, $comment->userText ) . |
350 | 369 | $this->mSkin->userToolLinks( $comment->user, $comment->userText ) . |
351 | 370 | ' ' . |
352 | 371 | $wgLang->timeanddate( $comment->timestamp ) . |
| 372 | + ' ' . |
| 373 | + $this->commentReplyLink( $comment->id ) . |
353 | 374 | '</div>' . |
354 | 375 | '<div class="mw-codereview-comment-text">' . |
355 | 376 | $wgOut->parse( $linker->link( $comment->text ) ) . |
356 | 377 | '</div>' . |
| 378 | + $replyForm . |
357 | 379 | '</div>'; |
358 | 380 | } |
359 | 381 | |
| 382 | + function commentStyle( $comment ) { |
| 383 | + $depth = $comment->threadDepth(); |
| 384 | + $margin = ($depth - 1) * 48; |
| 385 | + return "margin-left: ${margin}px"; |
| 386 | + } |
| 387 | + |
| 388 | + function commentReplyLink( $id ) { |
| 389 | + $repo = $this->mRepo->getName(); |
| 390 | + $rev = $this->mRev->getId(); |
| 391 | + $self = SpecialPage::getTitleFor( 'Code', "$repo/$rev/reply/$id" ); |
| 392 | + $self->setFragment( "#c$id" ); |
| 393 | + return '[' . |
| 394 | + $this->mSkin->link( $self, wfMsg( 'codereview-reply-link' ) ) . |
| 395 | + ']'; |
| 396 | + } |
| 397 | + |
360 | 398 | function postCommentForm( $parent=null ) { |
361 | 399 | global $wgUser; |
362 | 400 | return '<div class="mw-codereview-post-comment">' . |
— | — | @@ -364,9 +402,7 @@ |
365 | 403 | 'action' => '', // fixme |
366 | 404 | 'method' => 'post' ) ) . |
367 | 405 | Xml::hidden( 'wpEditToken', $wgUser->editToken() ) . |
368 | | - Xml::hidden( 'wpCodeRepo', $this->mRepo->getName() ) . |
369 | | - Xml::hidden( 'wpCodeRev', $this->mRev->getId() ) . |
370 | | - ($parent ? Xml::hidden( 'wpCodeParent', $parent ) : '') . |
| 406 | + ($parent ? Xml::hidden( 'wpParent', $parent ) : '') . |
371 | 407 | '<div>' . |
372 | 408 | Xml::textArea( 'wpTextbox1', '' ) . |
373 | 409 | '</div>' . |
Index: trunk/extensions/CodeReview/CodeComment.php |
— | — | @@ -10,5 +10,11 @@ |
11 | 11 | $this->userText = $row->cc_user_text; |
12 | 12 | $this->timestamp = wfTimestamp( TS_MW, $row->cc_timestamp ); |
13 | 13 | $this->review = $row->cc_review; |
| 14 | + $this->sortkey = $row->cc_sortkey; |
14 | 15 | } |
| 16 | + |
| 17 | + function threadDepth() { |
| 18 | + $timestamps = explode( ",", $this->sortkey ); |
| 19 | + return count( $timestamps ); |
| 20 | + } |
15 | 21 | } |
Index: trunk/extensions/CodeReview/codereview.css |
— | — | @@ -13,3 +13,8 @@ |
14 | 14 | background: white; |
15 | 15 | padding: 16px; |
16 | 16 | } |
| 17 | + |
| 18 | +.mw-codereview-comment .mw-codereview-post-comment { |
| 19 | + padding: 16px; |
| 20 | + padding-left: 48px; |
| 21 | +} |