@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+77 -9
+10 -8
src/aphront/response/AphrontResponse.php
··· 192 192 public function getCacheHeaders() { 193 193 $headers = array(); 194 194 if ($this->cacheable) { 195 + $cache_control = array(); 196 + $cache_control[] = sprintf('max-age=%d', $this->cacheable); 197 + 195 198 if ($this->canCDN) { 196 - $headers[] = array( 197 - 'Cache-Control', 198 - 'public', 199 - ); 199 + $cache_control[] = 'public'; 200 200 } else { 201 - $headers[] = array( 202 - 'Cache-Control', 203 - 'private', 204 - ); 201 + $cache_control[] = 'private'; 205 202 } 203 + 204 + $headers[] = array( 205 + 'Cache-Control', 206 + implode(', ', $cache_control), 207 + ); 206 208 207 209 $headers[] = array( 208 210 'Expires',
+13 -1
src/applications/files/markup/PhabricatorEmbedFileRemarkupRule.php
··· 16 16 $objects = id(new PhabricatorFileQuery()) 17 17 ->setViewer($viewer) 18 18 ->withIDs($ids) 19 + ->needTransforms( 20 + array( 21 + PhabricatorFileThumbnailTransform::TRANSFORM_PREVIEW, 22 + )) 19 23 ->execute(); 20 24 21 25 $phids_key = self::KEY_EMBED_FILE_PHIDS; ··· 109 113 default: 110 114 $preview_key = PhabricatorFileThumbnailTransform::TRANSFORM_PREVIEW; 111 115 $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; 113 125 114 126 $dimensions = $xform->getTransformedDimensions($file); 115 127 if ($dimensions) {
+44
src/applications/files/query/PhabricatorFileQuery.php
··· 15 15 private $maxLength; 16 16 private $names; 17 17 private $isPartial; 18 + private $needTransforms; 18 19 19 20 public function withIDs(array $ids) { 20 21 $this->ids = $ids; ··· 114 115 115 116 public function showOnlyExplicitUploads($explicit_uploads) { 116 117 $this->explicitUploads = $explicit_uploads; 118 + return $this; 119 + } 120 + 121 + public function needTransforms(array $transforms) { 122 + $this->needTransforms = $transforms; 117 123 return $this; 118 124 } 119 125 ··· 213 219 $original = null; 214 220 } 215 221 $file->attachOriginalFile($original); 222 + } 223 + 224 + return $files; 225 + } 226 + 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 + } 216 260 } 217 261 218 262 return $files;
+10
src/applications/files/storage/PhabricatorFile.php
··· 56 56 private $objects = self::ATTACHABLE; 57 57 private $objectPHIDs = self::ATTACHABLE; 58 58 private $originalFile = self::ATTACHABLE; 59 + private $transforms = self::ATTACHABLE; 59 60 60 61 public static function initializeNewFile() { 61 62 $app = id(new PhabricatorApplicationQuery()) ··· 1206 1207 return id(new AphrontRedirectResponse()) 1207 1208 ->setIsExternal($is_external) 1208 1209 ->setURI($uri); 1210 + } 1211 + 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); 1209 1219 } 1210 1220 1211 1221