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:
parent
94a95efa05
commit
fa2d30ee36
5 changed files with 103 additions and 77 deletions
|
@ -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();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue