1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-28 16:30:59 +01:00

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
This commit is contained in:
epriestley 2013-09-27 10:51:25 -07:00
parent ec02ac1806
commit 8e88a78c20
7 changed files with 144 additions and 49 deletions

View file

@ -3358,7 +3358,7 @@ celerity_register_resource_map(array(
),
'phabricator-property-list-view-css' =>
array(
'uri' => '/res/3a0ffc53/rsrc/css/layout/phabricator-property-list-view.css',
'uri' => '/res/d0d42da3/rsrc/css/layout/phabricator-property-list-view.css',
'type' => 'css',
'requires' =>
array(
@ -3367,7 +3367,7 @@ celerity_register_resource_map(array(
),
'phabricator-remarkup-css' =>
array(
'uri' => '/res/e0f773b1/rsrc/css/core/remarkup.css',
'uri' => '/res/974df8e6/rsrc/css/core/remarkup.css',
'type' => 'css',
'requires' =>
array(
@ -4162,7 +4162,7 @@ celerity_register_resource_map(array(
), array(
'packages' =>
array(
'e9892921' =>
'f44a66c5' =>
array(
'name' => 'core.pkg.css',
'symbols' =>
@ -4211,7 +4211,7 @@ celerity_register_resource_map(array(
41 => 'phabricator-tag-view-css',
42 => 'phui-list-view-css',
),
'uri' => '/res/pkg/e9892921/core.pkg.css',
'uri' => '/res/pkg/f44a66c5/core.pkg.css',
'type' => 'css',
),
'64eeda79' =>
@ -4403,15 +4403,15 @@ celerity_register_resource_map(array(
),
'reverse' =>
array(
'aphront-dialog-view-css' => 'e9892921',
'aphront-error-view-css' => 'e9892921',
'aphront-list-filter-view-css' => 'e9892921',
'aphront-pager-view-css' => 'e9892921',
'aphront-panel-view-css' => 'e9892921',
'aphront-table-view-css' => 'e9892921',
'aphront-tokenizer-control-css' => 'e9892921',
'aphront-tooltip-css' => 'e9892921',
'aphront-typeahead-control-css' => 'e9892921',
'aphront-dialog-view-css' => 'f44a66c5',
'aphront-error-view-css' => 'f44a66c5',
'aphront-list-filter-view-css' => 'f44a66c5',
'aphront-pager-view-css' => 'f44a66c5',
'aphront-panel-view-css' => 'f44a66c5',
'aphront-table-view-css' => 'f44a66c5',
'aphront-tokenizer-control-css' => 'f44a66c5',
'aphront-tooltip-css' => 'f44a66c5',
'aphront-typeahead-control-css' => 'f44a66c5',
'differential-changeset-view-css' => '44bfe40c',
'differential-core-view-css' => '44bfe40c',
'differential-inline-comment-editor' => '5e9e5c4e',
@ -4425,7 +4425,7 @@ celerity_register_resource_map(array(
'differential-table-of-contents-css' => '44bfe40c',
'diffusion-commit-view-css' => 'c8ce2d88',
'diffusion-icons-css' => 'c8ce2d88',
'global-drag-and-drop-css' => 'e9892921',
'global-drag-and-drop-css' => 'f44a66c5',
'inline-comment-summary-css' => '44bfe40c',
'javelin-aphlict' => '64eeda79',
'javelin-behavior' => '9564fa17',
@ -4500,56 +4500,56 @@ celerity_register_resource_map(array(
'javelin-util' => '9564fa17',
'javelin-vector' => '9564fa17',
'javelin-workflow' => '9564fa17',
'lightbox-attachment-css' => 'e9892921',
'lightbox-attachment-css' => 'f44a66c5',
'maniphest-task-summary-css' => '49898640',
'phabricator-action-list-view-css' => 'e9892921',
'phabricator-application-launch-view-css' => 'e9892921',
'phabricator-action-list-view-css' => 'f44a66c5',
'phabricator-application-launch-view-css' => 'f44a66c5',
'phabricator-busy' => '64eeda79',
'phabricator-content-source-view-css' => '44bfe40c',
'phabricator-core-css' => 'e9892921',
'phabricator-crumbs-view-css' => 'e9892921',
'phabricator-core-css' => 'f44a66c5',
'phabricator-crumbs-view-css' => 'f44a66c5',
'phabricator-drag-and-drop-file-upload' => '5e9e5c4e',
'phabricator-dropdown-menu' => '64eeda79',
'phabricator-file-upload' => '64eeda79',
'phabricator-filetree-view-css' => 'e9892921',
'phabricator-flag-css' => 'e9892921',
'phabricator-filetree-view-css' => 'f44a66c5',
'phabricator-flag-css' => 'f44a66c5',
'phabricator-hovercard' => '64eeda79',
'phabricator-jump-nav' => 'e9892921',
'phabricator-jump-nav' => 'f44a66c5',
'phabricator-keyboard-shortcut' => '64eeda79',
'phabricator-keyboard-shortcut-manager' => '64eeda79',
'phabricator-main-menu-view' => 'e9892921',
'phabricator-main-menu-view' => 'f44a66c5',
'phabricator-menu-item' => '64eeda79',
'phabricator-nav-view-css' => 'e9892921',
'phabricator-nav-view-css' => 'f44a66c5',
'phabricator-notification' => '64eeda79',
'phabricator-notification-css' => 'e9892921',
'phabricator-notification-menu-css' => 'e9892921',
'phabricator-notification-css' => 'f44a66c5',
'phabricator-notification-menu-css' => 'f44a66c5',
'phabricator-object-selector-css' => '44bfe40c',
'phabricator-phtize' => '64eeda79',
'phabricator-prefab' => '64eeda79',
'phabricator-project-tag-css' => '49898640',
'phabricator-property-list-view-css' => 'e9892921',
'phabricator-remarkup-css' => 'e9892921',
'phabricator-property-list-view-css' => 'f44a66c5',
'phabricator-remarkup-css' => 'f44a66c5',
'phabricator-shaped-request' => '5e9e5c4e',
'phabricator-side-menu-view-css' => 'e9892921',
'phabricator-standard-page-view' => 'e9892921',
'phabricator-tag-view-css' => 'e9892921',
'phabricator-side-menu-view-css' => 'f44a66c5',
'phabricator-standard-page-view' => 'f44a66c5',
'phabricator-tag-view-css' => 'f44a66c5',
'phabricator-textareautils' => '64eeda79',
'phabricator-tooltip' => '64eeda79',
'phabricator-transaction-view-css' => 'e9892921',
'phabricator-zindex-css' => 'e9892921',
'phui-button-css' => 'e9892921',
'phui-form-css' => 'e9892921',
'phui-form-view-css' => 'e9892921',
'phui-header-view-css' => 'e9892921',
'phui-icon-view-css' => 'e9892921',
'phui-list-view-css' => 'e9892921',
'phui-object-item-list-view-css' => 'e9892921',
'phui-spacing-css' => 'e9892921',
'sprite-apps-large-css' => 'e9892921',
'sprite-gradient-css' => 'e9892921',
'sprite-icons-css' => 'e9892921',
'sprite-menu-css' => 'e9892921',
'sprite-status-css' => 'e9892921',
'syntax-highlighting-css' => 'e9892921',
'phabricator-transaction-view-css' => 'f44a66c5',
'phabricator-zindex-css' => 'f44a66c5',
'phui-button-css' => 'f44a66c5',
'phui-form-css' => 'f44a66c5',
'phui-form-view-css' => 'f44a66c5',
'phui-header-view-css' => 'f44a66c5',
'phui-icon-view-css' => 'f44a66c5',
'phui-list-view-css' => 'f44a66c5',
'phui-object-item-list-view-css' => 'f44a66c5',
'phui-spacing-css' => 'f44a66c5',
'sprite-apps-large-css' => 'f44a66c5',
'sprite-gradient-css' => 'f44a66c5',
'sprite-icons-css' => 'f44a66c5',
'sprite-menu-css' => 'f44a66c5',
'sprite-status-css' => 'f44a66c5',
'syntax-highlighting-css' => 'f44a66c5',
),
));

View file

@ -29,6 +29,10 @@ final class PhabricatorFilesConfigOptions
'image/x-ico' => 'image/x-icon',
'image/x-icon' => 'image/x-icon',
'image/vnd.microsoft.icon' => 'image/x-icon',
'audio/x-wav' => 'audio/x-wav',
'application/ogg' => 'application/ogg',
'audio/mpeg' => 'audio/mpeg',
);
$image_default = array(
@ -41,6 +45,12 @@ final class PhabricatorFilesConfigOptions
'image/vnd.microsoft.icon' => true,
);
$audio_default = array(
'audio/x-wav' => true,
'application/ogg' => true,
'audio/mpeg' => true,
);
// largely lifted from http://en.wikipedia.org/wiki/Internet_media_type
$icon_default = array(
// audio file icon
@ -82,7 +92,7 @@ final class PhabricatorFilesConfigOptions
'browsers tend to freak out when viewing enormous binary files.'.
"\n\n".
'The keys in this map are vieweable MIME types; the values are '.
'the MIME type sthey are delivered as when they are viewed in '.
'the MIME types they are delivered as when they are viewed in '.
'the browser.')),
$this->newOption('files.image-mime-types', 'set', $image_default)
->setSummary(pht('Configure which MIME types are images.'))
@ -90,6 +100,12 @@ final class PhabricatorFilesConfigOptions
pht(
'List of MIME types which can be used as the `src` for an '.
'`<img />` tag.')),
$this->newOption('files.audio-mime-types', 'set', $audio_default)
->setSummary(pht('Configure which MIME types are audio.'))
->setDescription(
pht(
'List of MIME types which can be used to render an '.
'`<audio />` tag.')),
$this->newOption('files.icon-mime-types', 'wild', $icon_default)
->setSummary(pht('Configure which MIME types map to which icons.'))
->setDescription(

View file

@ -217,6 +217,20 @@ final class PhabricatorFileInfoController extends PhabricatorFileController {
$image);
$view->addImageContent($linked_image);
} else if ($file->isAudio()) {
$audio = phutil_tag(
'audio',
array(
'controls' => 'controls',
'class' => 'phabricator-property-list-audio',
),
phutil_tag(
'source',
array(
'src' => $file->getViewURI(),
'type' => $file->getMimeType(),
)));
$view->addImageContent($audio);
}
return $view;

View file

@ -57,6 +57,7 @@ final class PhabricatorRemarkupRuleEmbedFile
$options['name'] = $file_name;
$is_viewable_image = $file->isViewableImage();
$is_audio = $file->isAudio();
$attrs = array();
if ($is_viewable_image) {
@ -91,10 +92,20 @@ final class PhabricatorRemarkupRuleEmbedFile
$bundle['meta'] = array(
'phid' => $file->getPHID(),
'viewable' => $is_viewable_image,
'audio' => $is_audio,
'uri' => $file->getBestURI(),
'dUri' => $file->getDownloadURI(),
'name' => $options['name'],
'mime' => $file->getMimeType(),
);
if ($is_audio) {
$bundle['meta'] += array(
'autoplay' => idx($options, 'autoplay'),
'loop' => idx($options, 'loop'),
);
}
$metadata[$phid][] = $bundle;
$engine->setTextMetadata($metadata_key, $metadata);
@ -118,7 +129,10 @@ final class PhabricatorRemarkupRuleEmbedFile
$options = $data['options'];
$meta = $data['meta'];
if (!$meta['viewable'] || $options['layout'] == 'link') {
$is_image = idx($meta, 'viewable');
$is_audio = idx($meta, 'audio');
if ((!$is_image && !$is_audio) || $options['layout'] == 'link') {
$link = id(new PhabricatorFileLinkView())
->setFilePHID($meta['phid'])
->setFileName($meta['name'])
@ -130,6 +144,33 @@ final class PhabricatorRemarkupRuleEmbedFile
continue;
}
if ($is_audio) {
if (idx($options, 'autoplay')) {
$preload = 'auto';
$autoplay = 'autoplay';
} else {
$preload = 'none';
$autoplay = null;
}
$link = phutil_tag(
'audio',
array(
'controls' => 'controls',
'preload' => $preload,
'autoplay' => $autoplay,
'loop' => idx($options, 'loop') ? 'loop' : null,
),
phutil_tag(
'source',
array(
'src' => $meta['uri'],
'type' => $meta['mime'],
)));
$engine->overwriteStoredText($data['token'], $link);
continue;
}
require_celerity_resource('lightbox-attachment-css');
$img = phutil_tag('img', $data['attrs']);

View file

@ -564,6 +564,16 @@ final class PhabricatorFile extends PhabricatorFileDAO
return idx($mime_map, $mime_type);
}
public function isAudio() {
if (!$this->isViewableInBrowser()) {
return false;
}
$mime_map = PhabricatorEnv::getEnvConfig('files.audio-mime-types');
$mime_type = $this->getMimeType();
return idx($mime_map, $mime_type);
}
public function isTransformableImage() {
// NOTE: The way the 'gd' extension works in PHP is that you can install it

View file

@ -148,6 +148,13 @@
max-height: 640px;
}
.phabricator-remarkup audio {
display: block;
margin: 16px auto;
min-width: 300px;
width: 50%;
}
.phabricator-remarkup-mention-exists {
font-weight: bold;
background: #e6f3ff;

View file

@ -115,6 +115,13 @@
max-width: 95%;
}
.phabricator-property-list-audio {
display: block;
margin: 16px auto;
width: 50%;
min-width: 300px;
}
/* When tags appear in property lists, give them a little more vertical
spacing. */
.phabricator-property-list-view .phabricator-tag-view {