1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-19 03:50:54 +01:00

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
This commit is contained in:
epriestley 2016-06-06 15:05:48 -07:00
parent d1999557dc
commit fb2da8bd8b
5 changed files with 157 additions and 11 deletions

View file

@ -3,11 +3,16 @@
final class PhabricatorApplicationTransactionDetailController
extends PhabricatorApplicationTransactionController {
private $objectHandle;
public function shouldAllowPublic() {
return true;
}
public function handleRequest(AphrontRequest $request) {
// Users can end up on this page directly by following links in email,
// so we try to make it somewhat reasonable as a standalone page.
$viewer = $this->getViewer();
$phid = $request->getURIData('phid');
@ -20,13 +25,39 @@ final class PhabricatorApplicationTransactionDetailController
}
$details = $xaction->renderChangeDetails($viewer);
$cancel_uri = $this->guessCancelURI($viewer, $xaction);
$object_phid = $xaction->getObjectPHID();
$handles = $viewer->loadHandles(array($object_phid));
$handle = $handles[$object_phid];
$this->objectHandle = $handle;
$cancel_uri = $handle->getURI();
if ($request->isAjax()) {
$button_text = pht('Done');
} else {
$button_text = pht('Continue');
}
return $this->newDialog()
->setTitle(pht('Change Details'))
->setWidth(AphrontDialogView::WIDTH_FORM)
->appendChild($details)
->addCancelButton($cancel_uri);
->addCancelButton($cancel_uri, $button_text);
}
protected function buildApplicationCrumbs() {
$crumbs = parent::buildApplicationCrumbs();
$handle = $this->objectHandle;
if ($handle) {
$crumbs->addTextCrumb(
$handle->getObjectName(),
$handle->getURI());
}
return $crumbs;
}
}

View file

@ -2704,7 +2704,9 @@ abstract class PhabricatorApplicationTransactionEditor
$object_href = null) {
$headers = array();
$headers_html = array();
$comments = array();
$details = array();
foreach ($xactions as $xaction) {
if ($xaction->shouldHideForMail($xactions)) {
@ -2716,16 +2718,25 @@ abstract class PhabricatorApplicationTransactionEditor
$headers[] = $header;
}
$header_html = $xaction->getTitleForHTMLMail();
if ($header_html !== null) {
$headers_html[] = $header_html;
}
$comment = $xaction->getBodyForMail();
if ($comment !== null) {
$comments[] = $comment;
}
if ($xaction->hasChangeDetailsForMail()) {
$details[] = $xaction;
}
}
$headers_text = implode("\n", $headers);
$body->addRawPlaintextSection($headers_text);
$headers_html = phutil_implode_html(phutil_tag('br'), $headers);
$headers_html = phutil_implode_html(phutil_tag('br'), $headers_html);
$header_button = null;
if ($object_label !== null) {
@ -2765,7 +2776,13 @@ abstract class PhabricatorApplicationTransactionEditor
array(
'style' => implode(' ', $xactions_style),
),
$headers_html);
array(
$headers_html,
// Add an extra newline to prevent the "View Object" button from
// running into the transaction text in Mail.app text snippet
// previews.
"\n",
));
$headers_html = phutil_tag(
'table',
@ -2777,6 +2794,14 @@ abstract class PhabricatorApplicationTransactionEditor
foreach ($comments as $comment) {
$body->addRemarkupSection(null, $comment);
}
foreach ($details as $xaction) {
$details = $xaction->renderChangeDetailsForMail($body->getViewer());
if ($details !== null) {
$body->addHTMLSection(pht('EDIT DETAILS'), $details);
}
}
}
/**

View file

@ -693,6 +693,33 @@ abstract class PhabricatorApplicationTransaction
return id(clone $this)->setRenderingTarget('text')->getTitle();
}
public function getTitleForHTMLMail() {
$title = $this->getTitleForMail();
if ($title === null) {
return null;
}
if ($this->hasChangeDetails()) {
$details_uri = $this->getChangeDetailsURI();
$details_uri = PhabricatorEnv::getProductionURI($details_uri);
$show_details = phutil_tag(
'a',
array(
'href' => $details_uri,
),
pht('(Show Details)'));
$title = array($title, ' ', $show_details);
}
return $title;
}
public function getChangeDetailsURI() {
return '/transactions/detail/'.$this->getPHID().'/';
}
public function getBodyForMail() {
if ($this->isInlineCommentTransaction()) {
// We don't return inline comment content as mail body content, because
@ -1307,6 +1334,18 @@ abstract class PhabricatorApplicationTransaction
return false;
}
public function hasChangeDetailsForMail() {
return $this->hasChangeDetails();
}
public function renderChangeDetailsForMail(PhabricatorUser $viewer) {
$view = $this->renderChangeDetails($viewer);
if ($view instanceof PhabricatorApplicationTransactionTextDiffDetailView) {
return $view->renderForMail();
}
return null;
}
public function renderChangeDetails(PhabricatorUser $viewer) {
switch ($this->getTransactionType()) {
case PhabricatorTransactions::TYPE_CUSTOMFIELD:
@ -1327,15 +1366,10 @@ abstract class PhabricatorApplicationTransaction
PhabricatorUser $viewer,
$old,
$new) {
require_celerity_resource('differential-changeset-view-css');
$view = id(new PhabricatorApplicationTransactionTextDiffDetailView())
return id(new PhabricatorApplicationTransactionTextDiffDetailView())
->setUser($viewer)
->setOldText($old)
->setNewText($new);
return $view->render();
}
public function attachTransactionGroup(array $group) {

View file

@ -16,6 +16,62 @@ final class PhabricatorApplicationTransactionTextDiffDetailView
return $this;
}
public function renderForMail() {
$diff = $this->buildDiff();
$old_styles = array(
'padding: 0 2px;',
'color: #802b2b;',
'background: rgba(251, 175, 175, .7);',
);
$old_styles = implode(' ', $old_styles);
$new_styles = array(
'padding: 0 2px;',
'color: #3e6d35;',
'background: rgba(151, 234, 151, .6);',
);
$new_styles = implode(' ', $new_styles);
$result = array();
foreach ($diff->getParts() as $part) {
$type = $part['type'];
$text = $part['text'];
switch ($type) {
case '-':
$result[] = phutil_tag(
'span',
array(
'style' => $old_styles,
),
$text);
break;
case '+':
$result[] = phutil_tag(
'span',
array(
'style' => $new_styles,
),
$text);
break;
case '=':
$result[] = $text;
break;
}
}
$styles = array(
'white-space: pre-wrap;',
);
return phutil_tag(
'div',
array(
'style' => implode(' ', $styles),
),
$result);
}
public function render() {
$diff = $this->buildDiff();

View file

@ -259,7 +259,7 @@ class PhabricatorApplicationTransactionView extends AphrontView {
return javelin_tag(
'a',
array(
'href' => '/transactions/detail/'.$xaction->getPHID().'/',
'href' => $xaction->getChangeDetailsURI(),
'sigil' => 'workflow',
),
pht('(Show Details)'));