@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.

Support audio files with HTML5 `<audio />`

Summary: Ref T3887. Similar to how we render images with `<img />`, render audio with `<audio />` if possible.

Test Plan: See screenshots.

Reviewers: btrahan, chad

Reviewed By: btrahan

CC: aran

Maniphest Tasks: T3887

Differential Revision: https://secure.phabricator.com/D7156

+144 -49
+47 -47
src/__celerity_resource_map__.php
··· 3358 3358 ), 3359 3359 'phabricator-property-list-view-css' => 3360 3360 array( 3361 - 'uri' => '/res/3a0ffc53/rsrc/css/layout/phabricator-property-list-view.css', 3361 + 'uri' => '/res/d0d42da3/rsrc/css/layout/phabricator-property-list-view.css', 3362 3362 'type' => 'css', 3363 3363 'requires' => 3364 3364 array( ··· 3367 3367 ), 3368 3368 'phabricator-remarkup-css' => 3369 3369 array( 3370 - 'uri' => '/res/e0f773b1/rsrc/css/core/remarkup.css', 3370 + 'uri' => '/res/974df8e6/rsrc/css/core/remarkup.css', 3371 3371 'type' => 'css', 3372 3372 'requires' => 3373 3373 array( ··· 4162 4162 ), array( 4163 4163 'packages' => 4164 4164 array( 4165 - 'e9892921' => 4165 + 'f44a66c5' => 4166 4166 array( 4167 4167 'name' => 'core.pkg.css', 4168 4168 'symbols' => ··· 4211 4211 41 => 'phabricator-tag-view-css', 4212 4212 42 => 'phui-list-view-css', 4213 4213 ), 4214 - 'uri' => '/res/pkg/e9892921/core.pkg.css', 4214 + 'uri' => '/res/pkg/f44a66c5/core.pkg.css', 4215 4215 'type' => 'css', 4216 4216 ), 4217 4217 '64eeda79' => ··· 4403 4403 ), 4404 4404 'reverse' => 4405 4405 array( 4406 - 'aphront-dialog-view-css' => 'e9892921', 4407 - 'aphront-error-view-css' => 'e9892921', 4408 - 'aphront-list-filter-view-css' => 'e9892921', 4409 - 'aphront-pager-view-css' => 'e9892921', 4410 - 'aphront-panel-view-css' => 'e9892921', 4411 - 'aphront-table-view-css' => 'e9892921', 4412 - 'aphront-tokenizer-control-css' => 'e9892921', 4413 - 'aphront-tooltip-css' => 'e9892921', 4414 - 'aphront-typeahead-control-css' => 'e9892921', 4406 + 'aphront-dialog-view-css' => 'f44a66c5', 4407 + 'aphront-error-view-css' => 'f44a66c5', 4408 + 'aphront-list-filter-view-css' => 'f44a66c5', 4409 + 'aphront-pager-view-css' => 'f44a66c5', 4410 + 'aphront-panel-view-css' => 'f44a66c5', 4411 + 'aphront-table-view-css' => 'f44a66c5', 4412 + 'aphront-tokenizer-control-css' => 'f44a66c5', 4413 + 'aphront-tooltip-css' => 'f44a66c5', 4414 + 'aphront-typeahead-control-css' => 'f44a66c5', 4415 4415 'differential-changeset-view-css' => '44bfe40c', 4416 4416 'differential-core-view-css' => '44bfe40c', 4417 4417 'differential-inline-comment-editor' => '5e9e5c4e', ··· 4425 4425 'differential-table-of-contents-css' => '44bfe40c', 4426 4426 'diffusion-commit-view-css' => 'c8ce2d88', 4427 4427 'diffusion-icons-css' => 'c8ce2d88', 4428 - 'global-drag-and-drop-css' => 'e9892921', 4428 + 'global-drag-and-drop-css' => 'f44a66c5', 4429 4429 'inline-comment-summary-css' => '44bfe40c', 4430 4430 'javelin-aphlict' => '64eeda79', 4431 4431 'javelin-behavior' => '9564fa17', ··· 4500 4500 'javelin-util' => '9564fa17', 4501 4501 'javelin-vector' => '9564fa17', 4502 4502 'javelin-workflow' => '9564fa17', 4503 - 'lightbox-attachment-css' => 'e9892921', 4503 + 'lightbox-attachment-css' => 'f44a66c5', 4504 4504 'maniphest-task-summary-css' => '49898640', 4505 - 'phabricator-action-list-view-css' => 'e9892921', 4506 - 'phabricator-application-launch-view-css' => 'e9892921', 4505 + 'phabricator-action-list-view-css' => 'f44a66c5', 4506 + 'phabricator-application-launch-view-css' => 'f44a66c5', 4507 4507 'phabricator-busy' => '64eeda79', 4508 4508 'phabricator-content-source-view-css' => '44bfe40c', 4509 - 'phabricator-core-css' => 'e9892921', 4510 - 'phabricator-crumbs-view-css' => 'e9892921', 4509 + 'phabricator-core-css' => 'f44a66c5', 4510 + 'phabricator-crumbs-view-css' => 'f44a66c5', 4511 4511 'phabricator-drag-and-drop-file-upload' => '5e9e5c4e', 4512 4512 'phabricator-dropdown-menu' => '64eeda79', 4513 4513 'phabricator-file-upload' => '64eeda79', 4514 - 'phabricator-filetree-view-css' => 'e9892921', 4515 - 'phabricator-flag-css' => 'e9892921', 4514 + 'phabricator-filetree-view-css' => 'f44a66c5', 4515 + 'phabricator-flag-css' => 'f44a66c5', 4516 4516 'phabricator-hovercard' => '64eeda79', 4517 - 'phabricator-jump-nav' => 'e9892921', 4517 + 'phabricator-jump-nav' => 'f44a66c5', 4518 4518 'phabricator-keyboard-shortcut' => '64eeda79', 4519 4519 'phabricator-keyboard-shortcut-manager' => '64eeda79', 4520 - 'phabricator-main-menu-view' => 'e9892921', 4520 + 'phabricator-main-menu-view' => 'f44a66c5', 4521 4521 'phabricator-menu-item' => '64eeda79', 4522 - 'phabricator-nav-view-css' => 'e9892921', 4522 + 'phabricator-nav-view-css' => 'f44a66c5', 4523 4523 'phabricator-notification' => '64eeda79', 4524 - 'phabricator-notification-css' => 'e9892921', 4525 - 'phabricator-notification-menu-css' => 'e9892921', 4524 + 'phabricator-notification-css' => 'f44a66c5', 4525 + 'phabricator-notification-menu-css' => 'f44a66c5', 4526 4526 'phabricator-object-selector-css' => '44bfe40c', 4527 4527 'phabricator-phtize' => '64eeda79', 4528 4528 'phabricator-prefab' => '64eeda79', 4529 4529 'phabricator-project-tag-css' => '49898640', 4530 - 'phabricator-property-list-view-css' => 'e9892921', 4531 - 'phabricator-remarkup-css' => 'e9892921', 4530 + 'phabricator-property-list-view-css' => 'f44a66c5', 4531 + 'phabricator-remarkup-css' => 'f44a66c5', 4532 4532 'phabricator-shaped-request' => '5e9e5c4e', 4533 - 'phabricator-side-menu-view-css' => 'e9892921', 4534 - 'phabricator-standard-page-view' => 'e9892921', 4535 - 'phabricator-tag-view-css' => 'e9892921', 4533 + 'phabricator-side-menu-view-css' => 'f44a66c5', 4534 + 'phabricator-standard-page-view' => 'f44a66c5', 4535 + 'phabricator-tag-view-css' => 'f44a66c5', 4536 4536 'phabricator-textareautils' => '64eeda79', 4537 4537 'phabricator-tooltip' => '64eeda79', 4538 - 'phabricator-transaction-view-css' => 'e9892921', 4539 - 'phabricator-zindex-css' => 'e9892921', 4540 - 'phui-button-css' => 'e9892921', 4541 - 'phui-form-css' => 'e9892921', 4542 - 'phui-form-view-css' => 'e9892921', 4543 - 'phui-header-view-css' => 'e9892921', 4544 - 'phui-icon-view-css' => 'e9892921', 4545 - 'phui-list-view-css' => 'e9892921', 4546 - 'phui-object-item-list-view-css' => 'e9892921', 4547 - 'phui-spacing-css' => 'e9892921', 4548 - 'sprite-apps-large-css' => 'e9892921', 4549 - 'sprite-gradient-css' => 'e9892921', 4550 - 'sprite-icons-css' => 'e9892921', 4551 - 'sprite-menu-css' => 'e9892921', 4552 - 'sprite-status-css' => 'e9892921', 4553 - 'syntax-highlighting-css' => 'e9892921', 4538 + 'phabricator-transaction-view-css' => 'f44a66c5', 4539 + 'phabricator-zindex-css' => 'f44a66c5', 4540 + 'phui-button-css' => 'f44a66c5', 4541 + 'phui-form-css' => 'f44a66c5', 4542 + 'phui-form-view-css' => 'f44a66c5', 4543 + 'phui-header-view-css' => 'f44a66c5', 4544 + 'phui-icon-view-css' => 'f44a66c5', 4545 + 'phui-list-view-css' => 'f44a66c5', 4546 + 'phui-object-item-list-view-css' => 'f44a66c5', 4547 + 'phui-spacing-css' => 'f44a66c5', 4548 + 'sprite-apps-large-css' => 'f44a66c5', 4549 + 'sprite-gradient-css' => 'f44a66c5', 4550 + 'sprite-icons-css' => 'f44a66c5', 4551 + 'sprite-menu-css' => 'f44a66c5', 4552 + 'sprite-status-css' => 'f44a66c5', 4553 + 'syntax-highlighting-css' => 'f44a66c5', 4554 4554 ), 4555 4555 ));
+17 -1
src/applications/files/config/PhabricatorFilesConfigOptions.php
··· 29 29 'image/x-ico' => 'image/x-icon', 30 30 'image/x-icon' => 'image/x-icon', 31 31 'image/vnd.microsoft.icon' => 'image/x-icon', 32 + 33 + 'audio/x-wav' => 'audio/x-wav', 34 + 'application/ogg' => 'application/ogg', 35 + 'audio/mpeg' => 'audio/mpeg', 32 36 ); 33 37 34 38 $image_default = array( ··· 39 43 'image/x-ico' => true, 40 44 'image/x-icon' => true, 41 45 'image/vnd.microsoft.icon' => true, 46 + ); 47 + 48 + $audio_default = array( 49 + 'audio/x-wav' => true, 50 + 'application/ogg' => true, 51 + 'audio/mpeg' => true, 42 52 ); 43 53 44 54 // largely lifted from http://en.wikipedia.org/wiki/Internet_media_type ··· 82 92 'browsers tend to freak out when viewing enormous binary files.'. 83 93 "\n\n". 84 94 'The keys in this map are vieweable MIME types; the values are '. 85 - 'the MIME type sthey are delivered as when they are viewed in '. 95 + 'the MIME types they are delivered as when they are viewed in '. 86 96 'the browser.')), 87 97 $this->newOption('files.image-mime-types', 'set', $image_default) 88 98 ->setSummary(pht('Configure which MIME types are images.')) ··· 90 100 pht( 91 101 'List of MIME types which can be used as the `src` for an '. 92 102 '`<img />` tag.')), 103 + $this->newOption('files.audio-mime-types', 'set', $audio_default) 104 + ->setSummary(pht('Configure which MIME types are audio.')) 105 + ->setDescription( 106 + pht( 107 + 'List of MIME types which can be used to render an '. 108 + '`<audio />` tag.')), 93 109 $this->newOption('files.icon-mime-types', 'wild', $icon_default) 94 110 ->setSummary(pht('Configure which MIME types map to which icons.')) 95 111 ->setDescription(
+14
src/applications/files/controller/PhabricatorFileInfoController.php
··· 217 217 $image); 218 218 219 219 $view->addImageContent($linked_image); 220 + } else if ($file->isAudio()) { 221 + $audio = phutil_tag( 222 + 'audio', 223 + array( 224 + 'controls' => 'controls', 225 + 'class' => 'phabricator-property-list-audio', 226 + ), 227 + phutil_tag( 228 + 'source', 229 + array( 230 + 'src' => $file->getViewURI(), 231 + 'type' => $file->getMimeType(), 232 + ))); 233 + $view->addImageContent($audio); 220 234 } 221 235 222 236 return $view;
+42 -1
src/applications/files/remarkup/PhabricatorRemarkupRuleEmbedFile.php
··· 57 57 $options['name'] = $file_name; 58 58 59 59 $is_viewable_image = $file->isViewableImage(); 60 + $is_audio = $file->isAudio(); 60 61 61 62 $attrs = array(); 62 63 if ($is_viewable_image) { ··· 91 92 $bundle['meta'] = array( 92 93 'phid' => $file->getPHID(), 93 94 'viewable' => $is_viewable_image, 95 + 'audio' => $is_audio, 94 96 'uri' => $file->getBestURI(), 95 97 'dUri' => $file->getDownloadURI(), 96 98 'name' => $options['name'], 99 + 'mime' => $file->getMimeType(), 97 100 ); 101 + 102 + if ($is_audio) { 103 + $bundle['meta'] += array( 104 + 'autoplay' => idx($options, 'autoplay'), 105 + 'loop' => idx($options, 'loop'), 106 + ); 107 + } 108 + 98 109 $metadata[$phid][] = $bundle; 99 110 $engine->setTextMetadata($metadata_key, $metadata); 100 111 ··· 118 129 $options = $data['options']; 119 130 $meta = $data['meta']; 120 131 121 - if (!$meta['viewable'] || $options['layout'] == 'link') { 132 + $is_image = idx($meta, 'viewable'); 133 + $is_audio = idx($meta, 'audio'); 134 + 135 + if ((!$is_image && !$is_audio) || $options['layout'] == 'link') { 122 136 $link = id(new PhabricatorFileLinkView()) 123 137 ->setFilePHID($meta['phid']) 124 138 ->setFileName($meta['name']) ··· 127 141 ->setFileViewable($meta['viewable']); 128 142 $embed = $link->render(); 129 143 $engine->overwriteStoredText($data['token'], $embed); 144 + continue; 145 + } 146 + 147 + if ($is_audio) { 148 + if (idx($options, 'autoplay')) { 149 + $preload = 'auto'; 150 + $autoplay = 'autoplay'; 151 + } else { 152 + $preload = 'none'; 153 + $autoplay = null; 154 + } 155 + 156 + $link = phutil_tag( 157 + 'audio', 158 + array( 159 + 'controls' => 'controls', 160 + 'preload' => $preload, 161 + 'autoplay' => $autoplay, 162 + 'loop' => idx($options, 'loop') ? 'loop' : null, 163 + ), 164 + phutil_tag( 165 + 'source', 166 + array( 167 + 'src' => $meta['uri'], 168 + 'type' => $meta['mime'], 169 + ))); 170 + $engine->overwriteStoredText($data['token'], $link); 130 171 continue; 131 172 } 132 173
+10
src/applications/files/storage/PhabricatorFile.php
··· 564 564 return idx($mime_map, $mime_type); 565 565 } 566 566 567 + public function isAudio() { 568 + if (!$this->isViewableInBrowser()) { 569 + return false; 570 + } 571 + 572 + $mime_map = PhabricatorEnv::getEnvConfig('files.audio-mime-types'); 573 + $mime_type = $this->getMimeType(); 574 + return idx($mime_map, $mime_type); 575 + } 576 + 567 577 public function isTransformableImage() { 568 578 569 579 // NOTE: The way the 'gd' extension works in PHP is that you can install it
+7
webroot/rsrc/css/core/remarkup.css
··· 148 148 max-height: 640px; 149 149 } 150 150 151 + .phabricator-remarkup audio { 152 + display: block; 153 + margin: 16px auto; 154 + min-width: 300px; 155 + width: 50%; 156 + } 157 + 151 158 .phabricator-remarkup-mention-exists { 152 159 font-weight: bold; 153 160 background: #e6f3ff;
+7
webroot/rsrc/css/layout/phabricator-property-list-view.css
··· 115 115 max-width: 95%; 116 116 } 117 117 118 + .phabricator-property-list-audio { 119 + display: block; 120 + margin: 16px auto; 121 + width: 50%; 122 + min-width: 300px; 123 + } 124 + 118 125 /* When tags appear in property lists, give them a little more vertical 119 126 spacing. */ 120 127 .phabricator-property-list-view .phabricator-tag-view {