1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-26 08:42:41 +01:00

Allow macros to have associated audio and audio behaviors

Summary: Ref T3887. Implements storage and editors, but not the actual audio part.

Test Plan: Edited audio, audio behaviors of macros. Transactions and email looked good. Hit error cases.

Reviewers: btrahan

Reviewed By: btrahan

CC: aran

Maniphest Tasks: T3887

Differential Revision: https://secure.phabricator.com/D7159
This commit is contained in:
epriestley 2013-09-27 16:01:37 -07:00
parent 5ab15b51a3
commit 7091dad606
10 changed files with 325 additions and 0 deletions

View file

@ -0,0 +1,8 @@
ALTER TABLE {$NAMESPACE}_file.file_imagemacro
ADD audioPHID VARCHAR(64) COLLATE utf8_bin;
ALTER TABLE {$NAMESPACE}_file.file_imagemacro
ADD audioBehavior VARCHAR(64) NOT NULL COLLATE utf8_bin;
UPDATE {$NAMESPACE}_file.file_imagemacro
SET audioBehavior = 'audio:none' WHERE audioBehavior = '';

View file

@ -1270,6 +1270,7 @@ phutil_register_library_map(array(
'PhabricatorLocalDiskFileStorageEngine' => 'applications/files/engine/PhabricatorLocalDiskFileStorageEngine.php', 'PhabricatorLocalDiskFileStorageEngine' => 'applications/files/engine/PhabricatorLocalDiskFileStorageEngine.php',
'PhabricatorLocalTimeTestCase' => 'view/__tests__/PhabricatorLocalTimeTestCase.php', 'PhabricatorLocalTimeTestCase' => 'view/__tests__/PhabricatorLocalTimeTestCase.php',
'PhabricatorLogoutController' => 'applications/auth/controller/PhabricatorLogoutController.php', 'PhabricatorLogoutController' => 'applications/auth/controller/PhabricatorLogoutController.php',
'PhabricatorMacroAudioController' => 'applications/macro/controller/PhabricatorMacroAudioController.php',
'PhabricatorMacroCommentController' => 'applications/macro/controller/PhabricatorMacroCommentController.php', 'PhabricatorMacroCommentController' => 'applications/macro/controller/PhabricatorMacroCommentController.php',
'PhabricatorMacroConfigOptions' => 'applications/macro/config/PhabricatorMacroConfigOptions.php', 'PhabricatorMacroConfigOptions' => 'applications/macro/config/PhabricatorMacroConfigOptions.php',
'PhabricatorMacroController' => 'applications/macro/controller/PhabricatorMacroController.php', 'PhabricatorMacroController' => 'applications/macro/controller/PhabricatorMacroController.php',
@ -3416,6 +3417,7 @@ phutil_register_library_map(array(
'PhabricatorLocalDiskFileStorageEngine' => 'PhabricatorFileStorageEngine', 'PhabricatorLocalDiskFileStorageEngine' => 'PhabricatorFileStorageEngine',
'PhabricatorLocalTimeTestCase' => 'PhabricatorTestCase', 'PhabricatorLocalTimeTestCase' => 'PhabricatorTestCase',
'PhabricatorLogoutController' => 'PhabricatorAuthController', 'PhabricatorLogoutController' => 'PhabricatorAuthController',
'PhabricatorMacroAudioController' => 'PhabricatorMacroController',
'PhabricatorMacroCommentController' => 'PhabricatorMacroController', 'PhabricatorMacroCommentController' => 'PhabricatorMacroController',
'PhabricatorMacroConfigOptions' => 'PhabricatorApplicationConfigOptions', 'PhabricatorMacroConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorMacroController' => 'PhabricatorController', 'PhabricatorMacroController' => 'PhabricatorController',

View file

@ -34,6 +34,7 @@ final class PhabricatorApplicationMacro extends PhabricatorApplication {
'view/(?P<id>[1-9]\d*)/' => 'PhabricatorMacroViewController', 'view/(?P<id>[1-9]\d*)/' => 'PhabricatorMacroViewController',
'comment/(?P<id>[1-9]\d*)/' => 'PhabricatorMacroCommentController', 'comment/(?P<id>[1-9]\d*)/' => 'PhabricatorMacroCommentController',
'edit/(?P<id>[1-9]\d*)/' => 'PhabricatorMacroEditController', 'edit/(?P<id>[1-9]\d*)/' => 'PhabricatorMacroEditController',
'audio/(?P<id>[1-9]\d*)/' => 'PhabricatorMacroAudioController',
'disable/(?P<id>[1-9]\d*)/' => 'PhabricatorMacroDisableController', 'disable/(?P<id>[1-9]\d*)/' => 'PhabricatorMacroDisableController',
'meme/' => 'PhabricatorMacroMemeController', 'meme/' => 'PhabricatorMacroMemeController',
'meme/create/' => 'PhabricatorMacroMemeDialogController', 'meme/create/' => 'PhabricatorMacroMemeDialogController',

View file

@ -6,4 +6,7 @@ final class PhabricatorMacroTransactionType {
const TYPE_DISABLED = 'macro:disabled'; const TYPE_DISABLED = 'macro:disabled';
const TYPE_FILE = 'macro:file'; const TYPE_FILE = 'macro:file';
const TYPE_AUDIO = 'macro:audio';
const TYPE_AUDIO_BEHAVIOR = 'macro:audiobehavior';
} }

View file

@ -0,0 +1,173 @@
<?php
final class PhabricatorMacroAudioController
extends PhabricatorMacroController {
private $id;
public function willProcessRequest(array $data) {
$this->id = idx($data, 'id');
}
public function processRequest() {
$request = $this->getRequest();
$viewer = $request->getUser();
$macro = id(new PhabricatorMacroQuery())
->setViewer($viewer)
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->withIDs(array($this->id))
->executeOne();
if (!$macro) {
return new Aphront404Response();
}
$errors = array();
$view_uri = $this->getApplicationURI('/view/'.$macro->getID().'/');
$e_file = null;
$file = null;
if ($request->isFormPost()) {
$xactions = array();
if ($request->getBool('behaviorForm')) {
$xactions[] = id(new PhabricatorMacroTransaction())
->setTransactionType(
PhabricatorMacroTransactionType::TYPE_AUDIO_BEHAVIOR)
->setNewValue($request->getStr('audioBehavior'));
} else {
$file = null;
if ($request->getFileExists('file')) {
$file = PhabricatorFile::newFromPHPUpload(
$_FILES['file'],
array(
'name' => $request->getStr('name'),
'authorPHID' => $viewer->getPHID(),
'isExplicitUpload' => true,
));
}
if ($file) {
if (!$file->isAudio()) {
$errors[] = pht('You must upload audio.');
$e_file = pht('Invalid');
} else {
$xactions[] = id(new PhabricatorMacroTransaction())
->setTransactionType(PhabricatorMacroTransactionType::TYPE_AUDIO)
->setNewValue($file->getPHID());
}
} else {
$errors[] = pht('You must upload an audio file.');
$e_file = pht('Required');
}
}
if (!$errors) {
id(new PhabricatorMacroEditor())
->setActor($viewer)
->setContinueOnNoEffect(true)
->setContentSourceFromRequest($request)
->applyTransactions($macro, $xactions);
return id(new AphrontRedirectResponse())->setURI($view_uri);
}
}
if ($errors) {
$error_view = new AphrontErrorView();
$error_view->setTitle(pht('Form Errors'));
$error_view->setErrors($errors);
} else {
$error_view = null;
}
$form = id(new AphrontFormView())
->addHiddenInput('behaviorForm', 1)
->setUser($viewer);
$options = id(new AphrontFormRadioButtonControl())
->setLabel(pht('Audio Behavior'))
->setName('audioBehavior')
->setValue(
nonempty(
$macro->getAudioBehavior(),
PhabricatorFileImageMacro::AUDIO_BEHAVIOR_NONE));
$options->addButton(
PhabricatorFileImageMacro::AUDIO_BEHAVIOR_NONE,
pht('Do Not Play'),
pht('Do not play audio.'));
$options->addButton(
PhabricatorFileImageMacro::AUDIO_BEHAVIOR_ONCE,
pht('Play Once'),
pht('Play audio once, when the viewer looks at the macro.'));
$options->addButton(
PhabricatorFileImageMacro::AUDIO_BEHAVIOR_LOOP,
pht('Play Continuously'),
pht(
'Play audio continuously, treating the macro as an audio source. '.
'Best for ambient sounds.'));
$form->appendChild($options);
$form
->appendChild(
id(new AphrontFormSubmitControl())
->setValue(pht('Save Audio Behavior'))
->addCancelButton($view_uri));
$crumbs = $this->buildApplicationCrumbs();
$title = pht('Edit Audio Behavior');
$crumb = pht('Edit Audio');
$crumbs->addCrumb(
id(new PhabricatorCrumbView())
->setHref($view_uri)
->setName(pht('Macro "%s"', $macro->getName())));
$crumbs->addCrumb(
id(new PhabricatorCrumbView())
->setHref($request->getRequestURI())
->setName($crumb));
$upload_form = id(new AphrontFormView())
->setEncType('multipart/form-data')
->setUser($viewer)
->appendChild(
id(new AphrontFormFileControl())
->setLabel(pht('Audio File'))
->setName('file'))
->appendChild(
id(new AphrontFormSubmitControl())
->setValue(pht('Upload File')));
$upload = id(new PHUIObjectBoxView())
->setHeaderText(pht('Upload New Audio'))
->setForm($upload_form);
$form_box = id(new PHUIObjectBoxView())
->setHeaderText($title)
->setFormError($error_view)
->setForm($form);
return $this->buildApplicationPage(
array(
$crumbs,
$form_box,
$upload,
),
array(
'title' => $title,
'device' => true,
));
}
}

View file

@ -119,6 +119,12 @@ final class PhabricatorMacroViewController
->setHref($this->getApplicationURI('/edit/'.$macro->getID().'/')) ->setHref($this->getApplicationURI('/edit/'.$macro->getID().'/'))
->setIcon('edit')); ->setIcon('edit'));
$view->addAction(
id(new PhabricatorActionView())
->setName(pht('Edit Audio'))
->setHref($this->getApplicationURI('/audio/'.$macro->getID().'/'))
->setIcon('herald'));
if ($macro->getIsDisabled()) { if ($macro->getIsDisabled()) {
$view->addAction( $view->addAction(
id(new PhabricatorActionView()) id(new PhabricatorActionView())
@ -146,6 +152,25 @@ final class PhabricatorMacroViewController
->setUser($this->getRequest()->getUser()) ->setUser($this->getRequest()->getUser())
->setObject($macro); ->setObject($macro);
switch ($macro->getAudioBehavior()) {
case PhabricatorFileImageMacro::AUDIO_BEHAVIOR_ONCE:
$view->addProperty(pht('Audio Behavior'), pht('Play Once'));
break;
case PhabricatorFileImageMacro::AUDIO_BEHAVIOR_LOOP:
$view->addProperty(pht('Audio Behavior'), pht('Loop'));
break;
}
$audio_phid = $macro->getAudioPHID();
if ($audio_phid) {
$this->loadHandles(array($audio_phid));
$view->addProperty(
pht('Audio'),
$this->getHandle($audio_phid)->renderLink());
}
$view->invokeWillRenderEvent(); $view->invokeWillRenderEvent();
if ($file) { if ($file) {

View file

@ -10,6 +10,8 @@ final class PhabricatorMacroEditor
$types[] = PhabricatorMacroTransactionType::TYPE_NAME; $types[] = PhabricatorMacroTransactionType::TYPE_NAME;
$types[] = PhabricatorMacroTransactionType::TYPE_DISABLED; $types[] = PhabricatorMacroTransactionType::TYPE_DISABLED;
$types[] = PhabricatorMacroTransactionType::TYPE_FILE; $types[] = PhabricatorMacroTransactionType::TYPE_FILE;
$types[] = PhabricatorMacroTransactionType::TYPE_AUDIO;
$types[] = PhabricatorMacroTransactionType::TYPE_AUDIO_BEHAVIOR;
return $types; return $types;
} }
@ -25,6 +27,10 @@ final class PhabricatorMacroEditor
return $object->getIsDisabled(); return $object->getIsDisabled();
case PhabricatorMacroTransactionType::TYPE_FILE: case PhabricatorMacroTransactionType::TYPE_FILE:
return $object->getFilePHID(); return $object->getFilePHID();
case PhabricatorMacroTransactionType::TYPE_AUDIO:
return $object->getAudioPHID();
case PhabricatorMacroTransactionType::TYPE_AUDIO_BEHAVIOR:
return $object->getAudioBehavior();
} }
} }
@ -36,6 +42,8 @@ final class PhabricatorMacroEditor
case PhabricatorMacroTransactionType::TYPE_NAME: case PhabricatorMacroTransactionType::TYPE_NAME:
case PhabricatorMacroTransactionType::TYPE_DISABLED: case PhabricatorMacroTransactionType::TYPE_DISABLED:
case PhabricatorMacroTransactionType::TYPE_FILE: case PhabricatorMacroTransactionType::TYPE_FILE:
case PhabricatorMacroTransactionType::TYPE_AUDIO:
case PhabricatorMacroTransactionType::TYPE_AUDIO_BEHAVIOR:
return $xaction->getNewValue(); return $xaction->getNewValue();
} }
} }
@ -54,6 +62,12 @@ final class PhabricatorMacroEditor
case PhabricatorMacroTransactionType::TYPE_FILE: case PhabricatorMacroTransactionType::TYPE_FILE:
$object->setFilePHID($xaction->getNewValue()); $object->setFilePHID($xaction->getNewValue());
break; break;
case PhabricatorMacroTransactionType::TYPE_AUDIO:
$object->setAudioPHID($xaction->getNewValue());
break;
case PhabricatorMacroTransactionType::TYPE_AUDIO_BEHAVIOR:
$object->setAudioBehavior($xaction->getNewValue());
break;
} }
} }
@ -72,6 +86,8 @@ final class PhabricatorMacroEditor
case PhabricatorMacroTransactionType::TYPE_NAME: case PhabricatorMacroTransactionType::TYPE_NAME:
case PhabricatorMacroTransactionType::TYPE_DISABLED: case PhabricatorMacroTransactionType::TYPE_DISABLED:
case PhabricatorMacroTransactionType::TYPE_FILE: case PhabricatorMacroTransactionType::TYPE_FILE:
case PhabricatorMacroTransactionType::TYPE_AUDIO:
case PhabricatorMacroTransactionType::TYPE_AUDIO_BEHAVIOR:
return $v; return $v;
} }

