1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-23 14:00:56 +01:00

Lift inline comment draft behaviors to "InlineController"

Summary:
Ref T13513. Currently, if you:

  - click a line to create an inline;
  - type some text;
  - wait a moment; and
  - close the page.

...you don't get an "Unsubmitted Draft" marker in the revision list.

Lift all the draft behavior to "InlineController" and make saving a draft dirty the overall container draft state.

Test Plan:
  - Took the steps described above, got a draft state marker.
  - Created, edited, submitted, etc., inlines in Diffusion and Differential.

Maniphest Tasks: T13513

Differential Revision: https://secure.phabricator.com/D21235
This commit is contained in:
epriestley 2020-05-08 05:58:49 -07:00
parent 94a95efa05
commit fa2d30ee36
5 changed files with 103 additions and 77 deletions

View file

@ -7,6 +7,10 @@ final class DifferentialInlineCommentEditController
return new DifferentialDiffInlineCommentQuery(); return new DifferentialDiffInlineCommentQuery();
} }
protected function newContainerObject() {
return $this->loadRevision();
}
private function getRevisionID() { private function getRevisionID() {
return $this->getRequest()->getURIData('id'); return $this->getRequest()->getURIData('id');
} }
@ -137,28 +141,6 @@ final class DifferentialInlineCommentEditController
return true; return true;
} }
protected function deleteComment(PhabricatorInlineComment $inline) {
$inline->openTransaction();
$inline->setIsDeleted(1)->save();
$this->syncDraft();
$inline->saveTransaction();
}
protected function undeleteComment(
PhabricatorInlineComment $inline) {
$inline->openTransaction();
$inline->setIsDeleted(0)->save();
$this->syncDraft();
$inline->saveTransaction();
}
protected function saveComment(PhabricatorInlineComment $inline) {
$inline->openTransaction();
$inline->save();
$this->syncDraft();
$inline->saveTransaction();
}
protected function loadObjectOwnerPHID( protected function loadObjectOwnerPHID(
PhabricatorInlineComment $inline) { PhabricatorInlineComment $inline) {
return $this->loadRevision()->getAuthorPHID(); return $this->loadRevision()->getAuthorPHID();
@ -198,14 +180,4 @@ final class DifferentialInlineCommentEditController
$ids); $ids);
} }
private function syncDraft() {
$viewer = $this->getViewer();
$revision = $this->loadRevision();
$revision->newDraftEngine()
->setObject($revision)
->setViewer($viewer)
->synchronize();
}
} }

View file

@ -11,6 +11,7 @@ final class DifferentialRevisionDraftEngine
->setViewer($viewer) ->setViewer($viewer)
->withRevisionPHIDs(array($revision->getPHID())) ->withRevisionPHIDs(array($revision->getPHID()))
->withPublishableComments(true) ->withPublishableComments(true)
->setLimit(1)
->execute(); ->execute();
return (bool)$inlines; return (bool)$inlines;

View file

