1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-10 00:42:41 +01:00

Remove inline gutter in Pholio

Summary: This greatly simplifies inline comments while retaining their functionality. This is probably not where we want to end up, but will let us figure out what we're doing with the stage without worrying about inlines.

Test Plan: See screenshots.

Reviewers: chad

Reviewed By: chad

Subscribers: epriestley

Differential Revision: https://secure.phabricator.com/D9537
This commit is contained in:
epriestley 2014-06-14 18:41:45 -07:00
parent fc2c3a5ca8
commit 942f504893
16 changed files with 256 additions and 936 deletions

View file

@ -81,7 +81,7 @@ return array(
'rsrc/css/application/phame/phame.css' => '19ecc703',
'rsrc/css/application/pholio/pholio-edit.css' => 'b9e59b6d',
'rsrc/css/application/pholio/pholio-inline-comments.css' => '28a2e394',
'rsrc/css/application/pholio/pholio.css' => 'cea40026',
'rsrc/css/application/pholio/pholio.css' => 'cabb65b3',
'rsrc/css/application/phortune/phortune-credit-card-form.css' => 'b25b4beb',
'rsrc/css/application/phrequent/phrequent.css' => 'ffc185ad',
'rsrc/css/application/phriction/phriction-document-css.css' => '7d7f0071',
@ -389,7 +389,7 @@ return array(
'rsrc/js/application/passphrase/phame-credential-control.js' => '1e1c8a59',
'rsrc/js/application/phame/phame-post-preview.js' => '61d927ec',
'rsrc/js/application/pholio/behavior-pholio-mock-edit.js' => '1e1e8bb0',
'rsrc/js/application/pholio/behavior-pholio-mock-view.js' => '9cc93707',
'rsrc/js/application/pholio/behavior-pholio-mock-view.js' => '0c8a037a',
'rsrc/js/application/phortune/behavior-balanced-payment-form.js' => '3b3e1664',
'rsrc/js/application/phortune/behavior-stripe-payment-form.js' => '1693a296',
'rsrc/js/application/phortune/behavior-test-payment-form.js' => 'b3e5ee60',
@ -613,7 +613,7 @@ return array(
'javelin-behavior-phabricator-watch-anchor' => '06e05112',
'javelin-behavior-phame-post-preview' => '61d927ec',
'javelin-behavior-pholio-mock-edit' => '1e1e8bb0',
'javelin-behavior-pholio-mock-view' => '9cc93707',
'javelin-behavior-pholio-mock-view' => '0c8a037a',
'javelin-behavior-phui-object-box-tabs' => 'a3e2244e',
'javelin-behavior-phui-timeline-dropdown-menu' => '4d94d9c3',
'javelin-behavior-policy-control' => 'f3fef818',
@ -739,7 +739,7 @@ return array(
'phabricator-uiexample-reactor-sendproperties' => '551add57',
'phabricator-zindex-css' => 'efb673ac',
'phame-css' => '19ecc703',
'pholio-css' => 'cea40026',
'pholio-css' => 'cabb65b3',
'pholio-edit-css' => 'b9e59b6d',
'pholio-inline-comments-css' => '28a2e394',
'phortune-credit-card-form' => '2290aeef',
@ -896,6 +896,21 @@ return array(
3 => 'javelin-util',
4 => 'phabricator-notification-css',
),
'0c8a037a' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-util',
2 => 'javelin-stratcom',
3 => 'javelin-dom',
4 => 'javelin-vector',
5 => 'javelin-magical-init',
6 => 'javelin-request',
7 => 'javelin-history',
8 => 'javelin-workflow',
9 => 'javelin-mask',
10 => 'javelin-behavior-device',
11 => 'phabricator-keyboard-shortcut',
),
'0e34ca02' =>
array(
0 => 'javelin-behavior',
@ -1254,11 +1269,6 @@ return array(
2 => 'javelin-util',
3 => 'phabricator-shaped-request',
),
'7319e029' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
),
'62e18640' =>
array(
0 => 'javelin-install',
@ -1331,6 +1341,11 @@ return array(
1 => 'javelin-stratcom',
2 => 'javelin-dom',
),
'7319e029' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
),
'76f4ebed' =>
array(
0 => 'javelin-install',
@ -1527,21 +1542,6 @@ return array(
3 => 'javelin-vector',
4 => 'phabricator-hovercard',
),
'9cc93707' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-util',
2 => 'javelin-stratcom',
3 => 'javelin-dom',
4 => 'javelin-vector',
5 => 'javelin-magical-init',
6 => 'javelin-request',
7 => 'javelin-history',
8 => 'javelin-workflow',
9 => 'javelin-mask',
10 => 'javelin-behavior-device',
11 => 'phabricator-keyboard-shortcut',
),
'9db3d160' =>
array(
0 => 'javelin-behavior',

View file

@ -2413,15 +2413,9 @@ phutil_register_library_map(array(
'PholioImageHistoryController' => 'applications/pholio/controller/PholioImageHistoryController.php',
'PholioImageQuery' => 'applications/pholio/query/PholioImageQuery.php',
'PholioImageUploadController' => 'applications/pholio/controller/PholioImageUploadController.php',
'PholioInlineCommentEditView' => 'applications/pholio/view/PholioInlineCommentEditView.php',
'PholioInlineCommentSaveView' => 'applications/pholio/view/PholioInlineCommentSaveView.php',
'PholioInlineCommentView' => 'applications/pholio/view/PholioInlineCommentView.php',
'PholioInlineController' => 'applications/pholio/controller/PholioInlineController.php',
'PholioInlineDeleteController' => 'applications/pholio/controller/PholioInlineDeleteController.php',
'PholioInlineEditController' => 'applications/pholio/controller/PholioInlineEditController.php',
'PholioInlineSaveController' => 'applications/pholio/controller/PholioInlineSaveController.php',
'PholioInlineListController' => 'applications/pholio/controller/PholioInlineListController.php',
'PholioInlineThumbController' => 'applications/pholio/controller/PholioInlineThumbController.php',
'PholioInlineViewController' => 'applications/pholio/controller/PholioInlineViewController.php',
'PholioMock' => 'applications/pholio/storage/PholioMock.php',
'PholioMockCommentController' => 'applications/pholio/controller/PholioMockCommentController.php',
'PholioMockEditController' => 'applications/pholio/controller/PholioMockEditController.php',
@ -5321,15 +5315,9 @@ phutil_register_library_map(array(
'PholioImageHistoryController' => 'PholioController',
'PholioImageQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PholioImageUploadController' => 'PholioController',
'PholioInlineCommentEditView' => 'AphrontView',
'PholioInlineCommentSaveView' => 'AphrontView',
'PholioInlineCommentView' => 'AphrontView',
'PholioInlineController' => 'PholioController',
'PholioInlineDeleteController' => 'PholioController',
'PholioInlineEditController' => 'PholioController',
'PholioInlineSaveController' => 'PholioController',
'PholioInlineListController' => 'PholioController',
'PholioInlineThumbController' => 'PholioController',
'PholioInlineViewController' => 'PholioController',
'PholioMock' =>
array(
0 => 'PholioDAO',

View file

@ -47,11 +47,8 @@ final class PhabricatorApplicationPholio extends PhabricatorApplication {
'edit/(?P<id>\d+)/' => 'PholioMockEditController',
'comment/(?P<id>\d+)/' => 'PholioMockCommentController',
'inline/' => array(
'(?P<id>\d+)/' => 'PholioInlineController',
'save/' => 'PholioInlineSaveController',
'delete/(?P<id>\d+)/' => 'PholioInlineDeleteController',
'view/(?P<id>\d+)/' => 'PholioInlineViewController',
'edit/(?P<id>\d+)/' => 'PholioInlineEditController',
'(?:(?P<id>\d+)/)?' => 'PholioInlineController',
'list/(?P<id>\d+)/' => 'PholioInlineListController',
'thumb/(?P<imageid>\d+)/' => 'PholioInlineThumbController'
),
'image/' => array(

View file

@ -1,46 +1,139 @@
<?php
/**
* @group pholio
*/
final class PholioInlineController extends PholioController {
private $id;
public function willProcessRequest(array $data) {
$this->id = $data['id'];
$this->id = idx($data, 'id');
}
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
$viewer = $request->getUser();
$inline_comments = id(new PholioTransactionComment())->loadAllWhere(
'imageid = %d AND (transactionphid IS NOT NULL
OR (authorphid = %s AND transactionphid IS NULL))',
$this->id,
$user->getPHID());
if ($this->id) {
$inline = id(new PholioTransactionComment())->load($this->id);
if (!$inline) {
return new Aphront404Response();
}
$author_phids = mpull($inline_comments, 'getAuthorPHID');
$authors = $this->loadViewerHandles($author_phids);
if ($inline->getTransactionPHID()) {
$mode = 'view';
} else {
if ($inline->getAuthorPHID() == $viewer->getPHID()) {
$mode = 'edit';
} else {
return new Aphront404Response();
}
}
} else {
$mock = id(new PholioMockQuery())
->setViewer($viewer)
->withIDs(array($request->getInt('mockID')))
->executeOne();
$inlines = array();
if (!$mock) {
return new Aphront404Response();
}
$engine = new PhabricatorMarkupEngine();
$inline = id(new PholioTransactionComment())
->setImageID($request->getInt('imageID'))
->setX($request->getInt('startX'))
->setY($request->getInt('startY'))
->setCommentVersion(1)
->setAuthorPHID($viewer->getPHID())
->setEditPolicy($viewer->getPHID())
->setViewPolicy(PhabricatorPolicies::POLICY_PUBLIC)
->setContentSourceFromRequest($request)
->setWidth($request->getInt('endX') - $request->getInt('startX'))
->setHeight($request->getInt('endY') - $request->getInt('startY'));
foreach ($inline_comments as $inline_comment) {
$inline_view = id(new PholioInlineCommentView())
->setUser($user)
->setHandle($authors[$inline_comment->getAuthorPHID()])
->setInlineComment($inline_comment)
->setEngine($engine);
$inlines[] = $inline_comment->toDictionary() + array(
'contentHTML' => $inline_view->render(),
);
$mode = 'new';
}
return id(new AphrontAjaxResponse())->setContent($inlines);
$v_content = $inline->getContent();
// TODO: Not correct, but we don't always have a mock right now.
$mock_uri = '/';
if ($mode == 'view') {
$handles = $this->loadViewerHandles(array($inline->getAuthorPHID()));
$author_handle = $handles[$inline->getAuthorPHID()];
return $this->newDialog()
->setTitle(pht('Inline Comment'))
->appendParagraph(
phutil_tag(
'em',
array(),
pht('%s comments:', $author_handle->getName())))
->appendParagraph(
PhabricatorMarkupEngine::renderOneObject(
id(new PhabricatorMarkupOneOff())
->setContent($inline->getContent()),
'default',
$viewer))
->addCancelButton($mock_uri, pht('Close'));
}
if ($request->isFormPost()) {
$v_content = $request->getStr('content');
if (strlen($v_content)) {
$inline->setContent($v_content);
$inline->save();
$dictionary = $inline->toDictionary();
} else if ($inline->getID()) {
$inline->delete();
$dictionary = array();
}
return id(new AphrontAjaxResponse())->setContent($dictionary);
}
switch ($mode) {
case 'edit':
$title = pht('Edit Inline Comment');
$submit_text = pht('Save Draft');
break;
case 'new':
$title = pht('New Inline Comment');
$submit_text = pht('Save Draft');
break;
}
$form = id(new AphrontFormView())
->setUser($viewer);
if ($mode == 'new') {
$params = array(
'mockID' => $request->getInt('mockID'),
'imageID' => $request->getInt('imageID'),
'startX' => $request->getInt('startX'),
'startY' => $request->getInt('startY'),
'endX' => $request->getInt('endX'),
'endY' => $request->getInt('endY'),
);
foreach ($params as $key => $value) {
$form->addHiddenInput($key, $value);
}
}
$form
->appendChild(
id(new PhabricatorRemarkupControl())
->setName('content')
->setLabel(pht('Comment'))
->setValue($v_content));
return $this->newDialog()
->setTitle($title)
->setWidth(AphrontDialogView::WIDTH_FORM)
->appendChild($form->buildLayoutView())
->addCancelButton($mock_uri)
->addSubmitButton($submit_text);
}
}

View file

@ -1,34 +0,0 @@
<?php
/**
* @group pholio
*/
final class PholioInlineDeleteController extends PholioController {
private $id;
public function willProcessRequest(array $data) {
$this->id = $data['id'];
}
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
$inline_comment = id(new PholioTransactionComment())->loadOneWhere(
'id = %d AND authorphid = %s AND transactionphid IS NULL',
$this->id,
$user->getPHID());
if ($inline_comment == null) {
return new Aphront404Response();
} else {
$inline_comment->delete();
return id(new AphrontAjaxResponse())
->setContent(array('success' => true));
}
}
}

View file

@ -1,82 +0,0 @@
<?php
/**
* @group pholio
*/
final class PholioInlineEditController extends PholioController {
private $id;
private $operation;
public function getOperation() {
return $this->operation;
}
public function willProcessRequest(array $data) {
$this->id = $data['id'];
}
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
$this->operation = $request->getBool('op');
$inline_comment = id(new PholioTransactionComment())->loadOneWhere(
'id = %d AND authorphid = %s AND transactionphid IS NULL',
$this->id,
$user->getPHID());
if ($inline_comment == null) {
return new Aphront404Response();
}
switch ($this->getOperation()) {
case 'update':
$new_content = $request->getStr('content');
if (strlen(trim($new_content)) == 0) {
return id(new AphrontAjaxResponse())
->setContent(array('success' => false))
->setError(pht('Empty comment'));
}
$inline_comment->setContent($request->getStr('content'));
$inline_comment->save();
return id(new AphrontAjaxResponse())
->setContent(array('success' => true));
default:
$dialog = new PholioInlineCommentEditView();
$dialog->setInlineComment($inline_comment);
$dialog->setUser($user);
$dialog->setSubmitURI($request->getRequestURI());
$dialog->setTitle(pht('Edit inline comment'));
$dialog->addHiddenInput('id', $this->id);
$dialog->addHiddenInput('op', 'edit');
$dialog->appendChild(
$this->renderTextArea($inline_comment->getContent()));
return id(new AphrontAjaxResponse())->setContent($dialog->render());
}
}
private function renderTextArea($text) {
return javelin_tag(
'textarea',
array(
'class' => 'pholio-inline-comment-dialog-textarea',
'name' => 'text',
),
$text);
}
}

View file

@ -0,0 +1,40 @@
<?php
final class PholioInlineListController extends PholioController {
private $id;
public function willProcessRequest(array $data) {
$this->id = $data['id'];
}
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
$image = id(new PholioImageQuery())
->setViewer($user)
->withIDs(array($this->id))
->executeOne();
if (!$image) {
return new Aphront404Response();
}
$inline_comments = id(new PholioTransactionComment())->loadAllWhere(
'imageid = %d AND (transactionphid IS NOT NULL
OR (authorphid = %s AND transactionphid IS NULL))',
$this->id,
$user->getPHID());
$author_phids = mpull($inline_comments, 'getAuthorPHID');
$authors = $this->loadViewerHandles($author_phids);
$inlines = array();
foreach ($inline_comments as $inline_comment) {
$inlines[] = $inline_comment->toDictionary();
}
return id(new AphrontAjaxResponse())->setContent($inlines);
}
}

View file

@ -1,94 +0,0 @@
<?php
/**
* @group pholio
*/
final class PholioInlineSaveController extends PholioController {
private $operation;
public function getOperation() {
return $this->operation;
}
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
$mock = id(new PholioMockQuery())
->setViewer($user)
->withIDs(array($request->getInt('mockID')))
->executeOne();
if (!$mock) {
return new Aphront404Response();
}
$this->operation = $request->getStr('op');
if ($this->getOperation() == 'save') {
$new_content = $request->getStr('text');
if (!strlen($new_content)) {
throw new Exception('Content must not be empty.');
}
$draft = id(new PholioTransactionComment());
$draft->setImageID($request->getInt('imageID'));
$draft->setX($request->getInt('startX'));
$draft->setY($request->getInt('startY'));
$draft->setCommentVersion(1);
$draft->setAuthorPHID($user->getPHID());
$draft->setEditPolicy($user->getPHID());
$draft->setViewPolicy(PhabricatorPolicies::POLICY_PUBLIC);
$draft->setContentSourceFromRequest($request);
$draft->setWidth($request->getInt('endX') - $request->getInt('startX'));
$draft->setHeight($request->getInt('endY') - $request->getInt('startY'));
$draft->setContent($new_content);
$draft->save();
$handle = head($this->loadViewerHandles(array($user->getPHID())));
$inline_view = id(new PholioInlineCommentView())
->setInlineComment($draft)
->setEngine(new PhabricatorMarkupEngine())
->setUser($user)
->setHandle($handle);
return id(new AphrontAjaxResponse())
->setContent(
$draft->toDictionary() + array(
'contentHTML' => $inline_view->render(),
));
} else {
$dialog = new PholioInlineCommentSaveView();
$dialog->setUser($user);
$dialog->setSubmitURI($request->getRequestURI());
$dialog->setTitle(pht('Add Inline Comment'));
$dialog->addHiddenInput('op', 'save');
$dialog->appendChild($this->renderTextArea(''));
return id(new AphrontAjaxResponse())->setContent($dialog->render());
}
}
private function renderTextArea($text) {
return javelin_tag(
'textarea',
array(
'class' => 'pholio-inline-comment-dialog-textarea',
'name' => 'text',
),
$text);
}
}

View file

@ -1,34 +0,0 @@
<?php
/**
* @group pholio
*/
final class PholioInlineViewController extends PholioController {
private $id;
public function willProcessRequest(array $data) {
$this->id = $data['id'];
}
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
$inline_comment = id(new PholioTransactionComment())->load($this->id);
$handle = head($this->loadViewerHandles(
array($inline_comment->getAuthorPHID())));
$inline_view = id(new PholioInlineCommentView())
->setUser($user)
->setHandle($handle)
->setInlineComment($inline_comment)
->setEngine(new PhabricatorMarkupEngine());
return id(new AphrontAjaxResponse())->setContent(
$inline_comment->toDictionary() + array(
'contentHTML' => $inline_view->render(),
));
}
}

View file

@ -1,8 +1,5 @@
<?php
/**
* @group pholio
*/
final class PholioImageQuery
extends PhabricatorCursorPagedPolicyAwareQuery {

View file

@ -21,7 +21,7 @@ final class PholioTransactionComment
return array(
'id' => $this->getID(),
'phid' => $this->getPHID(),
'transactionphid' => $this->getTransactionPHID(),
'transactionPHID' => $this->getTransactionPHID(),
'x' => $this->getX(),
'y' => $this->getY(),
'width' => $this->getWidth(),

View file

@ -1,140 +0,0 @@
<?php
/**
* @group pholio
*/
final class PholioInlineCommentEditView extends AphrontView {
private $inputs = array();
private $uri;
private $title;
private $inlineComment;
public function addHiddenInput($key, $value) {
$this->inputs[] = array($key, $value);
return $this;
}
public function setSubmitURI($uri) {
$this->uri = $uri;
return $this;
}
public function setTitle($title) {
$this->title = $title;
return $this;
}
public function setInlineComment($inline_comment) {
$this->inlineComment = $inline_comment;
return $this;
}
public function render() {
if (!$this->uri) {
throw new Exception('Call setSubmitURI() before render()!');
}
if (!$this->user) {
throw new Exception('Call setUser() before render()!');
}
$content = phabricator_form(
$this->user,
array(
'action' => $this->uri,
'method' => 'POST',
'sigil' => 'inline-edit-form',
),
array(
$this->renderInputs(),
$this->renderBody(),
));
return $content;
}
private function renderInputs() {
$out = array();
foreach ($this->inputs as $input) {
list($name, $value) = $input;
$out[] = phutil_tag(
'input',
array(
'type' => 'hidden',
'name' => $name,
'value' => $value,
));
}
return $out;
}
private function renderBody() {
$buttons = array();
$buttons[] = javelin_tag(
'button',
array(
'sigil' => 'inline-edit-submit',
'meta' => array(
'id' => $this->inlineComment->getID(),
'phid' => $this->inlineComment->getPHID()
)
),
pht('Ready'));
$buttons[] = javelin_tag(
'button',
array(
'sigil' => 'inline-edit-cancel',
'meta' => array(
'id' => $this->inlineComment->getID()
),
'class' => 'grey',
),
pht('Cancel'));
$formatting = phutil_tag(
'a',
array(
'href' => PhabricatorEnv::getDoclink('Remarkup Reference'),
'tabindex' => '-1',
'target' => '_blank',
),
pht('Formatting Reference'));
$title = phutil_tag(
'div',
array(
'class' => 'pholio-inline-comment-dialog-title',
),
$this->title);
$body = phutil_tag(
'div',
array(),
$this->renderChildren());
$edit = phutil_tag(
'edit',
array(
'class' => 'pholio-inline-comment-dialog-buttons',
),
array(
$formatting,
$buttons,
phutil_tag('div', array('style' => 'clear: both'), ''),
));
return javelin_tag(
'div',
array(
'class' => 'pholio-inline-comment-dialog',
),
array(
$title,
$body,
$edit,
));
}
}

View file

@ -1,127 +0,0 @@
<?php
/**
* @group pholio
*/
final class PholioInlineCommentSaveView extends AphrontView {
private $inputs = array();
private $uri;
private $title;
public function addHiddenInput($key, $value) {
$this->inputs[] = array($key, $value);
return $this;
}
public function setSubmitURI($uri) {
$this->uri = $uri;
return $this;
}
public function setTitle($title) {
$this->title = $title;
return $this;
}
public function render() {
if (!$this->uri) {
throw new Exception('Call setSubmitURI() before render()!');
}
if (!$this->user) {
throw new Exception('Call setUser() before render()!');
}
$content = phabricator_form(
$this->user,
array(
'action' => $this->uri,
'method' => 'POST',
'sigil' => 'inline-save-form',
'class' => 'pholio-new-inline-comment',
'id' => 'pholio-new-inline-comment-dialog'
),
array(
$this->renderInputs(),
$this->renderBody(),
));
return $content;
}
private function renderInputs() {
$out = array();
foreach ($this->inputs as $input) {
list($name, $value) = $input;
$out[] = phutil_tag(
'input',
array(
'type' => 'hidden',
'name' => $name,
'value' => $value,
));
}
return $out;
}
private function renderBody() {
$buttons = array();
$buttons[] = javelin_tag(
'button',
array(
'sigil' => 'inline-save-submit',
),
pht('Done'));
$buttons[] = javelin_tag(
'button',
array(
'sigil' => 'inline-save-cancel',
'class' => 'grey',
),
pht('Cancel'));
$formatting = phutil_tag(
'a',
array(
'href' => PhabricatorEnv::getDoclink('Remarkup Reference'),
'tabindex' => '-1',
'target' => '_blank',
),
pht('Formatting Reference'));
$title = phutil_tag(
'div',
array(
'class' => 'pholio-inline-comment-dialog-title',
),
$this->title);
$body = phutil_tag(
'div',
array(),
$this->renderChildren());
$edit = phutil_tag(
'edit',
array(
'class' => 'pholio-inline-comment-dialog-buttons',
),
array(
$formatting,
$buttons,
phutil_tag('div', array('style' => 'clear: both'), ''),
));
return javelin_tag(
'div',
array(
),
array(
$title,
$body,
$edit,
));
}
}

View file

@ -1,136 +0,0 @@
<?php
/**
* @group pholio
*/
final class PholioInlineCommentView extends AphrontView {
private $engine;
private $handle;
private $inlineComment;
public function setEngine(PhabricatorMarkupEngine $engine) {
$this->engine = $engine;
return $this;
}
public function setHandle(PhabricatorObjectHandle $handle) {
$this->handle = $handle;
return $this;
}
public function setInlineComment(PholioTransactionComment $inline_comment) {
if ($inline_comment->getImageID() === null) {
throw new Exception('Comment provided is not inline comment');
}
$this->inlineComment = $inline_comment;
return $this;
}
public function render() {
if (!$this->inlineComment) {
throw new Exception('Call setInlineComment() before render()!');
}
if ($this->user === null) {
throw new Exception('Call setUser() before render()!');
}
if ($this->engine === null) {
throw new Exception('Call setEngine() before render()!');
}
if ($this->handle === null) {
throw new Exception('Call setHandle() before render()!');
}
$actions = null;
$inline = $this->inlineComment;
$phid = $inline->getPHID();
$id = $inline->getID();
$user = $this->user;
$is_draft = ($inline->getTransactionPHID() === null);
$can_edit = PhabricatorPolicyFilter::hasCapability(
$user,
$inline,
PhabricatorPolicyCapability::CAN_EDIT);
if ($is_draft && $can_edit) {
$draft = phutil_tag(
'span',
array(
'class' => 'pholio-inline-status',
),
pht('Not Submitted Yet'));
$edit_action = javelin_tag(
'a',
array(
'href' => '/pholio/inline/edit/'.$id.'/',
'sigil' => 'inline-edit',
'meta' => array(
'phid' => $phid,
'id' => $id,
)
),
pht('Edit'));
$delete_action = javelin_tag(
'a',
array(
'href' => '/pholio/inline/delete/'.$id.'/',
'sigil' => 'inline-delete',
'meta' => array(
'phid' => $phid,
'id' => $id,
)
),
pht('Delete'));
$actions = phutil_tag(
'span',
array(
'class' => 'pholio-inline-head-links'
),
phutil_implode_html(
" \xC2\xB7 ",
array($draft, $edit_action, $delete_action)));
}
$comment_header = phutil_tag(
'div',
array(
'class' => 'pholio-inline-comment-header'
),
array($this->handle->getName(), $actions));
$comment = $this->engine->renderOneObject(
$inline,
PholioTransactionComment::MARKUP_FIELD_COMMENT,
$this->user);
$comment_body = phutil_tag(
'div',
array(),
$comment);
$classes = array();
$classes[] = 'pholio-inline-comment';
if ($is_draft) {
$classes[] = 'pholio-inline-comment-draft';
}
return javelin_tag(
'div',
array(
'id' => "{$phid}_comment",
'class' => implode(' ', $classes),
'sigil' => 'inline_comment',
'meta' => array(
'phid' => $phid,
)
),
array($comment_header, $comment_body));
}
}

View file

@ -148,8 +148,7 @@
}
.pholio-mock-reticle-selection {
background: #ffffff;
opacity: 0.40;
background-color: rgba(255, 255, 255, 0.50);
border: 1px dashed #000;
}
@ -165,7 +164,8 @@
.pholio-mock-reticle-draft:hover,
.pholio-mock-reticle-final:hover {
border: 1px solid rgba(255, 255, 255, 0.50);
background-color: rgba(255, 255, 255, 0.50);
cursor: pointer;
}

View file

@ -34,10 +34,7 @@ JX.behavior('pholio-mock-view', function(config) {
var loading = false;
var stageElement = JX.$(config.panelID);
var viewElement = JX.$(config.viewportID);
var gutterElement = JX.$('mock-inline-comments');
var reticles = [];
var cards = [];
var inline_phid_map = {};
function begin_load() {
if (loading) {
@ -60,17 +57,9 @@ JX.behavior('pholio-mock-view', function(config) {
JX.DOM.alterClass(stageElement, 'pholio-image-loading', loading);
}
function add_inline_node(node, phid) {
inline_phid_map[phid] = (inline_phid_map[phid] || []);
inline_phid_map[phid].push(node);
}
function add_reticle(reticle, phid) {
mark_ref(reticle, phid);
function add_reticle(reticle, id) {
mark_ref(reticle, id);
reticles.push(reticle);
add_inline_node(reticle, phid);
viewElement.appendChild(reticle);
}
@ -79,61 +68,31 @@ JX.behavior('pholio-mock-view', function(config) {
for (ii = 0; ii < reticles.length; ii++) {
JX.DOM.remove(reticles[ii]);
}
for (ii = 0; ii < cards.length; ii++) {
JX.DOM.remove(cards[ii]);
}
reticles = [];
cards = [];
inline_phid_map = {};
}
function highlight_inline(phid, show) {
var nodes = inline_phid_map[phid] || [];
var cls = 'pholio-mock-inline-comment-highlight';
for (var ii = 0; ii < nodes.length; ii++) {
JX.DOM.alterClass(nodes[ii], cls, show);
}
}
function remove_inline(phid) {
var nodes = inline_phid_map[phid] || [];
for (var ii = 0; ii < nodes.length; ii++) {
JX.DOM.remove(nodes[ii]);
}
delete inline_phid_map[phid];
}
function mark_ref(node, phid) {
function mark_ref(node, id) {
JX.Stratcom.addSigil(node, 'pholio-inline-ref');
JX.Stratcom.addData(node, {phid: phid});
}
function add_card(card, phid) {
mark_ref(card, phid);
cards.push(card);
add_inline_node(card, phid);
gutterElement.appendChild(card);
JX.Stratcom.addData(node, {inlineID: id});
}
return {
beginLoad: begin_load,
endLoad: end_load,
addReticle: add_reticle,
clearStage: clear_stage,
highlightInline: highlight_inline,
removeInline: remove_inline,
addCard: add_card
clearStage: clear_stage
};
})();
JX.enableDispatch(document.body, 'mouseenter');
JX.enableDispatch(document.body, 'mouseleave');
JX.Stratcom.listen('mouseenter', 'mock-panel', function(e) {
JX.DOM.alterClass(e.getNode('mock-panel'), 'mock-has-cursor', true);
});
JX.Stratcom.listen(
['mouseenter', 'mouseover'],
'mock-panel',
function(e) {
JX.DOM.alterClass(e.getNode('mock-panel'), 'mock-has-cursor', true);
});
JX.Stratcom.listen('mouseleave', 'mock-panel', function(e) {
var node = e.getNode('mock-panel');
@ -248,7 +207,6 @@ JX.behavior('pholio-mock-view', function(config) {
}
load_inline_comments();
if (image_id != config.selectedID) {
JX.History.replace(active_image.pageURI);
}
@ -280,7 +238,11 @@ JX.behavior('pholio-mock-view', function(config) {
return;
}
if (drag_begin) {
if (JX.Stratcom.pass()) {
return;
}
if (is_dragging) {
return;
}
@ -304,12 +266,35 @@ JX.behavior('pholio-mock-view', function(config) {
});
JX.Stratcom.listen(
['mouseover', 'mouseout'],
'mousedown',
'pholio-inline-ref',
function(e) {
var phid = e.getNodeData('pholio-inline-ref').phid;
var show = (e.getType() == 'mouseover');
stage.highlightInline(phid, show);
e.kill();
var id = e.getNodeData('pholio-inline-ref').inlineID;
var active_id = active_image.id;
var handler = function(r) {
var inlines = inline_comments[active_id];
for (var ii = 0; ii < inlines.length; ii++) {
if (inlines[ii].id == id) {
if (r.id) {
inlines[ii] = r;
} else {
inlines.splice(ii, 1);
}
break;
}
}
redraw_inlines(active_id);
JX.DOM.invoke(JX.$(config.commentFormID), 'shouldRefresh');
};
new JX.Workflow('/pholio/inline/' + id + '/')
.setHandler(handler)
.start();
});
JX.Stratcom.listen(
@ -331,19 +316,28 @@ JX.behavior('pholio-mock-view', function(config) {
resize_selection(16);
var data = {mockID: config.mockID};
var handler = function(r) {
var dialog = JX.$H(r).getFragment().firstChild;
JX.DOM.appendContent(viewport, dialog);
var x = Math.min(drag_begin.x * scale, drag_end.x * scale);
var y = Math.max(drag_begin.y * scale, drag_end.y * scale) + 4;
JX.$V(x, y).setPos(dialog);
JX.DOM.focus(JX.DOM.find(dialog, 'textarea'));
var data = {
mockID: config.mockID,
imageID: active_image.id,
startX: Math.min(drag_begin.x, drag_end.x),
startY: Math.min(drag_begin.y, drag_end.y),
endX: Math.max(drag_begin.x, drag_end.x),
endY: Math.max(drag_begin.y, drag_end.y)
};
new JX.Workflow('/pholio/inline/save/', data)
var handler = function(r) {
if (!inline_comments[active_image.id]) {
inline_comments[active_image.id] = [];
}
inline_comments[active_image.id].push(r);
redraw_inlines(active_image.id);
JX.DOM.invoke(JX.$(config.commentFormID), 'shouldRefresh');
};
clear_selection();
new JX.Workflow('/pholio/inline/', data)
.setHandler(handler)
.start();
});
@ -413,9 +407,6 @@ JX.behavior('pholio-mock-view', function(config) {
for (var ii = 0; ii < inlines.length; ii++) {
var inline = inlines[ii];
var card = JX.$H(inline.contentHTML).getFragment().firstChild;
stage.addCard(card, inline.phid);
if (!active_image.tag) {
// The image itself hasn't loaded yet, so we can't draw the inline
@ -424,14 +415,14 @@ JX.behavior('pholio-mock-view', function(config) {
}
var classes = [];
if (!inline.transactionphid) {
if (!inline.transactionPHID) {
classes.push('pholio-mock-reticle-draft');
} else {
classes.push('pholio-mock-reticle-final');
}
var inline_selection = render_reticle(classes);
stage.addReticle(inline_selection, inline.phid);
stage.addReticle(inline_selection, inline.id);
position_inline_rectangle(inline, inline_selection);
}
}
@ -496,7 +487,7 @@ JX.behavior('pholio-mock-view', function(config) {
function load_inline_comments() {
var id = active_image.id;
var inline_comments_uri = "/pholio/inline/" + id + "/";
var inline_comments_uri = '/pholio/inline/list/' + id + '/';
new JX.Request(inline_comments_uri, function(r) {
inline_comments[id] = r;
@ -504,145 +495,6 @@ JX.behavior('pholio-mock-view', function(config) {
}).send();
}
JX.Stratcom.listen(
'click',
'inline-delete',
function(e) {
var data = e.getNodeData('inline-delete');
e.kill();
interrupt_typing();
stage.removeInline(data.phid);
var deleteURI = '/pholio/inline/delete/' + data.id + '/';
var del = new JX.Request(deleteURI, function(r) {
});
del.send();
});
JX.Stratcom.listen(
'click',
'inline-edit',
function(e) {
var data = e.getNodeData('inline-edit');
e.kill();
interrupt_typing();
var editURI = "/pholio/inline/edit/" + data.id + '/';
var edit_dialog = new JX.Request(editURI, function(r) {
var dialog = JX.$N(
'div',
{
className: 'pholio-edit-inline-popup'
},
JX.$H(r));
JX.DOM.setContent(JX.$(data.phid + '_comment'), dialog);
});
edit_dialog.send();
});
JX.Stratcom.listen(
'click',
'inline-edit-cancel',
function(e) {
var data = e.getNodeData('inline-edit-cancel');
e.kill();
load_inline_comment(data.id);
});
JX.Stratcom.listen(
'click',
'inline-edit-submit',
function(e) {
var data = e.getNodeData('inline-edit-submit');
var editURI = "/pholio/inline/edit/" + data.id + '/';
e.kill();
var edit = new JX.Request(editURI, function(r) {
load_inline_comment(data.id);
JX.DOM.invoke(JX.$(config.commentFormID), 'shouldRefresh');
});
edit.addData({
op: 'update',
content: JX.DOM.find(JX.$(data.phid + '_comment'), 'textarea').value
});
edit.send();
});
JX.Stratcom.listen(
'click',
'inline-save-cancel',
function(e) {
e.kill();
interrupt_typing();
}
);
JX.Stratcom.listen(
'click',
'inline-save-submit',
function(e) {
e.kill();
var form = JX.$('pholio-new-inline-comment-dialog');
var text = JX.DOM.find(form, 'textarea').value;
if (!text.length) {
interrupt_typing();
return;
}
var data = {
mockID: config.mockID,
imageID: active_image.id,
startX: Math.min(drag_begin.x, drag_end.x),
startY: Math.min(drag_begin.y, drag_end.y),
endX: Math.max(drag_begin.x, drag_end.x),
endY: Math.max(drag_begin.y, drag_end.y)
};
var handler = function(r) {
if (!inline_comments[active_image.id]) {
inline_comments[active_image.id] = [];
}
inline_comments[active_image.id].push(r);
interrupt_typing();
redraw_inlines(active_image.id);
JX.DOM.invoke(JX.$(config.commentFormID), 'shouldRefresh');
};
JX.Workflow.newFromForm(form, data)
.setHandler(handler)
.start();
}
);
function load_inline_comment(id) {
var viewInlineURI = '/pholio/inline/view/' + id + '/';
var inline_comment = new JX.Request(viewInlineURI, function(r) {
JX.DOM.replace(JX.$(r.phid + '_comment'), JX.$H(r.contentHTML));
});
inline_comment.send();
}
function interrupt_typing() {
clear_selection();
try {
JX.DOM.remove(JX.$('pholio-new-inline-comment-dialog'));
} catch (x) {
// TODO: For now, ignore this.
}
drag_begin = null;
}
load_inline_comments();
if (config.loggedIn && config.commentFormID) {
JX.DOM.invoke(JX.$(config.commentFormID), 'shouldRefresh');