diff --git a/resources/celerity/map.php b/resources/celerity/map.php index a67605eb7a..8ca3fd4821 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -353,7 +353,7 @@ return array( 'rsrc/js/application/auth/behavior-persona-login.js' => '9414ff18', 'rsrc/js/application/config/behavior-reorder-fields.js' => '14a827de', 'rsrc/js/application/conpherence/ConpherenceThreadManager.js' => 'bb928342', - 'rsrc/js/application/conpherence/behavior-durable-column.js' => 'eedc463c', + 'rsrc/js/application/conpherence/behavior-durable-column.js' => '70787038', 'rsrc/js/application/conpherence/behavior-menu.js' => 'de5579b4', 'rsrc/js/application/conpherence/behavior-pontificate.js' => '21ba5861', 'rsrc/js/application/conpherence/behavior-quicksand-blacklist.js' => '7927a7d3', @@ -583,7 +583,7 @@ return array( 'javelin-behavior-diffusion-locate-file' => '6d3e1947', 'javelin-behavior-diffusion-pull-lastmodified' => '2b228192', 'javelin-behavior-doorkeeper-tag' => 'e5822781', - 'javelin-behavior-durable-column' => 'eedc463c', + 'javelin-behavior-durable-column' => '70787038', 'javelin-behavior-error-log' => '6882e80a', 'javelin-behavior-fancy-datepicker' => 'c51ae228', 'javelin-behavior-global-drag-and-drop' => 'bbdf75ca', @@ -1324,6 +1324,16 @@ return array( '6f7a9da8' => array( 'javelin-install', ), + 70787038 => array( + 'javelin-behavior', + 'javelin-dom', + 'javelin-stratcom', + 'javelin-behavior-device', + 'javelin-scrollbar', + 'javelin-quicksand', + 'phabricator-keyboard-shortcut', + 'conpherence-thread-manager', + ), '70baed2f' => array( 'javelin-install', 'javelin-dom', @@ -1899,16 +1909,6 @@ return array( 'phabricator-phtize', 'javelin-dom', ), - 'eedc463c' => array( - 'javelin-behavior', - 'javelin-dom', - 'javelin-stratcom', - 'javelin-behavior-device', - 'javelin-scrollbar', - 'javelin-quicksand', - 'phabricator-keyboard-shortcut', - 'conpherence-thread-manager', - ), 'efe49472' => array( 'javelin-install', 'javelin-util', diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index e91bd4d1ef..cff6b38d72 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -249,14 +249,17 @@ phutil_register_library_map(array( 'ConpherenceQueryTransactionConduitAPIMethod' => 'applications/conpherence/conduit/ConpherenceQueryTransactionConduitAPIMethod.php', 'ConpherenceReplyHandler' => 'applications/conpherence/mail/ConpherenceReplyHandler.php', 'ConpherenceRoomListController' => 'applications/conpherence/controller/ConpherenceRoomListController.php', + 'ConpherenceRoomTestCase' => 'applications/conpherence/__tests__/ConpherenceRoomTestCase.php', 'ConpherenceSchemaSpec' => 'applications/conpherence/storage/ConpherenceSchemaSpec.php', 'ConpherenceSettings' => 'applications/conpherence/constants/ConpherenceSettings.php', + 'ConpherenceTestCase' => 'applications/conpherence/__tests__/ConpherenceTestCase.php', 'ConpherenceThread' => 'applications/conpherence/storage/ConpherenceThread.php', 'ConpherenceThreadIndexer' => 'applications/conpherence/search/ConpherenceThreadIndexer.php', 'ConpherenceThreadListView' => 'applications/conpherence/view/ConpherenceThreadListView.php', 'ConpherenceThreadMailReceiver' => 'applications/conpherence/mail/ConpherenceThreadMailReceiver.php', 'ConpherenceThreadQuery' => 'applications/conpherence/query/ConpherenceThreadQuery.php', 'ConpherenceThreadSearchEngine' => 'applications/conpherence/query/ConpherenceThreadSearchEngine.php', + 'ConpherenceThreadTestCase' => 'applications/conpherence/__tests__/ConpherenceThreadTestCase.php', 'ConpherenceTransaction' => 'applications/conpherence/storage/ConpherenceTransaction.php', 'ConpherenceTransactionComment' => 'applications/conpherence/storage/ConpherenceTransactionComment.php', 'ConpherenceTransactionQuery' => 'applications/conpherence/query/ConpherenceTransactionQuery.php', @@ -3414,8 +3417,10 @@ phutil_register_library_map(array( 'ConpherenceQueryTransactionConduitAPIMethod' => 'ConpherenceConduitAPIMethod', 'ConpherenceReplyHandler' => 'PhabricatorMailReplyHandler', 'ConpherenceRoomListController' => 'ConpherenceController', + 'ConpherenceRoomTestCase' => 'ConpherenceTestCase', 'ConpherenceSchemaSpec' => 'PhabricatorConfigSchemaSpec', 'ConpherenceSettings' => 'ConpherenceConstants', + 'ConpherenceTestCase' => 'PhabricatorTestCase', 'ConpherenceThread' => array( 'ConpherenceDAO', 'PhabricatorPolicyInterface', @@ -3425,6 +3430,7 @@ phutil_register_library_map(array( 'ConpherenceThreadMailReceiver' => 'PhabricatorObjectMailReceiver', 'ConpherenceThreadQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'ConpherenceThreadSearchEngine' => 'PhabricatorApplicationSearchEngine', + 'ConpherenceThreadTestCase' => 'ConpherenceTestCase', 'ConpherenceTransaction' => 'PhabricatorApplicationTransaction', 'ConpherenceTransactionComment' => 'PhabricatorApplicationTransactionComment', 'ConpherenceTransactionQuery' => 'PhabricatorApplicationTransactionQuery', diff --git a/src/applications/conpherence/__tests__/ConpherenceRoomTestCase.php b/src/applications/conpherence/__tests__/ConpherenceRoomTestCase.php new file mode 100644 index 0000000000..cd7912f280 --- /dev/null +++ b/src/applications/conpherence/__tests__/ConpherenceRoomTestCase.php @@ -0,0 +1,144 @@ + true, + ); + } + + public function testOneUserRoomCreate() { + $creator = $this->generateNewTestUser(); + $participant_phids = array($creator->getPHID()); + + $conpherence = $this->createRoom($creator, $participant_phids); + + $this->assertTrue((bool)$conpherence->getID()); + $this->assertEqual(1, count($conpherence->getParticipants())); + $this->assertEqual( + $participant_phids, + $conpherence->getRecentParticipantPHIDs()); + } + + public function testNUserRoomCreate() { + $creator = $this->generateNewTestUser(); + $friend_1 = $this->generateNewTestUser(); + $friend_2 = $this->generateNewTestUser(); + $friend_3 = $this->generateNewTestUser(); + + $participant_phids = array( + $creator->getPHID(), + $friend_1->getPHID(), + $friend_2->getPHID(), + $friend_3->getPHID(), + ); + + $conpherence = $this->createRoom($creator, $participant_phids); + + $this->assertTrue((bool)$conpherence->getID()); + $this->assertEqual(4, count($conpherence->getParticipants())); + $this->assertEqual( + $participant_phids, + $conpherence->getRecentParticipantPHIDs()); + } + + public function testRoomParticipantAddition() { + $creator = $this->generateNewTestUser(); + $friend_1 = $this->generateNewTestUser(); + $friend_2 = $this->generateNewTestUser(); + $friend_3 = $this->generateNewTestUser(); + + $participant_phids = array( + $creator->getPHID(), + $friend_1->getPHID(), + ); + + $conpherence = $this->createRoom($creator, $participant_phids); + + $this->assertTrue((bool)$conpherence->getID()); + $this->assertEqual(2, count($conpherence->getParticipants())); + $this->assertEqual( + $participant_phids, + $conpherence->getRecentParticipantPHIDs()); + + // test add by creator + $participant_phids[] = $friend_2->getPHID(); + $this->addParticipants($creator, $conpherence, array($friend_2->getPHID())); + $this->assertEqual( + $participant_phids, + $conpherence->getRecentParticipantPHIDs()); + + // test policy error as another user tries to add + $caught = null; + try { + $this->addParticipants( + $friend_2, + $conpherence, + array($friend_3->getPHID())); + } catch (PhabricatorPolicyException $ex) { + $caught = $ex; + } + $this->assertTrue($caught instanceof PhabricatorPolicyException); + + // update edit policy so user has a chance + $this->changeEditPolicy($creator, $conpherence, 'users'); + // test add by other participant, so recent participation should + // meaningfully change + $participant_phids = array( + $friend_2->getPHID(), // actor + $creator->getPHID(), // last actor + $friend_1->getPHID(), + $friend_3->getPHID(), // new addition + ); + $this->addParticipants( + $friend_2, + $conpherence, + array($friend_3->getPHID())); + $this->assertEqual( + $participant_phids, + $conpherence->getRecentParticipantPHIDs()); + } + + private function createRoom( + PhabricatorUser $creator, + array $participant_phids) { + + $conpherence = ConpherenceThread::initializeNewRoom($creator); + + $xactions = array(); + $xactions[] = id(new ConpherenceTransaction()) + ->setTransactionType(ConpherenceTransactionType::TYPE_PARTICIPANTS) + ->setNewValue(array('+' => $participant_phids)); + $xactions[] = id(new ConpherenceTransaction()) + ->setTransactionType(ConpherenceTransactionType::TYPE_TITLE) + ->setNewValue('Test'); + + id(new ConpherenceEditor()) + ->setActor($creator) + ->setContentSource(PhabricatorContentSource::newConsoleSource()) + ->setContinueOnNoEffect(true) + ->applyTransactions($conpherence, $xactions); + + return $conpherence; + } + + private function changeEditPolicy( + PhabricatorUser $actor, + ConpherenceThread $room, + $policy) { + + $xactions = array(); + $xactions[] = id(new ConpherenceTransaction()) + ->setTransactionType(PhabricatorTransactions::TYPE_EDIT_POLICY) + ->setNewValue($policy); + + id(new ConpherenceEditor()) + ->setActor($actor) + ->setContentSource(PhabricatorContentSource::newConsoleSource()) + ->setContinueOnNoEffect(true) + ->applyTransactions($room, $xactions); + } + + +} diff --git a/src/applications/conpherence/__tests__/ConpherenceTestCase.php b/src/applications/conpherence/__tests__/ConpherenceTestCase.php new file mode 100644 index 0000000000..c3454f26df --- /dev/null +++ b/src/applications/conpherence/__tests__/ConpherenceTestCase.php @@ -0,0 +1,20 @@ +setTransactionType(ConpherenceTransactionType::TYPE_PARTICIPANTS) + ->setNewValue(array('+' => $participant_phids)),); + $editor = id(new ConpherenceEditor()) + ->setActor($actor) + ->setContentSource(PhabricatorContentSource::newConsoleSource()) + ->applyTransactions($conpherence, $xactions); + + } + +} diff --git a/src/applications/conpherence/__tests__/ConpherenceThreadTestCase.php b/src/applications/conpherence/__tests__/ConpherenceThreadTestCase.php new file mode 100644 index 0000000000..928ce162e7 --- /dev/null +++ b/src/applications/conpherence/__tests__/ConpherenceThreadTestCase.php @@ -0,0 +1,102 @@ + true, + ); + } + + public function testOneUserThreadCreate() { + $creator = $this->generateNewTestUser(); + $participant_phids = array($creator->getPHID()); + + $conpherence = $this->createThread($creator, $participant_phids); + + $this->assertTrue((bool)$conpherence->getID()); + $this->assertEqual(1, count($conpherence->getParticipants())); + $this->assertEqual( + $participant_phids, + $conpherence->getRecentParticipantPHIDs()); + } + + public function testNUserThreadCreate() { + $creator = $this->generateNewTestUser(); + $friend_1 = $this->generateNewTestUser(); + $friend_2 = $this->generateNewTestUser(); + $friend_3 = $this->generateNewTestUser(); + + $participant_phids = array( + $creator->getPHID(), + $friend_1->getPHID(), + $friend_2->getPHID(), + $friend_3->getPHID(), + ); + + $conpherence = $this->createThread($creator, $participant_phids); + + $this->assertTrue((bool)$conpherence->getID()); + $this->assertEqual(4, count($conpherence->getParticipants())); + $this->assertEqual( + $participant_phids, + $conpherence->getRecentParticipantPHIDs()); + } + + public function testThreadParticipantAddition() { + $creator = $this->generateNewTestUser(); + $friend_1 = $this->generateNewTestUser(); + $friend_2 = $this->generateNewTestUser(); + $friend_3 = $this->generateNewTestUser(); + + $participant_phids = array( + $creator->getPHID(), + $friend_1->getPHID(), + ); + + $conpherence = $this->createThread($creator, $participant_phids); + + $this->assertTrue((bool)$conpherence->getID()); + $this->assertEqual(2, count($conpherence->getParticipants())); + $this->assertEqual( + $participant_phids, + $conpherence->getRecentParticipantPHIDs()); + + // test add by creator + $participant_phids[] = $friend_2->getPHID(); + $this->addParticipants($creator, $conpherence, array($friend_2->getPHID())); + $this->assertEqual( + $participant_phids, + $conpherence->getRecentParticipantPHIDs()); + + // test add by other participant, so recent participation should + // meaningfully change + $participant_phids = array( + $friend_2->getPHID(), // actor + $creator->getPHID(), // last actor + $friend_1->getPHID(), + $friend_3->getPHID(), // new addition + ); + $this->addParticipants( + $friend_2, + $conpherence, + array($friend_3->getPHID())); + $this->assertEqual( + $participant_phids, + $conpherence->getRecentParticipantPHIDs()); + } + + private function createThread( + PhabricatorUser $creator, + array $participant_phids) { + + list($errors, $conpherence) = ConpherenceEditor::createThread( + $creator, + $participant_phids, + 'Test', + 'Test', + PhabricatorContentSource::newConsoleSource()); + return $conpherence; + } + +} diff --git a/src/applications/conpherence/controller/ConpherenceController.php b/src/applications/conpherence/controller/ConpherenceController.php index f387c89e8c..6c7a331603 100644 --- a/src/applications/conpherence/controller/ConpherenceController.php +++ b/src/applications/conpherence/controller/ConpherenceController.php @@ -74,11 +74,21 @@ abstract class ConpherenceController extends PhabricatorController { return $crumbs; } - protected function buildHeaderPaneContent(ConpherenceThread $conpherence) { + protected function buildHeaderPaneContent( + ConpherenceThread $conpherence, + array $policy_objects) { + assert_instances_of($policy_objects, 'PhabricatorPolicy'); + $crumbs = $this->buildApplicationCrumbs(); $title = $this->getConpherenceTitle($conpherence); + if ($conpherence->getID()) { + $icon = $conpherence->getPolicyIconName($policy_objects); + } else { + $icon = null; + } $crumbs->addCrumb( id(new PHUICrumbView()) + ->setIcon($icon) ->setName($title) ->setHref($this->getApplicationURI('update/'.$conpherence->getID().'/')) ->setWorkflow(true)); diff --git a/src/applications/conpherence/controller/ConpherenceListController.php b/src/applications/conpherence/controller/ConpherenceListController.php index c6b77b0802..e637c1a668 100644 --- a/src/applications/conpherence/controller/ConpherenceListController.php +++ b/src/applications/conpherence/controller/ConpherenceListController.php @@ -157,13 +157,20 @@ final class ConpherenceListController extends ConpherenceController { ->setThreadView($thread_view) ->setRole('list'); if ($conpherence) { - $layout->setHeader($this->buildHeaderPaneContent($conpherence)); + $policy_objects = id(new PhabricatorPolicyQuery()) + ->setViewer($user) + ->setObject($conpherence) + ->execute(); + $layout->setHeader($this->buildHeaderPaneContent( + $conpherence, + $policy_objects)); $layout->setThread($conpherence); } else { $layout->setHeader( $this->buildHeaderPaneContent( id(new ConpherenceThread()) - ->makeEphemeral())); + ->makeEphemeral(), + array())); } $response = $this->buildApplicationPage( $layout, diff --git a/src/applications/conpherence/controller/ConpherenceUpdateController.php b/src/applications/conpherence/controller/ConpherenceUpdateController.php index 883b25149a..132e590c99 100644 --- a/src/applications/conpherence/controller/ConpherenceUpdateController.php +++ b/src/applications/conpherence/controller/ConpherenceUpdateController.php @@ -377,7 +377,11 @@ final class ConpherenceUpdateController $file_widget = null; switch ($action) { case ConpherenceUpdateActions::METADATA: - $header = $this->buildHeaderPaneContent($conpherence); + $policy_objects = id(new PhabricatorPolicyQuery()) + ->setViewer($user) + ->setObject($conpherence) + ->execute(); + $header = $this->buildHeaderPaneContent($conpherence, $policy_objects); $nav_item = id(new ConpherenceThreadListView()) ->setUser($user) ->setBaseURI($this->getApplicationURI()) diff --git a/src/applications/conpherence/controller/ConpherenceViewController.php b/src/applications/conpherence/controller/ConpherenceViewController.php index f2f551c540..efbc72531a 100644 --- a/src/applications/conpherence/controller/ConpherenceViewController.php +++ b/src/applications/conpherence/controller/ConpherenceViewController.php @@ -47,7 +47,11 @@ final class ConpherenceViewController extends $form = null; $content = array('messages' => $messages); } else { - $header = $this->buildHeaderPaneContent($conpherence); + $policy_objects = id(new PhabricatorPolicyQuery()) + ->setViewer($user) + ->setObject($conpherence) + ->execute(); + $header = $this->buildHeaderPaneContent($conpherence, $policy_objects); $form = $this->renderFormContent(); $content = array( 'header' => $header, diff --git a/src/applications/conpherence/editor/ConpherenceEditor.php b/src/applications/conpherence/editor/ConpherenceEditor.php index c5a88af055..7813273f40 100644 --- a/src/applications/conpherence/editor/ConpherenceEditor.php +++ b/src/applications/conpherence/editor/ConpherenceEditor.php @@ -13,7 +13,7 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor { return pht('Conpherence Threads'); } - public static function createConpherence( + public static function createThread( PhabricatorUser $creator, array $participant_phids, $title, @@ -28,8 +28,6 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor { } else { $participant_phids[] = $creator->getPHID(); $participant_phids = array_unique($participant_phids); - $conpherence->setRecentParticipantPHIDs( - array_slice($participant_phids, 0, 10)); } if (empty($message)) { @@ -70,9 +68,9 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor { ->setConpherencePHID($conpherence->getPHID())); id(new ConpherenceEditor()) + ->setActor($creator) ->setContentSource($source) ->setContinueOnNoEffect(true) - ->setActor($creator) ->applyTransactions($conpherence, $xactions); } @@ -177,13 +175,15 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor { /** * We need to apply initial effects IFF the conpherence is new. We must - * save the conpherence first thing to make sure we have an id and a phid. + * save the conpherence first thing to make sure we have an id and a phid, as + * well as create the initial set of participants so that we pass policy + * checks. */ protected function shouldApplyInitialEffects( PhabricatorLiskDAO $object, array $xactions) { - return !$object->getID(); + return $this->getIsNewObject(); } protected function applyInitialEffects( @@ -191,28 +191,19 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor { array $xactions) { $object->save(); - } - protected function applyCustomInternalTransaction( - PhabricatorLiskDAO $object, - PhabricatorApplicationTransaction $xaction) { - switch ($xaction->getTransactionType()) { - case PhabricatorTransactions::TYPE_COMMENT: - $object->setMessageCount((int)$object->getMessageCount() + 1); - break; - case ConpherenceTransactionType::TYPE_TITLE: - $object->setTitle($xaction->getNewValue()); - break; - case ConpherenceTransactionType::TYPE_PARTICIPANTS: - // If this is a new ConpherenceThread, we have to create the - // participation data asap to pass policy checks. For existing - // ConpherenceThreads, the existing participation is correct - // at this stage. Note that later in applyCustomExternalTransaction - // this participation data will be updated, particularly the - // behindTransactionPHID which is just a generated dummy for now. - if ($this->getIsNewObject()) { + foreach ($xactions as $xaction) { + switch ($xaction->getTransactionType()) { + case ConpherenceTransactionType::TYPE_PARTICIPANTS: + // Since this is a new ConpherenceThread, we have to create the + // participation data asap to pass policy checks. For existing + // ConpherenceThreads, the existing participation is correct + // at this stage. Note that later in applyCustomExternalTransaction + // this participation data will be updated, particularly the + // behindTransactionPHID which is just a generated dummy for now. $participants = array(); - foreach ($xaction->getNewValue() as $phid) { + $phids = $this->getPHIDTransactionNewValue($xaction, array()); + foreach ($phids as $phid) { if ($phid == $this->getActor()->getPHID()) { $status = ConpherenceParticipationStatus::UP_TO_DATE; $message_count = 1; @@ -230,6 +221,35 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor { ->setSeenMessageCount($message_count) ->save(); $object->attachParticipants($participants); + $object->setRecentParticipantPHIDs(array_keys($participants)); + } + break; + } + } + } + + protected function applyCustomInternalTransaction( + PhabricatorLiskDAO $object, + PhabricatorApplicationTransaction $xaction) { + + switch ($xaction->getTransactionType()) { + case PhabricatorTransactions::TYPE_COMMENT: + $object->setMessageCount((int)$object->getMessageCount() + 1); + break; + case ConpherenceTransactionType::TYPE_TITLE: + $object->setTitle($xaction->getNewValue()); + break; + case ConpherenceTransactionType::TYPE_PARTICIPANTS: + if (!$this->getIsNewObject()) { + // if we added people, add them to the end of "recent" participants + $old_map = array_fuse($xaction->getOldValue()); + $new_map = array_fuse($xaction->getNewValue()); + $add = array_keys(array_diff_key($new_map, $old_map)); + if ($add) { + $participants = $object->getRecentParticipantPHIDs(); + $participants = array_merge($participants, $add); + $participants = array_slice(array_unique($participants), 0, 10); + $object->setRecentParticipantPHIDs($participants); } } break; @@ -275,6 +295,9 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor { $editor->save(); break; case ConpherenceTransactionType::TYPE_PARTICIPANTS: + if ($this->getIsNewObject()) { + continue; + } $participants = $object->getParticipants(); $old_map = array_fuse($xaction->getOldValue()); @@ -289,28 +312,22 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor { $add = array_keys(array_diff_key($new_map, $old_map)); foreach ($add as $phid) { - if ($this->getIsNewObject()) { - $participants[$phid] - ->setBehindTransactionPHID($xaction->getPHID()) - ->save(); + if ($phid == $this->getActor()->getPHID()) { + $status = ConpherenceParticipationStatus::UP_TO_DATE; + $message_count = $object->getMessageCount(); } else { - if ($phid == $this->getActor()->getPHID()) { - $status = ConpherenceParticipationStatus::UP_TO_DATE; - $message_count = $object->getMessageCount(); - } else { - $status = ConpherenceParticipationStatus::BEHIND; - $message_count = 0; - } - $participants[$phid] = - id(new ConpherenceParticipant()) - ->setConpherencePHID($object->getPHID()) - ->setParticipantPHID($phid) - ->setParticipationStatus($status) - ->setDateTouched(time()) - ->setBehindTransactionPHID($xaction->getPHID()) - ->setSeenMessageCount($message_count) - ->save(); + $status = ConpherenceParticipationStatus::BEHIND; + $message_count = 0; } + $participants[$phid] = + id(new ConpherenceParticipant()) + ->setConpherencePHID($object->getPHID()) + ->setParticipantPHID($phid) + ->setParticipationStatus($status) + ->setDateTouched(time()) + ->setBehindTransactionPHID($xaction->getPHID()) + ->setSeenMessageCount($message_count) + ->save(); } $object->attachParticipants($participants); break; @@ -349,6 +366,7 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor { $participant->setDateTouched($time); } else { $participant->setSeenMessageCount($object->getMessageCount()); + $participant->setBehindTransactionPHID($xaction_phid); $participant->setParticipationStatus($up_to_date); $participant->setDateTouched($time); } diff --git a/src/applications/conpherence/storage/ConpherenceThread.php b/src/applications/conpherence/storage/ConpherenceThread.php index 41b29d09b7..1fe2eb1a63 100644 --- a/src/applications/conpherence/storage/ConpherenceThread.php +++ b/src/applications/conpherence/storage/ConpherenceThread.php @@ -31,7 +31,6 @@ final class ConpherenceThread extends ConpherenceDAO } public static function initializeNewRoom(PhabricatorUser $creator) { - $participant_phids = array($creator->getPHID()); return id(new ConpherenceThread()) ->setIsRoom(1) @@ -41,8 +40,7 @@ final class ConpherenceThread extends ConpherenceDAO ->attachFilePHIDs(array()) ->setViewPolicy(PhabricatorPolicies::POLICY_USER) ->setEditPolicy($creator->getPHID()) - ->setJoinPolicy(PhabricatorPolicies::POLICY_USER) - ->setRecentParticipantPHIDs($participant_phids); + ->setJoinPolicy(PhabricatorPolicies::POLICY_USER); } protected function getConfiguration() { @@ -277,4 +275,17 @@ final class ConpherenceThread extends ConpherenceDAO } } + public function getPolicyIconName(array $policy_objects) { + assert_instances_of($policy_objects, 'PhabricatorPolicy'); + + if ($this->getIsRoom()) { + $icon = $policy_objects[$this->getViewPolicy()]->getIcon(); + } else if (count($this->getRecentParticipantPHIDs()) > 2) { + $icon = 'fa-users'; + } else { + $icon = 'fa-user'; + } + return $icon; + } + } diff --git a/src/applications/conpherence/view/ConpherenceDurableColumnView.php b/src/applications/conpherence/view/ConpherenceDurableColumnView.php index 6d9d694e2b..aea77c10c7 100644 --- a/src/applications/conpherence/view/ConpherenceDurableColumnView.php +++ b/src/applications/conpherence/view/ConpherenceDurableColumnView.php @@ -8,6 +8,7 @@ final class ConpherenceDurableColumnView extends AphrontTagView { private $transactions; private $visible; private $initialLoad = false; + private $policyObjects; public function setConpherences(array $conpherences) { assert_instances_of($conpherences, 'ConpherenceThread'); @@ -66,6 +67,17 @@ final class ConpherenceDurableColumnView extends AphrontTagView { return $this->initialLoad; } + public function setPolicyObjects(array $objects) { + assert_instances_of($objects, 'PhabricatorPolicy'); + + $this->policyObjects = $objects; + return $this; + } + + public function getPolicyObjects() { + return $this->policyObjects; + } + protected function getTagAttributes() { if ($this->getVisible()) { $style = null; @@ -96,6 +108,23 @@ final class ConpherenceDurableColumnView extends AphrontTagView { 'settingsURI' => '/settings/adjust/?key='.$column_key, )); + $policies = array(); + $conpherences = $this->getConpherences(); + foreach ($conpherences as $conpherence) { + if (!$conpherence->getIsRoom()) { + continue; + } + $policies[] = $conpherence->getViewPolicy(); + } + $policy_objects = array(); + if ($policies) { + $policy_objects = id(new PhabricatorPolicyQuery()) + ->setViewer($this->getUser()) + ->withPHIDs($policies) + ->execute(); + } + $this->setPolicyObjects($policy_objects); + $classes = array(); $classes[] = 'conpherence-durable-column-header'; $classes[] = 'sprite-main-header'; @@ -178,6 +207,18 @@ final class ConpherenceDurableColumnView extends AphrontTagView { ); } + private function getPolicyIcon( + ConpherenceThread $conpherence, + array $policy_objects) { + + assert_instances_of($policy_objects, 'PhabricatorPolicy'); + + $icon = $conpherence->getPolicyIconName($policy_objects); + return id(new PHUIIconView()) + ->addClass('mmr') + ->setIconFont($icon.' lightgreytext'); + } + private function buildIconBar() { $icons = array(); $selected_conpherence = $this->getSelectedConpherence(); @@ -189,6 +230,14 @@ final class ConpherenceDurableColumnView extends AphrontTagView { $classes[] = 'selected'; } $data = $conpherence->getDisplayData($this->getUser()); + $icon = $this->getPolicyIcon($conpherence, $this->getPolicyObjects()); + $thread_title = phutil_tag( + 'span', + array(), + array( + $icon, + $data['js_title'], + )); $image = $data['image']; Javelin::initBehavior('phabricator-tooltips'); $icons[] = @@ -200,7 +249,7 @@ final class ConpherenceDurableColumnView extends AphrontTagView { 'sigil' => 'conpherence-durable-column-thread-icon has-tooltip', 'meta' => array( 'threadID' => $conpherence->getID(), - 'threadTitle' => $data['js_title'], + 'threadTitle' => hsprintf('%s', $thread_title), 'tip' => $data['js_title'], 'align' => 'S', ), @@ -220,7 +269,7 @@ final class ConpherenceDurableColumnView extends AphrontTagView { if (!$conpherence) { - $title = null; + $header = null; $settings_button = null; $settings_menu = null; @@ -282,6 +331,13 @@ final class ConpherenceDurableColumnView extends AphrontTagView { if (!$title) { $title = pht('[No Title]'); } + $header = phutil_tag( + 'span', + array(), + array( + $this->getPolicyIcon($conpherence, $this->getPolicyObjects()), + $title, + )); } return @@ -297,7 +353,7 @@ final class ConpherenceDurableColumnView extends AphrontTagView { 'sigil' => 'conpherence-durable-column-header-text', 'class' => 'conpherence-durable-column-header-text', ), - $title), + $header), $settings_button, $settings_menu,)); diff --git a/webroot/rsrc/js/application/conpherence/behavior-durable-column.js b/webroot/rsrc/js/application/conpherence/behavior-durable-column.js index 693fe14c9b..f7945017e8 100644 --- a/webroot/rsrc/js/application/conpherence/behavior-durable-column.js +++ b/webroot/rsrc/js/application/conpherence/behavior-durable-column.js @@ -183,7 +183,7 @@ JX.behavior('durable-column', function(config, statics) { 'selected', cdata.threadID == data.threadID); } - JX.DOM.setContent(_getColumnTitleNode(), data.threadTitle); + JX.DOM.setContent(_getColumnTitleNode(), JX.$H(data.threadTitle)); threadManager.loadThreadByID(data.threadID); });