mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-10 08:52:39 +01:00
Allow ApplicationTransaction comments to be edited and deleted
Summary: Allows you to edit or delete comments in appplications which support ApplicationTransactions. UI/UX stuff: - The dialogs are rough but I want to do a dialog design pass more generally, @chad has some mocks. - When you add new mentions via edit, they don't currently count as mentions. I'm not sure what I want to do about this. - When you edit or delete a comment, we do not publish any notifications about it. I think this is reasonable. - I didn't separate "delete" out versus "edit"; I assume it will be reasonably intuitive that deleting all the text deletes effectively deletes the comment. I also want to discourage deletion somewhat (we still show the transaction, just show that the comment has been deleted). Test Plan: Transaction view, note "Edit" and "Edited" links: {F26914} Edit view, has some design issues but I want to do a pass on dialogs in general: {F26915} History view: {F26913} Reviewers: vrana, btrahan, chad Reviewed By: vrana CC: aran Maniphest Tasks: T1082 Differential Revision: https://secure.phabricator.com/D4149
This commit is contained in:
parent
93938765c3
commit
26dd2a0eef
13 changed files with 295 additions and 24 deletions
|
@ -599,8 +599,11 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorApplicationSubscriptions' => 'applications/subscriptions/application/PhabricatorApplicationSubscriptions.php',
|
'PhabricatorApplicationSubscriptions' => 'applications/subscriptions/application/PhabricatorApplicationSubscriptions.php',
|
||||||
'PhabricatorApplicationTransaction' => 'applications/transactions/storage/PhabricatorApplicationTransaction.php',
|
'PhabricatorApplicationTransaction' => 'applications/transactions/storage/PhabricatorApplicationTransaction.php',
|
||||||
'PhabricatorApplicationTransactionComment' => 'applications/transactions/storage/PhabricatorApplicationTransactionComment.php',
|
'PhabricatorApplicationTransactionComment' => 'applications/transactions/storage/PhabricatorApplicationTransactionComment.php',
|
||||||
|
'PhabricatorApplicationTransactionCommentEditController' => 'applications/transactions/controller/PhabricatorApplicationTransactionCommentEditController.php',
|
||||||
'PhabricatorApplicationTransactionCommentEditor' => 'applications/transactions/editor/PhabricatorApplicationTransactionCommentEditor.php',
|
'PhabricatorApplicationTransactionCommentEditor' => 'applications/transactions/editor/PhabricatorApplicationTransactionCommentEditor.php',
|
||||||
|
'PhabricatorApplicationTransactionCommentHistoryController' => 'applications/transactions/controller/PhabricatorApplicationTransactionCommentHistoryController.php',
|
||||||
'PhabricatorApplicationTransactionCommentQuery' => 'applications/transactions/query/PhabricatorApplicationTransactionCommentQuery.php',
|
'PhabricatorApplicationTransactionCommentQuery' => 'applications/transactions/query/PhabricatorApplicationTransactionCommentQuery.php',
|
||||||
|
'PhabricatorApplicationTransactionController' => 'applications/transactions/controller/PhabricatorApplicationTransactionController.php',
|
||||||
'PhabricatorApplicationTransactionEditor' => 'applications/transactions/editor/PhabricatorApplicationTransactionEditor.php',
|
'PhabricatorApplicationTransactionEditor' => 'applications/transactions/editor/PhabricatorApplicationTransactionEditor.php',
|
||||||
'PhabricatorApplicationTransactionFeedStory' => 'applications/transactions/feed/PhabricatorApplicationTransactionFeedStory.php',
|
'PhabricatorApplicationTransactionFeedStory' => 'applications/transactions/feed/PhabricatorApplicationTransactionFeedStory.php',
|
||||||
'PhabricatorApplicationTransactionQuery' => 'applications/transactions/query/PhabricatorApplicationTransactionQuery.php',
|
'PhabricatorApplicationTransactionQuery' => 'applications/transactions/query/PhabricatorApplicationTransactionQuery.php',
|
||||||
|
@ -1873,8 +1876,11 @@ phutil_register_library_map(array(
|
||||||
1 => 'PhabricatorMarkupInterface',
|
1 => 'PhabricatorMarkupInterface',
|
||||||
2 => 'PhabricatorPolicyInterface',
|
2 => 'PhabricatorPolicyInterface',
|
||||||
),
|
),
|
||||||
|
'PhabricatorApplicationTransactionCommentEditController' => 'PhabricatorApplicationTransactionController',
|
||||||
'PhabricatorApplicationTransactionCommentEditor' => 'PhabricatorEditor',
|
'PhabricatorApplicationTransactionCommentEditor' => 'PhabricatorEditor',
|
||||||
|
'PhabricatorApplicationTransactionCommentHistoryController' => 'PhabricatorApplicationTransactionController',
|
||||||
'PhabricatorApplicationTransactionCommentQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
'PhabricatorApplicationTransactionCommentQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||||
|
'PhabricatorApplicationTransactionController' => 'PhabricatorController',
|
||||||
'PhabricatorApplicationTransactionEditor' => 'PhabricatorEditor',
|
'PhabricatorApplicationTransactionEditor' => 'PhabricatorEditor',
|
||||||
'PhabricatorApplicationTransactionFeedStory' => 'PhabricatorFeedStory',
|
'PhabricatorApplicationTransactionFeedStory' => 'PhabricatorFeedStory',
|
||||||
'PhabricatorApplicationTransactionQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
'PhabricatorApplicationTransactionQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||||
|
|
|
@ -8,6 +8,12 @@ final class PhabricatorApplicationTransactions extends PhabricatorApplication {
|
||||||
|
|
||||||
public function getRoutes() {
|
public function getRoutes() {
|
||||||
return array(
|
return array(
|
||||||
|
'/transactions/' => array(
|
||||||
|
'edit/(?<phid>[^/]+)/'
|
||||||
|
=> 'PhabricatorApplicationTransactionCommentEditController',
|
||||||
|
'history/(?<phid>[^/]+)/'
|
||||||
|
=> 'PhabricatorApplicationTransactionCommentHistoryController',
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorApplicationTransactionCommentEditController
|
||||||
|
extends PhabricatorApplicationTransactionController {
|
||||||
|
|
||||||
|
private $phid;
|
||||||
|
private $anchor;
|
||||||
|
|
||||||
|
public function willProcessRequest(array $data) {
|
||||||
|
$this->phid = $data['phid'];
|
||||||
|
$this->anchor = idx($data, 'anchor');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function processRequest() {
|
||||||
|
$request = $this->getRequest();
|
||||||
|
$user = $request->getUser();
|
||||||
|
|
||||||
|
$xactions = id(new PhabricatorObjectHandleData(array($this->phid)))
|
||||||
|
->setViewer($user)
|
||||||
|
->loadObjects();
|
||||||
|
$xaction = idx($xactions, $this->phid);
|
||||||
|
|
||||||
|
if (!$xaction) {
|
||||||
|
// TODO: This may also mean you don't have permission to edit the object,
|
||||||
|
// but we can't make that distinction via PhabricatorObjectHandleData
|
||||||
|
// at the moment.
|
||||||
|
return new Aphront404Response();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$xaction->getComment()) {
|
||||||
|
// You can't currently edit a transaction which doesn't have a comment.
|
||||||
|
// Some day you may be able to edit the visibility.
|
||||||
|
return new Aphront404Response();
|
||||||
|
}
|
||||||
|
|
||||||
|
$obj_phid = $xaction->getObjectPHID();
|
||||||
|
$obj_handle = PhabricatorObjectHandleData::loadOneHandle($obj_phid, $user);
|
||||||
|
if (!$obj_handle) {
|
||||||
|
// Require the corresponding object exist and be visible to the user.
|
||||||
|
return new Aphront404Response();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request->isDialogFormPost()) {
|
||||||
|
$text = $request->getStr('text');
|
||||||
|
|
||||||
|
$comment = $xaction->getApplicationTransactionCommentObject();
|
||||||
|
$comment->setContent($text);
|
||||||
|
if (!strlen($text)) {
|
||||||
|
$comment->setIsDeleted(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
$editor = id(new PhabricatorApplicationTransactionCommentEditor())
|
||||||
|
->setActor($user)
|
||||||
|
->setContentSource(
|
||||||
|
$content_source = PhabricatorContentSource::newForSource(
|
||||||
|
PhabricatorContentSource::SOURCE_WEB,
|
||||||
|
array(
|
||||||
|
'ip' => $request->getRemoteAddr(),
|
||||||
|
)))
|
||||||
|
->applyEdit($xaction, $comment);
|
||||||
|
|
||||||
|
return id(new AphrontReloadResponse())->setURI($obj_handle->getURI());
|
||||||
|
}
|
||||||
|
|
||||||
|
$dialog = id(new AphrontDialogView())
|
||||||
|
->setUser($user)
|
||||||
|
->setTitle(pht('Edit Comment'));
|
||||||
|
|
||||||
|
$dialog
|
||||||
|
->appendChild(
|
||||||
|
id(new PhabricatorRemarkupControl())
|
||||||
|
->setName('text')
|
||||||
|
->setValue($xaction->getComment()->getContent()));
|
||||||
|
|
||||||
|
$dialog
|
||||||
|
->addSubmitButton(pht('Edit Comment'))
|
||||||
|
->addCancelButton($obj_handle->getURI());
|
||||||
|
|
||||||
|
return id(new AphrontDialogResponse())->setDialog($dialog);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,81 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorApplicationTransactionCommentHistoryController
|
||||||
|
extends PhabricatorApplicationTransactionController {
|
||||||
|
|
||||||
|
private $phid;
|
||||||
|
|
||||||
|
public function willProcessRequest(array $data) {
|
||||||
|
$this->phid = $data['phid'];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function processRequest() {
|
||||||
|
$request = $this->getRequest();
|
||||||
|
$user = $request->getUser();
|
||||||
|
|
||||||
|
$xactions = id(new PhabricatorObjectHandleData(array($this->phid)))
|
||||||
|
->setViewer($user)
|
||||||
|
->loadObjects();
|
||||||
|
$xaction = idx($xactions, $this->phid);
|
||||||
|
|
||||||
|
if (!$xaction) {
|
||||||
|
// TODO: This may also mean you don't have permission to edit the object,
|
||||||
|
// but we can't make that distinction via PhabricatorObjectHandleData
|
||||||
|
// at the moment.
|
||||||
|
return new Aphront404Response();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$xaction->getComment()) {
|
||||||
|
// You can't view history of a transaction with no comments.
|
||||||
|
return new Aphront404Response();
|
||||||
|
}
|
||||||
|
|
||||||
|
$obj_phid = $xaction->getObjectPHID();
|
||||||
|
$obj_handle = PhabricatorObjectHandleData::loadOneHandle($obj_phid, $user);
|
||||||
|
if (!$obj_handle) {
|
||||||
|
// Require the corresponding object exist and be visible to the user.
|
||||||
|
return new Aphront404Response();
|
||||||
|
}
|
||||||
|
|
||||||
|
$comments = id(new PhabricatorApplicationTransactionCommentQuery())
|
||||||
|
->setViewer($user)
|
||||||
|
->setTemplate($xaction->getApplicationTransactionCommentObject())
|
||||||
|
->withTransactionPHIDs(array($xaction->getPHID()))
|
||||||
|
->execute();
|
||||||
|
|
||||||
|
if (!$comments) {
|
||||||
|
return new Aphront404Response();
|
||||||
|
}
|
||||||
|
|
||||||
|
$comments = msort($comments, 'getCommentVersion');
|
||||||
|
|
||||||
|
$xactions = array();
|
||||||
|
foreach ($comments as $comment) {
|
||||||
|
$xactions[] = id(clone $xaction)
|
||||||
|
->makeEphemeral()
|
||||||
|
->setCommentVersion($comment->getCommentVersion())
|
||||||
|
->setContentSource($comment->getContentSource())
|
||||||
|
->setDateCreated($comment->getDateCreated())
|
||||||
|
->attachComment($comment);
|
||||||
|
}
|
||||||
|
|
||||||
|
$view = id(new PhabricatorApplicationTransactionView())
|
||||||
|
->setViewer($user)
|
||||||
|
->setTransactions($xactions)
|
||||||
|
->setShowEditActions(false);
|
||||||
|
|
||||||
|
|
||||||
|
$dialog = id(new AphrontDialogView())
|
||||||
|
->setUser($user)
|
||||||
|
->setWidth(AphrontDialogView::WIDTH_FULL)
|
||||||
|
->setTitle(pht('Comment History'));
|
||||||
|
|
||||||
|
$dialog->appendChild($view);
|
||||||
|
|
||||||
|
$dialog
|
||||||
|
->addCancelButton($obj_handle->getURI());
|
||||||
|
|
||||||
|
return id(new AphrontDialogResponse())->setDialog($dialog);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
abstract class PhabricatorApplicationTransactionController
|
||||||
|
extends PhabricatorController {
|
||||||
|
|
||||||
|
}
|
|
@ -19,7 +19,7 @@ final class PhabricatorApplicationTransactionCommentQuery
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function withTranactionPHIDs(array $transaction_phids) {
|
public function withTransactionPHIDs(array $transaction_phids) {
|
||||||
$this->transactionPHIDs = $transaction_phids;
|
$this->transactionPHIDs = $transaction_phids;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,16 @@ class PhabricatorApplicationTransactionView extends AphrontView {
|
||||||
private $transactions;
|
private $transactions;
|
||||||
private $engine;
|
private $engine;
|
||||||
private $anchorOffset = 0;
|
private $anchorOffset = 0;
|
||||||
|
private $showEditActions = true;
|
||||||
|
|
||||||
|
public function setShowEditActions($show_edit_actions) {
|
||||||
|
$this->showEditActions = $show_edit_actions;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getShowEditActions() {
|
||||||
|
return $this->showEditActions;
|
||||||
|
}
|
||||||
|
|
||||||
public function setAnchorOffset($anchor_offset) {
|
public function setAnchorOffset($anchor_offset) {
|
||||||
$this->anchorOffset = $anchor_offset;
|
$this->anchorOffset = $anchor_offset;
|
||||||
|
@ -49,6 +59,7 @@ class PhabricatorApplicationTransactionView extends AphrontView {
|
||||||
}
|
}
|
||||||
|
|
||||||
$view = new PhabricatorTimelineView();
|
$view = new PhabricatorTimelineView();
|
||||||
|
$viewer = $this->viewer;
|
||||||
|
|
||||||
$anchor = $this->anchorOffset;
|
$anchor = $this->anchorOffset;
|
||||||
foreach ($this->transactions as $xaction) {
|
foreach ($this->transactions as $xaction) {
|
||||||
|
@ -58,7 +69,8 @@ class PhabricatorApplicationTransactionView extends AphrontView {
|
||||||
|
|
||||||
$anchor++;
|
$anchor++;
|
||||||
$event = id(new PhabricatorTimelineEventView())
|
$event = id(new PhabricatorTimelineEventView())
|
||||||
->setViewer($this->viewer)
|
->setViewer($viewer)
|
||||||
|
->setTransactionPHID($xaction->getPHID())
|
||||||
->setUserHandle($xaction->getHandle($xaction->getAuthorPHID()))
|
->setUserHandle($xaction->getHandle($xaction->getAuthorPHID()))
|
||||||
->setIcon($xaction->getIcon())
|
->setIcon($xaction->getIcon())
|
||||||
->setColor($xaction->getColor())
|
->setColor($xaction->getColor())
|
||||||
|
@ -67,9 +79,33 @@ class PhabricatorApplicationTransactionView extends AphrontView {
|
||||||
->setContentSource($xaction->getContentSource())
|
->setContentSource($xaction->getContentSource())
|
||||||
->setAnchor($anchor);
|
->setAnchor($anchor);
|
||||||
|
|
||||||
|
$has_deleted_comment = $xaction->getComment() &&
|
||||||
|
$xaction->getComment()->getIsDeleted();
|
||||||
|
|
||||||
|
if ($this->getShowEditActions()) {
|
||||||
|
if ($xaction->getCommentVersion() > 1) {
|
||||||
|
$event->setIsEdited(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
$can_edit = PhabricatorPolicyCapability::CAN_EDIT;
|
||||||
|
|
||||||
|
if ($xaction->hasComment() || $has_deleted_comment) {
|
||||||
|
$has_edit_capability = PhabricatorPolicyFilter::hasCapability(
|
||||||
|
$viewer,
|
||||||
|
$xaction,
|
||||||
|
$can_edit);
|
||||||
|
if ($has_edit_capability) {
|
||||||
|
$event->setIsEditable(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ($xaction->hasComment()) {
|
if ($xaction->hasComment()) {
|
||||||
$event->appendChild(
|
$event->appendChild(
|
||||||
$this->engine->getOutput($xaction->getComment(), $field));
|
$this->engine->getOutput($xaction->getComment(), $field));
|
||||||
|
} else if ($has_deleted_comment) {
|
||||||
|
$event->appendChild(
|
||||||
|
'<em>'.pht('This comment has been deleted.').'</em>');
|
||||||
}
|
}
|
||||||
|
|
||||||
$view->addEvent($event);
|
$view->addEvent($event);
|
||||||
|
|
|
@ -16,6 +16,7 @@ final class AphrontDialogView extends AphrontView {
|
||||||
private $width = 'default';
|
private $width = 'default';
|
||||||
const WIDTH_DEFAULT = 'default';
|
const WIDTH_DEFAULT = 'default';
|
||||||
const WIDTH_FORM = 'form';
|
const WIDTH_FORM = 'form';
|
||||||
|
const WIDTH_FULL = 'full';
|
||||||
|
|
||||||
public function setUser(PhabricatorUser $user) {
|
public function setUser(PhabricatorUser $user) {
|
||||||
$this->user = $user;
|
$this->user = $user;
|
||||||
|
@ -115,6 +116,7 @@ final class AphrontDialogView extends AphrontView {
|
||||||
|
|
||||||
switch ($this->width) {
|
switch ($this->width) {
|
||||||
case self::WIDTH_FORM:
|
case self::WIDTH_FORM:
|
||||||
|
case self::WIDTH_FULL:
|
||||||
$more .= ' aphront-dialog-view-width-'.$this->width;
|
$more .= ' aphront-dialog-view-width-'.$this->width;
|
||||||
break;
|
break;
|
||||||
case self::WIDTH_DEFAULT:
|
case self::WIDTH_DEFAULT:
|
||||||
|
|
|
@ -11,6 +11,37 @@ final class PhabricatorTimelineEventView extends AphrontView {
|
||||||
private $dateCreated;
|
private $dateCreated;
|
||||||
private $viewer;
|
private $viewer;
|
||||||
private $anchor;
|
private $anchor;
|
||||||
|
private $isEditable;
|
||||||
|
private $isEdited;
|
||||||
|
private $transactionPHID;
|
||||||
|
|
||||||
|
public function setTransactionPHID($transaction_phid) {
|
||||||
|
$this->transactionPHID = $transaction_phid;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTransactionPHID() {
|
||||||
|
return $this->transactionPHID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setIsEdited($is_edited) {
|
||||||
|
$this->isEdited = $is_edited;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getIsEdited() {
|
||||||
|
return $this->isEdited;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function setIsEditable($is_editable) {
|
||||||
|
$this->isEditable = $is_editable;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getIsEditable() {
|
||||||
|
return $this->isEditable;
|
||||||
|
}
|
||||||
|
|
||||||
public function setViewer(PhabricatorUser $viewer) {
|
public function setViewer(PhabricatorUser $viewer) {
|
||||||
$this->viewer = $viewer;
|
$this->viewer = $viewer;
|
||||||
|
@ -78,6 +109,27 @@ final class PhabricatorTimelineEventView extends AphrontView {
|
||||||
}
|
}
|
||||||
|
|
||||||
$extra = array();
|
$extra = array();
|
||||||
|
$xaction_phid = $this->getTransactionPHID();
|
||||||
|
|
||||||
|
if ($this->getIsEdited()) {
|
||||||
|
$extra[] = javelin_render_tag(
|
||||||
|
'a',
|
||||||
|
array(
|
||||||
|
'href' => '/transactions/history/'.$xaction_phid.'/',
|
||||||
|
'sigil' => 'workflow',
|
||||||
|
),
|
||||||
|
pht('Edited'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->getIsEditable()) {
|
||||||
|
$extra[] = javelin_render_tag(
|
||||||
|
'a',
|
||||||
|
array(
|
||||||
|
'href' => '/transactions/edit/'.$xaction_phid.'/',
|
||||||
|
'sigil' => 'workflow',
|
||||||
|
),
|
||||||
|
pht('Edit'));
|
||||||
|
}
|
||||||
|
|
||||||
$source = $this->getContentSource();
|
$source = $this->getContentSource();
|
||||||
if ($source) {
|
if ($source) {
|
||||||
|
|
|
@ -137,7 +137,7 @@ final class PhabricatorStandardPageView extends PhabricatorBarePageView {
|
||||||
'header' => AphrontRequest::getCSRFHeaderName(),
|
'header' => AphrontRequest::getCSRFHeaderName(),
|
||||||
'current' => $current_token,
|
'current' => $current_token,
|
||||||
));
|
));
|
||||||
Javelin::initBehavior('device', array('id' => 'base-page'));
|
Javelin::initBehavior('device');
|
||||||
|
|
||||||
if ($console) {
|
if ($console) {
|
||||||
require_celerity_resource('aphront-dark-console-css');
|
require_celerity_resource('aphront-dark-console-css');
|
||||||
|
@ -284,29 +284,12 @@ final class PhabricatorStandardPageView extends PhabricatorBarePageView {
|
||||||
'</div>';
|
'</div>';
|
||||||
}
|
}
|
||||||
|
|
||||||
$agent = idx($_SERVER, 'HTTP_USER_AGENT');
|
|
||||||
|
|
||||||
// Try to guess the device resolution based on UA strings to avoid a flash
|
|
||||||
// of incorrectly-styled content.
|
|
||||||
$device_guess = 'device-desktop';
|
|
||||||
if (preg_match('@iPhone|iPod|(Android.*Chrome/[.0-9]* Mobile)@', $agent)) {
|
|
||||||
$device_guess = 'device-phone device';
|
|
||||||
} else if (preg_match('@iPad|(Android.*Chrome/)@', $agent)) {
|
|
||||||
$device_guess = 'device-tablet device';
|
|
||||||
}
|
|
||||||
|
|
||||||
$classes = array(
|
|
||||||
'phabricator-standard-page',
|
|
||||||
$device_guess,
|
|
||||||
);
|
|
||||||
$classes = implode(' ', $classes);
|
|
||||||
|
|
||||||
return
|
return
|
||||||
phutil_render_tag(
|
phutil_render_tag(
|
||||||
'div',
|
'div',
|
||||||
array(
|
array(
|
||||||
'id' => 'base-page',
|
'id' => 'base-page',
|
||||||
'class' => $classes,
|
'class' => 'phabricator-standard-page',
|
||||||
),
|
),
|
||||||
$header_chrome.
|
$header_chrome.
|
||||||
'<div class="phabricator-standard-page-body">'.
|
'<div class="phabricator-standard-page-body">'.
|
||||||
|
@ -374,6 +357,19 @@ final class PhabricatorStandardPageView extends PhabricatorBarePageView {
|
||||||
$classes[] = 'phabricator-chromeless-page';
|
$classes[] = 'phabricator-chromeless-page';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$agent = idx($_SERVER, 'HTTP_USER_AGENT');
|
||||||
|
|
||||||
|
// Try to guess the device resolution based on UA strings to avoid a flash
|
||||||
|
// of incorrectly-styled content.
|
||||||
|
$device_guess = 'device-desktop';
|
||||||
|
if (preg_match('@iPhone|iPod|(Android.*Chrome/[.0-9]* Mobile)@', $agent)) {
|
||||||
|
$device_guess = 'device-phone device';
|
||||||
|
} else if (preg_match('@iPad|(Android.*Chrome/)@', $agent)) {
|
||||||
|
$device_guess = 'device-tablet device';
|
||||||
|
}
|
||||||
|
|
||||||
|
$classes[] = $device_guess;
|
||||||
|
|
||||||
return implode(' ', $classes);
|
return implode(' ', $classes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,10 @@
|
||||||
width: 600px;
|
width: 600px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.aphront-dialog-view-width-full {
|
||||||
|
width: 90%;
|
||||||
|
}
|
||||||
|
|
||||||
.aphront-dialog-body {
|
.aphront-dialog-body {
|
||||||
background: #ffffff;
|
background: #ffffff;
|
||||||
padding: 16px 12px;
|
padding: 16px 12px;
|
||||||
|
@ -44,6 +48,7 @@
|
||||||
.jx-client-dialog {
|
.jx-client-dialog {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 14;
|
z-index: 14;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.jx-mask {
|
.jx-mask {
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
|
|
||||||
.lightbox-attached {
|
.lightbox-attached {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.lightbox-attachment {
|
.lightbox-attachment {
|
||||||
|
|
|
@ -16,7 +16,7 @@ JX.install('Device', {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
JX.behavior('device', function(config) {
|
JX.behavior('device', function() {
|
||||||
|
|
||||||
function onresize() {
|
function onresize() {
|
||||||
var v = JX.Vector.getViewport();
|
var v = JX.Vector.getViewport();
|
||||||
|
@ -35,7 +35,7 @@ JX.behavior('device', function(config) {
|
||||||
|
|
||||||
JX.Device._device = device;
|
JX.Device._device = device;
|
||||||
|
|
||||||
var e = JX.$(config.id);
|
var e = document.body;
|
||||||
JX.DOM.alterClass(e, 'device-phone', (device == 'phone'));
|
JX.DOM.alterClass(e, 'device-phone', (device == 'phone'));
|
||||||
JX.DOM.alterClass(e, 'device-tablet', (device == 'tablet'));
|
JX.DOM.alterClass(e, 'device-tablet', (device == 'tablet'));
|
||||||
JX.DOM.alterClass(e, 'device-desktop', (device == 'desktop'));
|
JX.DOM.alterClass(e, 'device-desktop', (device == 'desktop'));
|
||||||
|
|
Loading…
Reference in a new issue