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

Convert Conpherence to use normal picture setting flows

Summary: This moves room pictures out of the dialog and into it's own PictureController. Also adds a standard image (and removes the "last person to chat" picture (though we could add that back. My plan is though that direct messages use auto use the other person's photo, after we have editengine and room pictures will have a plain, replaceable image.

Test Plan: Set a new room picture, remove a picture. Run migration, see old images properly set with new image.

Reviewers: epriestley

Reviewed By: epriestley

Subscribers: Korvin

Maniphest Tasks: T11730

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

+371 -257
resources/builtin/conpherence.png

This is a binary file and will not be displayed.

+3 -3
resources/celerity/map.php
··· 7 7 */ 8 8 return array( 9 9 'names' => array( 10 - 'conpherence.pkg.css' => '3c08b01f', 10 + 'conpherence.pkg.css' => '4601645d', 11 11 'conpherence.pkg.js' => '11f3e07e', 12 12 'core.pkg.css' => '3fa66cb3', 13 13 'core.pkg.js' => '30185d95', ··· 47 47 'rsrc/css/application/config/setup-issue.css' => 'f794cfc3', 48 48 'rsrc/css/application/config/unhandled-exception.css' => '4c96257a', 49 49 'rsrc/css/application/conpherence/durable-column.css' => '44bcaa19', 50 - 'rsrc/css/application/conpherence/header-pane.css' => '6a032d4c', 50 + 'rsrc/css/application/conpherence/header-pane.css' => '20a7028c', 51 51 'rsrc/css/application/conpherence/menu.css' => '4f51db5a', 52 52 'rsrc/css/application/conpherence/message-pane.css' => '0d7dff02', 53 53 'rsrc/css/application/conpherence/notification.css' => '965db05b', ··· 618 618 'config-options-css' => '0ede4c9b', 619 619 'config-page-css' => '8798e14f', 620 620 'conpherence-durable-column-view' => '44bcaa19', 621 - 'conpherence-header-pane-css' => '6a032d4c', 621 + 'conpherence-header-pane-css' => '20a7028c', 622 622 'conpherence-menu-css' => '4f51db5a', 623 623 'conpherence-message-pane-css' => '0d7dff02', 624 624 'conpherence-notification-css' => '965db05b',
+2
resources/sql/autopatches/20161005.conpherence.image.1.sql
··· 1 + ALTER TABLE {$NAMESPACE}_conpherence.conpherence_thread 2 + ADD profileImagePHID VARBINARY(64);
+34
resources/sql/autopatches/20161005.conpherence.image.2.php
··· 1 + <?php 2 + 3 + // Rebuild all Conpherence Room images to profile standards 4 + // 5 + $table = new ConpherenceThread(); 6 + $conn = $table->establishConnection('w'); 7 + $table_name = 'conpherence_thread'; 8 + 9 + foreach (new LiskRawMigrationIterator($conn, $table_name) as $row) { 10 + 11 + $images = phutil_json_decode($row['imagePHIDs']); 12 + if (!$images) { 13 + return; 14 + } 15 + 16 + $file_phid = idx($images, 'original'); 17 + 18 + $file = id(new PhabricatorFileQuery()) 19 + ->setViewer(PhabricatorUser::getOmnipotentUser()) 20 + ->withPHIDs(array($file_phid)) 21 + ->executeOne(); 22 + 23 + $xform = PhabricatorFileTransform::getTransformByKey( 24 + PhabricatorFileThumbnailTransform::TRANSFORM_PROFILE); 25 + $xformed = $xform->executeTransform($file); 26 + $new_phid = $xformed->getPHID(); 27 + 28 + queryfx( 29 + $conn, 30 + 'UPDATE %T SET profileImagePHID = %s WHERE id = %d', 31 + $table->getTableName(), 32 + $new_phid, 33 + $row['id']); 34 + }
+2 -2
src/__phutil_library_map__.php
··· 292 292 'ConpherenceEditor' => 'applications/conpherence/editor/ConpherenceEditor.php', 293 293 'ConpherenceFormDragAndDropUploadControl' => 'applications/conpherence/view/ConpherenceFormDragAndDropUploadControl.php', 294 294 'ConpherenceFulltextQuery' => 'applications/conpherence/query/ConpherenceFulltextQuery.php', 295 - 'ConpherenceImageData' => 'applications/conpherence/constants/ConpherenceImageData.php', 296 295 'ConpherenceIndex' => 'applications/conpherence/storage/ConpherenceIndex.php', 297 296 'ConpherenceLayoutView' => 'applications/conpherence/view/ConpherenceLayoutView.php', 298 297 'ConpherenceListController' => 'applications/conpherence/controller/ConpherenceListController.php', ··· 309 308 'ConpherenceQueryTransactionConduitAPIMethod' => 'applications/conpherence/conduit/ConpherenceQueryTransactionConduitAPIMethod.php', 310 309 'ConpherenceReplyHandler' => 'applications/conpherence/mail/ConpherenceReplyHandler.php', 311 310 'ConpherenceRoomListController' => 'applications/conpherence/controller/ConpherenceRoomListController.php', 311 + 'ConpherenceRoomPictureController' => 'applications/conpherence/controller/ConpherenceRoomPictureController.php', 312 312 'ConpherenceRoomTestCase' => 'applications/conpherence/__tests__/ConpherenceRoomTestCase.php', 313 313 'ConpherenceSchemaSpec' => 'applications/conpherence/storage/ConpherenceSchemaSpec.php', 314 314 'ConpherenceTestCase' => 'applications/conpherence/__tests__/ConpherenceTestCase.php', ··· 4768 4768 'ConpherenceEditor' => 'PhabricatorApplicationTransactionEditor', 4769 4769 'ConpherenceFormDragAndDropUploadControl' => 'AphrontFormControl', 4770 4770 'ConpherenceFulltextQuery' => 'PhabricatorOffsetPagedQuery', 4771 - 'ConpherenceImageData' => 'ConpherenceConstants', 4772 4771 'ConpherenceIndex' => 'ConpherenceDAO', 4773 4772 'ConpherenceLayoutView' => 'AphrontTagView', 4774 4773 'ConpherenceListController' => 'ConpherenceController', ··· 4785 4784 'ConpherenceQueryTransactionConduitAPIMethod' => 'ConpherenceConduitAPIMethod', 4786 4785 'ConpherenceReplyHandler' => 'PhabricatorMailReplyHandler', 4787 4786 'ConpherenceRoomListController' => 'ConpherenceController', 4787 + 'ConpherenceRoomPictureController' => 'ConpherenceController', 4788 4788 'ConpherenceRoomTestCase' => 'ConpherenceTestCase', 4789 4789 'ConpherenceSchemaSpec' => 'PhabricatorConfigSchemaSpec', 4790 4790 'ConpherenceTestCase' => 'PhabricatorTestCase',
+22 -11
src/applications/conpherence/application/PhabricatorConpherenceApplication.php
··· 30 30 31 31 public function getRoutes() { 32 32 return array( 33 - '/Z(?P<id>[1-9]\d*)' => 'ConpherenceViewController', 33 + '/Z(?P<id>[1-9]\d*)' 34 + => 'ConpherenceViewController', 34 35 '/conpherence/' => array( 35 - '' => 'ConpherenceListController', 36 - 'thread/(?P<id>[1-9]\d*)/' => 'ConpherenceListController', 37 - '(?P<id>[1-9]\d*)/' => 'ConpherenceViewController', 36 + '' 37 + => 'ConpherenceListController', 38 + 'thread/(?P<id>[1-9]\d*)/' 39 + => 'ConpherenceListController', 40 + '(?P<id>[1-9]\d*)/' 41 + => 'ConpherenceViewController', 38 42 '(?P<id>[1-9]\d*)/(?P<messageID>[1-9]\d*)/' 39 - => 'ConpherenceViewController', 40 - 'columnview/' => 'ConpherenceColumnViewController', 41 - 'new/' => 'ConpherenceNewRoomController', 43 + => 'ConpherenceViewController', 44 + 'columnview/' 45 + => 'ConpherenceColumnViewController', 46 + 'new/' 47 + => 'ConpherenceNewRoomController', 48 + 'picture/(?P<id>[1-9]\d*)/' 49 + => 'ConpherenceRoomPictureController', 42 50 'search/(?:query/(?P<queryKey>[^/]+)/)?' 43 - => 'ConpherenceRoomListController', 44 - 'panel/' => 'ConpherenceNotificationPanelController', 45 - 'participant/(?P<id>[1-9]\d*)/' => 'ConpherenceParticipantController', 46 - 'update/(?P<id>[1-9]\d*)/' => 'ConpherenceUpdateController', 51 + => 'ConpherenceRoomListController', 52 + 'panel/' 53 + => 'ConpherenceNotificationPanelController', 54 + 'participant/(?P<id>[1-9]\d*)/' 55 + => 'ConpherenceParticipantController', 56 + 'update/(?P<id>[1-9]\d*)/' 57 + => 'ConpherenceUpdateController', 47 58 ), 48 59 ); 49 60 }
-11
src/applications/conpherence/constants/ConpherenceImageData.php
··· 1 - <?php 2 - 3 - final class ConpherenceImageData extends ConpherenceConstants { 4 - 5 - const SIZE_ORIG = 'original'; 6 - const SIZE_CROP = 'crop'; 7 - 8 - const CROP_WIDTH = 200; 9 - const CROP_HEIGHT = 200; 10 - 11 - }
+3 -3
src/applications/conpherence/controller/ConpherenceColumnViewController.php
··· 16 16 $latest_conpherences = id(new ConpherenceThreadQuery()) 17 17 ->setViewer($user) 18 18 ->withPHIDs($conpherence_phids) 19 - ->needCropPics(true) 19 + ->needProfileImage(true) 20 20 ->needParticipantCache(true) 21 21 ->execute(); 22 22 $latest_conpherences = mpull($latest_conpherences, null, 'getPHID'); ··· 31 31 $conpherence = id(new ConpherenceThreadQuery()) 32 32 ->setViewer($user) 33 33 ->withIDs(array($request->getInt('id'))) 34 - ->needCropPics(true) 34 + ->needProfileImage(true) 35 35 ->needTransactions(true) 36 36 ->setTransactionLimit(ConpherenceThreadQuery::TRANSACTION_LIMIT) 37 37 ->executeOne(); ··· 41 41 $conpherence = id(new ConpherenceThreadQuery()) 42 42 ->setViewer($user) 43 43 ->withPHIDs(array($participant->getConpherencePHID())) 44 - ->needCropPics(true) 44 + ->needProfileImage(true) 45 45 ->needTransactions(true) 46 46 ->setTransactionLimit(ConpherenceThreadQuery::TRANSACTION_LIMIT) 47 47 ->executeOne();
+5
src/applications/conpherence/controller/ConpherenceController.php
··· 66 66 $conpherence, 67 67 PhabricatorPolicyCapability::CAN_EDIT); 68 68 69 + if ($can_edit) { 70 + $header->setImageURL( 71 + $this->getApplicationURI('picture/'.$conpherence->getID().'/')); 72 + } 73 + 69 74 $participating = $conpherence->getParticipantIfExists($viewer->getPHID()); 70 75 $can_join = PhabricatorPolicyFilter::hasCapability( 71 76 $viewer,
+1 -1
src/applications/conpherence/controller/ConpherenceListController.php
··· 158 158 $conpherences = id(new ConpherenceThreadQuery()) 159 159 ->setViewer($user) 160 160 ->withPHIDs($conpherence_phids) 161 - ->needCropPics(true) 161 + ->needProfileImage(true) 162 162 ->needParticipantCache(true) 163 163 ->execute(); 164 164
+1 -1
src/applications/conpherence/controller/ConpherenceNotificationPanelController.php
··· 18 18 $conpherences = id(new ConpherenceThreadQuery()) 19 19 ->setViewer($user) 20 20 ->withPHIDs(array_keys($participant_data)) 21 - ->needCropPics(true) 21 + ->needProfileImage(true) 22 22 ->needTransactions(true) 23 23 ->setTransactionLimit(3 * 5) 24 24 ->needParticipantCache(true)
+234
src/applications/conpherence/controller/ConpherenceRoomPictureController.php
··· 1 + <?php 2 + 3 + final class ConpherenceRoomPictureController 4 + extends ConpherenceController { 5 + 6 + public function handleRequest(AphrontRequest $request) { 7 + $viewer = $request->getViewer(); 8 + $id = $request->getURIData('id'); 9 + 10 + $conpherence = id(new ConpherenceThreadQuery()) 11 + ->setViewer($viewer) 12 + ->withIDs(array($id)) 13 + ->needProfileImage(true) 14 + ->requireCapabilities( 15 + array( 16 + PhabricatorPolicyCapability::CAN_VIEW, 17 + PhabricatorPolicyCapability::CAN_EDIT, 18 + )) 19 + ->executeOne(); 20 + if (!$conpherence) { 21 + return new Aphront404Response(); 22 + } 23 + 24 + $monogram = $conpherence->getMonogram(); 25 + 26 + $supported_formats = PhabricatorFile::getTransformableImageFormats(); 27 + $e_file = true; 28 + $errors = array(); 29 + 30 + if ($request->isFormPost()) { 31 + $phid = $request->getStr('phid'); 32 + $is_default = false; 33 + if ($phid == PhabricatorPHIDConstants::PHID_VOID) { 34 + $phid = null; 35 + $is_default = true; 36 + } else if ($phid) { 37 + $file = id(new PhabricatorFileQuery()) 38 + ->setViewer($viewer) 39 + ->withPHIDs(array($phid)) 40 + ->executeOne(); 41 + } else { 42 + if ($request->getFileExists('picture')) { 43 + $file = PhabricatorFile::newFromPHPUpload( 44 + $_FILES['picture'], 45 + array( 46 + 'authorPHID' => $viewer->getPHID(), 47 + 'canCDN' => true, 48 + )); 49 + } else { 50 + $e_file = pht('Required'); 51 + $errors[] = pht( 52 + 'You must choose a file when uploading a new room picture.'); 53 + } 54 + } 55 + 56 + if (!$errors && !$is_default) { 57 + if (!$file->isTransformableImage()) { 58 + $e_file = pht('Not Supported'); 59 + $errors[] = pht( 60 + 'This server only supports these image formats: %s.', 61 + implode(', ', $supported_formats)); 62 + } else { 63 + $xform = PhabricatorFileTransform::getTransformByKey( 64 + PhabricatorFileThumbnailTransform::TRANSFORM_PROFILE); 65 + $xformed = $xform->executeTransform($file); 66 + } 67 + } 68 + 69 + if (!$errors) { 70 + if ($is_default) { 71 + $new_value = null; 72 + } else { 73 + $xformed->attachToObject($conpherence->getPHID()); 74 + $new_value = $xformed->getPHID(); 75 + } 76 + 77 + $xactions = array(); 78 + $xactions[] = id(new ConpherenceTransaction()) 79 + ->setTransactionType(ConpherenceTransaction::TYPE_PICTURE) 80 + ->setNewValue($new_value); 81 + 82 + $editor = id(new ConpherenceEditor()) 83 + ->setActor($viewer) 84 + ->setContentSourceFromRequest($request) 85 + ->setContinueOnMissingFields(true) 86 + ->setContinueOnNoEffect(true); 87 + 88 + $editor->applyTransactions($conpherence, $xactions); 89 + 90 + return id(new AphrontRedirectResponse())->setURI('/'.$monogram); 91 + } 92 + } 93 + 94 + $title = pht('Edit Room Picture'); 95 + 96 + $form = id(new PHUIFormLayoutView()) 97 + ->setUser($viewer); 98 + 99 + $default_image = PhabricatorFile::loadBuiltin($viewer, 'conpherence.png'); 100 + 101 + $images = array(); 102 + 103 + $current = $conpherence->getProfileImagePHID(); 104 + $has_current = false; 105 + if ($current) { 106 + $file = id(new PhabricatorFileQuery()) 107 + ->setViewer($viewer) 108 + ->withPHIDs(array($current)) 109 + ->executeOne(); 110 + if ($file) { 111 + if ($file->isTransformableImage()) { 112 + $has_current = true; 113 + $images[$current] = array( 114 + 'uri' => $file->getBestURI(), 115 + 'tip' => pht('Current Picture'), 116 + ); 117 + } 118 + } 119 + } 120 + 121 + $images[PhabricatorPHIDConstants::PHID_VOID] = array( 122 + 'uri' => $default_image->getBestURI(), 123 + 'tip' => pht('Default Picture'), 124 + ); 125 + 126 + require_celerity_resource('people-profile-css'); 127 + Javelin::initBehavior('phabricator-tooltips', array()); 128 + 129 + $buttons = array(); 130 + foreach ($images as $phid => $spec) { 131 + $button = javelin_tag( 132 + 'button', 133 + array( 134 + 'class' => 'grey profile-image-button', 135 + 'sigil' => 'has-tooltip', 136 + 'meta' => array( 137 + 'tip' => $spec['tip'], 138 + 'size' => 300, 139 + ), 140 + ), 141 + phutil_tag( 142 + 'img', 143 + array( 144 + 'height' => 50, 145 + 'width' => 50, 146 + 'src' => $spec['uri'], 147 + ))); 148 + 149 + $button = array( 150 + phutil_tag( 151 + 'input', 152 + array( 153 + 'type' => 'hidden', 154 + 'name' => 'phid', 155 + 'value' => $phid, 156 + )), 157 + $button, 158 + ); 159 + 160 + $button = phabricator_form( 161 + $viewer, 162 + array( 163 + 'class' => 'profile-image-form', 164 + 'method' => 'POST', 165 + ), 166 + $button); 167 + 168 + $buttons[] = $button; 169 + } 170 + 171 + if ($has_current) { 172 + $form->appendChild( 173 + id(new AphrontFormMarkupControl()) 174 + ->setLabel(pht('Current Picture')) 175 + ->setValue(array_shift($buttons))); 176 + } 177 + 178 + $form->appendChild( 179 + id(new AphrontFormMarkupControl()) 180 + ->setLabel(pht('Use Picture')) 181 + ->setValue($buttons)); 182 + 183 + $form_box = id(new PHUIObjectBoxView()) 184 + ->setHeaderText($title) 185 + ->setFormErrors($errors) 186 + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) 187 + ->setForm($form); 188 + 189 + $upload_form = id(new AphrontFormView()) 190 + ->setUser($viewer) 191 + ->setEncType('multipart/form-data') 192 + ->appendChild( 193 + id(new AphrontFormFileControl()) 194 + ->setName('picture') 195 + ->setLabel(pht('Upload Picture')) 196 + ->setError($e_file) 197 + ->setCaption( 198 + pht('Supported formats: %s', implode(', ', $supported_formats)))) 199 + ->appendChild( 200 + id(new AphrontFormSubmitControl()) 201 + ->addCancelButton('/'.$monogram) 202 + ->setValue(pht('Upload Picture'))); 203 + 204 + $upload_box = id(new PHUIObjectBoxView()) 205 + ->setHeaderText(pht('Upload New Picture')) 206 + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) 207 + ->setForm($upload_form); 208 + 209 + $crumbs = $this->buildApplicationCrumbs(); 210 + $crumbs->addTextCrumb($conpherence->getTitle(), '/'.$monogram); 211 + $crumbs->addTextCrumb(pht('Room Picture')); 212 + $crumbs->setBorder(true); 213 + 214 + $header = id(new PHUIHeaderView()) 215 + ->setHeader(pht('Edit Room Picture')) 216 + ->setHeaderIcon('fa-camera'); 217 + 218 + $view = id(new PHUITwoColumnView()) 219 + ->setHeader($header) 220 + ->setFooter(array( 221 + $form_box, 222 + $upload_box, 223 + )); 224 + 225 + return $this->newPage() 226 + ->setTitle($title) 227 + ->setCrumbs($crumbs) 228 + ->appendChild( 229 + array( 230 + $view, 231 + )); 232 + 233 + } 234 + }
+1 -73
src/applications/conpherence/controller/ConpherenceUpdateController.php
··· 36 36 $conpherence = id(new ConpherenceThreadQuery()) 37 37 ->setViewer($user) 38 38 ->withIDs(array($conpherence_id)) 39 - ->needOrigPics(true) 40 - ->needCropPics(true) 41 39 ->needParticipants($need_participants) 42 40 ->requireCapabilities($needed_capabilities) 43 41 ->executeOne(); ··· 131 129 132 130 break; 133 131 case ConpherenceUpdateActions::METADATA: 134 - $top = $request->getInt('image_y'); 135 - $left = $request->getInt('image_x'); 136 - $file_id = $request->getInt('file_id'); 137 132 $title = $request->getStr('title'); 138 133 $topic = $request->getStr('topic'); 139 - if ($file_id) { 140 - $orig_file = id(new PhabricatorFileQuery()) 141 - ->setViewer($user) 142 - ->withIDs(array($file_id)) 143 - ->executeOne(); 144 - $xactions[] = id(new ConpherenceTransaction()) 145 - ->setTransactionType(ConpherenceTransaction::TYPE_PICTURE) 146 - ->setNewValue($orig_file); 147 - $okay = $orig_file->isTransformableImage(); 148 - if ($okay) { 149 - $xformer = new PhabricatorImageTransformer(); 150 - $crop_file = $xformer->executeConpherenceTransform( 151 - $orig_file, 152 - 0, 153 - 0, 154 - ConpherenceImageData::CROP_WIDTH, 155 - ConpherenceImageData::CROP_HEIGHT); 156 - $xactions[] = id(new ConpherenceTransaction()) 157 - ->setTransactionType( 158 - ConpherenceTransaction::TYPE_PICTURE_CROP) 159 - ->setNewValue($crop_file->getPHID()); 160 - } 161 - $response_mode = 'redirect'; 162 - } 163 134 164 135 // all other metadata updates are continue requests 165 136 if (!$request->isContinueRequest()) { 166 137 break; 167 138 } 168 139 169 - if ($top !== null || $left !== null) { 170 - $file = $conpherence->getImage(ConpherenceImageData::SIZE_ORIG); 171 - $xformer = new PhabricatorImageTransformer(); 172 - $xformed = $xformer->executeConpherenceTransform( 173 - $file, 174 - $top, 175 - $left, 176 - ConpherenceImageData::CROP_WIDTH, 177 - ConpherenceImageData::CROP_HEIGHT); 178 - $image_phid = $xformed->getPHID(); 179 - 180 - $xactions[] = id(new ConpherenceTransaction()) 181 - ->setTransactionType( 182 - ConpherenceTransaction::TYPE_PICTURE_CROP) 183 - ->setNewValue($image_phid); 184 - } 185 140 $title = $request->getStr('title'); 186 141 $topic = $request->getStr('topic'); 187 142 $xactions[] = id(new ConpherenceTransaction()) ··· 491 446 ->setName('topic') 492 447 ->setValue($conpherence->getTopic())); 493 448 494 - $nopic = $this->getRequest()->getExists('nopic'); 495 - $image = $conpherence->getImage(ConpherenceImageData::SIZE_ORIG); 496 - if ($nopic) { 497 - // do not render any pic related controls 498 - } else if ($image) { 499 - $crop_uri = $conpherence->loadImageURI(ConpherenceImageData::SIZE_CROP); 500 - $form 501 - ->appendChild( 502 - id(new AphrontFormMarkupControl()) 503 - ->setLabel(pht('Image')) 504 - ->setValue(phutil_tag( 505 - 'img', 506 - array( 507 - 'src' => $crop_uri, 508 - )))) 509 - ->appendChild( 510 - id(new ConpherenceFormDragAndDropUploadControl()) 511 - ->setLabel(pht('Change Image'))); 512 - } else { 513 - $form 514 - ->appendChild( 515 - id(new ConpherenceFormDragAndDropUploadControl()) 516 - ->setLabel(pht('Image'))); 517 - } 518 - 519 449 $policies = id(new PhabricatorPolicyQuery()) 520 450 ->setViewer($user) 521 451 ->setObject($conpherence) ··· 567 497 $latest_transaction_id) { 568 498 569 499 $minimal_display = $this->getRequest()->getExists('minimal_display'); 570 - $need_widget_data = false; 571 500 $need_transactions = false; 572 501 $need_participant_cache = true; 573 502 switch ($action) { ··· 578 507 case ConpherenceUpdateActions::MESSAGE: 579 508 case ConpherenceUpdateActions::ADD_PERSON: 580 509 $need_transactions = true; 581 - $need_widget_data = !$minimal_display; 582 510 break; 583 511 case ConpherenceUpdateActions::REMOVE_PERSON: 584 512 case ConpherenceUpdateActions::NOTIFICATIONS: ··· 590 518 $conpherence = id(new ConpherenceThreadQuery()) 591 519 ->setViewer($user) 592 520 ->setAfterTransactionID($latest_transaction_id) 593 - ->needCropPics(true) 521 + ->needProfileImage(true) 594 522 ->needParticipantCache($need_participant_cache) 595 523 ->needParticipants(true) 596 524 ->needTransactions($need_transactions)
+1 -1
src/applications/conpherence/controller/ConpherenceViewController.php
··· 19 19 $query = id(new ConpherenceThreadQuery()) 20 20 ->setViewer($user) 21 21 ->withIDs(array($conpherence_id)) 22 - ->needCropPics(true) 22 + ->needProfileImage(true) 23 23 ->needParticipantCache(true) 24 24 ->needTransactions(true) 25 25 ->setTransactionLimit($this->getMainQueryLimit());
+7 -44
src/applications/conpherence/editor/ConpherenceEditor.php
··· 91 91 $types[] = ConpherenceTransaction::TYPE_TOPIC; 92 92 $types[] = ConpherenceTransaction::TYPE_PARTICIPANTS; 93 93 $types[] = ConpherenceTransaction::TYPE_PICTURE; 94 - $types[] = ConpherenceTransaction::TYPE_PICTURE_CROP; 95 94 $types[] = PhabricatorTransactions::TYPE_VIEW_POLICY; 96 95 $types[] = PhabricatorTransactions::TYPE_EDIT_POLICY; 97 96 $types[] = PhabricatorTransactions::TYPE_JOIN_POLICY; ··· 109 108 case ConpherenceTransaction::TYPE_TOPIC: 110 109 return $object->getTopic(); 111 110 case ConpherenceTransaction::TYPE_PICTURE: 112 - return $object->getImagePHID(ConpherenceImageData::SIZE_ORIG); 113 - case ConpherenceTransaction::TYPE_PICTURE_CROP: 114 - return $object->getImagePHID(ConpherenceImageData::SIZE_CROP); 111 + return $object->getProfileImagePHID(); 115 112 case ConpherenceTransaction::TYPE_PARTICIPANTS: 116 113 if ($this->getIsNewObject()) { 117 114 return array(); ··· 127 124 switch ($xaction->getTransactionType()) { 128 125 case ConpherenceTransaction::TYPE_TITLE: 129 126 case ConpherenceTransaction::TYPE_TOPIC: 130 - case ConpherenceTransaction::TYPE_PICTURE_CROP: 127 + case ConpherenceTransaction::TYPE_PICTURE: 131 128 return $xaction->getNewValue(); 132 - case ConpherenceTransaction::TYPE_PICTURE: 133 - $file = $xaction->getNewValue(); 134 - return $file->getPHID(); 135 129 case ConpherenceTransaction::TYPE_PARTICIPANTS: 136 130 return $this->getPHIDTransactionNewValue($xaction); 137 131 } ··· 224 218 $object->setTopic($xaction->getNewValue()); 225 219 break; 226 220 case ConpherenceTransaction::TYPE_PICTURE: 227 - $object->setImagePHID( 228 - $xaction->getNewValue(), 229 - ConpherenceImageData::SIZE_ORIG); 230 - break; 231 - case ConpherenceTransaction::TYPE_PICTURE_CROP: 232 - $object->setImagePHID( 233 - $xaction->getNewValue(), 234 - ConpherenceImageData::SIZE_CROP); 221 + $object->setProfileImagePHID($xaction->getNewValue()); 235 222 break; 236 223 case ConpherenceTransaction::TYPE_PARTICIPANTS: 237 224 if (!$this->getIsNewObject()) { ··· 338 325 protected function applyFinalEffects( 339 326 PhabricatorLiskDAO $object, 340 327 array $xactions) { 328 + 329 + if (!$xactions) { 330 + return $xactions; 331 + } 341 332 342 333 $message_count = 0; 343 334 foreach ($xactions as $xaction) { ··· 571 562 return true; 572 563 } 573 564 574 - protected function extractFilePHIDsFromCustomTransaction( 575 - PhabricatorLiskDAO $object, 576 - PhabricatorApplicationTransaction $xaction) { 577 - 578 - switch ($xaction->getTransactionType()) { 579 - case ConpherenceTransaction::TYPE_PICTURE: 580 - case ConpherenceTransaction::TYPE_PICTURE_CROP: 581 - return array($xaction->getNewValue()); 582 - } 583 - 584 - return parent::extractFilePHIDsFromCustomTransaction($object, $xaction); 585 - } 586 - 587 565 protected function validateTransaction( 588 566 PhabricatorLiskDAO $object, 589 567 $type, ··· 610 588 611 589 $error->setIsMissingFieldError(true); 612 590 $errors[] = $error; 613 - } 614 - break; 615 - case ConpherenceTransaction::TYPE_PICTURE: 616 - foreach ($xactions as $xaction) { 617 - $file = $xaction->getNewValue(); 618 - if (!$file->isTransformableImage()) { 619 - $detail = pht('This server only supports these image formats: %s.', 620 - implode(', ', PhabricatorFile::getTransformableImageFormats())); 621 - $error = new PhabricatorApplicationTransactionValidationError( 622 - $type, 623 - pht('Invalid'), 624 - $detail, 625 - last($xactions)); 626 - $errors[] = $error; 627 - } 628 591 } 629 592 break; 630 593 case ConpherenceTransaction::TYPE_PARTICIPANTS:
+30 -61
src/applications/conpherence/query/ConpherenceThreadQuery.php
··· 9 9 private $ids; 10 10 private $participantPHIDs; 11 11 private $needParticipants; 12 - private $needCropPics; 13 - private $needOrigPics; 14 12 private $needTransactions; 15 13 private $needParticipantCache; 16 14 private $afterTransactionID; 17 15 private $beforeTransactionID; 18 16 private $transactionLimit; 19 17 private $fulltext; 18 + private $needProfileImage; 20 19 21 20 public function needParticipantCache($participant_cache) { 22 21 $this->needParticipantCache = $participant_cache; ··· 28 27 return $this; 29 28 } 30 29 31 - public function needCropPics($need) { 32 - $this->needCropPics = $need; 33 - return $this; 34 - } 35 - 36 - public function needOrigPics($need_widget_data) { 37 - $this->needOrigPics = $need_widget_data; 30 + public function needProfileImage($need) { 31 + $this->needProfileImage = $need; 38 32 return $this; 39 33 } 40 34 ··· 110 104 if ($this->needTransactions) { 111 105 $this->loadTransactionsAndHandles($conpherences); 112 106 } 113 - if ($this->needOrigPics || $this->needCropPics) { 114 - $this->initImages($conpherences); 115 - } 116 - if ($this->needOrigPics) { 117 - $this->loadOrigPics($conpherences); 118 - } 119 - if ($this->needCropPics) { 120 - $this->loadCropPics($conpherences); 107 + if ($this->needProfileImage) { 108 + $default = null; 109 + $file_phids = mpull($conpherences, 'getProfileImagePHID'); 110 + $file_phids = array_filter($file_phids); 111 + if ($file_phids) { 112 + $files = id(new PhabricatorFileQuery()) 113 + ->setParentQuery($this) 114 + ->setViewer($this->getViewer()) 115 + ->withPHIDs($file_phids) 116 + ->execute(); 117 + $files = mpull($files, null, 'getPHID'); 118 + } else { 119 + $files = array(); 120 + } 121 + 122 + foreach ($conpherences as $conpherence) { 123 + $file = idx($files, $conpherence->getProfileImagePHID()); 124 + if (!$file) { 125 + if (!$default) { 126 + $default = PhabricatorFile::loadBuiltin( 127 + $this->getViewer(), 128 + 'conpherence.png'); 129 + } 130 + $file = $default; 131 + } 132 + $conpherence->attachProfileImageFile($file); 133 + } 121 134 } 122 135 } 123 136 ··· 263 276 $conpherence->attachHandles($conpherence->getHandles() + $handles); 264 277 $conpherence->attachTransactions($current_transactions); 265 278 } 266 - return $this; 267 - } 268 - 269 - private function loadOrigPics(array $conpherences) { 270 - return $this->loadPics( 271 - $conpherences, 272 - ConpherenceImageData::SIZE_ORIG); 273 - } 274 - 275 - private function loadCropPics(array $conpherences) { 276 - return $this->loadPics( 277 - $conpherences, 278 - ConpherenceImageData::SIZE_CROP); 279 - } 280 - 281 - private function initImages($conpherences) { 282 - foreach ($conpherences as $conpherence) { 283 - $conpherence->attachImages(array()); 284 - } 285 - } 286 - 287 - private function loadPics(array $conpherences, $size) { 288 - $conpherence_pic_phids = array(); 289 - foreach ($conpherences as $conpherence) { 290 - $phid = $conpherence->getImagePHID($size); 291 - if ($phid) { 292 - $conpherence_pic_phids[$conpherence->getPHID()] = $phid; 293 - } 294 - } 295 - 296 - if (!$conpherence_pic_phids) { 297 - return $this; 298 - } 299 - 300 - $files = id(new PhabricatorFileQuery()) 301 - ->setViewer($this->getViewer()) 302 - ->withPHIDs($conpherence_pic_phids) 303 - ->execute(); 304 - $files = mpull($files, null, 'getPHID'); 305 - 306 - foreach ($conpherence_pic_phids as $conpherence_phid => $pic_phid) { 307 - $conpherences[$conpherence_phid]->setImage($files[$pic_phid], $size); 308 - } 309 - 310 279 return $this; 311 280 } 312 281
+20 -44
src/applications/conpherence/storage/ConpherenceThread.php
··· 9 9 10 10 protected $title; 11 11 protected $topic; 12 - protected $imagePHIDs = array(); 12 + protected $imagePHIDs = array(); // TODO; nuke after migrations 13 + protected $profileImagePHID; 13 14 protected $messageCount; 14 15 protected $recentParticipantPHIDs = array(); 15 16 protected $mailKey; ··· 19 20 20 21 private $participants = self::ATTACHABLE; 21 22 private $transactions = self::ATTACHABLE; 23 + private $profileImageFile = self::ATTACHABLE; 22 24 private $handles = self::ATTACHABLE; 23 - private $images = self::ATTACHABLE; 24 25 25 26 public static function initializeNewRoom(PhabricatorUser $sender) { 26 27 $default_policy = id(new ConpherenceThreadMembersPolicyRule()) ··· 30 31 ->setTitle('') 31 32 ->setTopic('') 32 33 ->attachParticipants(array()) 33 - ->attachImages(array()) 34 34 ->setViewPolicy($default_policy) 35 35 ->setEditPolicy($default_policy) 36 36 ->setJoinPolicy($default_policy); ··· 49 49 'messageCount' => 'uint64', 50 50 'mailKey' => 'text20', 51 51 'joinPolicy' => 'policy', 52 + 'profileImagePHID' => 'phid?', 52 53 ), 53 54 self::CONFIG_KEY_SCHEMA => array( 54 55 'key_phid' => null, ··· 76 77 return 'Z'.$this->getID(); 77 78 } 78 79 79 - public function getImagePHID($size) { 80 - $image_phids = $this->getImagePHIDs(); 81 - return idx($image_phids, $size); 82 - } 83 - public function setImagePHID($phid, $size) { 84 - $image_phids = $this->getImagePHIDs(); 85 - $image_phids[$size] = $phid; 86 - return $this->setImagePHIDs($image_phids); 87 - } 88 - 89 - public function getImage($size) { 90 - $images = $this->getImages(); 91 - return idx($images, $size); 92 - } 93 - public function setImage(PhabricatorFile $file, $size) { 94 - $files = $this->getImages(); 95 - $files[$size] = $file; 96 - return $this->attachImages($files); 97 - } 98 - public function attachImages(array $files) { 99 - assert_instances_of($files, 'PhabricatorFile'); 100 - $this->images = $files; 101 - return $this; 102 - } 103 - private function getImages() { 104 - return $this->assertAttached($this->images); 105 - } 106 - 107 80 public function attachParticipants(array $participants) { 108 81 assert_instances_of($participants, 'ConpherenceParticipant'); 109 82 $this->participants = $participants; 110 83 return $this; 111 84 } 85 + 112 86 public function getParticipants() { 113 87 return $this->assertAttached($this->participants); 114 88 } 89 + 115 90 public function getParticipant($phid) { 116 91 $participants = $this->getParticipants(); 117 92 return $participants[$phid]; 118 93 } 94 + 119 95 public function getParticipantIfExists($phid, $default = null) { 120 96 $participants = $this->getParticipants(); 121 97 return idx($participants, $phid, $default); ··· 131 107 $this->handles = $handles; 132 108 return $this; 133 109 } 110 + 134 111 public function getHandles() { 135 112 return $this->assertAttached($this->handles); 136 113 } ··· 140 117 $this->transactions = $transactions; 141 118 return $this; 142 119 } 120 + 143 121 public function getTransactions($assert_attached = true) { 144 122 return $this->assertAttached($this->transactions); 145 123 } 124 + 146 125 public function hasAttachedTransactions() { 147 126 return $this->transactions !== self::ATTACHABLE; 148 127 } ··· 156 135 $amount); 157 136 } 158 137 159 - public function loadImageURI($size) { 160 - $file = $this->getImage($size); 138 + public function getProfileImageURI() { 139 + return $this->getProfileImageFile()->getBestURI(); 140 + } 161 141 162 - if ($file) { 163 - return $file->getBestURI(); 164 - } 142 + public function attachProfileImageFile(PhabricatorFile $file) { 143 + $this->profileImageFile = $file; 144 + return $this; 145 + } 165 146 166 - return PhabricatorUser::getDefaultProfileImageURI(); 147 + public function getProfileImageFile() { 148 + return $this->assertAttached($this->profileImageFile); 167 149 } 168 150 169 151 /** ··· 273 255 $lucky_handle = reset($handles); 274 256 } 275 257 276 - $img_src = null; 277 - $size = ConpherenceImageData::SIZE_CROP; 278 - if ($this->getImagePHID($size)) { 279 - $img_src = $this->getImage($size)->getBestURI(); 280 - } else if ($lucky_handle) { 281 - $img_src = $lucky_handle->getImageURI(); 282 - } 258 + $img_src = $this->getProfileImageURI(); 283 259 284 260 $message_title = null; 285 261 if ($subtitle_mode == 'message') {
+1 -1
src/applications/conpherence/storage/ConpherenceTransaction.php
··· 7 7 const TYPE_PARTICIPANTS = 'participants'; 8 8 const TYPE_DATE_MARKER = 'date-marker'; 9 9 const TYPE_PICTURE = 'picture'; 10 - const TYPE_PICTURE_CROP = 'picture-crop'; 10 + const TYPE_PICTURE_CROP = 'picture-crop'; // TODO: Nuke these from DB. 11 11 12 12 public function getApplicationName() { 13 13 return 'conpherence';
-1
src/applications/conpherence/view/ConpherenceTransactionView.php
··· 228 228 case ConpherenceTransaction::TYPE_TITLE: 229 229 case ConpherenceTransaction::TYPE_TOPIC: 230 230 case ConpherenceTransaction::TYPE_PICTURE: 231 - case ConpherenceTransaction::TYPE_PICTURE_CROP: 232 231 case ConpherenceTransaction::TYPE_PARTICIPANTS: 233 232 case PhabricatorTransactions::TYPE_VIEW_POLICY: 234 233 case PhabricatorTransactions::TYPE_EDIT_POLICY:
+4
webroot/rsrc/css/application/conpherence/header-pane.css
··· 34 34 left: 0; 35 35 } 36 36 37 + .conpherence-header-pane .phui-header-image-href { 38 + position: inherit; 39 + } 40 + 37 41 .conpherence-header-pane .phui-header-col2 { 38 42 height: 40px; 39 43 }