Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15422964
D9543.id22874.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
20 KB
Referenced Files
None
Subscribers
None
D9543.id22874.diff
View Options
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -2410,7 +2410,6 @@
'PholioController' => 'applications/pholio/controller/PholioController.php',
'PholioDAO' => 'applications/pholio/storage/PholioDAO.php',
'PholioImage' => 'applications/pholio/storage/PholioImage.php',
- 'PholioImageHistoryController' => 'applications/pholio/controller/PholioImageHistoryController.php',
'PholioImageQuery' => 'applications/pholio/query/PholioImageQuery.php',
'PholioImageUploadController' => 'applications/pholio/controller/PholioImageUploadController.php',
'PholioInlineController' => 'applications/pholio/controller/PholioInlineController.php',
@@ -2426,6 +2425,7 @@
'PholioMockMailReceiver' => 'applications/pholio/mail/PholioMockMailReceiver.php',
'PholioMockQuery' => 'applications/pholio/query/PholioMockQuery.php',
'PholioMockSearchEngine' => 'applications/pholio/query/PholioMockSearchEngine.php',
+ 'PholioMockThumbGridView' => 'applications/pholio/view/PholioMockThumbGridView.php',
'PholioMockViewController' => 'applications/pholio/controller/PholioMockViewController.php',
'PholioPHIDTypeImage' => 'applications/pholio/phid/PholioPHIDTypeImage.php',
'PholioPHIDTypeMock' => 'applications/pholio/phid/PholioPHIDTypeMock.php',
@@ -5312,7 +5312,6 @@
1 => 'PhabricatorMarkupInterface',
2 => 'PhabricatorPolicyInterface',
),
- 'PholioImageHistoryController' => 'PholioController',
'PholioImageQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PholioImageUploadController' => 'PholioController',
'PholioInlineController' => 'PholioController',
@@ -5338,6 +5337,7 @@
'PholioMockMailReceiver' => 'PhabricatorObjectMailReceiver',
'PholioMockQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PholioMockSearchEngine' => 'PhabricatorApplicationSearchEngine',
+ 'PholioMockThumbGridView' => 'AphrontView',
'PholioMockViewController' => 'PholioController',
'PholioPHIDTypeImage' => 'PhabricatorPHIDType',
'PholioPHIDTypeMock' => 'PhabricatorPHIDType',
diff --git a/src/applications/files/controller/PhabricatorFileTransformController.php b/src/applications/files/controller/PhabricatorFileTransformController.php
--- a/src/applications/files/controller/PhabricatorFileTransformController.php
+++ b/src/applications/files/controller/PhabricatorFileTransformController.php
@@ -65,6 +65,9 @@
case 'thumb-220x165':
$xformed_file = $this->executeThumbTransform($file, 220, 165);
break;
+ case 'preview-100':
+ $xformed_file = $this->executePreviewTransform($file, 100);
+ break;
case 'preview-140':
$xformed_file = $this->executePreviewTransform($file, 140);
break;
diff --git a/src/applications/files/storage/PhabricatorFile.php b/src/applications/files/storage/PhabricatorFile.php
--- a/src/applications/files/storage/PhabricatorFile.php
+++ b/src/applications/files/storage/PhabricatorFile.php
@@ -538,6 +538,12 @@
return PhabricatorEnv::getCDNURI($path);
}
+ public function getPreview100URI() {
+ $path = '/file/xform/preview-100/'.$this->getPHID().'/'
+ .$this->getSecretKey().'/';
+ return PhabricatorEnv::getCDNURI($path);
+ }
+
public function getPreview140URI() {
$path = '/file/xform/preview-140/'.$this->getPHID().'/'
.$this->getSecretKey().'/';
diff --git a/src/applications/pholio/application/PhabricatorApplicationPholio.php b/src/applications/pholio/application/PhabricatorApplicationPholio.php
--- a/src/applications/pholio/application/PhabricatorApplicationPholio.php
+++ b/src/applications/pholio/application/PhabricatorApplicationPholio.php
@@ -53,7 +53,6 @@
),
'image/' => array(
'upload/' => 'PholioImageUploadController',
- 'history/(?P<id>\d+)/' => 'PholioImageHistoryController',
),
),
);
diff --git a/src/applications/pholio/controller/PholioImageHistoryController.php b/src/applications/pholio/controller/PholioImageHistoryController.php
deleted file mode 100644
--- a/src/applications/pholio/controller/PholioImageHistoryController.php
+++ /dev/null
@@ -1,90 +0,0 @@
-<?php
-
-/**
- * @group pholio
- */
-final class PholioImageHistoryController extends PholioController {
-
- private $imageID;
-
- public function willProcessRequest(array $data) {
- $this->imageID = $data['id'];
- }
-
- public function processRequest() {
- $request = $this->getRequest();
- $user = $request->getUser();
-
- $image = id(new PholioImageQuery())
- ->setViewer($user)
- ->withIDs(array($this->imageID))
- ->executeOne();
-
- if (!$image) {
- return new Aphront404Response();
- }
-
- // note while we have a mock object, its missing images we need to show
- // the history of what's happened here.
- // fetch the real deal
-
- $mock = id(new PholioMockQuery())
- ->setViewer($user)
- ->needImages(true)
- ->withIDs(array($image->getMockID()))
- ->executeOne();
-
- $phids = array($mock->getAuthorPHID());
- $this->loadHandles($phids);
-
- $engine = id(new PhabricatorMarkupEngine())
- ->setViewer($user);
- $engine->addObject($mock, PholioMock::MARKUP_FIELD_DESCRIPTION);
- $engine->process();
-
-
- $images = $mock->getImageHistorySet($this->imageID);
- $mock->attachImages($images);
- $latest_image = last($images);
-
- $title = pht(
- 'Image history for "%s" from the mock "%s."',
- $latest_image->getName(),
- $mock->getName());
-
- $header = id(new PHUIHeaderView())
- ->setHeader($title);
-
- require_celerity_resource('pholio-css');
- require_celerity_resource('pholio-inline-comments-css');
-
- $comment_form_id = null;
- $output = id(new PholioMockImagesView())
- ->setRequestURI($request->getRequestURI())
- ->setCommentFormID($comment_form_id)
- ->setUser($user)
- ->setMock($mock)
- ->setImageID($this->imageID)
- ->setViewMode('history');
-
- $crumbs = $this->buildApplicationCrumbs();
- $crumbs
- ->addTextCrumb('M'.$mock->getID(), '/M'.$mock->getID())
- ->addTextCrumb('Image History', $request->getRequestURI());
-
- $content = array(
- $crumbs,
- $header,
- $output->render(),
- );
-
- return $this->buildApplicationPage(
- $content,
- array(
- 'title' => 'M'.$mock->getID().' '.$title,
- 'device' => true,
- 'pageObjects' => array($mock->getPHID()),
- ));
- }
-
-}
diff --git a/src/applications/pholio/controller/PholioMockViewController.php b/src/applications/pholio/controller/PholioMockViewController.php
--- a/src/applications/pholio/controller/PholioMockViewController.php
+++ b/src/applications/pholio/controller/PholioMockViewController.php
@@ -1,8 +1,5 @@
<?php
-/**
- * @group pholio
- */
final class PholioMockViewController extends PholioController {
private $id;
@@ -89,8 +86,6 @@
require_celerity_resource('pholio-css');
require_celerity_resource('pholio-inline-comments-css');
- $image_status = $this->getImageStatus($mock, $this->imageID);
-
$comment_form_id = celerity_generate_unique_node_id();
$output = id(new PholioMockImagesView())
->setRequestURI($request->getRequestURI())
@@ -115,11 +110,16 @@
->setHeader($header)
->addPropertyList($properties);
+ $thumb_grid = id(new PholioMockThumbGridView())
+ ->setUser($user)
+ ->setMock($mock);
+
$content = array(
$crumbs,
- $image_status,
$object_box,
- $output->render(),
+ $output,
+ phutil_tag('br'),
+ $thumb_grid,
$xaction_view,
$add_comment,
);
@@ -133,43 +133,6 @@
));
}
- private function getImageStatus(PholioMock $mock, $image_id) {
- $status = null;
- $images = $mock->getImages();
- foreach ($images as $image) {
- if ($image->getID() == $image_id) {
- return $status;
- }
- }
-
- $images = $mock->getAllImages();
- $images = mpull($images, null, 'getID');
- $image = idx($images, $image_id);
-
- if ($image) {
- $history = $mock->getImageHistorySet($image_id);
- $latest_image = last($history);
- $href = $this->getApplicationURI(
- 'image/history/'.$latest_image->getID().'/');
- $status = id(new AphrontErrorView())
- ->setSeverity(AphrontErrorView::SEVERITY_NOTICE)
- ->setTitle(pht('The requested image is obsolete.'))
- ->appendChild(phutil_tag(
- 'p',
- array(),
- array(
- pht('You are viewing this mock with the latest image set.'),
- ' ',
- phutil_tag(
- 'a',
- array('href' => $href),
- pht(
- 'Click here to see the history of the now obsolete image.')))));
- }
-
- return $status;
- }
-
private function buildActionView(PholioMock $mock) {
$user = $this->getRequest()->getUser();
diff --git a/src/applications/pholio/view/PholioMockImagesView.php b/src/applications/pholio/view/PholioMockImagesView.php
--- a/src/applications/pholio/view/PholioMockImagesView.php
+++ b/src/applications/pholio/view/PholioMockImagesView.php
@@ -9,25 +9,12 @@
private $imageID;
private $requestURI;
private $commentFormID;
- private $viewMode = 'normal';
-
- /**
- * Supports normal (/MX, /MX/Y/) and history (/pholio/image/history/Y/)
- * modes. The former has handy dandy commenting functionality and the
- * latter does not.
- */
- public function setViewMode($view_mode) {
- $this->viewMode = $view_mode;
- return $this;
- }
- public function getViewMode() {
- return $this->viewMode;
- }
public function setCommentFormID($comment_form_id) {
$this->commentFormID = $comment_form_id;
return $this;
}
+
public function getCommentFormID() {
return $this->commentFormID;
}
@@ -36,6 +23,7 @@
$this->requestURI = $request_uri;
return $this;
}
+
public function getRequestURI() {
return $this->requestURI;
}
@@ -74,7 +62,7 @@
$selected_id = head_key($ids);
}
- foreach ($mock->getImages() as $image) {
+ foreach ($mock->getAllImages() as $image) {
$file = $image->getFile();
$metadata = $file->getMetadata();
$x = idx($metadata, PhabricatorFile::METADATA_IMAGE_WIDTH);
@@ -90,10 +78,15 @@
'height' => $y,
'title' => $image->getName(),
'desc' => $image->getDescription(),
- 'isObsolete' => (bool) $image->getIsObsolete(),
+ 'isObsolete' => (bool)$image->getIsObsolete(),
);
}
+ $navsequence = array();
+ foreach ($mock->getImages() as $image) {
+ $navsequence[] = $image->getID();
+ }
+
$login_uri = id(new PhutilURI('/login/'))
->setQueryParam('next', (string) $this->getRequestURI());
$config = array(
@@ -105,7 +98,7 @@
'selectedID' => $selected_id,
'loggedIn' => $this->getUser()->isLoggedIn(),
'logInLink' => (string) $login_uri,
- 'viewMode' => $this->getViewMode()
+ 'navsequence' => $navsequence,
);
Javelin::initBehavior('pholio-mock-view', $config);
@@ -149,65 +142,19 @@
),
'');
- $carousel_holder = '';
- if (count($mock->getImages()) > 0) {
- $thumbnails = array();
- foreach ($mock->getImages() as $image) {
- $thumbfile = $image->getFile();
-
- $dimensions = PhabricatorImageTransformer::getPreviewDimensions(
- $thumbfile,
- 140);
-
- $tag = phutil_tag(
- 'img',
- array(
- 'width' => $dimensions['sdx'],
- 'height' => $dimensions['sdy'],
- 'src' => $thumbfile->getPreview140URI(),
- 'class' => 'pholio-mock-carousel-thumbnail',
- 'style' => 'top: '.floor((140 - $dimensions['sdy'] ) / 2).'px',
- ));
-
- $thumbnails[] = javelin_tag(
- 'a',
- array(
- 'sigil' => 'mock-thumbnail',
- 'class' => 'pholio-mock-carousel-thumb-item',
- 'href' => $this->getImagePageURI($image, $mock),
- 'meta' => array(
- 'imageID' => $image->getID(),
- ),
- ),
- $tag);
- }
-
- $carousel_holder = phutil_tag(
- 'div',
- array(
- 'id' => 'pholio-mock-carousel',
- 'class' => 'pholio-mock-carousel',
- ),
- $thumbnails);
- }
-
$mockview[] = phutil_tag(
'div',
- array(
- 'class' => 'pholio-mock-image-container',
- 'id' => 'pholio-mock-image-container'
- ),
- array($mock_wrapper, $inline_comments_holder, $carousel_holder));
+ array(
+ 'class' => 'pholio-mock-image-container',
+ 'id' => 'pholio-mock-image-container'
+ ),
+ array($mock_wrapper, $inline_comments_holder));
return $mockview;
}
private function getImagePageURI(PholioImage $image, PholioMock $mock) {
- if ($this->getViewMode() == 'normal') {
- $uri = '/M'.$mock->getID().'/'.$image->getID().'/';
- } else {
- $uri = '/pholio/image/history/'.$image->getID().'/';
- }
+ $uri = '/M'.$mock->getID().'/'.$image->getID().'/';
return $uri;
}
}
diff --git a/src/applications/pholio/view/PholioMockThumbGridView.php b/src/applications/pholio/view/PholioMockThumbGridView.php
new file mode 100644
--- /dev/null
+++ b/src/applications/pholio/view/PholioMockThumbGridView.php
@@ -0,0 +1,135 @@
+<?php
+
+final class PholioMockThumbGridView extends AphrontView {
+
+ private $mock;
+
+ public function setMock(PholioMock $mock) {
+ $this->mock = $mock;
+ return $this;
+ }
+
+ public function render() {
+ $mock = $this->mock;
+
+ $all_images = $mock->getAllImages();
+ $all_images = mpull($all_images, null, 'getPHID');
+
+ $history = mpull($all_images, 'getReplacesImagePHID', 'getPHID');
+
+ $replaced = array();
+ foreach ($history as $phid => $replaces_phid) {
+ if ($replaces_phid) {
+ $replaced[$replaces_phid] = true;
+ }
+ }
+
+ // Figure out the columns. Start with all the active images.
+ $images = mpull($mock->getImages(), null, 'getPHID');
+
+ // Now, find deleted images: obsolete images which were not replaced.
+ foreach ($mock->getAllImages() as $image) {
+ if (!$image->getIsObsolete()) {
+ // Image is current.
+ continue;
+ }
+
+ if (isset($replaced[$image->getPHID()])) {
+ // Image was replaced.
+ continue;
+ }
+
+ // This is an obsolete image which was not replaced, so it must be
+ // a deleted image.
+ $images[$image->getPHID()] = $image;
+ }
+
+ $cols = array();
+ $depth = 0;
+ foreach ($images as $image) {
+ $phid = $image->getPHID();
+
+ $col = array();
+
+ // If this is a deleted image, null out the final column.
+ if ($image->getIsObsolete()) {
+ $col[] = null;
+ }
+
+ $col[] = $phid;
+ while ($phid && isset($history[$phid])) {
+ $col[] = $history[$phid];
+ $phid = $history[$phid];
+ }
+
+ $cols[] = $col;
+ $depth = max($depth, count($col));
+ }
+
+ $grid = array();
+ for ($ii = 0; $ii < $depth; $ii++) {
+ $row = array();
+ foreach ($cols as $col) {
+ if (empty($col[$ii])) {
+ $row[] = phutil_tag('td', array(), null);
+ } else {
+ $thumb = $this->renderThumbnail($all_images[$col[$ii]]);
+ $row[] = phutil_tag('td', array(), $thumb);
+ }
+ }
+ $grid[] = phutil_tag('tr', array(), $row);
+ }
+
+ $grid = phutil_tag(
+ 'table',
+ array(
+ 'id' => 'pholio-mock-thumb-grid',
+ 'class' => 'pholio-mock-thumb-grid',
+ ),
+ $grid);
+
+ return phutil_tag(
+ 'div',
+ array(
+ 'class' => 'pholio-mock-thumb-grid-container',
+ ),
+ $grid);
+ }
+
+
+ private function renderThumbnail(PholioImage $image) {
+ $thumbfile = $image->getFile();
+
+ $dimensions = PhabricatorImageTransformer::getPreviewDimensions(
+ $thumbfile,
+ 100);
+
+ $tag = phutil_tag(
+ 'img',
+ array(
+ 'width' => $dimensions['sdx'],
+ 'height' => $dimensions['sdy'],
+ 'src' => $thumbfile->getPreview100URI(),
+ 'class' => 'pholio-mock-thumb-grid-image',
+ 'style' => 'top: '.floor((100 - $dimensions['sdy'] ) / 2).'px',
+ ));
+
+ $classes = array('pholio-mock-thumb-grid-item');
+ if ($image->getIsObsolete()) {
+ $classes[] = 'pholio-mock-thumb-grid-item-obsolete';
+ }
+
+ return javelin_tag(
+ 'a',
+ array(
+ 'sigil' => 'mock-thumbnail',
+ 'class' => implode(' ', $classes),
+ 'href' => '#',
+ 'meta' => array(
+ 'imageID' => $image->getID(),
+ ),
+ ),
+ $tag);
+ }
+
+}
diff --git a/webroot/rsrc/css/application/pholio/pholio.css b/webroot/rsrc/css/application/pholio/pholio.css
--- a/webroot/rsrc/css/application/pholio/pholio.css
+++ b/webroot/rsrc/css/application/pholio/pholio.css
@@ -10,50 +10,41 @@
background: url('/rsrc/image/texture/pholio-background.gif');
}
-.pholio-mock-carousel {
+.pholio-mock-thumb-grid-container {
background-color: #282828;
- text-align: center;
+ padding: 12px;
+ overflow-x: auto;
+ overflow-y: hidden;
+}
+
+.pholio-mock-thumb-grid {
+ margin: 0 auto;
}
-.pholio-mock-carousel-thumb-item {
+.pholio-mock-thumb-grid-item {
display: inline-block;
cursor: pointer;
- width: 140px;
- height: 140px;
+ width: 100px;
+ height: 100px;
padding: 5px;
margin: 3px;
background: #181818;
vertical-align: middle;
- border: 1px solid #383838;
+ border: 1px solid {$greyborder};
position: relative;
}
-.device-desktop .pholio-mock-carousel-thumb-item:hover,
-.pholio-mock-carousel-thumb-current {
- background: #383838;
- border-color: #686868;
-}
-
-.device .pholio-mock-carousel-thumb-item {
- width: 5px;
- height: 5px;
- padding: 0px;
- border-radius: 5px;
- margin: 5px 2px;
+.device-desktop .pholio-mock-thumb-grid-item:hover,
+.pholio-mock-thumb-grid-current {
background: #383838;
- border-color: #686868;
+ border-color: {$sky};
}
-.device .pholio-mock-carousel-thumb-current {
- background: #dfdfdf;
- border-color: #ffffff;
+.pholio-mock-thumb-grid-item-obsolete {
+ opacity: 0.5;
}
-.device .pholio-mock-carousel-thumb-item img {
- display: none;
-}
-
-.pholio-mock-carousel-thumbnail {
+.pholio-mock-thumb-grid-image {
margin: auto;
position: relative;
}
@@ -78,10 +69,6 @@
opacity: 0.50;
}
-.pholio-image-info {
- border-bottom: 1px solid #101010;
- margin-bottom: 5px;
-}
.pholio-image-info-item {
padding: 0 8px;
diff --git a/webroot/rsrc/js/application/pholio/behavior-pholio-mock-view.js b/webroot/rsrc/js/application/pholio/behavior-pholio-mock-view.js
--- a/webroot/rsrc/js/application/pholio/behavior-pholio-mock-view.js
+++ b/webroot/rsrc/js/application/pholio/behavior-pholio-mock-view.js
@@ -110,6 +110,15 @@
return null;
}
+ function get_image_navindex(id) {
+ for (var ii = 0; ii < config.navsequence.length; ii++) {
+ if (config.navsequence[ii] == id) {
+ return ii;
+ }
+ }
+ return null;
+ }
+
function get_image(id) {
var idx = get_image_index(id);
if (idx === null) {
@@ -133,9 +142,12 @@
if (!active_image) {
return;
}
- var idx = get_image_index(active_image.id);
- idx = (idx + delta + config.images.length) % config.images.length;
- select_image(config.images[idx].id);
+ var idx = get_image_navindex(active_image.id);
+ if (idx === null) {
+ return;
+ }
+ idx = (idx + delta + config.navsequence.length) % config.navsequence.length;
+ select_image(config.navsequence[idx]);
}
function redraw_image() {
@@ -197,7 +209,7 @@
img.src = active_image.fullURI;
var thumbs = JX.DOM.scry(
- JX.$('pholio-mock-carousel'),
+ JX.$('pholio-mock-thumb-grid'),
'a',
'mock-thumbnail');
@@ -206,7 +218,7 @@
JX.DOM.alterClass(
thumbs[k],
- 'pholio-mock-carousel-thumb-current',
+ 'pholio-mock-thumb-grid-current',
(active_image.id == thumb_meta.imageID));
}
@@ -217,7 +229,7 @@
}
JX.Stratcom.listen(
- ['mousedown', 'click'],
+ 'click',
'mock-thumbnail',
function(e) {
if (!e.isNormalMouseEvent()) {
@@ -238,10 +250,6 @@
return;
}
- if (config.viewMode == 'history') {
- return;
- }
-
if (JX.Stratcom.pass()) {
return;
}
@@ -602,15 +610,6 @@
'View Full Image');
info.push(full_link);
- if (config.viewMode != 'history') {
- var history_link = JX.$N(
- 'a',
- { href: image.historyURI },
- 'View Image History');
- info.push(history_link);
- }
-
-
for (var ii = 0; ii < info.length; ii++) {
info[ii] = JX.$N('div', {className: 'pholio-image-info-item'}, info[ii]);
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Mar 23, 11:41 AM (2 w, 2 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7386672
Default Alt Text
D9543.id22874.diff (20 KB)
Attached To
Mode
D9543: Turn thumbs into a history grid thing
Attached
Detach File
Event Timeline
Log In to Comment