1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-30 10:42:41 +01:00

Explicitly track inline comment reply threading

Summary:
Ref T1460. Track and store which comments are threaded replies to other comments, vs merely appearing on the same lines.

This doesn't actually write `hasReplies` yet, since that needs to happen when we un-draft comments on submission.

Test Plan: Made inline comments in Differential and Diffusion, including replies. Replies were marked as "Is Reply".

Reviewers: btrahan

Reviewed By: btrahan

Subscribers: epriestley

Maniphest Tasks: T1460

Differential Revision: https://secure.phabricator.com/D12017
This commit is contained in:
epriestley 2015-03-08 13:04:38 -07:00
parent 7a9768fc79
commit 082b7f95e6
11 changed files with 175 additions and 12 deletions

View file

@ -47,6 +47,16 @@ final class PhabricatorAuditInlineComment
return head(self::buildProxies($inlines)); return head(self::buildProxies($inlines));
} }
public static function loadPHID($phid) {
$inlines = id(new PhabricatorAuditTransactionComment())->loadAllWhere(
'phid = %s',
$phid);
if (!$inlines) {
return null;
}
return head(self::buildProxies($inlines));
}
public static function loadDraftComments( public static function loadDraftComments(
PhabricatorUser $viewer, PhabricatorUser $viewer,
$commit_phid) { $commit_phid) {
@ -256,6 +266,24 @@ final class PhabricatorAuditInlineComment
return $this->getPathID(); return $this->getPathID();
} }
public function setReplyToCommentPHID($phid) {
$this->proxy->setReplyToCommentPHID($phid);
return $this;
}
public function getReplyToCommentPHID() {
return $this->proxy->getReplyToCommentPHID();
}
public function setHasReplies($has_replies) {
$this->proxy->setHasReplies($has_replies);
return $this;
}
public function getHasReplies() {
return $this->proxy->getHasReplies();
}
/* -( PhabricatorMarkupInterface Implementation )-------------------------- */ /* -( PhabricatorMarkupInterface Implementation )-------------------------- */

View file

@ -40,6 +40,12 @@ final class DifferentialInlineCommentEditController
->executeOne(); ->executeOne();
} }
protected function loadCommentByPHID($phid) {
return id(new DifferentialInlineCommentQuery())
->withPHIDs(array($phid))
->executeOne();
}
protected function loadCommentForEdit($id) { protected function loadCommentForEdit($id) {
$request = $this->getRequest(); $request = $this->getRequest();
$user = $request->getUser(); $user = $request->getUser();

View file

@ -9,6 +9,7 @@ final class DifferentialInlineCommentQuery
private $revisionIDs; private $revisionIDs;
private $notDraft; private $notDraft;
private $ids; private $ids;
private $phids;
private $commentIDs; private $commentIDs;
private $viewerAndChangesetIDs; private $viewerAndChangesetIDs;
@ -30,6 +31,11 @@ final class DifferentialInlineCommentQuery
return $this; return $this;
} }
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withViewerAndChangesetIDs($author_phid, array $ids) { public function withViewerAndChangesetIDs($author_phid, array $ids) {
$this->viewerAndChangesetIDs = array($author_phid, $ids); $this->viewerAndChangesetIDs = array($author_phid, $ids);
return $this; return $this;
@ -111,6 +117,13 @@ final class DifferentialInlineCommentQuery
$this->ids); $this->ids);
} }
if ($this->phids !== null) {
$where[] = qsprintf(
$conn_r,
'phid IN (%Ls)',
$this->phids);
}
if ($this->viewerAndChangesetIDs) { if ($this->viewerAndChangesetIDs) {
list($phid, $ids) = $this->viewerAndChangesetIDs; list($phid, $ids) = $this->viewerAndChangesetIDs;
$where[] = qsprintf( $where[] = qsprintf(

View file

@ -189,6 +189,25 @@ final class DifferentialInlineComment
return $this; return $this;
} }
public function setReplyToCommentPHID($phid) {
$this->proxy->setReplyToCommentPHID($phid);
return $this;
}
public function getReplyToCommentPHID() {
return $this->proxy->getReplyToCommentPHID();
}
public function setHasReplies($has_replies) {
$this->proxy->setHasReplies($has_replies);
return $this;
}
public function getHasReplies() {
return $this->proxy->getHasReplies();
}
/* -( PhabricatorMarkupInterface Implementation )-------------------------- */ /* -( PhabricatorMarkupInterface Implementation )-------------------------- */

View file

@ -43,6 +43,10 @@ final class DiffusionInlineCommentController
return PhabricatorAuditInlineComment::loadID($id); return PhabricatorAuditInlineComment::loadID($id);
} }
protected function loadCommentByPHID($phid) {
return PhabricatorAuditInlineComment::loadPHID($phid);
}
protected function loadCommentForEdit($id) { protected function loadCommentForEdit($id) {
$request = $this->getRequest(); $request = $this->getRequest();
$user = $request->getUser(); $user = $request->getUser();

View file

@ -6,6 +6,7 @@ abstract class PhabricatorInlineCommentController
abstract protected function createComment(); abstract protected function createComment();
abstract protected function loadComment($id); abstract protected function loadComment($id);
abstract protected function loadCommentForEdit($id); abstract protected function loadCommentForEdit($id);
abstract protected function loadCommentByPHID($phid);
abstract protected function deleteComment( abstract protected function deleteComment(
PhabricatorInlineCommentInterface $inline); PhabricatorInlineCommentInterface $inline);
abstract protected function saveComment( abstract protected function saveComment(
@ -20,6 +21,7 @@ abstract class PhabricatorInlineCommentController
private $operation; private $operation;
private $commentID; private $commentID;
private $renderer; private $renderer;
private $replyToCommentPHID;
public function getCommentID() { public function getCommentID() {
return $this->commentID; return $this->commentID;
@ -62,6 +64,15 @@ abstract class PhabricatorInlineCommentController
return $this->renderer; return $this->renderer;
} }
public function setReplyToCommentPHID($phid) {
$this->replyToCommentPHID = $phid;
return $this;
}
public function getReplyToCommentPHID() {
return $this->replyToCommentPHID;
}
public function processRequest() { public function processRequest() {
$request = $this->getRequest(); $request = $this->getRequest();
$user = $request->getUser(); $user = $request->getUser();
@ -114,7 +125,6 @@ abstract class PhabricatorInlineCommentController
$edit_dialog->addHiddenInput('id', $this->getCommentID()); $edit_dialog->addHiddenInput('id', $this->getCommentID());
$edit_dialog->addHiddenInput('op', 'edit'); $edit_dialog->addHiddenInput('op', 'edit');
$edit_dialog->addHiddenInput('renderer', $this->getRenderer());
$edit_dialog->appendChild( $edit_dialog->appendChild(
$this->renderTextArea( $this->renderTextArea(
@ -136,6 +146,11 @@ abstract class PhabricatorInlineCommentController
->setLineLength($this->getLineLength()) ->setLineLength($this->getLineLength())
->setIsNewFile($this->getIsNewFile()) ->setIsNewFile($this->getIsNewFile())
->setContent($text); ->setContent($text);
if ($this->getReplyToCommentPHID()) {
$inline->setReplyToCommentPHID($this->getReplyToCommentPHID());
}
$this->saveComment($inline); $this->saveComment($inline);
return $this->buildRenderedCommentResponse( return $this->buildRenderedCommentResponse(
@ -162,11 +177,9 @@ abstract class PhabricatorInlineCommentController
} }
$edit_dialog->addHiddenInput('op', 'create'); $edit_dialog->addHiddenInput('op', 'create');
$edit_dialog->addHiddenInput('changeset', $changeset);
$edit_dialog->addHiddenInput('is_new', $is_new); $edit_dialog->addHiddenInput('is_new', $is_new);
$edit_dialog->addHiddenInput('number', $number); $edit_dialog->addHiddenInput('number', $number);
$edit_dialog->addHiddenInput('length', $length); $edit_dialog->addHiddenInput('length', $length);
$edit_dialog->addHiddenInput('renderer', $this->getRenderer());
$text_area = $this->renderTextArea($this->getCommentText()); $text_area = $this->renderTextArea($this->getCommentText());
$edit_dialog->appendChild($text_area); $edit_dialog->appendChild($text_area);
@ -181,7 +194,7 @@ abstract class PhabricatorInlineCommentController
// NOTE: This isn't necessarily a DifferentialChangeset ID, just an // NOTE: This isn't necessarily a DifferentialChangeset ID, just an
// application identifier for the changeset. In Diffusion, it's a Path ID. // application identifier for the changeset. In Diffusion, it's a Path ID.
$this->changesetID = $request->getInt('changeset'); $this->changesetID = $request->getInt('changesetID');
$this->isNewFile = (int)$request->getBool('is_new'); $this->isNewFile = (int)$request->getBool('is_new');
$this->isOnRight = $request->getBool('on_right'); $this->isOnRight = $request->getBool('on_right');
@ -191,6 +204,25 @@ abstract class PhabricatorInlineCommentController
$this->commentID = $request->getInt('id'); $this->commentID = $request->getInt('id');
$this->operation = $request->getStr('op'); $this->operation = $request->getStr('op');
$this->renderer = $request->getStr('renderer'); $this->renderer = $request->getStr('renderer');
$this->replyToCommentPHID = $request->getStr('replyToCommentPHID');
if ($this->getReplyToCommentPHID()) {
$reply_phid = $this->getReplyToCommentPHID();
$reply_comment = $this->loadCommentByPHID($reply_phid);
if (!$reply_comment) {
throw new Exception(
pht('Failed to load comment "%s".', $reply_phid));
}
if ($reply_comment->getChangesetID() != $this->getChangesetID()) {
throw new Exception(
pht(
'Comment "%s" belongs to wrong changeset (%s vs %s).',
$reply_phid,
$reply_comment->getChangesetID(),
$this->getChangesetID()));
}
}
} }
private function buildEditDialog() { private function buildEditDialog() {
@ -204,7 +236,9 @@ abstract class PhabricatorInlineCommentController
->setIsNewFile($this->getIsNewFile()) ->setIsNewFile($this->getIsNewFile())
->setNumber($this->getLineNumber()) ->setNumber($this->getLineNumber())
->setLength($this->getLineLength()) ->setLength($this->getLineLength())
->setRenderer($this->getRenderer()); ->setRenderer($this->getRenderer())
->setReplyToCommentPHID($this->getReplyToCommentPHID())
->setChangesetID($this->getChangesetID());
return $edit_dialog; return $edit_dialog;
} }

View file

@ -19,6 +19,12 @@ interface PhabricatorInlineCommentInterface extends PhabricatorMarkupInterface {
public function setLineLength($length); public function setLineLength($length);
public function getLineLength(); public function getLineLength();
public function setReplyToCommentPHID($phid);
public function getReplyToCommentPHID();
public function setHasReplies($has_replies);
public function getHasReplies();
public function setContent($content); public function setContent($content);
public function getContent(); public function getContent();

View file

@ -76,11 +76,14 @@ final class PHUIDiffInlineCommentDetailView
$metadata = array( $metadata = array(
'id' => $inline->getID(), 'id' => $inline->getID(),
'phid' => $inline->getPHID(),
'changesetID' => $inline->getChangesetID(),
'number' => $inline->getLineNumber(), 'number' => $inline->getLineNumber(),
'length' => $inline->getLineLength(), 'length' => $inline->getLineLength(),
'isNewFile' => (bool)$inline->getIsNewFile(), 'isNewFile' => (bool)$inline->getIsNewFile(),
'on_right' => $this->onRight, 'on_right' => $this->onRight,
'original' => $inline->getContent(), 'original' => $inline->getContent(),
'replyToCommentPHID' => $inline->getReplyToCommentPHID(),
); );
$sigil = 'differential-inline-comment'; $sigil = 'differential-inline-comment';
@ -104,6 +107,15 @@ final class PHUIDiffInlineCommentDetailView
$is_draft = true; $is_draft = true;
} }
// TODO: This stuff is nonfinal, just making it do something.
if ($inline->getHasReplies()) {
$links[] = pht('Has Reply');
}
if ($inline->getReplyToCommentPHID()) {
$links[] = pht('Is Reply');
}
if (!$this->preview) { if (!$this->preview) {
$links[] = javelin_tag( $links[] = javelin_tag(
'a', 'a',

View file

@ -11,6 +11,8 @@ final class PHUIDiffInlineCommentEditView
private $length; private $length;
private $renderer; private $renderer;
private $isNewFile; private $isNewFile;
private $replyToCommentPHID;
private $changesetID;
public function setIsNewFile($is_new_file) { public function setIsNewFile($is_new_file) {
$this->isNewFile = $is_new_file; $this->isNewFile = $is_new_file;
@ -49,9 +51,26 @@ final class PHUIDiffInlineCommentEditView
return $this; return $this;
} }
public function setReplyToCommentPHID($reply_to_phid) {
$this->replyToCommentPHID = $reply_to_phid;
return $this;
}
public function getReplyToCommentPHID() {
return $this->replyToCommentPHID;
}
public function setChangesetID($changeset_id) {
$this->changesetID = $changeset_id;
return $this;
}
public function getChangesetID() {
return $this->changesetID;
}
public function setOnRight($on_right) { public function setOnRight($on_right) {
$this->onRight = $on_right; $this->onRight = $on_right;
$this->addHiddenInput('on_right', $on_right);
return $this; return $this;
} }
@ -114,8 +133,15 @@ final class PHUIDiffInlineCommentEditView
} }
private function renderInputs() { private function renderInputs() {
$inputs = $this->inputs;
$out = array(); $out = array();
foreach ($this->inputs as $input) {
$inputs[] = array('on_right', (bool)$this->getIsOnRight());
$inputs[] = array('replyToCommentPHID', $this->getReplyToCommentPHID());
$inputs[] = array('renderer', $this->getRenderer());
$inputs[] = array('changesetID', $this->getChangesetID());
foreach ($inputs as $input) {
list($name, $value) = $input; list($name, $value) = $input;
$out[] = phutil_tag( $out[] = phutil_tag(
'input', 'input',
@ -170,10 +196,12 @@ final class PHUIDiffInlineCommentEditView
'class' => 'differential-inline-comment-edit', 'class' => 'differential-inline-comment-edit',
'sigil' => 'differential-inline-comment', 'sigil' => 'differential-inline-comment',
'meta' => array( 'meta' => array(
'changesetID' => $this->getChangesetID(),
'on_right' => $this->getIsOnRight(), 'on_right' => $this->getIsOnRight(),
'isNewFile' => (bool)$this->getIsNewFile(), 'isNewFile' => (bool)$this->getIsNewFile(),
'number' => $this->number, 'number' => $this->number,
'length' => $this->length, 'length' => $this->length,
'replyToCommentPHID' => $this->getReplyToCommentPHID(),
), ),
), ),
array( array(

View file

@ -34,9 +34,10 @@ JX.install('DifferentialInlineCommentEditor', {
number : this.getLineNumber(), number : this.getLineNumber(),
is_new : this.getIsNew(), is_new : this.getIsNew(),
length : this.getLength(), length : this.getLength(),
changeset : this.getChangeset(), changesetID : this.getChangesetID(),
text : this.getText() || '', text : this.getText() || '',
renderer: this.getRenderer() renderer: this.getRenderer(),
replyToCommentPHID: this.getReplyToCommentPHID() || '',
}; };
}, },
_draw : function(content, exact_row) { _draw : function(content, exact_row) {
@ -284,13 +285,14 @@ JX.install('DifferentialInlineCommentEditor', {
onRight : null, onRight : null,
ID : null, ID : null,
lineNumber : null, lineNumber : null,
changeset : null, changesetID : null,
length : null, length : null,
isNew : null, isNew : null,
text : null, text : null,
templates : null, templates : null,
originalText : null, originalText : null,
renderer: null renderer: null,
replyToCommentPHID: null
} }
}); });

View file

@ -245,7 +245,7 @@ JX.behavior('differential-edit-inline-comments', function(config) {
editor = new JX.DifferentialInlineCommentEditor(config.uri) editor = new JX.DifferentialInlineCommentEditor(config.uri)
.setTemplates(config.undo_templates) .setTemplates(config.undo_templates)
.setOperation('new') .setOperation('new')
.setChangeset(changeset) .setChangesetID(changeset)
.setLineNumber(o) .setLineNumber(o)
.setLength(len) .setLength(len)
.setIsNew(isNewFile(target) ? 1 : 0) .setIsNew(isNewFile(target) ? 1 : 0)
@ -320,16 +320,25 @@ JX.behavior('differential-edit-inline-comments', function(config) {
} }
var original = data.original; var original = data.original;
var reply_phid = null;
if (op == 'reply') { if (op == 'reply') {
// If the user hit "reply", the original text is empty (a new reply), not // If the user hit "reply", the original text is empty (a new reply), not
// the text of the comment they're replying to. // the text of the comment they're replying to.
original = ''; original = '';
reply_phid = data.phid;
} }
var changeset_root = JX.DOM.findAbove(
node,
'div',
'differential-changeset');
var view = JX.ChangesetViewManager.getForNode(changeset_root);
editor = new JX.DifferentialInlineCommentEditor(config.uri) editor = new JX.DifferentialInlineCommentEditor(config.uri)
.setTemplates(config.undo_templates) .setTemplates(config.undo_templates)
.setOperation(op) .setOperation(op)
.setID(data.id) .setID(data.id)
.setChangesetID(data.changesetID)
.setLineNumber(data.number) .setLineNumber(data.number)
.setLength(data.length) .setLength(data.length)
.setOnRight(data.on_right) .setOnRight(data.on_right)
@ -337,6 +346,8 @@ JX.behavior('differential-edit-inline-comments', function(config) {
.setRow(row) .setRow(row)
.setOtherRows(other_rows) .setOtherRows(other_rows)
.setTable(row.parentNode) .setTable(row.parentNode)
.setReplyToCommentPHID(reply_phid)
.setRenderer(view.getRenderer())
.start(); .start();
set_link_state(true); set_link_state(true);