Skip to content
This repository was archived by the owner on Apr 26, 2024. It is now read-only.

Commit fa2d30e

Browse files
author
epriestley
committed
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
1 parent 94a95ef commit fa2d30e

File tree

5 files changed

+103
-77
lines changed

5 files changed

+103
-77
lines changed

src/applications/differential/controller/DifferentialInlineCommentEditController.php

Lines changed: 4 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ protected function newInlineCommentQuery() {
77
return new DifferentialDiffInlineCommentQuery();
88
}
99

10+
protected function newContainerObject() {
11+
return $this->loadRevision();
12+
}
13+
1014
private function getRevisionID() {
1115
return $this->getRequest()->getURIData('id');
1216
}
@@ -137,28 +141,6 @@ protected function canEditInlineComment(
137141
return true;
138142
}
139143

140-
protected function deleteComment(PhabricatorInlineComment $inline) {
141-
$inline->openTransaction();
142-
$inline->setIsDeleted(1)->save();
143-
$this->syncDraft();
144-
$inline->saveTransaction();
145-
}
146-
147-
protected function undeleteComment(
148-
PhabricatorInlineComment $inline) {
149-
$inline->openTransaction();
150-
$inline->setIsDeleted(0)->save();
151-
$this->syncDraft();
152-
$inline->saveTransaction();
153-
}
154-
155-
protected function saveComment(PhabricatorInlineComment $inline) {
156-
$inline->openTransaction();
157-
$inline->save();
158-
$this->syncDraft();
159-
$inline->saveTransaction();
160-
}
161-
162144
protected function loadObjectOwnerPHID(
163145
PhabricatorInlineComment $inline) {
164146
return $this->loadRevision()->getAuthorPHID();
@@ -198,14 +180,4 @@ protected function showComments(array $ids) {
198180
$ids);
199181
}
200182

201-
private function syncDraft() {
202-
$viewer = $this->getViewer();
203-
$revision = $this->loadRevision();
204-
205-
$revision->newDraftEngine()
206-
->setObject($revision)
207-
->setViewer($viewer)
208-
->synchronize();
209-
}
210-
211183
}