View file

@ -11,8 +11,15 @@ final class PhabricatorFileImageMacro extends PhabricatorFileDAO
protected $phid; protected $phid;
protected $name; protected $name;
protected $isDisabled = 0; protected $isDisabled = 0;
protected $audioPHID;
protected $audioBehavior = self::AUDIO_BEHAVIOR_NONE;
private $file = self::ATTACHABLE; private $file = self::ATTACHABLE;
private $audio = self::ATTACHABLE;
const AUDIO_BEHAVIOR_NONE = 'audio:none';
const AUDIO_BEHAVIOR_ONCE = 'audio:once';
const AUDIO_BEHAVIOR_LOOP = 'audio:loop';
public function attachFile(PhabricatorFile $file) { public function attachFile(PhabricatorFile $file) {
$this->file = $file; $this->file = $file;
@ -23,6 +30,15 @@ final class PhabricatorFileImageMacro extends PhabricatorFileDAO
return $this->assertAttached($this->file); return $this->assertAttached($this->file);
} }
public function attachAudio(PhabricatorFile $audio = null) {
$this->audio = $audio;
return $this;
}
public function getAudio() {
return $this->assertAttached($this->audio);
}
public function getConfiguration() { public function getConfiguration() {
return array( return array(
self::CONFIG_AUX_PHID => true, self::CONFIG_AUX_PHID => true,

View file

@ -27,6 +27,7 @@ final class PhabricatorMacroTransaction
switch ($this->getTransactionType()) { switch ($this->getTransactionType()) {
case PhabricatorMacroTransactionType::TYPE_FILE: case PhabricatorMacroTransactionType::TYPE_FILE:
case PhabricatorMacroTransactionType::TYPE_AUDIO:
if ($old !== null) { if ($old !== null) {
$phids[] = $old; $phids[] = $old;
} }
@ -74,6 +75,37 @@ final class PhabricatorMacroTransaction
$this->renderHandleLink($author_phid)); $this->renderHandleLink($author_phid));
} }
break; break;
case PhabricatorMacroTransactionType::TYPE_AUDIO:
if (!$old) {
return pht(
'%s attached audio: %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($new));
} else {
return pht(
'%s changed the audio for this macro from %s to %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($old),
$this->renderHandleLink($new));
}
case PhabricatorMacroTransactionType::TYPE_AUDIO_BEHAVIOR:
switch ($new) {
case PhabricatorFileImageMacro::AUDIO_BEHAVIOR_ONCE:
return pht(
'%s set the audio to play once.',
$this->renderHandleLink($author_phid));
case PhabricatorFileImageMacro::AUDIO_BEHAVIOR_LOOP:
return pht(
'%s set the audio to loop.',
$this->renderHandleLink($author_phid));
default:
return pht(
'%s disabled the audio for this macro.',
$this->renderHandleLink($author_phid));
}
case PhabricatorMacroTransactionType::TYPE_FILE: case PhabricatorMacroTransactionType::TYPE_FILE:
if ($old === null) { if ($old === null) {
return pht( return pht(
@ -131,6 +163,42 @@ final class PhabricatorMacroTransaction
$this->renderHandleLink($author_phid), $this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid)); $this->renderHandleLink($object_phid));
} }
case PhabricatorMacroTransactionType::TYPE_AUDIO:
if (!$old) {
return pht(
'%s attached audio to %s: %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid),
$this->renderHandleLink($new));
} else {
return pht(
'%s changed the audio for %s from %s to %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid),
$this->renderHandleLink($old),
$this->renderHandleLink($new));
}
case PhabricatorMacroTransactionType::TYPE_AUDIO_BEHAVIOR:
switch ($new) {
case PhabricatorFileImageMacro::AUDIO_BEHAVIOR_ONCE:
return pht(
'%s set the audio for %s to play once.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid));
case PhabricatorFileImageMacro::AUDIO_BEHAVIOR_LOOP:
return pht(
'%s set the audio for %s to loop.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid));
default:
return pht(
'%s disabled the audio for %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid));
}
} }
return parent::getTitleForFeed($story); return parent::getTitleForFeed($story);
@ -159,6 +227,13 @@ final class PhabricatorMacroTransaction
} else { } else {
return pht('Edited Image'); return pht('Edited Image');
} }
case PhabricatorMacroTransactionType::TYPE_AUDIO:
return pht('Audio');
case PhabricatorMacroTransactionType::TYPE_AUDIO_BEHAVIOR:
return pht('Audio Behavior');
} }
return parent::getActionName(); return parent::getActionName();
@ -193,6 +268,8 @@ final class PhabricatorMacroTransaction
} else { } else {
return 'undo'; return 'undo';
} }
case PhabricatorMacroTransactionType::TYPE_AUDIO:
return 'herald';
} }
return parent::getIcon(); return parent::getIcon();

View file

@ -1644,6 +1644,10 @@ final class PhabricatorBuiltinPatchList extends PhabricatorSQLPatchList {
'type' => 'sql', 'type' => 'sql',
'name' => $this->getPatchPath('20130926.dinkeys.sql'), 'name' => $this->getPatchPath('20130926.dinkeys.sql'),
), ),
'20130927.audiomacro.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('20130927.audiomacro.sql'),
),
); );
} }
} }