@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add links and diffs for text block edits to mail

Summary:
Ref T7643.

- When a transaction edits a text block, add a link to the changes (for HTML mail).
- Also, inline the changes in the mail (for HTML mail).
- Do nothing for text mail since I don't think we really have room? And I don't know how we can make the diff look any good.

Test Plan:
Edited a task description, generated mail, examined mail.

- It contained a link leading to a prose diff.
- It had a more-or-less reasonable inline text diff.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T7643

Differential Revision: https://secure.phabricator.com/D16063

+157 -11
+33 -2
src/applications/transactions/controller/PhabricatorApplicationTransactionDetailController.php
··· 3 3 final class PhabricatorApplicationTransactionDetailController 4 4 extends PhabricatorApplicationTransactionController { 5 5 6 + private $objectHandle; 7 + 6 8 public function shouldAllowPublic() { 7 9 return true; 8 10 } 9 11 10 12 public function handleRequest(AphrontRequest $request) { 13 + // Users can end up on this page directly by following links in email, 14 + // so we try to make it somewhat reasonable as a standalone page. 15 + 11 16 $viewer = $this->getViewer(); 12 17 $phid = $request->getURIData('phid'); 13 18 ··· 20 25 } 21 26 22 27 $details = $xaction->renderChangeDetails($viewer); 23 - $cancel_uri = $this->guessCancelURI($viewer, $xaction); 28 + 29 + $object_phid = $xaction->getObjectPHID(); 30 + $handles = $viewer->loadHandles(array($object_phid)); 31 + $handle = $handles[$object_phid]; 32 + $this->objectHandle = $handle; 33 + 34 + $cancel_uri = $handle->getURI(); 35 + 36 + if ($request->isAjax()) { 37 + $button_text = pht('Done'); 38 + } else { 39 + $button_text = pht('Continue'); 40 + } 24 41 25 42 return $this->newDialog() 26 43 ->setTitle(pht('Change Details')) 27 44 ->setWidth(AphrontDialogView::WIDTH_FORM) 28 45 ->appendChild($details) 29 - ->addCancelButton($cancel_uri); 46 + ->addCancelButton($cancel_uri, $button_text); 47 + } 48 + 49 + protected function buildApplicationCrumbs() { 50 + $crumbs = parent::buildApplicationCrumbs(); 51 + 52 + $handle = $this->objectHandle; 53 + if ($handle) { 54 + $crumbs->addTextCrumb( 55 + $handle->getObjectName(), 56 + $handle->getURI()); 57 + } 58 + 59 + return $crumbs; 30 60 } 61 + 31 62 32 63 }
+27 -2
src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php
··· 2704 2704 $object_href = null) { 2705 2705 2706 2706 $headers = array(); 2707 + $headers_html = array(); 2707 2708 $comments = array(); 2709 + $details = array(); 2708 2710 2709 2711 foreach ($xactions as $xaction) { 2710 2712 if ($xaction->shouldHideForMail($xactions)) { ··· 2714 2716 $header = $xaction->getTitleForMail(); 2715 2717 if ($header !== null) { 2716 2718 $headers[] = $header; 2719 + } 2720 + 2721 + $header_html = $xaction->getTitleForHTMLMail(); 2722 + if ($header_html !== null) { 2723 + $headers_html[] = $header_html; 2717 2724 } 2718 2725 2719 2726 $comment = $xaction->getBodyForMail(); 2720 2727 if ($comment !== null) { 2721 2728 $comments[] = $comment; 2722 2729 } 2730 + 2731 + if ($xaction->hasChangeDetailsForMail()) { 2732 + $details[] = $xaction; 2733 + } 2723 2734 } 2724 2735 2725 2736 $headers_text = implode("\n", $headers); 2726 2737 $body->addRawPlaintextSection($headers_text); 2727 2738 2728 - $headers_html = phutil_implode_html(phutil_tag('br'), $headers); 2739 + $headers_html = phutil_implode_html(phutil_tag('br'), $headers_html); 2729 2740 2730 2741 $header_button = null; 2731 2742 if ($object_label !== null) { ··· 2765 2776 array( 2766 2777 'style' => implode(' ', $xactions_style), 2767 2778 ), 2768 - $headers_html); 2779 + array( 2780 + $headers_html, 2781 + // Add an extra newline to prevent the "View Object" button from 2782 + // running into the transaction text in Mail.app text snippet 2783 + // previews. 2784 + "\n", 2785 + )); 2769 2786 2770 2787 $headers_html = phutil_tag( 2771 2788 'table', ··· 2777 2794 foreach ($comments as $comment) { 2778 2795 $body->addRemarkupSection(null, $comment); 2779 2796 } 2797 + 2798 + foreach ($details as $xaction) { 2799 + $details = $xaction->renderChangeDetailsForMail($body->getViewer()); 2800 + if ($details !== null) { 2801 + $body->addHTMLSection(pht('EDIT DETAILS'), $details); 2802 + } 2803 + } 2804 + 2780 2805 } 2781 2806 2782 2807 /**
+40 -6
src/applications/transactions/storage/PhabricatorApplicationTransaction.php
··· 693 693 return id(clone $this)->setRenderingTarget('text')->getTitle(); 694 694 } 695 695 696 + public function getTitleForHTMLMail() { 697 + $title = $this->getTitleForMail(); 698 + if ($title === null) { 699 + return null; 700 + } 701 + 702 + if ($this->hasChangeDetails()) { 703 + $details_uri = $this->getChangeDetailsURI(); 704 + $details_uri = PhabricatorEnv::getProductionURI($details_uri); 705 + 706 + $show_details = phutil_tag( 707 + 'a', 708 + array( 709 + 'href' => $details_uri, 710 + ), 711 + pht('(Show Details)')); 712 + 713 + $title = array($title, ' ', $show_details); 714 + } 715 + 716 + return $title; 717 + } 718 + 719 + public function getChangeDetailsURI() { 720 + return '/transactions/detail/'.$this->getPHID().'/'; 721 + } 722 + 696 723 public function getBodyForMail() { 697 724 if ($this->isInlineCommentTransaction()) { 698 725 // We don't return inline comment content as mail body content, because ··· 1307 1334 return false; 1308 1335 } 1309 1336 1337 + public function hasChangeDetailsForMail() { 1338 + return $this->hasChangeDetails(); 1339 + } 1340 + 1341 + public function renderChangeDetailsForMail(PhabricatorUser $viewer) { 1342 + $view = $this->renderChangeDetails($viewer); 1343 + if ($view instanceof PhabricatorApplicationTransactionTextDiffDetailView) { 1344 + return $view->renderForMail(); 1345 + } 1346 + return null; 1347 + } 1348 + 1310 1349 public function renderChangeDetails(PhabricatorUser $viewer) { 1311 1350 switch ($this->getTransactionType()) { 1312 1351 case PhabricatorTransactions::TYPE_CUSTOMFIELD: ··· 1327 1366 PhabricatorUser $viewer, 1328 1367 $old, 1329 1368 $new) { 1330 - 1331 - require_celerity_resource('differential-changeset-view-css'); 1332 - 1333 - $view = id(new PhabricatorApplicationTransactionTextDiffDetailView()) 1369 + return id(new PhabricatorApplicationTransactionTextDiffDetailView()) 1334 1370 ->setUser($viewer) 1335 1371 ->setOldText($old) 1336 1372 ->setNewText($new); 1337 - 1338 - return $view->render(); 1339 1373 } 1340 1374 1341 1375 public function attachTransactionGroup(array $group) {
+56
src/applications/transactions/view/PhabricatorApplicationTransactionTextDiffDetailView.php
··· 16 16 return $this; 17 17 } 18 18 19 + public function renderForMail() { 20 + $diff = $this->buildDiff(); 21 + 22 + $old_styles = array( 23 + 'padding: 0 2px;', 24 + 'color: #802b2b;', 25 + 'background: rgba(251, 175, 175, .7);', 26 + ); 27 + $old_styles = implode(' ', $old_styles); 28 + 29 + $new_styles = array( 30 + 'padding: 0 2px;', 31 + 'color: #3e6d35;', 32 + 'background: rgba(151, 234, 151, .6);', 33 + ); 34 + $new_styles = implode(' ', $new_styles); 35 + 36 + $result = array(); 37 + foreach ($diff->getParts() as $part) { 38 + $type = $part['type']; 39 + $text = $part['text']; 40 + switch ($type) { 41 + case '-': 42 + $result[] = phutil_tag( 43 + 'span', 44 + array( 45 + 'style' => $old_styles, 46 + ), 47 + $text); 48 + break; 49 + case '+': 50 + $result[] = phutil_tag( 51 + 'span', 52 + array( 53 + 'style' => $new_styles, 54 + ), 55 + $text); 56 + break; 57 + case '=': 58 + $result[] = $text; 59 + break; 60 + } 61 + } 62 + 63 + $styles = array( 64 + 'white-space: pre-wrap;', 65 + ); 66 + 67 + return phutil_tag( 68 + 'div', 69 + array( 70 + 'style' => implode(' ', $styles), 71 + ), 72 + $result); 73 + } 74 + 19 75 public function render() { 20 76 $diff = $this->buildDiff(); 21 77
+1 -1
src/applications/transactions/view/PhabricatorApplicationTransactionView.php
··· 259 259 return javelin_tag( 260 260 'a', 261 261 array( 262 - 'href' => '/transactions/detail/'.$xaction->getPHID().'/', 262 + 'href' => $xaction->getChangeDetailsURI(), 263 263 'sigil' => 'workflow', 264 264 ), 265 265 pht('(Show Details)'));