1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-18 12:52:42 +01:00

Conpherence - add back in custom images

Summary: Fixes T7254. This reverts the previous functionality, but makes pertinent updates like scaling the images to 35 x 35. Codebase had moved on quite a bit so far from a straight revert but nothing too tricky relative to the code that was here before. This does not allow for changing the images from the conpherence durable column view -- that would require some JS trickery, but also doesn't fit into the current notion of the column being "light". Can always modify this later.

Test Plan:
 - from full conpherence, uploaded a square pic and things looked nice
 - from full conpherence, uploaded a rectangular pic and wasnt happy, so reinvoked edit dialog and used crop control to make it better
 - noted could not update picture from conpherence durable column
 - used different user and noted could see custom picture

Reviewers: epriestley

Reviewed By: epriestley

Subscribers: CodeMouse92, Korvin, epriestley

Maniphest Tasks: T7254

Differential Revision: https://secure.phabricator.com/D12648
This commit is contained in:
Bob Trahan 2015-05-04 13:52:22 -07:00
parent 9c7d1b0b90
commit 16ce63ec20
19 changed files with 447 additions and 8 deletions

View file

@ -356,6 +356,7 @@ return array(
'rsrc/js/application/auth/behavior-persona-login.js' => '9414ff18', 'rsrc/js/application/auth/behavior-persona-login.js' => '9414ff18',
'rsrc/js/application/config/behavior-reorder-fields.js' => '14a827de', 'rsrc/js/application/config/behavior-reorder-fields.js' => '14a827de',
'rsrc/js/application/conpherence/ConpherenceThreadManager.js' => '6709c934', 'rsrc/js/application/conpherence/ConpherenceThreadManager.js' => '6709c934',
'rsrc/js/application/conpherence/behavior-drag-and-drop-photo.js' => 'cf86d16a',
'rsrc/js/application/conpherence/behavior-durable-column.js' => '657c2b50', 'rsrc/js/application/conpherence/behavior-durable-column.js' => '657c2b50',
'rsrc/js/application/conpherence/behavior-menu.js' => '804b0773', 'rsrc/js/application/conpherence/behavior-menu.js' => '804b0773',
'rsrc/js/application/conpherence/behavior-pontificate.js' => '21ba5861', 'rsrc/js/application/conpherence/behavior-pontificate.js' => '21ba5861',
@ -561,6 +562,7 @@ return array(
'javelin-behavior-audit-preview' => 'd835b03a', 'javelin-behavior-audit-preview' => 'd835b03a',
'javelin-behavior-choose-control' => '6153c708', 'javelin-behavior-choose-control' => '6153c708',
'javelin-behavior-config-reorder-fields' => '14a827de', 'javelin-behavior-config-reorder-fields' => '14a827de',
'javelin-behavior-conpherence-drag-and-drop-photo' => 'cf86d16a',
'javelin-behavior-conpherence-menu' => '804b0773', 'javelin-behavior-conpherence-menu' => '804b0773',
'javelin-behavior-conpherence-pontificate' => '21ba5861', 'javelin-behavior-conpherence-pontificate' => '21ba5861',
'javelin-behavior-conpherence-widget-pane' => '93568464', 'javelin-behavior-conpherence-widget-pane' => '93568464',
@ -1789,6 +1791,12 @@ return array(
'javelin-stratcom', 'javelin-stratcom',
'phabricator-phtize', 'phabricator-phtize',
), ),
'cf86d16a' => array(
'javelin-behavior',
'javelin-dom',
'javelin-workflow',
'phabricator-drag-and-drop-file-upload',
),
'd19198c8' => array( 'd19198c8' => array(
'javelin-install', 'javelin-install',
'javelin-dom', 'javelin-dom',

View file

@ -0,0 +1,5 @@
ALTER TABLE {$NAMESPACE}_conpherence.conpherence_thread
ADD imagePHIDs LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL AFTER title;
UPDATE {$NAMESPACE}_conpherence.conpherence_thread
SET imagePHIDS = '[]';

View file

@ -230,8 +230,10 @@ phutil_register_library_map(array(
'ConpherenceDurableColumnView' => 'applications/conpherence/view/ConpherenceDurableColumnView.php', 'ConpherenceDurableColumnView' => 'applications/conpherence/view/ConpherenceDurableColumnView.php',
'ConpherenceEditor' => 'applications/conpherence/editor/ConpherenceEditor.php', 'ConpherenceEditor' => 'applications/conpherence/editor/ConpherenceEditor.php',
'ConpherenceFileWidgetView' => 'applications/conpherence/view/ConpherenceFileWidgetView.php', 'ConpherenceFileWidgetView' => 'applications/conpherence/view/ConpherenceFileWidgetView.php',
'ConpherenceFormDragAndDropUploadControl' => 'applications/conpherence/view/ConpherenceFormDragAndDropUploadControl.php',
'ConpherenceFulltextQuery' => 'applications/conpherence/query/ConpherenceFulltextQuery.php', 'ConpherenceFulltextQuery' => 'applications/conpherence/query/ConpherenceFulltextQuery.php',
'ConpherenceHovercardEventListener' => 'applications/conpherence/events/ConpherenceHovercardEventListener.php', 'ConpherenceHovercardEventListener' => 'applications/conpherence/events/ConpherenceHovercardEventListener.php',
'ConpherenceImageData' => 'applications/conpherence/constants/ConpherenceImageData.php',
'ConpherenceIndex' => 'applications/conpherence/storage/ConpherenceIndex.php', 'ConpherenceIndex' => 'applications/conpherence/storage/ConpherenceIndex.php',
'ConpherenceLayoutView' => 'applications/conpherence/view/ConpherenceLayoutView.php', 'ConpherenceLayoutView' => 'applications/conpherence/view/ConpherenceLayoutView.php',
'ConpherenceListController' => 'applications/conpherence/controller/ConpherenceListController.php', 'ConpherenceListController' => 'applications/conpherence/controller/ConpherenceListController.php',
@ -244,6 +246,7 @@ phutil_register_library_map(array(
'ConpherenceParticipantQuery' => 'applications/conpherence/query/ConpherenceParticipantQuery.php', 'ConpherenceParticipantQuery' => 'applications/conpherence/query/ConpherenceParticipantQuery.php',
'ConpherenceParticipationStatus' => 'applications/conpherence/constants/ConpherenceParticipationStatus.php', 'ConpherenceParticipationStatus' => 'applications/conpherence/constants/ConpherenceParticipationStatus.php',
'ConpherencePeopleWidgetView' => 'applications/conpherence/view/ConpherencePeopleWidgetView.php', 'ConpherencePeopleWidgetView' => 'applications/conpherence/view/ConpherencePeopleWidgetView.php',
'ConpherencePicCropControl' => 'applications/conpherence/view/ConpherencePicCropControl.php',
'ConpherenceQueryThreadConduitAPIMethod' => 'applications/conpherence/conduit/ConpherenceQueryThreadConduitAPIMethod.php', 'ConpherenceQueryThreadConduitAPIMethod' => 'applications/conpherence/conduit/ConpherenceQueryThreadConduitAPIMethod.php',
'ConpherenceQueryTransactionConduitAPIMethod' => 'applications/conpherence/conduit/ConpherenceQueryTransactionConduitAPIMethod.php', 'ConpherenceQueryTransactionConduitAPIMethod' => 'applications/conpherence/conduit/ConpherenceQueryTransactionConduitAPIMethod.php',
'ConpherenceReplyHandler' => 'applications/conpherence/mail/ConpherenceReplyHandler.php', 'ConpherenceReplyHandler' => 'applications/conpherence/mail/ConpherenceReplyHandler.php',
@ -3467,8 +3470,10 @@ phutil_register_library_map(array(
'ConpherenceDurableColumnView' => 'AphrontTagView', 'ConpherenceDurableColumnView' => 'AphrontTagView',
'ConpherenceEditor' => 'PhabricatorApplicationTransactionEditor', 'ConpherenceEditor' => 'PhabricatorApplicationTransactionEditor',
'ConpherenceFileWidgetView' => 'ConpherenceWidgetView', 'ConpherenceFileWidgetView' => 'ConpherenceWidgetView',
'ConpherenceFormDragAndDropUploadControl' => 'AphrontFormControl',
'ConpherenceFulltextQuery' => 'PhabricatorOffsetPagedQuery', 'ConpherenceFulltextQuery' => 'PhabricatorOffsetPagedQuery',
'ConpherenceHovercardEventListener' => 'PhabricatorEventListener', 'ConpherenceHovercardEventListener' => 'PhabricatorEventListener',
'ConpherenceImageData' => 'ConpherenceConstants',
'ConpherenceIndex' => 'ConpherenceDAO', 'ConpherenceIndex' => 'ConpherenceDAO',
'ConpherenceLayoutView' => 'AphrontView', 'ConpherenceLayoutView' => 'AphrontView',
'ConpherenceListController' => 'ConpherenceController', 'ConpherenceListController' => 'ConpherenceController',
@ -3481,6 +3486,7 @@ phutil_register_library_map(array(
'ConpherenceParticipantQuery' => 'PhabricatorOffsetPagedQuery', 'ConpherenceParticipantQuery' => 'PhabricatorOffsetPagedQuery',
'ConpherenceParticipationStatus' => 'ConpherenceConstants', 'ConpherenceParticipationStatus' => 'ConpherenceConstants',
'ConpherencePeopleWidgetView' => 'ConpherenceWidgetView', 'ConpherencePeopleWidgetView' => 'ConpherenceWidgetView',
'ConpherencePicCropControl' => 'AphrontFormControl',
'ConpherenceQueryThreadConduitAPIMethod' => 'ConpherenceConduitAPIMethod', 'ConpherenceQueryThreadConduitAPIMethod' => 'ConpherenceConduitAPIMethod',
'ConpherenceQueryTransactionConduitAPIMethod' => 'ConpherenceConduitAPIMethod', 'ConpherenceQueryTransactionConduitAPIMethod' => 'ConpherenceConduitAPIMethod',
'ConpherenceReplyHandler' => 'PhabricatorMailReplyHandler', 'ConpherenceReplyHandler' => 'PhabricatorMailReplyHandler',

View file

@ -0,0 +1,11 @@
<?php
final class ConpherenceImageData extends ConpherenceConstants {
const SIZE_ORIG = 'original';
const SIZE_CROP = 'crop';
const CROP_WIDTH = 35;
const CROP_HEIGHT = 35;
}

View file

@ -6,8 +6,6 @@ final class ConpherenceTransactionType extends ConpherenceConstants {
const TYPE_TITLE = 'title'; const TYPE_TITLE = 'title';
const TYPE_PARTICIPANTS = 'participants'; const TYPE_PARTICIPANTS = 'participants';
const TYPE_DATE_MARKER = 'date-marker'; const TYPE_DATE_MARKER = 'date-marker';
/* these two are deprecated but keep them around for legacy installs */
const TYPE_PICTURE = 'picture'; const TYPE_PICTURE = 'picture';
const TYPE_PICTURE_CROP = 'picture-crop'; const TYPE_PICTURE_CROP = 'picture-crop';

View file

@ -16,6 +16,7 @@ final class ConpherenceColumnViewController extends
$latest_conpherences = id(new ConpherenceThreadQuery()) $latest_conpherences = id(new ConpherenceThreadQuery())
->setViewer($user) ->setViewer($user)
->withPHIDs($conpherence_phids) ->withPHIDs($conpherence_phids)
->needCropPics(true)
->needParticipantCache(true) ->needParticipantCache(true)
->execute(); ->execute();
$latest_conpherences = mpull($latest_conpherences, null, 'getPHID'); $latest_conpherences = mpull($latest_conpherences, null, 'getPHID');
@ -30,6 +31,7 @@ final class ConpherenceColumnViewController extends
$conpherence = id(new ConpherenceThreadQuery()) $conpherence = id(new ConpherenceThreadQuery())
->setViewer($user) ->setViewer($user)
->withIDs(array($request->getInt('id'))) ->withIDs(array($request->getInt('id')))
->needCropPics(true)
->needTransactions(true) ->needTransactions(true)
->setTransactionLimit(ConpherenceThreadQuery::TRANSACTION_LIMIT) ->setTransactionLimit(ConpherenceThreadQuery::TRANSACTION_LIMIT)
->executeOne(); ->executeOne();
@ -39,6 +41,7 @@ final class ConpherenceColumnViewController extends
$conpherence = id(new ConpherenceThreadQuery()) $conpherence = id(new ConpherenceThreadQuery())
->setViewer($user) ->setViewer($user)
->withPHIDs(array($participant->getConpherencePHID())) ->withPHIDs(array($participant->getConpherencePHID()))
->needCropPics(true)
->needTransactions(true) ->needTransactions(true)
->setTransactionLimit(ConpherenceThreadQuery::TRANSACTION_LIMIT) ->setTransactionLimit(ConpherenceThreadQuery::TRANSACTION_LIMIT)
->executeOne(); ->executeOne();

View file

@ -138,6 +138,7 @@ final class ConpherenceListController extends ConpherenceController {
$conpherences = id(new ConpherenceThreadQuery()) $conpherences = id(new ConpherenceThreadQuery())
->setViewer($user) ->setViewer($user)
->withPHIDs($conpherence_phids) ->withPHIDs($conpherence_phids)
->needCropPics(true)
->needParticipantCache(true) ->needParticipantCache(true)
->execute(); ->execute();

View file

@ -17,6 +17,7 @@ final class ConpherenceNotificationPanelController
$conpherences = id(new ConpherenceThreadQuery()) $conpherences = id(new ConpherenceThreadQuery())
->setViewer($user) ->setViewer($user)
->withPHIDs(array_keys($participant_data)) ->withPHIDs(array_keys($participant_data))
->needCropPics(true)
->needTransactions(true) ->needTransactions(true)
->setTransactionLimit(3 * 5) ->setTransactionLimit(3 * 5)
->needParticipantCache(true) ->needParticipantCache(true)

View file

@ -37,6 +37,8 @@ final class ConpherenceUpdateController
->setViewer($user) ->setViewer($user)
->withIDs(array($conpherence_id)) ->withIDs(array($conpherence_id))
->needFilePHIDs(true) ->needFilePHIDs(true)
->needOrigPics(true)
->needCropPics(true)
->needParticipants($need_participants) ->needParticipants($need_participants)
->requireCapabilities($needed_capabilities) ->requireCapabilities($needed_capabilities)
->executeOne(); ->executeOne();
@ -132,11 +134,56 @@ final class ConpherenceUpdateController
->setContent($result); ->setContent($result);
break; break;
case ConpherenceUpdateActions::METADATA: case ConpherenceUpdateActions::METADATA:
// all metadata updates are continue requests $top = $request->getInt('image_y');
$left = $request->getInt('image_x');
$file_id = $request->getInt('file_id');
$title = $request->getStr('title');
if ($file_id) {
$orig_file = id(new PhabricatorFileQuery())
->setViewer($user)
->withIDs(array($file_id))
->executeOne();
$xactions[] = id(new ConpherenceTransaction())
->setTransactionType(ConpherenceTransactionType::TYPE_PICTURE)
->setNewValue($orig_file);
$okay = $orig_file->isTransformableImage();
if ($okay) {
$xformer = new PhabricatorImageTransformer();
$crop_file = $xformer->executeConpherenceTransform(
$orig_file,
0,
0,
ConpherenceImageData::CROP_WIDTH,
ConpherenceImageData::CROP_HEIGHT);
$xactions[] = id(new ConpherenceTransaction())
->setTransactionType(
ConpherenceTransactionType::TYPE_PICTURE_CROP)
->setNewValue($crop_file->getPHID());
}
$response_mode = 'redirect';
}
// all other metadata updates are continue requests
if (!$request->isContinueRequest()) { if (!$request->isContinueRequest()) {
break; break;
} }
if ($top !== null || $left !== null) {
$file = $conpherence->getImage(ConpherenceImageData::SIZE_ORIG);
$xformer = new PhabricatorImageTransformer();
$xformed = $xformer->executeConpherenceTransform(
$file,
$top,
$left,
ConpherenceImageData::CROP_WIDTH,
ConpherenceImageData::CROP_HEIGHT);
$image_phid = $xformed->getPHID();
$xactions[] = id(new ConpherenceTransaction())
->setTransactionType(
ConpherenceTransactionType::TYPE_PICTURE_CROP)
->setNewValue($image_phid);
}
$title = $request->getStr('title'); $title = $request->getStr('title');
$xactions[] = id(new ConpherenceTransaction()) $xactions[] = id(new ConpherenceTransaction())
->setTransactionType(ConpherenceTransactionType::TYPE_TITLE) ->setTransactionType(ConpherenceTransactionType::TYPE_TITLE)
@ -323,6 +370,35 @@ final class ConpherenceUpdateController
->setName('title') ->setName('title')
->setValue($conpherence->getTitle())); ->setValue($conpherence->getTitle()));
$nopic = $this->getRequest()->getExists('nopic');
$image = $conpherence->getImage(ConpherenceImageData::SIZE_ORIG);
if ($nopic) {
// do not render any pic related controls
} else if ($image) {
$crop_uri = $conpherence->loadImageURI(ConpherenceImageData::SIZE_CROP);
$form
->appendChild(
id(new AphrontFormMarkupControl())
->setLabel(pht('Image'))
->setValue(phutil_tag(
'img',
array(
'src' => $crop_uri,
))))
->appendChild(
id(new ConpherencePicCropControl())
->setLabel(pht('Crop Image'))
->setValue($image))
->appendChild(
id(new ConpherenceFormDragAndDropUploadControl())
->setLabel(pht('Change Image')));
} else {
$form
->appendChild(
id(new ConpherenceFormDragAndDropUploadControl())
->setLabel(pht('Image')));
}
if ($conpherence->getIsRoom()) { if ($conpherence->getIsRoom()) {
$title = pht('Update Room'); $title = pht('Update Room');
$policies = id(new PhabricatorPolicyQuery()) $policies = id(new PhabricatorPolicyQuery())
@ -400,6 +476,7 @@ final class ConpherenceUpdateController
$conpherence = id(new ConpherenceThreadQuery()) $conpherence = id(new ConpherenceThreadQuery())
->setViewer($user) ->setViewer($user)
->setAfterTransactionID($latest_transaction_id) ->setAfterTransactionID($latest_transaction_id)
->needCropPics(true)
->needParticipantCache($need_participant_cache) ->needParticipantCache($need_participant_cache)
->needWidgetData($need_widget_data) ->needWidgetData($need_widget_data)
->needTransactions($need_transactions) ->needTransactions($need_transactions)

View file

@ -15,6 +15,7 @@ final class ConpherenceViewController extends
$query = id(new ConpherenceThreadQuery()) $query = id(new ConpherenceThreadQuery())
->setViewer($user) ->setViewer($user)
->withIDs(array($conpherence_id)) ->withIDs(array($conpherence_id))
->needCropPics(true)
->needParticipantCache(true) ->needParticipantCache(true)
->needTransactions(true) ->needTransactions(true)
->setTransactionLimit($this->getMainQueryLimit()); ->setTransactionLimit($this->getMainQueryLimit());

View file

@ -120,6 +120,8 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
$types[] = ConpherenceTransactionType::TYPE_TITLE; $types[] = ConpherenceTransactionType::TYPE_TITLE;
$types[] = ConpherenceTransactionType::TYPE_PARTICIPANTS; $types[] = ConpherenceTransactionType::TYPE_PARTICIPANTS;
$types[] = ConpherenceTransactionType::TYPE_FILES; $types[] = ConpherenceTransactionType::TYPE_FILES;
$types[] = ConpherenceTransactionType::TYPE_PICTURE;
$types[] = ConpherenceTransactionType::TYPE_PICTURE_CROP;
$types[] = PhabricatorTransactions::TYPE_VIEW_POLICY; $types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
$types[] = PhabricatorTransactions::TYPE_EDIT_POLICY; $types[] = PhabricatorTransactions::TYPE_EDIT_POLICY;
$types[] = PhabricatorTransactions::TYPE_JOIN_POLICY; $types[] = PhabricatorTransactions::TYPE_JOIN_POLICY;
@ -134,6 +136,10 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
switch ($xaction->getTransactionType()) { switch ($xaction->getTransactionType()) {
case ConpherenceTransactionType::TYPE_TITLE: case ConpherenceTransactionType::TYPE_TITLE:
return $object->getTitle(); return $object->getTitle();
case ConpherenceTransactionType::TYPE_PICTURE:
return $object->getImagePHID(ConpherenceImageData::SIZE_ORIG);
case ConpherenceTransactionType::TYPE_PICTURE_CROP:
return $object->getImagePHID(ConpherenceImageData::SIZE_CROP);
case ConpherenceTransactionType::TYPE_PARTICIPANTS: case ConpherenceTransactionType::TYPE_PARTICIPANTS:
if ($this->getIsNewObject()) { if ($this->getIsNewObject()) {
return array(); return array();
@ -150,7 +156,11 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
switch ($xaction->getTransactionType()) { switch ($xaction->getTransactionType()) {
case ConpherenceTransactionType::TYPE_TITLE: case ConpherenceTransactionType::TYPE_TITLE:
case ConpherenceTransactionType::TYPE_PICTURE_CROP:
return $xaction->getNewValue(); return $xaction->getNewValue();
case ConpherenceTransactionType::TYPE_PICTURE:
$file = $xaction->getNewValue();
return $file->getPHID();
case ConpherenceTransactionType::TYPE_PARTICIPANTS: case ConpherenceTransactionType::TYPE_PARTICIPANTS:
case ConpherenceTransactionType::TYPE_FILES: case ConpherenceTransactionType::TYPE_FILES:
return $this->getPHIDTransactionNewValue($xaction); return $this->getPHIDTransactionNewValue($xaction);
@ -243,6 +253,16 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
case ConpherenceTransactionType::TYPE_TITLE: case ConpherenceTransactionType::TYPE_TITLE:
$object->setTitle($xaction->getNewValue()); $object->setTitle($xaction->getNewValue());
break; break;
case ConpherenceTransactionType::TYPE_PICTURE:
$object->setImagePHID(
$xaction->getNewValue(),
ConpherenceImageData::SIZE_ORIG);
break;
case ConpherenceTransactionType::TYPE_PICTURE_CROP:
$object->setImagePHID(
$xaction->getNewValue(),
ConpherenceImageData::SIZE_CROP);
break;
case ConpherenceTransactionType::TYPE_PARTICIPANTS: case ConpherenceTransactionType::TYPE_PARTICIPANTS:
if (!$this->getIsNewObject()) { if (!$this->getIsNewObject()) {
$old_map = array_fuse($xaction->getOldValue()); $old_map = array_fuse($xaction->getOldValue());
@ -576,6 +596,20 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
); );
} }
protected function extractFilePHIDsFromCustomTransaction(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case ConpherenceTransactionType::TYPE_PICTURE:
return array($xaction->getNewValue()->getPHID());
case ConpherenceTransactionType::TYPE_PICTURE_CROP:
return array($xaction->getNewValue());
}
return parent::extractFilePHIDsFromCustomTransaction($object, $xaction);
}
protected function validateTransaction( protected function validateTransaction(
PhabricatorLiskDAO $object, PhabricatorLiskDAO $object,
$type, $type,
@ -608,6 +642,21 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
$errors[] = $error; $errors[] = $error;
} }
break; break;
case ConpherenceTransactionType::TYPE_PICTURE:
foreach ($xactions as $xaction) {
$file = $xaction->getNewValue();
if (!$file->isTransformableImage()) {
$detail = pht('This server only supports these image formats: %s.',
implode(', ', PhabricatorFile::getTransformableImageFormats()));
$error = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Invalid'),
$detail,
last($xactions));
$errors[] = $error;
}
}
break;
case ConpherenceTransactionType::TYPE_PARTICIPANTS: case ConpherenceTransactionType::TYPE_PARTICIPANTS:
foreach ($xactions as $xaction) { foreach ($xactions as $xaction) {
$new_phids = $this->getPHIDTransactionNewValue($xaction, array()); $new_phids = $this->getPHIDTransactionNewValue($xaction, array());

View file

@ -11,6 +11,8 @@ final class ConpherenceThreadQuery
private $isRoom; private $isRoom;
private $needParticipants; private $needParticipants;
private $needWidgetData; private $needWidgetData;
private $needCropPics;
private $needOrigPics;
private $needTransactions; private $needTransactions;
private $needParticipantCache; private $needParticipantCache;
private $needFilePHIDs; private $needFilePHIDs;
@ -39,6 +41,16 @@ final class ConpherenceThreadQuery
return $this; return $this;
} }
public function needCropPics($need) {
$this->needCropPics = $need;
return $this;
}
public function needOrigPics($need_widget_data) {
$this->needOrigPics = $need_widget_data;
return $this;
}
public function needTransactions($need_transactions) { public function needTransactions($need_transactions) {
$this->needTransactions = $need_transactions; $this->needTransactions = $need_transactions;
return $this; return $this;
@ -122,6 +134,15 @@ final class ConpherenceThreadQuery
if ($this->needWidgetData) { if ($this->needWidgetData) {
$this->loadWidgetData($conpherences); $this->loadWidgetData($conpherences);
} }
if ($this->needOrigPics || $this->needCropPics) {
$this->initImages($conpherences);
}
if ($this->needOrigPics) {
$this->loadOrigPics($conpherences);
}
if ($this->needCropPics) {
$this->loadCropPics($conpherences);
}
} }
return $conpherences; return $conpherences;
@ -395,6 +416,50 @@ final class ConpherenceThreadQuery
return $this; return $this;
} }
private function loadOrigPics(array $conpherences) {
return $this->loadPics(
$conpherences,
ConpherenceImageData::SIZE_ORIG);
}
private function loadCropPics(array $conpherences) {
return $this->loadPics(
$conpherences,
ConpherenceImageData::SIZE_CROP);
}
private function initImages($conpherences) {
foreach ($conpherences as $conpherence) {
$conpherence->attachImages(array());
}
}
private function loadPics(array $conpherences, $size) {
$conpherence_pic_phids = array();
foreach ($conpherences as $conpherence) {
$phid = $conpherence->getImagePHID($size);
if ($phid) {
$conpherence_pic_phids[$conpherence->getPHID()] = $phid;
}
}
if (!$conpherence_pic_phids) {
return $this;
}
$files = id(new PhabricatorFileQuery())
->setViewer($this->getViewer())
->withPHIDs($conpherence_pic_phids)
->execute();
$files = mpull($files, null, 'getPHID');
foreach ($conpherence_pic_phids as $conpherence_phid => $pic_phid) {
$conpherences[$conpherence_phid]->setImage($files[$pic_phid], $size);
}
return $this;
}
public function getQueryApplicationClass() { public function getQueryApplicationClass() {
return 'PhabricatorConpherenceApplication'; return 'PhabricatorConpherenceApplication';
} }

View file

@ -8,6 +8,7 @@ final class ConpherenceThread extends ConpherenceDAO
PhabricatorDestructibleInterface { PhabricatorDestructibleInterface {
protected $title; protected $title;
protected $imagePHIDs = array();
protected $isRoom = 0; protected $isRoom = 0;
protected $messageCount; protected $messageCount;
protected $recentParticipantPHIDs = array(); protected $recentParticipantPHIDs = array();
@ -21,7 +22,7 @@ final class ConpherenceThread extends ConpherenceDAO
private $handles = self::ATTACHABLE; private $handles = self::ATTACHABLE;
private $filePHIDs = self::ATTACHABLE; private $filePHIDs = self::ATTACHABLE;
private $widgetData = self::ATTACHABLE; private $widgetData = self::ATTACHABLE;
private $images = array(); private $images = self::ATTACHABLE;
public static function initializeNewThread(PhabricatorUser $sender) { public static function initializeNewThread(PhabricatorUser $sender) {
return id(new ConpherenceThread()) return id(new ConpherenceThread())
@ -29,6 +30,7 @@ final class ConpherenceThread extends ConpherenceDAO
->setTitle('') ->setTitle('')
->attachParticipants(array()) ->attachParticipants(array())
->attachFilePHIDs(array()) ->attachFilePHIDs(array())
->attachImages(array())
->setViewPolicy(PhabricatorPolicies::POLICY_USER) ->setViewPolicy(PhabricatorPolicies::POLICY_USER)
->setEditPolicy(PhabricatorPolicies::POLICY_USER) ->setEditPolicy(PhabricatorPolicies::POLICY_USER)
->setJoinPolicy(PhabricatorPolicies::POLICY_USER); ->setJoinPolicy(PhabricatorPolicies::POLICY_USER);
@ -42,6 +44,7 @@ final class ConpherenceThread extends ConpherenceDAO
->setTitle('') ->setTitle('')
->attachParticipants(array()) ->attachParticipants(array())
->attachFilePHIDs(array()) ->attachFilePHIDs(array())
->attachImages(array())
->setViewPolicy(PhabricatorPolicies::POLICY_USER) ->setViewPolicy(PhabricatorPolicies::POLICY_USER)
->setEditPolicy($creator->getPHID()) ->setEditPolicy($creator->getPHID())
->setJoinPolicy(PhabricatorPolicies::POLICY_USER); ->setJoinPolicy(PhabricatorPolicies::POLICY_USER);
@ -52,6 +55,7 @@ final class ConpherenceThread extends ConpherenceDAO
self::CONFIG_AUX_PHID => true, self::CONFIG_AUX_PHID => true,
self::CONFIG_SERIALIZATION => array( self::CONFIG_SERIALIZATION => array(
'recentParticipantPHIDs' => self::SERIALIZATION_JSON, 'recentParticipantPHIDs' => self::SERIALIZATION_JSON,
'imagePHIDs' => self::SERIALIZATION_JSON,
), ),
self::CONFIG_COLUMN_SCHEMA => array( self::CONFIG_COLUMN_SCHEMA => array(
'title' => 'text255?', 'title' => 'text255?',
@ -89,6 +93,34 @@ final class ConpherenceThread extends ConpherenceDAO
return 'Z'.$this->getID(); return 'Z'.$this->getID();
} }
public function getImagePHID($size) {
$image_phids = $this->getImagePHIDs();
return idx($image_phids, $size);
}
public function setImagePHID($phid, $size) {
$image_phids = $this->getImagePHIDs();
$image_phids[$size] = $phid;
return $this->setImagePHIDs($image_phids);
}
public function getImage($size) {
$images = $this->getImages();
return idx($images, $size);
}
public function setImage(PhabricatorFile $file, $size) {
$files = $this->getImages();
$files[$size] = $file;
return $this->attachImages($files);
}
public function attachImages(array $files) {
assert_instances_of($files, 'PhabricatorFile');
$this->images = $files;
return $this;
}
private function getImages() {
return $this->assertAttached($this->images);
}
public function attachParticipants(array $participants) { public function attachParticipants(array $participants) {
assert_instances_of($participants, 'ConpherenceParticipant'); assert_instances_of($participants, 'ConpherenceParticipant');
$this->participants = $participants; $this->participants = $participants;
@ -157,6 +189,16 @@ final class ConpherenceThread extends ConpherenceDAO
return $this->assertAttached($this->widgetData); return $this->assertAttached($this->widgetData);
} }
public function loadImageURI($size) {
$file = $this->getImage($size);
if ($file) {
return $file->getBestURI();
}
return PhabricatorUser::getDefaultProfileImageURI();
}
public function getDisplayData(PhabricatorUser $user) { public function getDisplayData(PhabricatorUser $user) {
if ($this->hasAttachedTransactions()) { if ($this->hasAttachedTransactions()) {
$transactions = $this->getTransactions(); $transactions = $this->getTransactions();
@ -201,7 +243,10 @@ final class ConpherenceThread extends ConpherenceDAO
} }
$img_src = null; $img_src = null;
if ($lucky_handle) { $size = ConpherenceImageData::SIZE_CROP;
if ($this->getImagePHID($size)) {
$img_src = $this->getImage($size)->getBestURI();
} else if ($lucky_handle) {
$img_src = $lucky_handle->getImageURI(); $img_src = $lucky_handle->getImageURI();
} }

View file

@ -32,12 +32,11 @@ final class ConpherenceTransaction extends PhabricatorApplicationTransaction {
case ConpherenceTransactionType::TYPE_PARTICIPANTS: case ConpherenceTransactionType::TYPE_PARTICIPANTS:
return ($old === null); return ($old === null);
case ConpherenceTransactionType::TYPE_TITLE: case ConpherenceTransactionType::TYPE_TITLE:
case ConpherenceTransactionType::TYPE_PICTURE:
case ConpherenceTransactionType::TYPE_DATE_MARKER: case ConpherenceTransactionType::TYPE_DATE_MARKER:
return false; return false;
case ConpherenceTransactionType::TYPE_FILES: case ConpherenceTransactionType::TYPE_FILES:
return true; return true;
// we used to have them so just always hide
case ConpherenceTransactionType::TYPE_PICTURE:
case ConpherenceTransactionType::TYPE_PICTURE_CROP: case ConpherenceTransactionType::TYPE_PICTURE_CROP:
return true; return true;
} }
@ -56,6 +55,7 @@ final class ConpherenceTransaction extends PhabricatorApplicationTransaction {
case PhabricatorTransactions::TYPE_VIEW_POLICY: case PhabricatorTransactions::TYPE_VIEW_POLICY:
case PhabricatorTransactions::TYPE_EDIT_POLICY: case PhabricatorTransactions::TYPE_EDIT_POLICY:
case PhabricatorTransactions::TYPE_JOIN_POLICY: case PhabricatorTransactions::TYPE_JOIN_POLICY:
case ConpherenceTransactionType::TYPE_PICTURE:
if ($this->getObject()->getIsRoom()) { if ($this->getObject()->getIsRoom()) {
return $this->getRoomTitle(); return $this->getRoomTitle();
} else { } else {
@ -144,6 +144,11 @@ final class ConpherenceTransaction extends PhabricatorApplicationTransaction {
} }
return $title; return $title;
break; break;
case ConpherenceTransactionType::TYPE_PICTURE:
return pht(
'%s updated the room image.',
$this->renderHandleLink($author_phid));
break;
case PhabricatorTransactions::TYPE_VIEW_POLICY: case PhabricatorTransactions::TYPE_VIEW_POLICY:
return pht( return pht(
'%s changed the visibility of this room from "%s" to "%s".', '%s changed the visibility of this room from "%s" to "%s".',
@ -195,6 +200,11 @@ final class ConpherenceTransaction extends PhabricatorApplicationTransaction {
} }
return $title; return $title;
break; break;
case ConpherenceTransactionType::TYPE_PICTURE:
return pht(
'%s updated the room image.',
$this->renderHandleLink($author_phid));
break;
case PhabricatorTransactions::TYPE_VIEW_POLICY: case PhabricatorTransactions::TYPE_VIEW_POLICY:
return pht( return pht(
'%s changed the visibility of this thread from "%s" to "%s".', '%s changed the visibility of this thread from "%s" to "%s".',
@ -228,6 +238,7 @@ final class ConpherenceTransaction extends PhabricatorApplicationTransaction {
$phids[] = $this->getAuthorPHID(); $phids[] = $this->getAuthorPHID();
switch ($this->getTransactionType()) { switch ($this->getTransactionType()) {
case ConpherenceTransactionType::TYPE_TITLE: case ConpherenceTransactionType::TYPE_TITLE:
case ConpherenceTransactionType::TYPE_PICTURE:
case ConpherenceTransactionType::TYPE_FILES: case ConpherenceTransactionType::TYPE_FILES:
case ConpherenceTransactionType::TYPE_DATE_MARKER: case ConpherenceTransactionType::TYPE_DATE_MARKER:
break; break;

View file

@ -412,7 +412,7 @@ final class ConpherenceDurableColumnView extends AphrontTagView {
array( array(
'name' => $rename_label, 'name' => $rename_label,
'disabled' => !$can_edit, 'disabled' => !$can_edit,
'href' => '/conpherence/update/'.$conpherence->getID().'/', 'href' => '/conpherence/update/'.$conpherence->getID().'/?nopic',
'icon' => 'fa-pencil', 'icon' => 'fa-pencil',
'key' => ConpherenceUpdateActions::METADATA, 'key' => ConpherenceUpdateActions::METADATA,
), ),

View file

@ -0,0 +1,40 @@
<?php
final class ConpherenceFormDragAndDropUploadControl extends AphrontFormControl {
private $dropID;
public function setDropID($drop_id) {
$this->dropID = $drop_id;
return $this;
}
public function getDropID() {
return $this->dropID;
}
protected function getCustomControlClass() {
return null;
}
protected function renderInput() {
$drop_id = celerity_generate_unique_node_id();
Javelin::initBehavior('conpherence-drag-and-drop-photo',
array(
'target' => $drop_id,
'form_pane' => 'conpherence-form',
'upload_uri' => '/file/dropupload/',
'activated_class' => 'conpherence-dialogue-upload-photo',
));
require_celerity_resource('conpherence-update-css');
return phutil_tag(
'div',
array(
'id' => $drop_id,
'class' => 'conpherence-dialogue-drag-photo',
),
pht('Drag and drop an image here to upload it.'));
}
}

View file

@ -0,0 +1,78 @@
<?php
final class ConpherencePicCropControl extends AphrontFormControl {
protected function getCustomControlClass() {
return 'aphront-form-crop';
}
protected function renderInput() {
$width = ConpherenceImageData::CROP_WIDTH;
$height = ConpherenceImageData::CROP_HEIGHT;
$file = $this->getValue();
if ($file === null) {
return phutil_tag(
'img',
array(
'src' => PhabricatorUser::getDefaultProfileImageURI(),
),
'');
}
$c_id = celerity_generate_unique_node_id();
$metadata = $file->getMetadata();
$scale = PhabricatorImageTransformer::getScaleForCrop(
$file,
$width,
$height);
Javelin::initBehavior(
'aphront-crop',
array(
'cropBoxID' => $c_id,
'width' => $width,
'height' => $height,
'scale' => $scale,
'imageH' => $metadata[PhabricatorFile::METADATA_IMAGE_HEIGHT],
'imageW' => $metadata[PhabricatorFile::METADATA_IMAGE_WIDTH],
));
return javelin_tag(
'div',
array(
'id' => $c_id,
'sigil' => 'crop-box',
'mustcapture' => true,
'class' => 'crop-box',
),
array(
javelin_tag(
'img',
array(
'src' => $file->getBestURI(),
'class' => 'crop-image',
'sigil' => 'crop-image',
),
''),
javelin_tag(
'input',
array(
'type' => 'hidden',
'name' => 'image_x',
'sigil' => 'crop-x',
),
''),
javelin_tag(
'input',
array(
'type' => 'hidden',
'name' => 'image_y',
'sigil' => 'crop-y',
),
''),
));
}
}

View file

@ -256,6 +256,8 @@ final class ConpherenceTransactionView extends AphrontView {
$content = $transaction->getTitle(); $content = $transaction->getTitle();
break; break;
case ConpherenceTransactionType::TYPE_TITLE: case ConpherenceTransactionType::TYPE_TITLE:
case ConpherenceTransactionType::TYPE_PICTURE:
case ConpherenceTransactionType::TYPE_PICTURE_CROP:
case ConpherenceTransactionType::TYPE_PARTICIPANTS: case ConpherenceTransactionType::TYPE_PARTICIPANTS:
case PhabricatorTransactions::TYPE_VIEW_POLICY: case PhabricatorTransactions::TYPE_VIEW_POLICY:
case PhabricatorTransactions::TYPE_EDIT_POLICY: case PhabricatorTransactions::TYPE_EDIT_POLICY:

View file

@ -0,0 +1,38 @@
/**
* @provides javelin-behavior-conpherence-drag-and-drop-photo
* @requires javelin-behavior
* javelin-dom
* javelin-workflow
* phabricator-drag-and-drop-file-upload
*/
JX.behavior('conpherence-drag-and-drop-photo', function(config) {
var target = JX.$(config.target);
var form_pane = JX.$(config.form_pane);
function onupload(f) {
var data = {
'file_id' : f.getID(),
'action' : 'metadata'
};
var form = JX.DOM.find(form_pane, 'form');
var workflow = JX.Workflow.newFromForm(form, data);
workflow.start();
}
if (JX.PhabricatorDragAndDropFileUpload.isSupported()) {
var drop = new JX.PhabricatorDragAndDropFileUpload(target)
.setURI(config.upload_uri);
drop.listen('didBeginDrag', function() {
JX.DOM.alterClass(target, config.activated_class, true);
});
drop.listen('didEndDrag', function() {
JX.DOM.alterClass(target, config.activated_class, false);
});
drop.listen('didUpload', onupload);
drop.start();
}
});