mirror of
https://we.phorge.it/source/phorge.git
synced 2025-02-18 09:48:39 +01:00
Convert "profile" image transforms to the new pathway
Summary: Ref T7707. This ends up being sort of complicated: to support 100x100 images in T4406, we need to scale small images //up// so they look OK when we scale them back down with `background-size` in CSS. The rest of it is mostly straightforward. Test Plan: - Did an OAuth handshake and saw a scaled-up, scaled-down profile picture that looked correct. - Used Pholio, edited pholio, embedded pholio. - Uploaded a bunch of small/weird/big images and regenerated all their transforms. - Uploaded some text files into Pholio. - Grepped for removed methods, etc. Reviewers: chad, btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T7707 Differential Revision: https://secure.phabricator.com/D12818
This commit is contained in:
parent
75f6211233
commit
7e365eb8ae
16 changed files with 115 additions and 141 deletions
|
@ -89,13 +89,17 @@ final class PhabricatorAuthAccountView extends AphrontView {
|
||||||
$account_uri);
|
$account_uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
$image_uri = $account->getProfileImageFile()->getProfileThumbURI();
|
$image_file = $account->getProfileImageFile();
|
||||||
|
$xform = PhabricatorFileTransform::getTransformByKey(
|
||||||
|
PhabricatorFileThumbnailTransform::TRANSFORM_PROFILE);
|
||||||
|
$image_uri = $image_file->getURIForTransform($xform);
|
||||||
|
list($x, $y) = $xform->getTransformedDimensions($image_file);
|
||||||
|
|
||||||
return phutil_tag(
|
return phutil_tag(
|
||||||
'div',
|
'div',
|
||||||
array(
|
array(
|
||||||
'class' => 'auth-account-view',
|
'class' => 'auth-account-view',
|
||||||
'style' => 'background-image: url('.$image_uri.')',
|
'style' => 'background-image: url('.$image_uri.');',
|
||||||
),
|
),
|
||||||
$content);
|
$content);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,21 +20,6 @@ final class PhabricatorImageTransformer {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function executeThumbTransform(
|
|
||||||
PhabricatorFile $file,
|
|
||||||
$x,
|
|
||||||
$y) {
|
|
||||||
|
|
||||||
$image = $this->crudelyScaleTo($file, $x, $y);
|
|
||||||
|
|
||||||
return PhabricatorFile::newFromFileData(
|
|
||||||
$image,
|
|
||||||
array(
|
|
||||||
'name' => 'thumb-'.$file->getName(),
|
|
||||||
'canCDN' => true,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function executeProfileTransform(
|
public function executeProfileTransform(
|
||||||
PhabricatorFile $file,
|
PhabricatorFile $file,
|
||||||
$x,
|
$x,
|
||||||
|
@ -123,21 +108,6 @@ final class PhabricatorImageTransformer {
|
||||||
return self::saveImageDataInAnyFormat($dst, $file->getMimeType());
|
return self::saveImageDataInAnyFormat($dst, $file->getMimeType());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Very crudely scale an image up or down to an exact size.
|
|
||||||
*/
|
|
||||||
private function crudelyScaleTo(PhabricatorFile $file, $dx, $dy) {
|
|
||||||
$scaled = $this->applyScaleWithImagemagick($file, $dx, $dy);
|
|
||||||
|
|
||||||
if ($scaled != null) {
|
|
||||||
return $scaled;
|
|
||||||
}
|
|
||||||
|
|
||||||
$dst = $this->applyScaleTo($file, $dx, $dy);
|
|
||||||
return self::saveImageDataInAnyFormat($dst, $file->getMimeType());
|
|
||||||
}
|
|
||||||
|
|
||||||
private function getBlankDestinationFile($dx, $dy) {
|
private function getBlankDestinationFile($dx, $dy) {
|
||||||
$dst = imagecreatetruecolor($dx, $dy);
|
$dst = imagecreatetruecolor($dx, $dy);
|
||||||
imagesavealpha($dst, true);
|
imagesavealpha($dst, true);
|
||||||
|
|
|
@ -44,50 +44,33 @@ final class PhabricatorFileTransformController
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$type = $file->getMimeType();
|
$xforms = PhabricatorFileTransform::getAllTransforms();
|
||||||
|
if (!isset($xforms[$transform])) {
|
||||||
if (!$file->isViewableInBrowser() || !$file->isTransformableImage()) {
|
return new Aphront404Response();
|
||||||
return $this->buildDefaultTransformation($file, $transform);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$xform = $xforms[$transform];
|
||||||
|
|
||||||
// We're essentially just building a cache here and don't need CSRF
|
// We're essentially just building a cache here and don't need CSRF
|
||||||
// protection.
|
// protection.
|
||||||
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
|
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
|
||||||
|
|
||||||
$xformed_file = null;
|
$xformed_file = null;
|
||||||
|
if ($xform->canApplyTransform($file)) {
|
||||||
$xforms = PhabricatorFileTransform::getAllTransforms();
|
try {
|
||||||
if (isset($xforms[$transform])) {
|
$xformed_file = $xforms[$transform]->applyTransform($file);
|
||||||
$xform = $xforms[$transform];
|
} catch (Exception $ex) {
|
||||||
if ($xform->canApplyTransform($file)) {
|
// In normal transform mode, we ignore failures and generate a
|
||||||
try {
|
// default transform below. If we're explicitly regenerating the
|
||||||
$xformed_file = $xforms[$transform]->applyTransform($file);
|
// thumbnail, rethrow the exception.
|
||||||
} catch (Exception $ex) {
|
if ($is_regenerate) {
|
||||||
// In normal transform mode, we ignore failures and generate a
|
throw $ex;
|
||||||
// default transform below. If we're explicitly regenerating the
|
|
||||||
// thumbnail, rethrow the exception.
|
|
||||||
if ($is_regenerate) {
|
|
||||||
throw $ex;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$xformed_file) {
|
|
||||||
$xformed_file = $xform->getDefaultTransform($file);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$xformed_file) {
|
if (!$xformed_file) {
|
||||||
switch ($transform) {
|
$xformed_file = $xform->getDefaultTransform($file);
|
||||||
case 'thumb-profile':
|
|
||||||
$xformed_file = $this->executeThumbTransform($file, 50, 50);
|
|
||||||
break;
|
|
||||||
case 'thumb-280x210':
|
|
||||||
$xformed_file = $this->executeThumbTransform($file, 280, 210);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return new Aphront400Response();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$xformed_file) {
|
if (!$xformed_file) {
|
||||||
|
@ -103,40 +86,6 @@ final class PhabricatorFileTransformController
|
||||||
return $this->buildTransformedFileResponse($xform);
|
return $this->buildTransformedFileResponse($xform);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildDefaultTransformation(
|
|
||||||
PhabricatorFile $file,
|
|
||||||
$transform) {
|
|
||||||
static $regexps = array(
|
|
||||||
'@application/zip@' => 'zip',
|
|
||||||
'@image/@' => 'image',
|
|
||||||
'@application/pdf@' => 'pdf',
|
|
||||||
'@.*@' => 'default',
|
|
||||||
);
|
|
||||||
|
|
||||||
$type = $file->getMimeType();
|
|
||||||
$prefix = 'default';
|
|
||||||
foreach ($regexps as $regexp => $implied_prefix) {
|
|
||||||
if (preg_match($regexp, $type)) {
|
|
||||||
$prefix = $implied_prefix;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch ($transform) {
|
|
||||||
case 'thumb-280x210':
|
|
||||||
$suffix = '280x210';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new Exception('Unsupported transformation type!');
|
|
||||||
}
|
|
||||||
|
|
||||||
$path = celerity_get_resource_uri(
|
|
||||||
"rsrc/image/icon/fatcow/thumbnails/{$prefix}{$suffix}.png");
|
|
||||||
|
|
||||||
return id(new AphrontRedirectResponse())
|
|
||||||
->setURI($path);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function buildTransformedFileResponse(
|
private function buildTransformedFileResponse(
|
||||||
PhabricatorTransformedFile $xform) {
|
PhabricatorTransformedFile $xform) {
|
||||||
|
|
||||||
|
@ -154,11 +103,6 @@ final class PhabricatorFileTransformController
|
||||||
return $file->getRedirectResponse();
|
return $file->getRedirectResponse();
|
||||||
}
|
}
|
||||||
|
|
||||||
private function executeThumbTransform(PhabricatorFile $file, $x, $y) {
|
|
||||||
$xformer = new PhabricatorImageTransformer();
|
|
||||||
return $xformer->executeThumbTransform($file, $x, $y);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function destroyTransform(PhabricatorTransformedFile $xform) {
|
private function destroyTransform(PhabricatorTransformedFile $xform) {
|
||||||
$file = id(new PhabricatorFileQuery())
|
$file = id(new PhabricatorFileQuery())
|
||||||
->setViewer(PhabricatorUser::getOmnipotentUser())
|
->setViewer(PhabricatorUser::getOmnipotentUser())
|
||||||
|
|
|
@ -784,14 +784,6 @@ final class PhabricatorFile extends PhabricatorFileDAO
|
||||||
return PhabricatorEnv::getCDNURI($path);
|
return PhabricatorEnv::getCDNURI($path);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getProfileThumbURI() {
|
|
||||||
return $this->getTransformedURI('thumb-profile');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getThumb280x210URI() {
|
|
||||||
return $this->getTransformedURI('thumb-280x210');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function isViewableInBrowser() {
|
public function isViewableInBrowser() {
|
||||||
return ($this->getViewableMimeType() !== null);
|
return ($this->getViewableMimeType() !== null);
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,13 +42,20 @@ abstract class PhabricatorFileImageTransform extends PhabricatorFileTransform {
|
||||||
$dst_w, $dst_h,
|
$dst_w, $dst_h,
|
||||||
$src_x, $src_y,
|
$src_x, $src_y,
|
||||||
$src_w, $src_h,
|
$src_w, $src_h,
|
||||||
$use_w, $use_h) {
|
$use_w, $use_h,
|
||||||
|
$scale_up) {
|
||||||
|
|
||||||
|
// Figure out the effective destination width, height, and offsets.
|
||||||
|
$cpy_w = min($dst_w, $use_w);
|
||||||
|
$cpy_h = min($dst_h, $use_h);
|
||||||
|
|
||||||
|
// If we aren't scaling up, and are copying a very small source image,
|
||||||
|
// we're just going to center it in the destination image.
|
||||||
|
if (!$scale_up) {
|
||||||
|
$cpy_w = min($cpy_w, $src_w);
|
||||||
|
$cpy_h = min($cpy_h, $src_h);
|
||||||
|
}
|
||||||
|
|
||||||
// Figure out the effective destination width, height, and offsets. We
|
|
||||||
// never want to scale images up, so if we're copying a very small source
|
|
||||||
// image we're just going to center it in the destination image.
|
|
||||||
$cpy_w = min($dst_w, $src_w, $use_w);
|
|
||||||
$cpy_h = min($dst_h, $src_h, $use_h);
|
|
||||||
$off_x = ($dst_w - $cpy_w) / 2;
|
$off_x = ($dst_w - $cpy_w) / 2;
|
||||||
$off_y = ($dst_h - $cpy_h) / 2;
|
$off_y = ($dst_h - $cpy_h) / 2;
|
||||||
|
|
||||||
|
@ -58,11 +65,18 @@ abstract class PhabricatorFileImageTransform extends PhabricatorFileTransform {
|
||||||
$argv[] = '-shave';
|
$argv[] = '-shave';
|
||||||
$argv[] = $src_x.'x'.$src_y;
|
$argv[] = $src_x.'x'.$src_y;
|
||||||
$argv[] = '-resize';
|
$argv[] = '-resize';
|
||||||
$argv[] = $dst_w.'x'.$dst_h.'>';
|
|
||||||
|
if ($scale_up) {
|
||||||
|
$argv[] = $dst_w.'x'.$dst_h;
|
||||||
|
} else {
|
||||||
|
$argv[] = $dst_w.'x'.$dst_h.'>';
|
||||||
|
}
|
||||||
|
|
||||||
$argv[] = '-bordercolor';
|
$argv[] = '-bordercolor';
|
||||||
$argv[] = 'rgba(255, 255, 255, 0)';
|
$argv[] = 'rgba(255, 255, 255, 0)';
|
||||||
$argv[] = '-border';
|
$argv[] = '-border';
|
||||||
$argv[] = $off_x.'x'.$off_y;
|
$argv[] = $off_x.'x'.$off_y;
|
||||||
|
|
||||||
return $this->applyImagemagick($argv);
|
return $this->applyImagemagick($argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,7 +131,13 @@ abstract class PhabricatorFileImageTransform extends PhabricatorFileTransform {
|
||||||
* @param string Raw file data.
|
* @param string Raw file data.
|
||||||
*/
|
*/
|
||||||
protected function newFileFromData($data) {
|
protected function newFileFromData($data) {
|
||||||
$name = $this->getTransformKey().'-'.$this->file->getName();
|
if ($this->file) {
|
||||||
|
$name = $this->file->getName();
|
||||||
|
} else {
|
||||||
|
$name = 'default.png';
|
||||||
|
}
|
||||||
|
|
||||||
|
$name = $this->getTransformKey().'-'.$name;
|
||||||
|
|
||||||
return PhabricatorFile::newFromFileData(
|
return PhabricatorFile::newFromFileData(
|
||||||
$data,
|
$data,
|
||||||
|
|
|
@ -12,6 +12,7 @@ final class PhabricatorFileThumbnailTransform
|
||||||
private $key;
|
private $key;
|
||||||
private $dstX;
|
private $dstX;
|
||||||
private $dstY;
|
private $dstY;
|
||||||
|
private $scaleUp;
|
||||||
|
|
||||||
public function setName($name) {
|
public function setName($name) {
|
||||||
$this->name = $name;
|
$this->name = $name;
|
||||||
|
@ -29,6 +30,11 @@ final class PhabricatorFileThumbnailTransform
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setScaleUp($scale) {
|
||||||
|
$this->scaleUp = $scale;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function getTransformName() {
|
public function getTransformName() {
|
||||||
return $this->name;
|
return $this->name;
|
||||||
}
|
}
|
||||||
|
@ -42,7 +48,8 @@ final class PhabricatorFileThumbnailTransform
|
||||||
id(new PhabricatorFileThumbnailTransform())
|
id(new PhabricatorFileThumbnailTransform())
|
||||||
->setName(pht("Profile (100px \xC3\x97 100px)"))
|
->setName(pht("Profile (100px \xC3\x97 100px)"))
|
||||||
->setKey(self::TRANSFORM_PROFILE)
|
->setKey(self::TRANSFORM_PROFILE)
|
||||||
->setDimensions(100, 100),
|
->setDimensions(100, 100)
|
||||||
|
->setScaleUp(true),
|
||||||
id(new PhabricatorFileThumbnailTransform())
|
id(new PhabricatorFileThumbnailTransform())
|
||||||
->setName(pht("Pinboard (280px \xC3\x97 210px)"))
|
->setName(pht("Pinboard (280px \xC3\x97 210px)"))
|
||||||
->setKey(self::TRANSFORM_PINBOARD)
|
->setKey(self::TRANSFORM_PINBOARD)
|
||||||
|
@ -86,7 +93,8 @@ final class PhabricatorFileThumbnailTransform
|
||||||
$copy_x,
|
$copy_x,
|
||||||
$copy_y,
|
$copy_y,
|
||||||
$use_x,
|
$use_x,
|
||||||
$use_y);
|
$use_y,
|
||||||
|
$this->scaleUp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -144,22 +152,35 @@ final class PhabricatorFileThumbnailTransform
|
||||||
$copy_x = $src_x;
|
$copy_x = $src_x;
|
||||||
$copy_y = $src_y;
|
$copy_y = $src_y;
|
||||||
} else {
|
} else {
|
||||||
|
$scale_up = $this->scaleUp;
|
||||||
|
|
||||||
// Otherwise, both dimensions are fixed. Figure out how much we'd have to
|
// Otherwise, both dimensions are fixed. Figure out how much we'd have to
|
||||||
// scale the image down along each dimension to get the entire thing to
|
// scale the image down along each dimension to get the entire thing to
|
||||||
// fit.
|
// fit.
|
||||||
$scale_x = min(($dst_x / $src_x), 1);
|
$scale_x = ($dst_x / $src_x);
|
||||||
$scale_y = min(($dst_y / $src_y), 1);
|
$scale_y = ($dst_y / $src_y);
|
||||||
|
|
||||||
|
if (!$scale_up) {
|
||||||
|
$scale_x = min($scale_x, 1);
|
||||||
|
$scale_y = min($scale_y, 1);
|
||||||
|
}
|
||||||
|
|
||||||
if ($scale_x > $scale_y) {
|
if ($scale_x > $scale_y) {
|
||||||
// This image is relatively tall and narrow. We're going to crop off the
|
// This image is relatively tall and narrow. We're going to crop off the
|
||||||
// top and bottom.
|
// top and bottom.
|
||||||
$copy_x = $src_x;
|
$scale = $scale_x;
|
||||||
$copy_y = min($src_y, $dst_y / $scale_x);
|
|
||||||
} else {
|
} else {
|
||||||
// This image is relatively short and wide. We're going to crop off the
|
// This image is relatively short and wide. We're going to crop off the
|
||||||
// left and right.
|
// left and right.
|
||||||
$copy_x = min($src_x, $dst_x / $scale_y);
|
$scale = $scale_y;
|
||||||
$copy_y = $src_y;
|
}
|
||||||
|
|
||||||
|
$copy_x = $dst_x / $scale_x;
|
||||||
|
$copy_y = $dst_y / $scale_x;
|
||||||
|
|
||||||
|
if (!$scale_up) {
|
||||||
|
$copy_x = min($src_x, $copy_x);
|
||||||
|
$copy_y = min($src_y, $copy_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
// In this mode, we always use the entire destination image. We may
|
// In this mode, we always use the entire destination image. We may
|
||||||
|
|
|
@ -179,14 +179,18 @@ final class PhabricatorMacroSearchEngine
|
||||||
assert_instances_of($macros, 'PhabricatorFileImageMacro');
|
assert_instances_of($macros, 'PhabricatorFileImageMacro');
|
||||||
$viewer = $this->requireViewer();
|
$viewer = $this->requireViewer();
|
||||||
|
|
||||||
|
$xform = PhabricatorFileTransform::getTransformByKey(
|
||||||
|
PhabricatorFileThumbnailTransform::TRANSFORM_PINBOARD);
|
||||||
|
|
||||||
$pinboard = new PHUIPinboardView();
|
$pinboard = new PHUIPinboardView();
|
||||||
foreach ($macros as $macro) {
|
foreach ($macros as $macro) {
|
||||||
$file = $macro->getFile();
|
$file = $macro->getFile();
|
||||||
|
|
||||||
$item = new PHUIPinboardItemView();
|
$item = new PHUIPinboardItemView();
|
||||||
if ($file) {
|
if ($file) {
|
||||||
$item->setImageURI($file->getThumb280x210URI());
|
$item->setImageURI($file->getURIForTransform($xform));
|
||||||
$item->setImageSize(280, 210);
|
list($x, $y) = $xform->getTransformedDimensions($file);
|
||||||
|
$item->setImageSize($x, $y);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($macro->getDateCreated()) {
|
if ($macro->getDateCreated()) {
|
||||||
|
|
|
@ -141,15 +141,22 @@ final class PholioMockSearchEngine extends PhabricatorApplicationSearchEngine {
|
||||||
|
|
||||||
$viewer = $this->requireViewer();
|
$viewer = $this->requireViewer();
|
||||||
|
|
||||||
|
$xform = PhabricatorFileTransform::getTransformByKey(
|
||||||
|
PhabricatorFileThumbnailTransform::TRANSFORM_PINBOARD);
|
||||||
|
|
||||||
$board = new PHUIPinboardView();
|
$board = new PHUIPinboardView();
|
||||||
foreach ($mocks as $mock) {
|
foreach ($mocks as $mock) {
|
||||||
|
|
||||||
|
$image = $mock->getCoverFile();
|
||||||
|
$image_uri = $image->getURIForTransform($xform);
|
||||||
|
list($x, $y) = $xform->getTransformedDimensions($image);
|
||||||
|
|
||||||
$header = 'M'.$mock->getID().' '.$mock->getName();
|
$header = 'M'.$mock->getID().' '.$mock->getName();
|
||||||
$item = id(new PHUIPinboardItemView())
|
$item = id(new PHUIPinboardItemView())
|
||||||
->setHeader($header)
|
->setHeader($header)
|
||||||
->setURI('/M'.$mock->getID())
|
->setURI('/M'.$mock->getID())
|
||||||
->setImageURI($mock->getCoverFile()->getThumb280x210URI())
|
->setImageURI($image_uri)
|
||||||
->setImageSize(280, 210)
|
->setImageSize($x, $y)
|
||||||
->setDisabled($mock->isClosed())
|
->setDisabled($mock->isClosed())
|
||||||
->addIconCount('fa-picture-o', count($mock->getImages()))
|
->addIconCount('fa-picture-o', count($mock->getImages()))
|
||||||
->addIconCount('fa-trophy', $mock->getTokenCount());
|
->addIconCount('fa-trophy', $mock->getTokenCount());
|
||||||
|
|
|
@ -28,25 +28,29 @@ final class PholioMockEmbedView extends AphrontView {
|
||||||
$this->mock->getImages(), array_flip($this->images));
|
$this->mock->getImages(), array_flip($this->images));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$xform = PhabricatorFileTransform::getTransformByKey(
|
||||||
|
PhabricatorFileThumbnailTransform::TRANSFORM_PINBOARD);
|
||||||
|
|
||||||
if ($images_to_show) {
|
if ($images_to_show) {
|
||||||
foreach ($images_to_show as $image) {
|
$image = head($images_to_show);
|
||||||
$thumbfile = $image->getFile();
|
$thumbfile = $image->getFile();
|
||||||
$thumbnail = $thumbfile->getThumb280x210URI();
|
|
||||||
}
|
|
||||||
$header = 'M'.$mock->getID().' '.$mock->getName().
|
$header = 'M'.$mock->getID().' '.$mock->getName().
|
||||||
' (#'.$image->getID().')';
|
' (#'.$image->getID().')';
|
||||||
$uri = '/M'.$this->mock->getID().'/'.$image->getID().'/';
|
$uri = '/M'.$this->mock->getID().'/'.$image->getID().'/';
|
||||||
} else {
|
} else {
|
||||||
$thumbnail = $mock->getCoverFile()->getThumb280x210URI();
|
$thumbfile = $mock->getCoverFile();
|
||||||
$header = 'M'.$mock->getID().' '.$mock->getName();
|
$header = 'M'.$mock->getID().' '.$mock->getName();
|
||||||
$uri = '/M'.$this->mock->getID();
|
$uri = '/M'.$this->mock->getID();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$thumbnail = $thumbfile->getURIForTransform($xform);
|
||||||
|
list($x, $y) = $xform->getTransformedDimensions($thumbfile);
|
||||||
|
|
||||||
$item = id(new PHUIPinboardItemView())
|
$item = id(new PHUIPinboardItemView())
|
||||||
->setHeader($header)
|
->setHeader($header)
|
||||||
->setURI($uri)
|
->setURI($uri)
|
||||||
->setImageURI($thumbnail)
|
->setImageURI($thumbnail)
|
||||||
->setImageSize(280, 210)
|
->setImageSize($x, $y)
|
||||||
->setDisabled($mock->isClosed())
|
->setDisabled($mock->isClosed())
|
||||||
->addIconCount('fa-picture-o', count($mock->getImages()))
|
->addIconCount('fa-picture-o', count($mock->getImages()))
|
||||||
->addIconCount('fa-trophy', $mock->getTokenCount());
|
->addIconCount('fa-trophy', $mock->getTokenCount());
|
||||||
|
|
|
@ -68,8 +68,11 @@ final class PholioMockImagesView extends AphrontView {
|
||||||
|
|
||||||
// TODO: We could maybe do a better job with tailoring this, which is the
|
// TODO: We could maybe do a better job with tailoring this, which is the
|
||||||
// image shown on the review stage.
|
// image shown on the review stage.
|
||||||
$nonimage_uri = celerity_get_resource_uri(
|
$default_name = 'image-100x100.png';
|
||||||
'rsrc/image/icon/fatcow/thumbnails/default.p100.png');
|
$builtins = PhabricatorFile::loadBuiltins(
|
||||||
|
$this->getUser(),
|
||||||
|
array($default_name));
|
||||||
|
$default = $builtins[$default_name];
|
||||||
|
|
||||||
$engine = id(new PhabricatorMarkupEngine())
|
$engine = id(new PhabricatorMarkupEngine())
|
||||||
->setViewer($this->getUser());
|
->setViewer($this->getUser());
|
||||||
|
@ -97,7 +100,7 @@ final class PholioMockImagesView extends AphrontView {
|
||||||
'fullURI' => $file->getBestURI(),
|
'fullURI' => $file->getBestURI(),
|
||||||
'stageURI' => ($file->isViewableImage()
|
'stageURI' => ($file->isViewableImage()
|
||||||
? $file->getBestURI()
|
? $file->getBestURI()
|
||||||
: $nonimage_uri),
|
: $default->getBestURI()),
|
||||||
'pageURI' => $this->getImagePageURI($image, $mock),
|
'pageURI' => $this->getImagePageURI($image, $mock),
|
||||||
'downloadURI' => $file->getDownloadURI(),
|
'downloadURI' => $file->getDownloadURI(),
|
||||||
'historyURI' => $history_uri,
|
'historyURI' => $history_uri,
|
||||||
|
|
|
@ -38,11 +38,15 @@ final class PholioUploadedImageView extends AphrontView {
|
||||||
->setSigil('image-description')
|
->setSigil('image-description')
|
||||||
->setLabel(pht('Description'));
|
->setLabel(pht('Description'));
|
||||||
|
|
||||||
|
$xform = PhabricatorFileTransform::getTransformByKey(
|
||||||
|
PhabricatorFileThumbnailTransform::TRANSFORM_PINBOARD);
|
||||||
|
$thumbnail_uri = $file->getURIForTransform($xform);
|
||||||
|
|
||||||
$thumb_frame = phutil_tag(
|
$thumb_frame = phutil_tag(
|
||||||
'div',
|
'div',
|
||||||
array(
|
array(
|
||||||
'class' => 'pholio-thumb-frame',
|
'class' => 'pholio-thumb-frame',
|
||||||
'style' => 'background-image: url('.$file->getThumb280x210URI().');',
|
'style' => 'background-image: url('.$thumbnail_uri.');',
|
||||||
));
|
));
|
||||||
|
|
||||||
$handle = javelin_tag(
|
$handle = javelin_tag(
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
border: 1px solid {$lightblueborder};
|
border: 1px solid {$lightblueborder};
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: 4px 4px;
|
background-position: 4px 4px;
|
||||||
|
background-size: 50px 50px;
|
||||||
padding: 4px 4px 4px 62px;
|
padding: 4px 4px 4px 62px;
|
||||||
min-height: 50px;
|
min-height: 50px;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 2.1 KiB |
Binary file not shown.
Before Width: | Height: | Size: 2.5 KiB |
Binary file not shown.
Before Width: | Height: | Size: 2.8 KiB |
Binary file not shown.
Before Width: | Height: | Size: 2.5 KiB |
Loading…
Add table
Reference in a new issue