src/applications/differential/engine/DifferentialRevisionDraftEngine.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ protected function hasCustomDraftContent() {
1111
->setViewer($viewer)
1212
->withRevisionPHIDs(array($revision->getPHID()))
1313
->withPublishableComments(true)
14+
->setLimit(1)
1415
->execute();
1516

1617
return (bool)$inlines;

src/applications/diffusion/controller/DiffusionInlineCommentController.php

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ protected function newInlineCommentQuery() {
77
return new DiffusionDiffInlineCommentQuery();
88
}
99

10+
protected function newContainerObject() {
11+
return $this->loadCommit();
12+
}
13+
1014
private function getCommitPHID() {
1115
return $this->getRequest()->getURIData('phid');
1216
}
@@ -103,19 +107,6 @@ protected function canEditInlineComment(
103107
return true;
104108
}
105109

106-
protected function deleteComment(PhabricatorInlineComment $inline) {
107-
$inline->setIsDeleted(1)->save();
108-
}
109-
110-
protected function undeleteComment(
111-
PhabricatorInlineComment $inline) {
112-
$inline->setIsDeleted(0)->save();
113-
}
114-
115-
protected function saveComment(PhabricatorInlineComment $inline) {
116-
return $inline->save();
117-
}
118-
119110
protected function loadObjectOwnerPHID(
120111
PhabricatorInlineComment $inline) {
121112
return $this->loadCommit()->getAuthorPHID();

src/applications/diffusion/engine/DiffusionCommitDraftEngine.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ protected function hasCustomDraftContent() {
1111
->setViewer($viewer)
1212
->withCommitPHIDs(array($commit->getPHID()))
1313
->withPublishableComments(true)
14+
->setLimit(1)
1415
->execute();
1516

1617
return (bool)$inlines;

src/infrastructure/diff/PhabricatorInlineCommentController.php

Lines changed: 93 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,28 @@
33
abstract class PhabricatorInlineCommentController
44
extends PhabricatorController {
55

6+
private $containerObject;
7+
68
abstract protected function createComment();
79
abstract protected function newInlineCommentQuery();
810
abstract protected function loadCommentForDone($id);
911
abstract protected function loadObjectOwnerPHID(
1012
PhabricatorInlineComment $inline);
11-
abstract protected function deleteComment(
12-
PhabricatorInlineComment $inline);
13-
abstract protected function undeleteComment(
14-
PhabricatorInlineComment $inline);
15-
abstract protected function saveComment(
16-
PhabricatorInlineComment $inline);
13+
abstract protected function newContainerObject();
14+
15+
final protected function getContainerObject() {
16+
if ($this->containerObject === null) {
17+
$object = $this->newContainerObject();
18+
if (!$object) {
19+
throw new Exception(
20+
pht(
21+
'Failed to load container object for inline comment.'));
22+
}
23+
$this->containerObject = $object;
24+
}
25+
26+
return $this->containerObject;
27+
}
1728

1829
protected function hideComments(array $ids) {
1930
throw new PhutilMethodNotImplementedException();
@@ -173,11 +184,13 @@ public function processRequest() {
173184
$inline = $this->loadCommentByIDForEdit($this->getCommentID());
174185

175186
if ($is_delete) {
176-
$this->deleteComment($inline);
187+
$inline->setIsDeleted(1);
177188
} else {
178-
$this->undeleteComment($inline);
189+
$inline->setIsDeleted(0);
179190
}
180191

192+
$this->saveComment($inline);
193+
181194
return $this->buildEmptyResponse();
182195
case 'edit':
183196
$inline = $this->loadCommentByIDForEdit($this->getCommentID());
@@ -190,33 +203,49 @@ public function processRequest() {
190203
->setIsEditing(false);
191204

192205
$this->saveComment($inline);
193-
$this->purgeVersionedDrafts($inline);
194206

195207
return $this->buildRenderedCommentResponse(
196208
$inline,
197209
$this->getIsOnRight());
198210
} else {
199-
$this->deleteComment($inline);
200-
$this->purgeVersionedDrafts($inline);
211+
$inline->setIsDeleted(1);
212+
213+
$this->saveComment($inline);
201214

202215
return $this->buildEmptyResponse();
203216
}
204217
} else {
205-
$inline->setIsEditing(true);
218+
// NOTE: At time of writing, the "editing" state of inlines is
219+
// preserved by simluating a click on "Edit" when the inline loads.
206220

207-
if (strlen($text)) {
208-
$inline->setContent($text);
209-
}
221+
// In this case, we don't want to "saveComment()", because it
222+
// recalculates object drafts and purges versioned drafts.
223+
224+
// The recalculation is merely unnecessary (state doesn't change)
225+
// but purging drafts means that loading a page and then closing it
226+
// discards your drafts.
210227

211-
$this->saveComment($inline);
228+
// To avoid the purge, only invoke "saveComment()" if we actually
229+
// have changes to apply.
230+
231+
$is_dirty = false;
232+
if (!$inline->getIsEditing()) {
233+
$inline->setIsEditing(true);
234+
$is_dirty = true;
235+
}
212236

213237
if (strlen($text)) {
214-
$this->purgeVersionedDrafts($inline);
238+
$inline->setContent($text);
239+
$is_dirty = true;
240+
} else {
241+
PhabricatorInlineComment::loadAndAttachVersionedDrafts(
242+
$viewer,
243+
array($inline));
215244
}
216245

217-
PhabricatorInlineComment::loadAndAttachVersionedDrafts(
218-
$viewer,
219-
array($inline));
246+
if ($is_dirty) {
247+
$this->saveComment($inline);
248+
}
220249
}
221250

222251
$edit_dialog = $this->buildEditDialog($inline)
@@ -240,12 +269,10 @@ public function processRequest() {
240269

241270
$content = $inline->getContent();
242271
if (!strlen($content)) {
243-
$this->deleteComment($inline);
244-
} else {
245-
$this->saveComment($inline);
272+
$inline->setIsDeleted(1);
246273
}
247274

248-
$this->purgeVersionedDrafts($inline);
275+
$this->saveComment($inline);
249276

250277
return $this->buildEmptyResponse();
251278
case 'draft':
@@ -262,6 +289,17 @@ public function processRequest() {
262289
->setProperty('inline.text', $text)
263290
->save();
264291

292+
// We have to synchronize the draft engine after saving a versioned
293+
// draft, because taking an inline comment from "no text, no draft"
294+
// to "no text, text in a draft" marks the container object as having
295+
// a draft.
296+
$draft_engine = $this->newDraftEngine();
297+
if ($draft_engine) {
298+
$draft_engine->synchronize();
299+
} else {
300+
phlog('no draft engine');
301+
}
302+
265303
return $this->buildEmptyResponse();
266304
case 'new':
267305
case 'reply':
@@ -432,14 +470,6 @@ private function newInlineResponse(
432470
->setContent($response);
433471
}
434472

435-
private function purgeVersionedDrafts(
436-
PhabricatorInlineComment $inline) {
437-
$viewer = $this->getViewer();
438-
PhabricatorVersionedDraft::purgeDrafts(
439-
$inline->getPHID(),
440-
$viewer->getPHID());
441-
}
442-
443473
final protected function loadCommentByID($id) {
444474
$query = $this->newInlineCommentQuery()
445475
->withIDs(array($id));
@@ -494,4 +524,35 @@ private function loadCommentByQuery(
494524
return $inline;
495525
}
496526

527+
private function saveComment(PhabricatorInlineComment $inline) {
528+
$viewer = $this->getViewer();
529+
$draft_engine = $this->newDraftEngine();
530+
531+
$inline->openTransaction();
532+
$inline->save();
533+
534+
PhabricatorVersionedDraft::purgeDrafts(
535+
$inline->getPHID(),
536+
$viewer->getPHID());
537+
538+
if ($draft_engine) {
539+
$draft_engine->synchronize();
540+
}
541+
542+
$inline->saveTransaction();
543+
}
544+
545+
private function newDraftEngine() {
546+
$viewer = $this->getViewer();
547+
$object = $this->getContainerObject();
548+
549+
if (!($object instanceof PhabricatorDraftInterface)) {
550+
return null;
551+
}
552+
553+
return $object->newDraftEngine()
554+
->setObject($object)
555+
->setViewer($viewer);
556+
}
557+
497558
}

0 commit comments

Comments
 (0)