mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-28 16:30:59 +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:
parent
7a9768fc79
commit
082b7f95e6
11 changed files with 175 additions and 12 deletions
|
@ -47,6 +47,16 @@ final class PhabricatorAuditInlineComment
|
|||
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(
|
||||
PhabricatorUser $viewer,
|
||||
$commit_phid) {
|
||||
|
@ -256,6 +266,24 @@ final class PhabricatorAuditInlineComment
|
|||
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 )-------------------------- */
|
||||
|
||||
|
|
|
@ -40,6 +40,12 @@ final class DifferentialInlineCommentEditController
|
|||
->executeOne();
|
||||
}
|
||||
|
||||
protected function loadCommentByPHID($phid) {
|
||||
return id(new DifferentialInlineCommentQuery())
|
||||
->withPHIDs(array($phid))
|
||||
->executeOne();
|
||||
}
|
||||
|
||||
protected function loadCommentForEdit($id) {
|
||||
$request = $this->getRequest();
|
||||
$user = $request->getUser();
|
||||
|
|
|
@ -9,6 +9,7 @@ final class DifferentialInlineCommentQuery
|
|||
private $revisionIDs;
|
||||
private $notDraft;
|
||||
private $ids;
|
||||
private $phids;
|
||||
private $commentIDs;
|
||||
|
||||
private $viewerAndChangesetIDs;
|
||||
|
@ -30,6 +31,11 @@ final class DifferentialInlineCommentQuery
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function withPHIDs(array $phids) {
|
||||
$this->phids = $phids;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withViewerAndChangesetIDs($author_phid, array $ids) {
|
||||
$this->viewerAndChangesetIDs = array($author_phid, $ids);
|
||||
return $this;
|
||||
|
@ -111,6 +117,13 @@ final class DifferentialInlineCommentQuery
|
|||
$this->ids);
|
||||
}
|
||||
|
||||
if ($this->phids !== null) {
|
||||
$where[] = qsprintf(
|
||||
$conn_r,
|
||||
'phid IN (%Ls)',
|
||||
$this->phids);
|
||||
}
|
||||
|
||||
if ($this->viewerAndChangesetIDs) {
|
||||
list($phid, $ids) = $this->viewerAndChangesetIDs;
|
||||
$where[] = qsprintf(
|
||||
|
|
|
@ -189,6 +189,25 @@ final class DifferentialInlineComment
|
|||
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 )-------------------------- */
|
||||
|
||||
|
||||
|
|
|
@ -43,6 +43,10 @@ final class DiffusionInlineCommentController
|
|||
return PhabricatorAuditInlineComment::loadID($id);
|
||||
}
|
||||
|
||||
protected function loadCommentByPHID($phid) {
|
||||
return PhabricatorAuditInlineComment::loadPHID($phid);
|
||||
}
|
||||
|
||||
protected function loadCommentForEdit($id) {
|
||||
$request = $this->getRequest();
|
||||
$user = $request->getUser();
|
||||
|
|
|
@ -6,6 +6,7 @@ abstract class PhabricatorInlineCommentController
|
|||
abstract protected function createComment();
|
||||
abstract protected function loadComment($id);
|
||||
abstract protected function loadCommentForEdit($id);
|
||||
abstract protected function loadCommentByPHID($phid);
|
||||
abstract protected function deleteComment(
|
||||
PhabricatorInlineCommentInterface $inline);
|
||||
abstract protected function saveComment(
|
||||
|
@ -20,6 +21,7 @@ abstract class PhabricatorInlineCommentController
|
|||
private $operation;
|
||||
private $commentID;
|
||||
private $renderer;
|
||||
private $replyToCommentPHID;
|
||||
|
||||
public function getCommentID() {
|
||||
return $this->commentID;
|
||||
|
@ -62,6 +64,15 @@ abstract class PhabricatorInlineCommentController
|
|||
return $this->renderer;
|
||||
}
|
||||
|
||||
public function setReplyToCommentPHID($phid) {
|
||||
$this->replyToCommentPHID = $phid;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getReplyToCommentPHID() {
|
||||
return $this->replyToCommentPHID;
|
||||
}
|
||||
|
||||
public function processRequest() {
|
||||
$request = $this->getRequest();
|
||||
$user = $request->getUser();
|
||||
|
@ -114,7 +125,6 @@ abstract class PhabricatorInlineCommentController
|
|||
|
||||
$edit_dialog->addHiddenInput('id', $this->getCommentID());
|
||||
$edit_dialog->addHiddenInput('op', 'edit');
|
||||
$edit_dialog->addHiddenInput('renderer', $this->getRenderer());
|
||||
|
||||
$edit_dialog->appendChild(
|
||||
$this->renderTextArea(
|
||||
|
@ -136,6 +146,11 @@ abstract class PhabricatorInlineCommentController
|
|||
->setLineLength($this->getLineLength())
|
||||
->setIsNewFile($this->getIsNewFile())
|
||||
->setContent($text);
|
||||
|
||||
if ($this->getReplyToCommentPHID()) {
|
||||
$inline->setReplyToCommentPHID($this->getReplyToCommentPHID());
|
||||
}
|
||||
|
||||
$this->saveComment($inline);
|
||||
|
||||
return $this->buildRenderedCommentResponse(
|
||||
|
@ -162,11 +177,9 @@ abstract class PhabricatorInlineCommentController
|
|||
}
|
||||
|
||||
$edit_dialog->addHiddenInput('op', 'create');
|
||||
$edit_dialog->addHiddenInput('changeset', $changeset);
|
||||
$edit_dialog->addHiddenInput('is_new', $is_new);
|
||||
$edit_dialog->addHiddenInput('number', $number);
|
||||
$edit_dialog->addHiddenInput('length', $length);
|
||||
$edit_dialog->addHiddenInput('renderer', $this->getRenderer());
|
||||
|
||||
$text_area = $this->renderTextArea($this->getCommentText());
|
||||
$edit_dialog->appendChild($text_area);
|
||||
|
@ -181,7 +194,7 @@ abstract class PhabricatorInlineCommentController
|
|||
|
||||
// NOTE: This isn't necessarily a DifferentialChangeset ID, just an
|
||||
// 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->isOnRight = $request->getBool('on_right');
|
||||
|
@ -191,6 +204,25 @@ abstract class PhabricatorInlineCommentController
|
|||
$this->commentID = $request->getInt('id');
|
||||
$this->operation = $request->getStr('op');
|
||||
$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() {
|
||||
|
@ -204,7 +236,9 @@ abstract class PhabricatorInlineCommentController
|
|||
->setIsNewFile($this->getIsNewFile())
|
||||
->setNumber($this->getLineNumber())
|
||||
->setLength($this->getLineLength())
|
||||
->setRenderer($this->getRenderer());
|
||||
->setRenderer($this->getRenderer())
|
||||
->setReplyToCommentPHID($this->getReplyToCommentPHID())
|
||||
->setChangesetID($this->getChangesetID());
|
||||
|
||||
return $edit_dialog;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,12 @@ interface PhabricatorInlineCommentInterface extends PhabricatorMarkupInterface {
|
|||
public function setLineLength($length);
|
||||
public function getLineLength();
|
||||
|
||||
public function setReplyToCommentPHID($phid);
|
||||
public function getReplyToCommentPHID();
|
||||
|
||||
public function setHasReplies($has_replies);
|
||||
public function getHasReplies();
|
||||
|
||||
public function setContent($content);
|
||||
public function getContent();
|
||||
|
||||
|
|
|
@ -76,11 +76,14 @@ final class PHUIDiffInlineCommentDetailView
|
|||
|
||||
$metadata = array(
|
||||
'id' => $inline->getID(),
|
||||
'phid' => $inline->getPHID(),
|
||||
'changesetID' => $inline->getChangesetID(),
|
||||
'number' => $inline->getLineNumber(),
|
||||
'length' => $inline->getLineLength(),
|
||||
'isNewFile' => (bool)$inline->getIsNewFile(),
|
||||
'on_right' => $this->onRight,
|
||||
'original' => $inline->getContent(),
|
||||
'replyToCommentPHID' => $inline->getReplyToCommentPHID(),
|
||||
);
|
||||
|
||||
$sigil = 'differential-inline-comment';
|
||||
|
@ -104,6 +107,15 @@ final class PHUIDiffInlineCommentDetailView
|
|||
$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) {
|
||||
$links[] = javelin_tag(
|
||||
'a',
|
||||
|
|
|
@ -11,6 +11,8 @@ final class PHUIDiffInlineCommentEditView
|
|||
private $length;
|
||||
private $renderer;
|
||||
private $isNewFile;
|
||||
private $replyToCommentPHID;
|
||||
private $changesetID;
|
||||
|
||||
public function setIsNewFile($is_new_file) {
|
||||
$this->isNewFile = $is_new_file;
|
||||
|
@ -49,9 +51,26 @@ final class PHUIDiffInlineCommentEditView
|
|||
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) {
|
||||
$this->onRight = $on_right;
|
||||
$this->addHiddenInput('on_right', $on_right);
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -114,8 +133,15 @@ final class PHUIDiffInlineCommentEditView
|
|||
}
|
||||
|
||||
private function renderInputs() {
|
||||
$inputs = $this->inputs;
|
||||
$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;
|
||||
$out[] = phutil_tag(
|
||||
'input',
|
||||
|
@ -170,10 +196,12 @@ final class PHUIDiffInlineCommentEditView
|
|||
'class' => 'differential-inline-comment-edit',
|
||||
'sigil' => 'differential-inline-comment',
|
||||
'meta' => array(
|
||||
'changesetID' => $this->getChangesetID(),
|
||||
'on_right' => $this->getIsOnRight(),
|
||||
'isNewFile' => (bool)$this->getIsNewFile(),
|
||||
'number' => $this->number,
|
||||
'length' => $this->length,
|
||||
'replyToCommentPHID' => $this->getReplyToCommentPHID(),
|
||||
),
|
||||
),
|
||||
array(
|
||||
|
|
|
@ -34,9 +34,10 @@ JX.install('DifferentialInlineCommentEditor', {
|
|||
number : this.getLineNumber(),
|
||||
is_new : this.getIsNew(),
|
||||
length : this.getLength(),
|
||||
changeset : this.getChangeset(),
|
||||
changesetID : this.getChangesetID(),
|
||||
text : this.getText() || '',
|
||||
renderer: this.getRenderer()
|
||||
renderer: this.getRenderer(),
|
||||
replyToCommentPHID: this.getReplyToCommentPHID() || '',
|
||||
};
|
||||
},
|
||||
_draw : function(content, exact_row) {
|
||||
|
@ -284,13 +285,14 @@ JX.install('DifferentialInlineCommentEditor', {
|
|||
onRight : null,
|
||||
ID : null,
|
||||
lineNumber : null,
|
||||
changeset : null,
|
||||
changesetID : null,
|
||||
length : null,
|
||||
isNew : null,
|
||||
text : null,
|
||||
templates : null,
|
||||
originalText : null,
|
||||
renderer: null
|
||||
renderer: null,
|
||||
replyToCommentPHID: null
|
||||
}
|
||||
|
||||
});
|
||||
|
|
|
@ -245,7 +245,7 @@ JX.behavior('differential-edit-inline-comments', function(config) {
|
|||
editor = new JX.DifferentialInlineCommentEditor(config.uri)
|
||||
.setTemplates(config.undo_templates)
|
||||
.setOperation('new')
|
||||
.setChangeset(changeset)
|
||||
.setChangesetID(changeset)
|
||||
.setLineNumber(o)
|
||||
.setLength(len)
|
||||
.setIsNew(isNewFile(target) ? 1 : 0)
|
||||
|
@ -320,16 +320,25 @@ JX.behavior('differential-edit-inline-comments', function(config) {
|
|||
}
|
||||
|
||||
var original = data.original;
|
||||
var reply_phid = null;
|
||||
if (op == 'reply') {
|
||||
// If the user hit "reply", the original text is empty (a new reply), not
|
||||
// the text of the comment they're replying to.
|
||||
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)
|
||||
.setTemplates(config.undo_templates)
|
||||
.setOperation(op)
|
||||
.setID(data.id)
|
||||
.setChangesetID(data.changesetID)
|
||||
.setLineNumber(data.number)
|
||||
.setLength(data.length)
|
||||
.setOnRight(data.on_right)
|
||||
|
@ -337,6 +346,8 @@ JX.behavior('differential-edit-inline-comments', function(config) {
|
|||
.setRow(row)
|
||||
.setOtherRows(other_rows)
|
||||
.setTable(row.parentNode)
|
||||
.setReplyToCommentPHID(reply_phid)
|
||||
.setRenderer(view.getRenderer())
|
||||
.start();
|
||||
|
||||
set_link_state(true);
|
||||
|
|
Loading…
Reference in a new issue