@ -7,6 +7,10 @@ final class DiffusionInlineCommentController
return new DiffusionDiffInlineCommentQuery(); return new DiffusionDiffInlineCommentQuery();
} }
protected function newContainerObject() {
return $this->loadCommit();
}
private function getCommitPHID() { private function getCommitPHID() {
return $this->getRequest()->getURIData('phid'); return $this->getRequest()->getURIData('phid');
} }
@ -103,19 +107,6 @@ final class DiffusionInlineCommentController
return true; return true;
} }
protected function deleteComment(PhabricatorInlineComment $inline) {
$inline->setIsDeleted(1)->save();
}
protected function undeleteComment(
PhabricatorInlineComment $inline) {
$inline->setIsDeleted(0)->save();
}
protected function saveComment(PhabricatorInlineComment $inline) {
return $inline->save();
}
protected function loadObjectOwnerPHID( protected function loadObjectOwnerPHID(
PhabricatorInlineComment $inline) { PhabricatorInlineComment $inline) {
return $this->loadCommit()->getAuthorPHID(); return $this->loadCommit()->getAuthorPHID();

View file

@ -11,6 +11,7 @@ final class DiffusionCommitDraftEngine
->setViewer($viewer) ->setViewer($viewer)
->withCommitPHIDs(array($commit->getPHID())) ->withCommitPHIDs(array($commit->getPHID()))
->withPublishableComments(true) ->withPublishableComments(true)
->setLimit(1)
->execute(); ->execute();
return (bool)$inlines; return (bool)$inlines;

View file

@ -3,17 +3,28 @@
abstract class PhabricatorInlineCommentController abstract class PhabricatorInlineCommentController
extends PhabricatorController { extends PhabricatorController {
private $containerObject;
abstract protected function createComment(); abstract protected function createComment();
abstract protected function newInlineCommentQuery(); abstract protected function newInlineCommentQuery();
abstract protected function loadCommentForDone($id); abstract protected function loadCommentForDone($id);
abstract protected function loadObjectOwnerPHID( abstract protected function loadObjectOwnerPHID(
PhabricatorInlineComment $inline); PhabricatorInlineComment $inline);
abstract protected function deleteComment( abstract protected function newContainerObject();
PhabricatorInlineComment $inline);
abstract protected function undeleteComment( final protected function getContainerObject() {
PhabricatorInlineComment $inline); if ($this->containerObject === null) {
abstract protected function saveComment( $object = $this->newContainerObject();
PhabricatorInlineComment $inline); if (!$object) {
throw new Exception(
pht(
'Failed to load container object for inline comment.'));
}
$this->containerObject = $object;
}
return $this->containerObject;
}
protected function hideComments(array $ids) { protected function hideComments(array $ids) {
throw new PhutilMethodNotImplementedException(); throw new PhutilMethodNotImplementedException();
@ -173,11 +184,13 @@ abstract class PhabricatorInlineCommentController
$inline = $this->loadCommentByIDForEdit($this->getCommentID()); $inline = $this->loadCommentByIDForEdit($this->getCommentID());
if ($is_delete) { if ($is_delete) {
$this->deleteComment($inline); $inline->setIsDeleted(1);
} else { } else {
$this->undeleteComment($inline); $inline->setIsDeleted(0);
} }
$this->saveComment($inline);
return $this->buildEmptyResponse(); return $this->buildEmptyResponse();
case 'edit': case 'edit':
$inline = $this->loadCommentByIDForEdit($this->getCommentID()); $inline = $this->loadCommentByIDForEdit($this->getCommentID());
@ -190,33 +203,49 @@ abstract class PhabricatorInlineCommentController
->setIsEditing(false); ->setIsEditing(false);
$this->saveComment($inline); $this->saveComment($inline);
$this->purgeVersionedDrafts($inline);
return $this->buildRenderedCommentResponse( return $this->buildRenderedCommentResponse(
$inline, $inline,
$this->getIsOnRight()); $this->getIsOnRight());
} else { } else {
$this->deleteComment($inline); $inline->setIsDeleted(1);
$this->purgeVersionedDrafts($inline);
$this->saveComment($inline);
return $this->buildEmptyResponse(); return $this->buildEmptyResponse();
} }
} else { } else {
$inline->setIsEditing(true); // NOTE: At time of writing, the "editing" state of inlines is
// preserved by simluating a click on "Edit" when the inline loads.
// In this case, we don't want to "saveComment()", because it
// recalculates object drafts and purges versioned drafts.
// The recalculation is merely unnecessary (state doesn't change)
// but purging drafts means that loading a page and then closing it
// discards your drafts.
// To avoid the purge, only invoke "saveComment()" if we actually
// have changes to apply.
$is_dirty = false;
if (!$inline->getIsEditing()) {
$inline->setIsEditing(true);
$is_dirty = true;
}
if (strlen($text)) { if (strlen($text)) {
$inline->setContent($text); $inline->setContent($text);
$is_dirty = true;
} else {
PhabricatorInlineComment::loadAndAttachVersionedDrafts(
$viewer,
array($inline));
} }
$this->saveComment($inline); if ($is_dirty) {
$this->saveComment($inline);
if (strlen($text)) {
$this->purgeVersionedDrafts($inline);
} }
PhabricatorInlineComment::loadAndAttachVersionedDrafts(
$viewer,
array($inline));
} }
$edit_dialog = $this->buildEditDialog($inline) $edit_dialog = $this->buildEditDialog($inline)
@ -240,12 +269,10 @@ abstract class PhabricatorInlineCommentController
$content = $inline->getContent(); $content = $inline->getContent();
if (!strlen($content)) { if (!strlen($content)) {
$this->deleteComment($inline); $inline->setIsDeleted(1);
} else {
$this->saveComment($inline);
} }
$this->purgeVersionedDrafts($inline); $this->saveComment($inline);
return $this->buildEmptyResponse(); return $this->buildEmptyResponse();
case 'draft': case 'draft':
@ -262,6 +289,17 @@ abstract class PhabricatorInlineCommentController
->setProperty('inline.text', $text) ->setProperty('inline.text', $text)
->save(); ->save();
// We have to synchronize the draft engine after saving a versioned
// draft, because taking an inline comment from "no text, no draft"
// to "no text, text in a draft" marks the container object as having
// a draft.
$draft_engine = $this->newDraftEngine();
if ($draft_engine) {
$draft_engine->synchronize();
} else {
phlog('no draft engine');
}
return $this->buildEmptyResponse(); return $this->buildEmptyResponse();
case 'new': case 'new':
case 'reply': case 'reply':
@ -432,14 +470,6 @@ abstract class PhabricatorInlineCommentController
->setContent($response); ->setContent($response);
} }
private function purgeVersionedDrafts(
PhabricatorInlineComment $inline) {
$viewer = $this->getViewer();
PhabricatorVersionedDraft::purgeDrafts(
$inline->getPHID(),
$viewer->getPHID());
}
final protected function loadCommentByID($id) { final protected function loadCommentByID($id) {
$query = $this->newInlineCommentQuery() $query = $this->newInlineCommentQuery()
->withIDs(array($id)); ->withIDs(array($id));
@ -494,4 +524,35 @@ abstract class PhabricatorInlineCommentController
return $inline; return $inline;
} }
private function saveComment(PhabricatorInlineComment $inline) {
$viewer = $this->getViewer();
$draft_engine = $this->newDraftEngine();
$inline->openTransaction();
$inline->save();
PhabricatorVersionedDraft::purgeDrafts(
$inline->getPHID(),
$viewer->getPHID());
if ($draft_engine) {
$draft_engine->synchronize();
}
$inline->saveTransaction();
}
private function newDraftEngine() {
$viewer = $this->getViewer();
$object = $this->getContainerObject();
if (!($object instanceof PhabricatorDraftInterface)) {
return null;
}
return $object->newDraftEngine()
->setObject($object)
->setViewer($viewer);
}
} }