Skip to content

Commit 5664c83

Browse files
author
epriestley
committedApr 6, 2016
Reduce thumbnail flickering in comment previews
Summary: Ref T10262. Currently, we always render a tag like this when you `{F123}` an image in remarkup: ``` <img src="/xform/preview/abcdef/" /> ``` This either generates the preview or redirects to an existing preview. This is a good behavior in general, because the preview may take a while to generate and we don't want to wait for it to generate on the server side. However, this flickers a lot in Safari. We might be able to cache this, but we really shouldn't, since the preview URI isn't a legitimately stable/permanent one. Instead, do a (cheap) server-side check to see if the preview already exists. If it does, return a direct URI. This gives us a stable thumbnail in Safari. Test Plan: - Dragged a dog picture into comment box. - Typed text. - Thing didn't flicker like crazy all the time in Safari. Reviewers: chad Reviewed By: chad Maniphest Tasks: T10262 Differential Revision: https://secure.phabricator.com/D15646
1 parent 8aad862 commit 5664c83

File tree

4 files changed

+77
-9
lines changed

4 files changed

+77
-9
lines changed
 

‎src/aphront/response/AphrontResponse.php

+10-8
Original file line numberDiff line numberDiff line change
@@ -192,18 +192,20 @@ protected function addJSONShield($json_response) {
192192
public function getCacheHeaders() {
193193
$headers = array();
194194
if ($this->cacheable) {
195+
$cache_control = array();
196+
$cache_control[] = sprintf('max-age=%d', $this->cacheable);
197+
195198
if ($this->canCDN) {
196-
$headers[] = array(
197-
'Cache-Control',
198-
'public',
199-
);
199+
$cache_control[] = 'public';
200200
} else {
201-
$headers[] = array(
202-
'Cache-Control',
203-
'private',
204-
);
201+
$cache_control[] = 'private';
205202
}
206203

204+
$headers[] = array(
205+
'Cache-Control',
206+
implode(', ', $cache_control),
207+
);
208+
207209
$headers[] = array(
208210
'Expires',
209211
$this->formatEpochTimestampForHTTPHeader(time() + $this->cacheable),

‎src/applications/files/markup/PhabricatorEmbedFileRemarkupRule.php

+13-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ protected function loadObjects(array $ids) {
1616
$objects = id(new PhabricatorFileQuery())
1717
->setViewer($viewer)
1818
->withIDs($ids)
19+
->needTransforms(
20+
array(
21+
PhabricatorFileThumbnailTransform::TRANSFORM_PREVIEW,
22+
))
1923
->execute();
2024

2125
$phids_key = self::KEY_EMBED_FILE_PHIDS;
@@ -109,7 +113,15 @@ private function renderImageFile(
109113
default:
110114
$preview_key = PhabricatorFileThumbnailTransform::TRANSFORM_PREVIEW;
111115
$xform = PhabricatorFileTransform::getTransformByKey($preview_key);
112-
$attrs['src'] = $file->getURIForTransform($xform);
116+
117+
$existing_xform = $file->getTransform($preview_key);
118+
if ($existing_xform) {
119+
$xform_uri = $existing_xform->getCDNURI();
120+
} else {
121+
$xform_uri = $file->getURIForTransform($xform);
122+
}
123+
124+
$attrs['src'] = $xform_uri;
113125

114126
$dimensions = $xform->getTransformedDimensions($file);
115127
if ($dimensions) {

‎src/applications/files/query/PhabricatorFileQuery.php

+44
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ final class PhabricatorFileQuery
1515
private $maxLength;
1616
private $names;
1717
private $isPartial;
18+
private $needTransforms;
1819

1920
public function withIDs(array $ids) {
2021
$this->ids = $ids;
@@ -117,6 +118,11 @@ public function showOnlyExplicitUploads($explicit_uploads) {
117118
return $this;
118119
}
119120

121+
public function needTransforms(array $transforms) {
122+
$this->needTransforms = $transforms;
123+
return $this;
124+
}
125+
120126
public function newResultObject() {
121127
return new PhabricatorFile();
122128
}
@@ -218,6 +224,44 @@ protected function loadPage() {
218224
return $files;
219225
}
220226

227+
protected function didFilterPage(array $files) {
228+
$xform_keys = $this->needTransforms;
229+
if ($xform_keys !== null) {
230+
$xforms = id(new PhabricatorTransformedFile())->loadAllWhere(
231+
'originalPHID IN (%Ls) AND transform IN (%Ls)',
232+
mpull($files, 'getPHID'),
233+
$xform_keys);
234+
235+
if ($xforms) {
236+
$xfiles = id(new PhabricatorFile())->loadAllWhere(
237+
'phid IN (%Ls)',
238+
mpull($xforms, 'getTransformedPHID'));
239+
$xfiles = mpull($xfiles, null, 'getPHID');
240+
}
241+
242+
$xform_map = array();
243+
foreach ($xforms as $xform) {
244+
$xfile = idx($xfiles, $xform->getTransformedPHID());
245+
if (!$xfile) {
246+
continue;
247+
}
248+
$original_phid = $xform->getOriginalPHID();
249+
$xform_key = $xform->getTransform();
250+
$xform_map[$original_phid][$xform_key] = $xfile;
251+
}
252+
253+
$default_xforms = array_fill_keys($xform_keys, null);
254+
255+
foreach ($files as $file) {
256+
$file_xforms = idx($xform_map, $file->getPHID(), array());
257+
$file_xforms += $default_xforms;
258+
$file->attachTransforms($file_xforms);
259+
}
260+
}
261+
262+
return $files;
263+
}
264+
221265
protected function buildJoinClauseParts(AphrontDatabaseConnection $conn) {
222266
$joins = parent::buildJoinClauseParts($conn);
223267

‎src/applications/files/storage/PhabricatorFile.php

+10
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ final class PhabricatorFile extends PhabricatorFileDAO
5656
private $objects = self::ATTACHABLE;
5757
private $objectPHIDs = self::ATTACHABLE;
5858
private $originalFile = self::ATTACHABLE;
59+
private $transforms = self::ATTACHABLE;
5960

6061
public static function initializeNewFile() {
6162
$app = id(new PhabricatorApplicationQuery())
@@ -1208,6 +1209,15 @@ public function getRedirectResponse() {
12081209
->setURI($uri);
12091210
}
12101211

1212+
public function attachTransforms(array $map) {
1213+
$this->transforms = $map;
1214+
return $this;
1215+
}
1216+
1217+
public function getTransform($key) {
1218+
return $this->assertAttachedKey($this->transforms, $key);
1219+
}
1220+
12111221

12121222
/* -( PhabricatorApplicationTransactionInterface )------------------------- */
12131223

0 commit comments

Comments
 (0)
Failed to load comments.