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

Conpherence - remove room vs message distinction as far as users are concerned

Summary:
Ref T8488, T8469, T8485.

This is done in regards to T8488 as far as users are concerned. There's still some classes, and etc. that should be re-named probably. T8469 and T8485 are basically moot now though.

Rather than having "Send Message" exposed, just expose "Create Room". Users get the full form. One change is "title" is now required.

This diff removes the concept of "isRoom" entirely.

Test Plan: Verifed a user with no conpherences had sensible data in both column view and full conpherence view. Created rooms with various policies and things worked well.

Reviewers: epriestley

Reviewed By: epriestley

Subscribers: chad, epriestley, Korvin

Maniphest Tasks: T8469, T8485, T8488

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

+261 -735
+15 -15
resources/celerity/map.php
··· 342 342 'rsrc/js/application/conpherence/behavior-menu.js' => 'd3782c93', 343 343 'rsrc/js/application/conpherence/behavior-pontificate.js' => '21ba5861', 344 344 'rsrc/js/application/conpherence/behavior-quicksand-blacklist.js' => '7927a7d3', 345 - 'rsrc/js/application/conpherence/behavior-widget-pane.js' => '93568464', 345 + 'rsrc/js/application/conpherence/behavior-widget-pane.js' => 'cafc59ab', 346 346 'rsrc/js/application/countdown/timer.js' => 'e4cc26b3', 347 347 'rsrc/js/application/daemon/behavior-bulk-job-reload.js' => 'edf8a145', 348 348 'rsrc/js/application/dashboard/behavior-dashboard-async-panel.js' => '469c0d9e', ··· 550 550 'javelin-behavior-conpherence-drag-and-drop-photo' => 'cf86d16a', 551 551 'javelin-behavior-conpherence-menu' => 'd3782c93', 552 552 'javelin-behavior-conpherence-pontificate' => '21ba5861', 553 - 'javelin-behavior-conpherence-widget-pane' => '93568464', 553 + 'javelin-behavior-conpherence-widget-pane' => 'cafc59ab', 554 554 'javelin-behavior-countdown-timer' => 'e4cc26b3', 555 555 'javelin-behavior-dark-console' => 'f411b6ae', 556 556 'javelin-behavior-dashboard-async-panel' => '469c0d9e', ··· 1501 1501 'javelin-dom', 1502 1502 'javelin-stratcom', 1503 1503 ), 1504 - 93568464 => array( 1505 - 'javelin-behavior', 1506 - 'javelin-dom', 1507 - 'javelin-stratcom', 1508 - 'javelin-workflow', 1509 - 'javelin-util', 1510 - 'phabricator-notification', 1511 - 'javelin-behavior-device', 1512 - 'phuix-dropdown-menu', 1513 - 'phuix-action-list-view', 1514 - 'phuix-action-view', 1515 - 'conpherence-thread-manager', 1516 - ), 1517 1504 '93d0c9e3' => array( 1518 1505 'javelin-behavior', 1519 1506 'javelin-stratcom', ··· 1767 1754 'javelin-dom', 1768 1755 'javelin-stratcom', 1769 1756 'phabricator-phtize', 1757 + ), 1758 + 'cafc59ab' => array( 1759 + 'javelin-behavior', 1760 + 'javelin-dom', 1761 + 'javelin-stratcom', 1762 + 'javelin-workflow', 1763 + 'javelin-util', 1764 + 'phabricator-notification', 1765 + 'javelin-behavior-device', 1766 + 'phuix-dropdown-menu', 1767 + 'phuix-action-list-view', 1768 + 'phuix-action-view', 1769 + 'conpherence-thread-manager', 1770 1770 ), 1771 1771 'ccf1cbf8' => array( 1772 1772 'javelin-install',
+6
resources/sql/autopatches/20150619.conpherencerooms.1.sql
··· 1 + UPDATE {$NAMESPACE}_conpherence.conpherence_thread 2 + SET 3 + viewPolicy = 'obj.conpherence.members', 4 + editPolicy = 'obj.conpherence.members', 5 + joinPolicy = 'obj.conpherence.members' 6 + WHERE isRoom = 0;
+2
resources/sql/autopatches/20150619.conpherencerooms.2.sql
··· 1 + ALTER TABLE {$NAMESPACE}_conpherence.conpherence_thread 2 + DROP KEY `key_room`;
+2
resources/sql/autopatches/20150619.conpherencerooms.3.sql
··· 1 + ALTER TABLE {$NAMESPACE}_conpherence.conpherence_thread 2 + DROP COLUMN isRoom;
-4
src/__phutil_library_map__.php
··· 238 238 'ConpherenceLayoutView' => 'applications/conpherence/view/ConpherenceLayoutView.php', 239 239 'ConpherenceListController' => 'applications/conpherence/controller/ConpherenceListController.php', 240 240 'ConpherenceMenuItemView' => 'applications/conpherence/view/ConpherenceMenuItemView.php', 241 - 'ConpherenceNewController' => 'applications/conpherence/controller/ConpherenceNewController.php', 242 241 'ConpherenceNewRoomController' => 'applications/conpherence/controller/ConpherenceNewRoomController.php', 243 242 'ConpherenceNotificationPanelController' => 'applications/conpherence/controller/ConpherenceNotificationPanelController.php', 244 243 'ConpherenceParticipant' => 'applications/conpherence/storage/ConpherenceParticipant.php', ··· 263 262 'ConpherenceThreadQuery' => 'applications/conpherence/query/ConpherenceThreadQuery.php', 264 263 'ConpherenceThreadRemarkupRule' => 'applications/conpherence/remarkup/ConpherenceThreadRemarkupRule.php', 265 264 'ConpherenceThreadSearchEngine' => 'applications/conpherence/query/ConpherenceThreadSearchEngine.php', 266 - 'ConpherenceThreadTestCase' => 'applications/conpherence/__tests__/ConpherenceThreadTestCase.php', 267 265 'ConpherenceTransaction' => 'applications/conpherence/storage/ConpherenceTransaction.php', 268 266 'ConpherenceTransactionComment' => 'applications/conpherence/storage/ConpherenceTransactionComment.php', 269 267 'ConpherenceTransactionQuery' => 'applications/conpherence/query/ConpherenceTransactionQuery.php', ··· 3609 3607 'ConpherenceLayoutView' => 'AphrontView', 3610 3608 'ConpherenceListController' => 'ConpherenceController', 3611 3609 'ConpherenceMenuItemView' => 'AphrontTagView', 3612 - 'ConpherenceNewController' => 'ConpherenceController', 3613 3610 'ConpherenceNewRoomController' => 'ConpherenceController', 3614 3611 'ConpherenceNotificationPanelController' => 'ConpherenceController', 3615 3612 'ConpherenceParticipant' => 'ConpherenceDAO', ··· 3640 3637 'ConpherenceThreadQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 3641 3638 'ConpherenceThreadRemarkupRule' => 'PhabricatorObjectRemarkupRule', 3642 3639 'ConpherenceThreadSearchEngine' => 'PhabricatorApplicationSearchEngine', 3643 - 'ConpherenceThreadTestCase' => 'ConpherenceTestCase', 3644 3640 'ConpherenceTransaction' => 'PhabricatorApplicationTransaction', 3645 3641 'ConpherenceTransactionComment' => 'PhabricatorApplicationTransactionComment', 3646 3642 'ConpherenceTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
-18
src/applications/conpherence/__tests__/ConpherenceRoomTestCase.php
··· 69 69 $participant_phids, 70 70 $conpherence->getRecentParticipantPHIDs()); 71 71 72 - // test policy error as another user tries to add 73 - $caught = null; 74 - try { 75 - $this->addParticipants( 76 - $friend_2, 77 - $conpherence, 78 - array($friend_3->getPHID())); 79 - } catch (PhabricatorPolicyException $ex) { 80 - $caught = $ex; 81 - } 82 - $this->assertTrue($caught instanceof PhabricatorPolicyException); 83 - 84 - // update edit policy so user has a chance 85 - $this->changeEditPolicy($creator, $conpherence, 'users'); 86 72 // test add by other participant, so recent participation should 87 73 // meaningfully change 88 74 $participant_phids = array( ··· 129 115 public function testAddMessageWithFileAttachments() { 130 116 $creator = $this->generateNewTestUser(); 131 117 $friend_1 = $this->generateNewTestUser(); 132 - $join_via_add = $this->generateNewTestUser(); 133 118 134 119 $participant_map = array( 135 120 $creator->getPHID() => $creator, ··· 144 129 $xactions = $this->addMessageWithFile($user, $conpherence); 145 130 $this->assertEqual(2, count($xactions)); 146 131 } 147 - 148 - $xactions = $this->addMessageWithFile($join_via_add, $conpherence); 149 - $this->assertEqual(2, count($xactions)); 150 132 } 151 133 152 134 private function createRoom(
-169
src/applications/conpherence/__tests__/ConpherenceThreadTestCase.php
··· 1 - <?php 2 - 3 - final class ConpherenceThreadTestCase extends ConpherenceTestCase { 4 - 5 - protected function getPhabricatorTestCaseConfiguration() { 6 - return array( 7 - self::PHABRICATOR_TESTCONFIG_BUILD_STORAGE_FIXTURES => true, 8 - ); 9 - } 10 - 11 - public function testOneUserThreadCreate() { 12 - $creator = $this->generateNewTestUser(); 13 - $participant_phids = array($creator->getPHID()); 14 - 15 - $conpherence = $this->createThread($creator, $participant_phids); 16 - 17 - $this->assertTrue((bool)$conpherence->getID()); 18 - $this->assertEqual(1, count($conpherence->getParticipants())); 19 - $this->assertEqual( 20 - $participant_phids, 21 - $conpherence->getRecentParticipantPHIDs()); 22 - } 23 - 24 - public function testNUserThreadCreate() { 25 - $creator = $this->generateNewTestUser(); 26 - $friend_1 = $this->generateNewTestUser(); 27 - $friend_2 = $this->generateNewTestUser(); 28 - $friend_3 = $this->generateNewTestUser(); 29 - 30 - $participant_phids = array( 31 - $creator->getPHID(), 32 - $friend_1->getPHID(), 33 - $friend_2->getPHID(), 34 - $friend_3->getPHID(), 35 - ); 36 - 37 - $conpherence = $this->createThread($creator, $participant_phids); 38 - 39 - $this->assertTrue((bool)$conpherence->getID()); 40 - $this->assertEqual(4, count($conpherence->getParticipants())); 41 - $this->assertEqual( 42 - $participant_phids, 43 - $conpherence->getRecentParticipantPHIDs()); 44 - } 45 - 46 - public function testThreadParticipantAddition() { 47 - $creator = $this->generateNewTestUser(); 48 - $friend_1 = $this->generateNewTestUser(); 49 - $friend_2 = $this->generateNewTestUser(); 50 - $friend_3 = $this->generateNewTestUser(); 51 - 52 - $participant_phids = array( 53 - $creator->getPHID(), 54 - $friend_1->getPHID(), 55 - ); 56 - 57 - $conpherence = $this->createThread($creator, $participant_phids); 58 - 59 - $this->assertTrue((bool)$conpherence->getID()); 60 - $this->assertEqual(2, count($conpherence->getParticipants())); 61 - $this->assertEqual( 62 - $participant_phids, 63 - $conpherence->getRecentParticipantPHIDs()); 64 - 65 - // test add by creator 66 - $participant_phids[] = $friend_2->getPHID(); 67 - $this->addParticipants($creator, $conpherence, array($friend_2->getPHID())); 68 - $this->assertEqual( 69 - $participant_phids, 70 - $conpherence->getRecentParticipantPHIDs()); 71 - 72 - // test add by other participant, so recent participation should 73 - // meaningfully change 74 - $participant_phids = array( 75 - $friend_2->getPHID(), // actor 76 - $creator->getPHID(), // last actor 77 - $friend_1->getPHID(), 78 - $friend_3->getPHID(), // new addition 79 - ); 80 - $this->addParticipants( 81 - $friend_2, 82 - $conpherence, 83 - array($friend_3->getPHID())); 84 - $this->assertEqual( 85 - $participant_phids, 86 - $conpherence->getRecentParticipantPHIDs()); 87 - } 88 - 89 - public function testThreadParticipantDeletion() { 90 - $creator = $this->generateNewTestUser(); 91 - $friend_1 = $this->generateNewTestUser(); 92 - $friend_2 = $this->generateNewTestUser(); 93 - $friend_3 = $this->generateNewTestUser(); 94 - 95 - $participant_map = array( 96 - $creator->getPHID() => $creator, 97 - $friend_1->getPHID() => $friend_1, 98 - $friend_2->getPHID() => $friend_2, 99 - $friend_3->getPHID() => $friend_3, 100 - ); 101 - 102 - $conpherence = $this->createThread( 103 - $creator, 104 - array_keys($participant_map)); 105 - 106 - foreach ($participant_map as $phid => $user) { 107 - $this->removeParticipants($user, $conpherence, array($phid)); 108 - unset($participant_map[$phid]); 109 - $this->assertEqual( 110 - count($participant_map), 111 - count($conpherence->getParticipants())); 112 - } 113 - } 114 - 115 - public function testAddMessageWithFileAttachments() { 116 - $creator = $this->generateNewTestUser(); 117 - $friend_1 = $this->generateNewTestUser(); 118 - $policy_exception_user = $this->generateNewTestUser(); 119 - 120 - $participant_map = array( 121 - $creator->getPHID() => $creator, 122 - $friend_1->getPHID() => $friend_1, 123 - ); 124 - 125 - $conpherence = $this->createThread( 126 - $creator, 127 - array_keys($participant_map)); 128 - 129 - foreach ($participant_map as $phid => $user) { 130 - $xactions = $this->addMessageWithFile($user, $conpherence); 131 - $this->assertEqual(2, count($xactions), pht('hi')); 132 - } 133 - 134 - $caught = null; 135 - try { 136 - $xactions = $this->addMessageWithFile( 137 - $policy_exception_user, 138 - $conpherence); 139 - } catch (PhabricatorPolicyException $ex) { 140 - $caught = $ex; 141 - } 142 - $this->assertTrue( 143 - $caught instanceof PhabricatorPolicyException, 144 - pht( 145 - 'User not participating in thread should get policy exception '. 146 - 'trying to add message.')); 147 - $this->assertTrue( 148 - $conpherence->establishConnection('w')->isReadLocking(), 149 - pht( 150 - 'Conpherence object should still be read locked from policy '. 151 - 'exception.')); 152 - $conpherence->endReadLocking(); 153 - $conpherence->killTransaction(); 154 - } 155 - 156 - private function createThread( 157 - PhabricatorUser $creator, 158 - array $participant_phids) { 159 - 160 - list($errors, $conpherence) = ConpherenceEditor::createThread( 161 - $creator, 162 - $participant_phids, 163 - pht('Test'), 164 - pht('Test'), 165 - PhabricatorContentSource::newConsoleSource()); 166 - return $conpherence; 167 - } 168 - 169 - }
+3 -4
src/applications/conpherence/application/PhabricatorConpherenceApplication.php
··· 11 11 } 12 12 13 13 public function getShortDescription() { 14 - return pht('Send Messages'); 14 + return pht('Chat with Others'); 15 15 } 16 16 17 17 public function getFontIcon() { ··· 44 44 '(?P<id>[1-9]\d*)/(?P<messageID>[1-9]\d*)/' 45 45 => 'ConpherenceViewController', 46 46 'columnview/' => 'ConpherenceColumnViewController', 47 - 'new/' => 'ConpherenceNewController', 48 - 'room/new/' => 'ConpherenceNewRoomController', 47 + 'new/' => 'ConpherenceNewRoomController', 49 48 'search/(?:query/(?P<queryKey>[^/]+)/)?' 50 49 => 'ConpherenceRoomListController', 51 50 'panel/' => 'ConpherenceNotificationPanelController', ··· 59 58 $items = array(); 60 59 61 60 $item = id(new PHUIListItemView()) 62 - ->setName(pht('Conpherence Thread')) 61 + ->setName(pht('Conpherence Room')) 63 62 ->setIcon('fa-comments') 64 63 ->setWorkflow(true) 65 64 ->setHref($this->getBaseURI().'new/');
+15 -15
src/applications/conpherence/conduit/ConpherenceQueryTransactionConduitAPIMethod.php
··· 10 10 public function getMethodDescription() { 11 11 return pht( 12 12 'Query for transactions for the logged in user within a specific '. 13 - 'Conpherence thread. You can specify the thread by ID or PHID. '. 13 + 'Conpherence room. You can specify the room by ID or PHID. '. 14 14 'Otherwise, specify limit and offset to query the most recent '. 15 - 'transactions within the Conpherence for the logged in user.'); 15 + 'transactions within the Conpherence room for the logged in user.'); 16 16 } 17 17 18 18 protected function defineParamTypes() { 19 19 return array( 20 - 'threadID' => 'optional int', 21 - 'threadPHID' => 'optional phid', 20 + 'roomID' => 'optional int', 21 + 'roomPHID' => 'optional phid', 22 22 'limit' => 'optional int', 23 23 'offset' => 'optional int', 24 24 ); ··· 30 30 31 31 protected function defineErrorTypes() { 32 32 return array( 33 - 'ERR_USAGE_NO_THREAD_ID' => pht( 34 - 'You must specify a thread id or thread PHID to query transactions '. 33 + 'ERR_USAGE_NO_ROOM_ID' => pht( 34 + 'You must specify a room id or room PHID to query transactions '. 35 35 'from.'), 36 36 ); 37 37 } 38 38 39 39 protected function execute(ConduitAPIRequest $request) { 40 40 $user = $request->getUser(); 41 - $thread_id = $request->getValue('threadID'); 42 - $thread_phid = $request->getValue('threadPHID'); 41 + $room_id = $request->getValue('roomID'); 42 + $room_phid = $request->getValue('roomPHID'); 43 43 $limit = $request->getValue('limit'); 44 44 $offset = $request->getValue('offset'); 45 45 46 46 $query = id(new ConpherenceThreadQuery()) 47 47 ->setViewer($user); 48 48 49 - if ($thread_id) { 50 - $query->withIDs(array($thread_id)); 51 - } else if ($thread_phid) { 52 - $query->withPHIDs(array($thread_phid)); 49 + if ($room_id) { 50 + $query->withIDs(array($room_id)); 51 + } else if ($room_phid) { 52 + $query->withPHIDs(array($room_phid)); 53 53 } else { 54 - throw new ConduitException('ERR_USAGE_NO_THREAD_ID'); 54 + throw new ConduitException('ERR_USAGE_NO_ROOM_ID'); 55 55 } 56 56 57 57 $conpherence = $query->executeOne(); ··· 87 87 'transactionMetadata' => $transaction->getMetadata(), 88 88 'authorPHID' => $transaction->getAuthorPHID(), 89 89 'dateCreated' => $transaction->getDateCreated(), 90 - 'conpherenceID' => $conpherence->getID(), 91 - 'conpherencePHID' => $conpherence->getPHID(), 90 + 'roomID' => $conpherence->getID(), 91 + 'roomPHID' => $conpherence->getPHID(), 92 92 ); 93 93 } 94 94 return $data;
+8 -8
src/applications/conpherence/conduit/ConpherenceUpdateThreadConduitAPIMethod.php
··· 8 8 } 9 9 10 10 public function getMethodDescription() { 11 - return pht('Update an existing conpherence thread.'); 11 + return pht('Update an existing conpherence room.'); 12 12 } 13 13 14 14 protected function defineParamTypes() { ··· 28 28 29 29 protected function defineErrorTypes() { 30 30 return array( 31 - 'ERR_USAGE_NO_THREAD_ID' => pht( 32 - 'You must specify a thread id or thread phid to query transactions '. 31 + 'ERR_USAGE_NO_ROOM_ID' => pht( 32 + 'You must specify a room id or room phid to query transactions '. 33 33 'from.'), 34 - 'ERR_USAGE_THREAD_NOT_FOUND' => pht( 35 - 'Thread does not exist or logged in user can not see it.'), 34 + 'ERR_USAGE_ROOM_NOT_FOUND' => pht( 35 + 'room does not exist or logged in user can not see it.'), 36 36 'ERR_USAGE_ONLY_SELF_REMOVE' => pht( 37 - 'Only a user can remove themselves from a thread.'), 37 + 'Only a user can remove themselves from a room.'), 38 38 'ERR_USAGE_NO_UPDATES' => pht( 39 39 'You must specify data that actually updates the conpherence.'), 40 40 ); ··· 52 52 } else if ($phid) { 53 53 $query->withPHIDs(array($phid)); 54 54 } else { 55 - throw new ConduitException('ERR_USAGE_NO_THREAD_ID'); 55 + throw new ConduitException('ERR_USAGE_NO_ROOM_ID'); 56 56 } 57 57 $conpherence = $query->executeOne(); 58 58 if (!$conpherence) { 59 - throw new ConduitException('ERR_USAGE_THREAD_NOT_FOUND'); 59 + throw new ConduitException('ERR_USAGE_ROOM_NOT_FOUND'); 60 60 } 61 61 62 62 $source = PhabricatorContentSource::newFromConduitRequest($request);
+4 -10
src/applications/conpherence/controller/ConpherenceController.php
··· 16 16 $nav = new PHUIListView(); 17 17 18 18 $nav->newLink( 19 - pht('New Message'), 19 + pht('New Room'), 20 20 $this->getApplicationURI('new/')); 21 21 22 22 $nav->addMenuItem( ··· 51 51 ->addAction( 52 52 id(new PHUIListItemView()) 53 53 ->setName(pht('New Room')) 54 - ->setHref($this->getApplicationURI('room/new/')) 54 + ->setHref($this->getApplicationURI('new/')) 55 55 ->setIcon('fa-plus-square') 56 56 ->setWorkflow(true)); 57 57 } else { 58 58 $crumbs 59 59 ->addAction( 60 60 id(new PHUIListItemView()) 61 - ->setName(pht('New Message')) 61 + ->setName(pht('New Room')) 62 62 ->setHref($this->getApplicationURI('new/')) 63 63 ->setIcon('fa-plus-square') 64 64 ->setWorkflow(true)) 65 65 ->addAction( 66 66 id(new PHUIListItemView()) 67 - ->setName(pht('Thread')) 67 + ->setName(pht('Room')) 68 68 ->setHref('#') 69 69 ->setIcon('fa-bars') 70 70 ->setStyle('display: none;') ··· 81 81 82 82 $crumbs = $this->buildApplicationCrumbs(); 83 83 $data = $conpherence->getDisplayData($this->getViewer()); 84 - if ($conpherence->getID() && $conpherence->getIsRoom()) { 85 - $icon = $conpherence->getPolicyIconName($policy_objects); 86 - } else { 87 - $icon = null; 88 - } 89 84 $crumbs->addCrumb( 90 85 id(new PHUICrumbView()) 91 - ->setIcon($icon) 92 86 ->setName($data['title']) 93 87 ->setHref($this->getApplicationURI('update/'.$conpherence->getID().'/')) 94 88 ->setWorkflow(true));
+35 -17
src/applications/conpherence/controller/ConpherenceListController.php
··· 34 34 $title = pht('Conpherence'); 35 35 $conpherence = null; 36 36 37 - $limit = ConpherenceThreadListView::SEE_MORE_LIMIT * 5; 37 + $limit = (ConpherenceThreadListView::SEE_MORE_LIMIT * 2) + 1; 38 38 $all_participation = array(); 39 39 40 40 $mode = $this->determineMode(); ··· 62 62 } else { 63 63 $menu_participation = $cursor; 64 64 } 65 - $all_participation = 66 - array($conpherence->getPHID() => $menu_participation) + 67 - $all_participation; 65 + 66 + // check to see if the loaded conpherence is going to show up 67 + // within the SEE_MORE_LIMIT amount of conpherences. 68 + // If its not there, then we just pre-pend it as the "first" 69 + // conpherence so folks have a navigation item in the menu. 70 + $count = 0; 71 + $found = false; 72 + foreach ($all_participation as $phid => $curr_participation) { 73 + if ($conpherence->getPHID() == $phid) { 74 + $found = true; 75 + break; 76 + } 77 + $count++; 78 + if ($count > ConpherenceThreadListView::SEE_MORE_LIMIT) { 79 + break; 80 + } 81 + } 82 + if (!$found) { 83 + $all_participation = 84 + array($conpherence->getPHID() => $menu_participation) + 85 + $all_participation; 86 + } 68 87 break; 69 88 case self::UNSELECTED_MODE: 70 89 default: ··· 93 112 ->setThreadView($thread_view) 94 113 ->setRole('list'); 95 114 if ($conpherence) { 96 - $policy_objects = id(new PhabricatorPolicyQuery()) 97 - ->setViewer($user) 98 - ->setObject($conpherence) 99 - ->execute(); 100 - $layout->setHeader($this->buildHeaderPaneContent( 101 - $conpherence, 102 - $policy_objects)); 103 115 $layout->setThread($conpherence); 104 116 } else { 105 - $thread = ConpherenceThread::initializeNewThread($user); 106 - $thread->attachHandles(array()); 107 - $thread->attachTransactions(array()); 108 - $thread->makeEphemeral(); 109 - $layout->setHeader( 110 - $this->buildHeaderPaneContent($thread, array())); 117 + // make a dummy conpherence so we can render something 118 + $conpherence = ConpherenceThread::initializeNewRoom($user); 119 + $conpherence->attachHandles(array()); 120 + $conpherence->attachTransactions(array()); 121 + $conpherence->makeEphemeral(); 111 122 } 123 + $policy_objects = id(new PhabricatorPolicyQuery()) 124 + ->setViewer($user) 125 + ->setObject($conpherence) 126 + ->execute(); 127 + $layout->setHeader($this->buildHeaderPaneContent( 128 + $conpherence, 129 + $policy_objects)); 112 130 $response = $this->buildApplicationPage( 113 131 $layout, 114 132 array(
-90
src/applications/conpherence/controller/ConpherenceNewController.php
··· 1 - <?php 2 - 3 - final class ConpherenceNewController extends ConpherenceController { 4 - 5 - public function handleRequest(AphrontRequest $request) { 6 - $user = $request->getUser(); 7 - 8 - $title = pht('New Message'); 9 - $participants = array(); 10 - $participant_prefill = null; 11 - $message = ''; 12 - $e_participants = null; 13 - $e_message = null; 14 - $errors = array(); 15 - 16 - // this comes from ajax requests from all over. should be a single phid. 17 - 18 - if ($request->isFormPost()) { 19 - $participants = $request->getArr('participants'); 20 - $message = $request->getStr('message'); 21 - list($error_codes, $conpherence) = ConpherenceEditor::createThread( 22 - $user, 23 - $participants, 24 - $conpherence_title = null, 25 - $message, 26 - PhabricatorContentSource::newFromRequest($request)); 27 - 28 - if ($error_codes) { 29 - foreach ($error_codes as $error_code) { 30 - switch ($error_code) { 31 - case ConpherenceEditor::ERROR_EMPTY_MESSAGE: 32 - $e_message = pht('Required'); 33 - $errors[] = pht( 34 - 'You can not send an empty message.'); 35 - break; 36 - case ConpherenceEditor::ERROR_EMPTY_PARTICIPANTS: 37 - $e_participants = pht('Required'); 38 - $errors[] = pht( 39 - 'You must choose at least one recipient for your '. 40 - 'message.'); 41 - break; 42 - } 43 - } 44 - } else { 45 - return id(new AphrontRedirectResponse()) 46 - ->setURI('/'.$conpherence->getMonogram()); 47 - } 48 - } else { 49 - $participant_prefill = $request->getStr('participant'); 50 - if ($participant_prefill) { 51 - $participants[] = $participant_prefill; 52 - } 53 - } 54 - 55 - $submit_uri = $this->getApplicationURI('new/'); 56 - $cancel_uri = $this->getApplicationURI(); 57 - 58 - $dialog = id(new AphrontDialogView()) 59 - ->setWidth(AphrontDialogView::WIDTH_FORM) 60 - ->setErrors($errors) 61 - ->setUser($user) 62 - ->setTitle($title) 63 - ->addCancelButton($cancel_uri) 64 - ->addSubmitButton(pht('Send Message')); 65 - 66 - $form = id(new AphrontFormView()) 67 - ->setUser($user) 68 - ->setFullWidth(true) 69 - ->appendControl( 70 - id(new AphrontFormTokenizerControl()) 71 - ->setName('participants') 72 - ->setValue($participants) 73 - ->setUser($user) 74 - ->setDatasource(new PhabricatorPeopleDatasource()) 75 - ->setLabel(pht('To')) 76 - ->setError($e_participants)) 77 - ->appendChild( 78 - id(new PhabricatorRemarkupControl()) 79 - ->setUser($user) 80 - ->setName('message') 81 - ->setValue($message) 82 - ->setLabel(pht('Message')) 83 - ->setError($e_message)); 84 - 85 - $dialog->appendForm($form); 86 - 87 - return id(new AphrontDialogResponse())->setDialog($dialog); 88 - } 89 - 90 - }
+37 -7
src/applications/conpherence/controller/ConpherenceNewRoomController.php
··· 10 10 $validation_exception = null; 11 11 12 12 $conpherence = ConpherenceThread::initializeNewRoom($user); 13 + $participants = array(); 13 14 if ($request->isFormPost()) { 15 + $editor = new ConpherenceEditor(); 16 + $xactions = array(); 14 17 15 - $xactions = array(); 18 + $participants = $request->getArr('participants'); 19 + $participants[] = $user->getPHID(); 20 + $participants = array_unique($participants); 16 21 $xactions[] = id(new ConpherenceTransaction()) 17 22 ->setTransactionType(ConpherenceTransaction::TYPE_PARTICIPANTS) 18 - ->setNewValue(array('+' => array($user->getPHID()))); 23 + ->setNewValue(array('+' => $participants)); 24 + 19 25 $xactions[] = id(new ConpherenceTransaction()) 20 26 ->setTransactionType(ConpherenceTransaction::TYPE_TITLE) 21 27 ->setNewValue($request->getStr('title')); ··· 29 35 ->setTransactionType(PhabricatorTransactions::TYPE_JOIN_POLICY) 30 36 ->setNewValue($request->getStr('joinPolicy')); 31 37 38 + $message = $request->getStr('message'); 39 + if ($message) { 40 + $message_xactions = $editor->generateTransactionsFromText( 41 + $user, 42 + $conpherence, 43 + $message); 44 + $xactions = array_merge($xactions, $message_xactions); 45 + } 46 + 32 47 try { 33 - id(new ConpherenceEditor()) 48 + $editor 34 49 ->setContentSourceFromRequest($request) 35 50 ->setContinueOnNoEffect(true) 36 51 ->setActor($user) ··· 47 62 $conpherence->setEditPolicy($request->getStr('editPolicy')); 48 63 $conpherence->setJoinPolicy($request->getStr('joinPolicy')); 49 64 } 65 + } else { 66 + if ($request->getStr('participant')) { 67 + $participants[] = $request->getStr('participant'); 68 + } 50 69 } 51 70 52 71 $policies = id(new PhabricatorPolicyQuery()) ··· 54 73 ->setObject($conpherence) 55 74 ->execute(); 56 75 57 - $submit_uri = $this->getApplicationURI('room/new/'); 76 + $submit_uri = $this->getApplicationURI('new/'); 58 77 $cancel_uri = $this->getApplicationURI('search/'); 59 78 60 79 $dialog = $this->newDialog() ··· 67 86 68 87 $form = id(new PHUIFormLayoutView()) 69 88 ->setUser($user) 70 - ->setFullWidth(true) 71 89 ->appendChild( 72 90 id(new AphrontFormTextControl()) 73 91 ->setError($e_title) 74 - ->setLabel(pht('Title')) 92 + ->setLabel(pht('Name')) 75 93 ->setName('title') 76 94 ->setValue($request->getStr('title'))) 77 95 ->appendChild( 96 + id(new AphrontFormTokenizerControl()) 97 + ->setName('participants') 98 + ->setUser($user) 99 + ->setDatasource(new PhabricatorPeopleDatasource()) 100 + ->setValue($participants) 101 + ->setLabel(pht('Other Participants'))) 102 + ->appendChild( 78 103 id(new AphrontFormPolicyControl()) 79 104 ->setName('viewPolicy') 80 105 ->setPolicyObject($conpherence) ··· 91 116 ->setName('joinPolicy') 92 117 ->setPolicyObject($conpherence) 93 118 ->setCapability(PhabricatorPolicyCapability::CAN_JOIN) 94 - ->setPolicies($policies)); 119 + ->setPolicies($policies)) 120 + ->appendChild( 121 + id(new PhabricatorRemarkupControl()) 122 + ->setUser($user) 123 + ->setName('message') 124 + ->setLabel(pht('First Message'))); 95 125 96 126 $dialog->appendChild($form); 97 127
+1 -1
src/applications/conpherence/controller/ConpherenceNotificationPanelController.php
··· 83 83 array( 84 84 'href' => '/conpherence/', 85 85 ), 86 - pht('Messages')), 86 + pht('Rooms')), 87 87 $content); 88 88 89 89 $unread = id(new ConpherenceParticipantCountQuery())
+1 -1
src/applications/conpherence/controller/ConpherenceRoomListController.php
··· 33 33 $nav->setBaseURI(new PhutilURI($this->getApplicationURI())); 34 34 35 35 if ($for_app) { 36 - $nav->addFilter('room/new/', pht('Create Room')); 36 + $nav->addFilter('new/', pht('Create Room')); 37 37 } 38 38 39 39 id(new ConpherenceThreadSearchEngine())
+34 -33
src/applications/conpherence/controller/ConpherenceUpdateController.php
··· 188 188 $xactions[] = id(new ConpherenceTransaction()) 189 189 ->setTransactionType(ConpherenceTransaction::TYPE_TITLE) 190 190 ->setNewValue($title); 191 - if ($conpherence->getIsRoom()) { 192 - $xactions[] = id(new ConpherenceTransaction()) 193 - ->setTransactionType(PhabricatorTransactions::TYPE_VIEW_POLICY) 194 - ->setNewValue($request->getStr('viewPolicy')); 195 - $xactions[] = id(new ConpherenceTransaction()) 196 - ->setTransactionType(PhabricatorTransactions::TYPE_EDIT_POLICY) 197 - ->setNewValue($request->getStr('editPolicy')); 198 - $xactions[] = id(new ConpherenceTransaction()) 199 - ->setTransactionType(PhabricatorTransactions::TYPE_JOIN_POLICY) 200 - ->setNewValue($request->getStr('joinPolicy')); 201 - } 191 + $xactions[] = id(new ConpherenceTransaction()) 192 + ->setTransactionType(PhabricatorTransactions::TYPE_VIEW_POLICY) 193 + ->setNewValue($request->getStr('viewPolicy')); 194 + $xactions[] = id(new ConpherenceTransaction()) 195 + ->setTransactionType(PhabricatorTransactions::TYPE_EDIT_POLICY) 196 + ->setNewValue($request->getStr('editPolicy')); 197 + $xactions[] = id(new ConpherenceTransaction()) 198 + ->setTransactionType(PhabricatorTransactions::TYPE_JOIN_POLICY) 199 + ->setNewValue($request->getStr('joinPolicy')); 202 200 if (!$request->getExists('force_ajax')) { 203 201 $response_mode = 'redirect'; 204 202 } ··· 245 243 ->setContent($content); 246 244 break; 247 245 case 'go-home': 248 - return id(new AphrontRedirectResponse()) 249 - ->setURI($this->getApplicationURI()); 246 + $content = array( 247 + 'href' => $this->getApplicationURI(), 248 + ); 249 + return id(new AphrontAjaxResponse()) 250 + ->setContent($content); 250 251 break; 251 252 case 'redirect': 252 253 default: ··· 323 324 $user = $request->getUser(); 324 325 $remove_person = $request->getStr('remove_person'); 325 326 $participants = $conpherence->getParticipants(); 326 - if ($conpherence->getIsRoom()) { 327 - $message = pht( 328 - 'Are you sure you want to remove yourself from this room?'); 329 - } else { 330 - $message = pht( 331 - 'Are you sure you want to remove yourself from this thread?'); 327 + 328 + $message = pht( 329 + 'Are you sure you want to leave this room?'); 330 + $test_conpherence = clone $conpherence; 331 + $test_conpherence->attachParticipants(array()); 332 + if (!PhabricatorPolicyFilter::hasCapability( 333 + $user, 334 + $test_conpherence, 335 + PhabricatorPolicyCapability::CAN_VIEW)) { 332 336 if (count($participants) == 1) { 333 337 $message .= pht( 334 - 'The thread will be inaccessible forever and ever.'); 338 + ' The room will be inaccessible forever and ever.'); 335 339 } else { 336 340 $message .= pht( 337 - 'Someone else in the thread can add you back later.'); 341 + ' Someone else in the room can add you back later.'); 338 342 } 339 343 } 340 344 $body = phutil_tag( ··· 345 349 346 350 require_celerity_resource('conpherence-update-css'); 347 351 return id(new AphrontDialogView()) 348 - ->setTitle(pht('Remove Participants')) 352 + ->setTitle(pht('Leave Room')) 349 353 ->addHiddenInput('action', 'remove_person') 350 354 ->addHiddenInput('remove_person', $remove_person) 351 355 ->addHiddenInput( ··· 362 366 $request = $this->getRequest(); 363 367 $user = $request->getUser(); 364 368 369 + $title = pht('Update Room'); 365 370 $form = id(new PHUIFormLayoutView()) 366 371 ->appendChild($error_view) 367 372 ->appendChild( ··· 399 404 ->setLabel(pht('Image'))); 400 405 } 401 406 402 - if ($conpherence->getIsRoom()) { 403 - $title = pht('Update Room'); 404 - $policies = id(new PhabricatorPolicyQuery()) 405 - ->setViewer($user) 406 - ->setObject($conpherence) 407 - ->execute(); 407 + $policies = id(new PhabricatorPolicyQuery()) 408 + ->setViewer($user) 409 + ->setObject($conpherence) 410 + ->execute(); 408 411 409 - $form->appendChild( 412 + $form 413 + ->appendChild( 410 414 id(new AphrontFormPolicyControl()) 411 415 ->setName('viewPolicy') 412 416 ->setPolicyObject($conpherence) ··· 424 428 ->setPolicyObject($conpherence) 425 429 ->setCapability(PhabricatorPolicyCapability::CAN_JOIN) 426 430 ->setPolicies($policies)); 427 - } else { 428 - $title = pht('Update Thread'); 429 - } 430 431 431 432 require_celerity_resource('conpherence-update-css'); 432 433 $view = id(new AphrontDialogView()) ··· 520 521 $nav_item = id(new ConpherenceThreadListView()) 521 522 ->setUser($user) 522 523 ->setBaseURI($this->getApplicationURI()) 523 - ->renderSingleThread($conpherence); 524 + ->renderSingleThread($conpherence, $policy_objects); 524 525 $nav_item = hsprintf('%s', $nav_item); 525 526 break; 526 527 case ConpherenceUpdateActions::MESSAGE:
+8 -16
src/applications/conpherence/editor/ConpherenceEditor.php
··· 10 10 } 11 11 12 12 public function getEditorObjectsDescription() { 13 - return pht('Conpherence Threads'); 13 + return pht('Conpherence Rooms'); 14 14 } 15 15 16 16 public static function createThread( ··· 20 20 $message, 21 21 PhabricatorContentSource $source) { 22 22 23 - $conpherence = ConpherenceThread::initializeNewThread($creator); 23 + $conpherence = ConpherenceThread::initializeNewRoom($creator); 24 24 $files = array(); 25 25 $errors = array(); 26 26 if (empty($participant_phids)) { ··· 456 456 $is_leave = (($rem === array($actor_phid)) && !$add); 457 457 458 458 if ($is_join) { 459 - // You need CAN_JOIN to join a thread / room. 459 + // You need CAN_JOIN to join a room. 460 460 PhabricatorPolicyFilter::requireCapability( 461 461 $this->requireActor(), 462 462 $object, ··· 583 583 584 584 $href = PhabricatorEnv::getProductionURI( 585 585 '/'.$object->getMonogram().'?settings'); 586 - if ($object->getIsRoom()) { 587 - $label = pht('EMAIL PREFERENCES FOR THIS ROOM'); 588 - } else { 589 - $label = pht('EMAIL PREFERENCES FOR THIS MESSAGE'); 590 - } 586 + $label = pht('EMAIL PREFERENCES FOR THIS ROOM'); 591 587 $body->addLinkSection($label, $href); 592 588 } 593 589 ··· 644 640 645 641 switch ($type) { 646 642 case ConpherenceTransaction::TYPE_TITLE: 647 - if (!$object->getIsRoom()) { 648 - continue; 643 + if (empty($xactions)) { 644 + break; 649 645 } 650 646 $missing = $this->validateIsEmptyTextField( 651 647 $object->getTitle(), 652 648 $xactions); 653 649 654 650 if ($missing) { 655 - if ($object->getIsRoom()) { 656 - $detail = pht('Room title is required.'); 657 - } else { 658 - $detail = pht('Thread title can not be blank.'); 659 - } 651 + $detail = pht('Room title is required.'); 660 652 $error = new PhabricatorApplicationTransactionValidationError( 661 653 $type, 662 654 pht('Required'), ··· 704 696 $errors[] = new PhabricatorApplicationTransactionValidationError( 705 697 $type, 706 698 pht('Invalid'), 707 - pht('New thread member "%s" is not a valid user.', $phid), 699 + pht('New room participant "%s" is not a valid user.', $phid), 708 700 $xaction); 709 701 } 710 702 }
+2 -2
src/applications/conpherence/events/ConpherenceHovercardEventListener.php
··· 30 30 return; 31 31 } 32 32 33 - $conpherence_uri = new PhutilURI( 34 - '/conpherence/new/?participant='.$user->getPHID()); 33 + $conpherence_uri = id(new PhutilURI('/conpherence/new/')) 34 + ->setQueryParam('participant', $user->getPHID()); 35 35 $name = pht('Send a Message'); 36 36 $hovercard->addAction($name, $conpherence_uri, true); 37 37
+1 -1
src/applications/conpherence/mail/ConpherenceCreateThreadMailReceiver.php
··· 53 53 $phids = mpull($users, 'getPHID'); 54 54 55 55 $conpherence = id(new ConpherenceReplyHandler()) 56 - ->setMailReceiver(ConpherenceThread::initializeNewThread($sender)) 56 + ->setMailReceiver(ConpherenceThread::initializeNewRoom($sender)) 57 57 ->setMailAddedParticipantPHIDs($phids) 58 58 ->setActor($sender) 59 59 ->setExcludeMailRecipientPHIDs($mail->loadExcludeMailRecipientPHIDs())
+1 -1
src/applications/conpherence/phid/PhabricatorConpherenceThreadPHIDType.php
··· 5 5 const TYPECONST = 'CONP'; 6 6 7 7 public function getTypeName() { 8 - return pht('Conpherence Thread'); 8 + return pht('Conpherence Room'); 9 9 } 10 10 11 11 public function newObject() {
+7 -3
src/applications/conpherence/policyrule/ConpherenceThreadMembersPolicyRule.php
··· 8 8 } 9 9 10 10 public function getObjectPolicyName() { 11 - return pht('Thread Members'); 11 + return pht('Room Participants'); 12 12 } 13 13 14 14 public function getPolicyExplanation() { 15 - return pht('Members of this thread can take this action.'); 15 + return pht('Participants in this room can take this action.'); 16 16 } 17 17 18 18 public function getRuleDescription() { 19 - return pht('thread members'); 19 + return pht('room participants'); 20 + } 21 + 22 + public function getObjectPolicyIcon() { 23 + return 'fa-comments'; 20 24 } 21 25 22 26 public function canApplyToObject(PhabricatorPolicyInterface $object) {
-43
src/applications/conpherence/query/ConpherenceThreadQuery.php
··· 8 8 private $phids; 9 9 private $ids; 10 10 private $participantPHIDs; 11 - private $isRoom; 12 11 private $needParticipants; 13 12 private $needWidgetData; 14 13 private $needCropPics; ··· 68 67 69 68 public function withParticipantPHIDs(array $phids) { 70 69 $this->participantPHIDs = $phids; 71 - return $this; 72 - } 73 - 74 - public function withIsRoom($bool) { 75 - $this->isRoom = $bool; 76 70 return $this; 77 71 } 78 72 ··· 166 160 id(new ConpherenceParticipant())->getTableName()); 167 161 } 168 162 169 - $viewer = $this->getViewer(); 170 - if ($this->shouldJoinForViewer($viewer)) { 171 - $joins[] = qsprintf( 172 - $conn_r, 173 - 'LEFT JOIN %T v ON v.conpherencePHID = conpherence_thread.phid '. 174 - 'AND v.participantPHID = %s', 175 - id(new ConpherenceParticipant())->getTableName(), 176 - $viewer->getPHID()); 177 - } 178 - 179 163 if (strlen($this->fulltext)) { 180 164 $joins[] = qsprintf( 181 165 $conn_r, ··· 187 171 return implode(' ', $joins); 188 172 } 189 173 190 - private function shouldJoinForViewer(PhabricatorUser $viewer) { 191 - if ($viewer->isLoggedIn() && 192 - $this->ids === null && 193 - $this->phids === null) { 194 - return true; 195 - } 196 - return false; 197 - } 198 - 199 174 protected function buildWhereClause(AphrontDatabaseConnection $conn_r) { 200 175 $where = array(); 201 176 ··· 222 197 $this->participantPHIDs); 223 198 } 224 199 225 - if ($this->isRoom !== null) { 226 - $where[] = qsprintf( 227 - $conn_r, 228 - 'conpherence_thread.isRoom = %d', 229 - (int)$this->isRoom); 230 - } 231 - 232 200 if (strlen($this->fulltext)) { 233 201 $where[] = qsprintf( 234 202 $conn_r, 235 203 'MATCH(idx.corpus) AGAINST (%s IN BOOLEAN MODE)', 236 204 $this->fulltext); 237 - } 238 - 239 - $viewer = $this->getViewer(); 240 - if ($this->shouldJoinForViewer($viewer)) { 241 - $where[] = qsprintf( 242 - $conn_r, 243 - 'conpherence_thread.isRoom = 1 OR v.participantPHID IS NOT NULL'); 244 - } else if ($this->phids === null && $this->ids === null) { 245 - $where[] = qsprintf( 246 - $conn_r, 247 - 'conpherence_thread.isRoom = 1'); 248 205 } 249 206 250 207 return $this->formatWhereClause($where);
+4 -49
src/applications/conpherence/query/ConpherenceThreadSearchEngine.php
··· 4 4 extends PhabricatorApplicationSearchEngine { 5 5 6 6 public function getResultTypeDescription() { 7 - return pht('Threads'); 7 + return pht('Rooms'); 8 8 } 9 9 10 10 public function getApplicationClassName() { ··· 20 20 21 21 $saved->setParameter('fulltext', $request->getStr('fulltext')); 22 22 23 - $saved->setParameter( 24 - 'threadType', 25 - $request->getStr('threadType')); 26 - 27 23 return $saved; 28 24 } 29 25 ··· 41 37 $query->withFulltext($fulltext); 42 38 } 43 39 44 - $thread_type = $saved->getParameter('threadType'); 45 - if (idx($this->getTypeOptions(), $thread_type)) { 46 - switch ($thread_type) { 47 - case 'rooms': 48 - $query->withIsRoom(true); 49 - break; 50 - case 'messages': 51 - $query->withIsRoom(false); 52 - break; 53 - case 'both': 54 - $query->withIsRoom(null); 55 - break; 56 - } 57 - } 58 - 59 40 return $query; 60 41 } 61 42 ··· 77 58 id(new AphrontFormTextControl()) 78 59 ->setName('fulltext') 79 60 ->setLabel(pht('Contains Words')) 80 - ->setValue($fulltext)) 81 - ->appendControl( 82 - id(new AphrontFormSelectControl()) 83 - ->setLabel(pht('Type')) 84 - ->setName('threadType') 85 - ->setOptions($this->getTypeOptions()) 86 - ->setValue($saved->getParameter('threadType'))); 61 + ->setValue($fulltext)); 87 62 } 88 63 89 64 protected function getURI($path) { ··· 99 74 100 75 if ($this->requireViewer()->isLoggedIn()) { 101 76 $names['participant'] = pht('Joined Rooms'); 102 - $names['messages'] = pht('All Messages'); 103 77 } 104 78 105 79 return $names; ··· 112 86 113 87 switch ($query_key) { 114 88 case 'all': 115 - $query->setParameter('threadType', 'rooms'); 116 89 return $query; 117 90 case 'participant': 118 - $query->setParameter('threadType', 'rooms'); 119 - return $query->setParameter( 120 - 'participantPHIDs', 121 - array($this->requireViewer()->getPHID())); 122 - case 'messages': 123 - $query->setParameter('threadType', 'messages'); 124 91 return $query->setParameter( 125 92 'participantPHIDs', 126 93 array($this->requireViewer()->getPHID())); ··· 145 112 146 113 $viewer = $this->requireViewer(); 147 114 148 - $policy_objects = ConpherenceThread::loadPolicyObjects( 115 + $policy_objects = ConpherenceThread::loadViewPolicyObjects( 149 116 $viewer, 150 117 $conpherences); 151 118 ··· 192 159 $title = $conpherence->getDisplayTitle($viewer); 193 160 $monogram = $conpherence->getMonogram(); 194 161 195 - if ($conpherence->getIsRoom()) { 196 - $icon_name = $conpherence->getPolicyIconName($policy_objects); 197 - } else { 198 - $icon_name = 'fa-envelope-o'; 199 - } 162 + $icon_name = $conpherence->getPolicyIconName($policy_objects); 200 163 $icon = id(new PHUIIconView()) 201 164 ->setIconFont($icon_name); 202 165 $item = id(new PHUIObjectItemView()) ··· 254 217 } 255 218 256 219 return $list; 257 - } 258 - 259 - private function getTypeOptions() { 260 - return array( 261 - 'rooms' => pht('Rooms'), 262 - 'messages' => pht('Messages'), 263 - 'both' => pht('Both'), 264 - ); 265 220 } 266 221 267 222 private function loadContextMessages(array $threads, $fulltext) {
+27 -61
src/applications/conpherence/storage/ConpherenceThread.php
··· 9 9 10 10 protected $title; 11 11 protected $imagePHIDs = array(); 12 - protected $isRoom = 0; 13 12 protected $messageCount; 14 13 protected $recentParticipantPHIDs = array(); 15 14 protected $mailKey; ··· 24 23 private $widgetData = self::ATTACHABLE; 25 24 private $images = self::ATTACHABLE; 26 25 27 - public static function initializeNewThread(PhabricatorUser $sender) { 28 - return id(new ConpherenceThread()) 29 - ->setMessageCount(0) 30 - ->setTitle('') 31 - ->attachParticipants(array()) 32 - ->attachFilePHIDs(array()) 33 - ->attachImages(array()) 34 - ->setViewPolicy(PhabricatorPolicies::POLICY_USER) 35 - ->setEditPolicy(PhabricatorPolicies::POLICY_USER) 36 - ->setJoinPolicy(PhabricatorPolicies::POLICY_USER); 37 - } 38 - 39 - public static function initializeNewRoom(PhabricatorUser $creator) { 40 - 26 + public static function initializeNewRoom(PhabricatorUser $sender) { 27 + $default_policy = id(new ConpherenceThreadMembersPolicyRule()) 28 + ->getObjectPolicyFullKey(); 41 29 return id(new ConpherenceThread()) 42 - ->setIsRoom(1) 43 30 ->setMessageCount(0) 44 31 ->setTitle('') 45 32 ->attachParticipants(array()) 46 33 ->attachFilePHIDs(array()) 47 34 ->attachImages(array()) 48 - ->setViewPolicy(PhabricatorPolicies::POLICY_USER) 49 - ->setEditPolicy($creator->getPHID()) 50 - ->setJoinPolicy(PhabricatorPolicies::POLICY_USER); 35 + ->setViewPolicy($default_policy) 36 + ->setEditPolicy($default_policy) 37 + ->setJoinPolicy($default_policy); 51 38 } 52 39 53 40 protected function getConfiguration() { ··· 59 46 ), 60 47 self::CONFIG_COLUMN_SCHEMA => array( 61 48 'title' => 'text255?', 62 - 'isRoom' => 'bool', 63 49 'messageCount' => 'uint64', 64 50 'mailKey' => 'text20', 65 51 'joinPolicy' => 'policy', 66 52 ), 67 53 self::CONFIG_KEY_SCHEMA => array( 68 - 'key_room' => array( 69 - 'columns' => array('isRoom', 'dateModified'), 70 - ), 71 54 'key_phid' => null, 72 55 'phid' => array( 73 56 'columns' => array('phid'), ··· 214 197 return $title; 215 198 } 216 199 217 - return pht('Private Correspondence'); 200 + return pht('Private Room'); 218 201 } 219 202 220 203 /** ··· 382 365 } 383 366 384 367 public function getPolicy($capability) { 385 - if ($this->getIsRoom()) { 386 - switch ($capability) { 387 - case PhabricatorPolicyCapability::CAN_VIEW: 388 - return $this->getViewPolicy(); 389 - case PhabricatorPolicyCapability::CAN_EDIT: 390 - return $this->getEditPolicy(); 391 - case PhabricatorPolicyCapability::CAN_JOIN: 392 - return $this->getJoinPolicy(); 393 - } 368 + switch ($capability) { 369 + case PhabricatorPolicyCapability::CAN_VIEW: 370 + return $this->getViewPolicy(); 371 + case PhabricatorPolicyCapability::CAN_EDIT: 372 + return $this->getEditPolicy(); 373 + case PhabricatorPolicyCapability::CAN_JOIN: 374 + return $this->getJoinPolicy(); 394 375 } 395 376 return PhabricatorPolicies::POLICY_NOONE; 396 377 } ··· 401 382 return true; 402 383 } 403 384 404 - if ($this->getIsRoom()) { 405 - switch ($capability) { 406 - case PhabricatorPolicyCapability::CAN_EDIT: 407 - case PhabricatorPolicyCapability::CAN_JOIN: 408 - return false; 409 - } 385 + switch ($capability) { 386 + case PhabricatorPolicyCapability::CAN_EDIT: 387 + case PhabricatorPolicyCapability::CAN_JOIN: 388 + return false; 410 389 } 411 390 412 391 $participants = $this->getParticipants(); ··· 414 393 } 415 394 416 395 public function describeAutomaticCapability($capability) { 417 - if ($this->getIsRoom()) { 418 - switch ($capability) { 419 - case PhabricatorPolicyCapability::CAN_VIEW: 420 - return pht('Participants in a room can always view it.'); 421 - break; 422 - } 423 - } else { 424 - return pht('Participants in a thread can always view and edit it.'); 396 + switch ($capability) { 397 + case PhabricatorPolicyCapability::CAN_VIEW: 398 + return pht('Participants in a room can always view it.'); 399 + break; 425 400 } 426 401 } 427 402 428 - public static function loadPolicyObjects( 403 + public static function loadViewPolicyObjects( 429 404 PhabricatorUser $viewer, 430 405 array $conpherences) { 431 406 432 407 assert_instances_of($conpherences, __CLASS__); 433 408 434 - $grouped = mgroup($conpherences, 'getIsRoom'); 435 - $rooms = idx($grouped, 1, array()); 436 - 437 409 $policies = array(); 438 - foreach ($rooms as $room) { 439 - $policies[] = $room->getViewPolicy(); 410 + foreach ($conpherences as $room) { 411 + $policies[$room->getViewPolicy()] = 1; 440 412 } 441 413 $policy_objects = array(); 442 414 if ($policies) { 443 415 $policy_objects = id(new PhabricatorPolicyQuery()) 444 416 ->setViewer($viewer) 445 - ->withPHIDs($policies) 417 + ->withPHIDs(array_keys($policies)) 446 418 ->execute(); 447 419 } 448 420 ··· 452 424 public function getPolicyIconName(array $policy_objects) { 453 425 assert_instances_of($policy_objects, 'PhabricatorPolicy'); 454 426 455 - if ($this->getIsRoom()) { 456 - $icon = $policy_objects[$this->getViewPolicy()]->getIcon(); 457 - } else if (count($this->getRecentParticipantPHIDs()) > 2) { 458 - $icon = 'fa-users'; 459 - } else { 460 - $icon = 'fa-user'; 461 - } 427 + $icon = $policy_objects[$this->getViewPolicy()]->getIcon(); 462 428 return $icon; 463 429 } 464 430
+1 -61
src/applications/conpherence/storage/ConpherenceTransaction.php
··· 63 63 case PhabricatorTransactions::TYPE_EDIT_POLICY: 64 64 case PhabricatorTransactions::TYPE_JOIN_POLICY: 65 65 case self::TYPE_PICTURE: 66 - if ($this->getObject()->getIsRoom()) { 67 - return $this->getRoomTitle(); 68 - } else { 69 - return $this->getThreadTitle(); 70 - } 66 + return $this->getRoomTitle(); 71 67 break; 72 68 case self::TYPE_FILES: 73 69 $add = array_diff($new, $old); ··· 173 169 case PhabricatorTransactions::TYPE_JOIN_POLICY: 174 170 return pht( 175 171 '%s changed the join policy of this room from "%s" to "%s".', 176 - $this->renderHandleLink($author_phid), 177 - $this->renderPolicyName($old, 'old'), 178 - $this->renderPolicyName($new, 'new')); 179 - break; 180 - } 181 - } 182 - 183 - private function getThreadTitle() { 184 - $author_phid = $this->getAuthorPHID(); 185 - 186 - $old = $this->getOldValue(); 187 - $new = $this->getNewValue(); 188 - 189 - switch ($this->getTransactionType()) { 190 - case self::TYPE_TITLE: 191 - if ($old && $new) { 192 - $title = pht( 193 - '%s renamed this thread from "%s" to "%s".', 194 - $this->renderHandleLink($author_phid), 195 - $old, 196 - $new); 197 - } else if ($old) { 198 - $title = pht( 199 - '%s deleted the thread name "%s".', 200 - $this->renderHandleLink($author_phid), 201 - $old); 202 - } else { 203 - $title = pht( 204 - '%s named this thread "%s".', 205 - $this->renderHandleLink($author_phid), 206 - $new); 207 - } 208 - return $title; 209 - break; 210 - case self::TYPE_PICTURE: 211 - return pht( 212 - '%s updated the room image.', 213 - $this->renderHandleLink($author_phid)); 214 - break; 215 - case PhabricatorTransactions::TYPE_VIEW_POLICY: 216 - return pht( 217 - '%s changed the visibility of this thread from "%s" to "%s".', 218 - $this->renderHandleLink($author_phid), 219 - $this->renderPolicyName($old, 'old'), 220 - $this->renderPolicyName($new, 'new')); 221 - break; 222 - case PhabricatorTransactions::TYPE_EDIT_POLICY: 223 - return pht( 224 - '%s changed the edit policy of this thread from "%s" to "%s".', 225 - $this->renderHandleLink($author_phid), 226 - $this->renderPolicyName($old, 'old'), 227 - $this->renderPolicyName($new, 'new')); 228 - break; 229 - case PhabricatorTransactions::TYPE_JOIN_POLICY: 230 - return pht( 231 - '%s changed the join policy of this thread from "%s" to "%s".', 232 172 $this->renderHandleLink($author_phid), 233 173 $this->renderPolicyName($old, 'old'), 234 174 $this->renderPolicyName($new, 'new'));
+10 -30
src/applications/conpherence/view/ConpherenceDurableColumnView.php
··· 119 119 'quicksandConfig' => $this->getQuicksandConfig(), 120 120 )); 121 121 122 - $policies = array(); 123 - $conpherences = $this->getConpherences(); 124 - foreach ($conpherences as $conpherence) { 125 - if (!$conpherence->getIsRoom()) { 126 - continue; 127 - } 128 - $policies[] = $conpherence->getViewPolicy(); 129 - } 130 - $policy_objects = array(); 131 - if ($policies) { 132 - $policy_objects = id(new PhabricatorPolicyQuery()) 133 - ->setViewer($this->getUser()) 134 - ->withPHIDs($policies) 135 - ->execute(); 136 - } 122 + $policy_objects = ConpherenceThread::loadViewPolicyObjects( 123 + $this->getUser(), 124 + $this->getConpherences()); 137 125 $this->setPolicyObjects($policy_objects); 138 126 139 127 $classes = array(); ··· 224 212 225 213 assert_instances_of($policy_objects, 'PhabricatorPolicy'); 226 214 227 - $icon = null; 228 - if ($conpherence->getIsRoom()) { 229 - $icon = $conpherence->getPolicyIconName($policy_objects); 230 - $icon = id(new PHUIIconView()) 231 - ->addClass('mmr') 232 - ->setIconFont($icon); 233 - } 215 + $icon = $conpherence->getPolicyIconName($policy_objects); 216 + $icon = id(new PHUIIconView()) 217 + ->addClass('mmr') 218 + ->setIconFont($icon); 234 219 return $icon; 235 220 } 236 221 ··· 391 376 } 392 377 393 378 private function getHeaderActionsConfig(ConpherenceThread $conpherence) { 394 - if ($conpherence->getIsRoom()) { 395 - $rename_label = pht('Edit Room'); 396 - } else { 397 - $rename_label = pht('Rename Thread'); 398 - } 399 379 $can_edit = PhabricatorPolicyFilter::hasCapability( 400 380 $this->getUser(), 401 381 $conpherence, ··· 410 390 'key' => ConpherenceUpdateActions::ADD_PERSON, 411 391 ), 412 392 array( 413 - 'name' => $rename_label, 393 + 'name' => pht('Edit Room'), 414 394 'disabled' => !$can_edit, 415 395 'href' => '/conpherence/update/'.$conpherence->getID().'/?nopic', 416 396 'icon' => 'fa-pencil', ··· 445 425 array( 446 426 'class' => 'mmb', 447 427 ), 448 - pht('You do not have any messages yet.')), 428 + pht('You are not in any rooms yet.')), 449 429 javelin_tag( 450 430 'a', 451 431 array( ··· 453 433 'class' => 'button grey', 454 434 'sigil' => 'workflow', 455 435 ), 456 - pht('Send a Message')), 436 + pht('Create a Room')), 457 437 ); 458 438 } 459 439
+2 -2
src/applications/conpherence/view/ConpherenceLayoutView.php
··· 147 147 array( 148 148 'class' => 'text', 149 149 ), 150 - pht('You do not have any messages yet.')), 150 + pht('You are not in any rooms yet.')), 151 151 javelin_tag( 152 152 'a', 153 153 array( ··· 155 155 'class' => 'button grey', 156 156 'sigil' => 'workflow', 157 157 ), 158 - pht('Send a Message')), 158 + pht('Create a Room')), 159 159 )), 160 160 javelin_tag( 161 161 'div',
+14 -71
src/applications/conpherence/view/ConpherenceThreadListView.php
··· 2 2 3 3 final class ConpherenceThreadListView extends AphrontView { 4 4 5 - const SEE_MORE_LIMIT = 5; 5 + const SEE_MORE_LIMIT = 15; 6 6 7 7 private $baseURI; 8 8 private $threads; ··· 25 25 ->addClass('conpherence-menu') 26 26 ->setID('conpherence-menu'); 27 27 28 - $policy_objects = ConpherenceThread::loadPolicyObjects( 28 + $policy_objects = ConpherenceThread::loadViewPolicyObjects( 29 29 $this->getUser(), 30 30 $this->threads); 31 31 32 - $grouped = mgroup($this->threads, 'getIsRoom'); 33 - $rooms = idx($grouped, 1, array()); 34 - $this->addRoomsToMenu($menu, $rooms, $policy_objects); 35 - $messages = idx($grouped, 0, array()); 36 - $this->addMessagesToMenu($menu, $messages); 32 + $this->addRoomsToMenu($menu, $this->threads, $policy_objects); 37 33 38 34 return $menu; 39 35 } 40 36 41 - public function renderSingleThread(ConpherenceThread $thread) { 42 - $policy_objects = id(new PhabricatorPolicyQuery()) 43 - ->setViewer($this->getUser()) 44 - ->setObject($thread) 45 - ->execute(); 37 + public function renderSingleThread( 38 + ConpherenceThread $thread, 39 + array $policy_objects) { 40 + assert_instances_of($policy_objects, 'PhabricatorPolicy'); 46 41 return $this->renderThread($thread, $policy_objects); 47 42 } 48 43 49 - public function renderThreadsHTML() { 50 - $thread_html = array(); 51 - 52 - foreach ($this->threads as $thread) { 53 - $thread_html[] = $this->renderSingleThread($thread); 54 - } 55 - 56 - return phutil_implode_html('', $thread_html); 57 - } 58 - 59 44 private function renderThreadItem( 60 45 ConpherenceThread $thread, 61 - $policy_objects = array()) { 46 + array $policy_objects) { 62 47 return id(new PHUIListItemView()) 63 48 ->setType(PHUIListItemView::TYPE_CUSTOM) 64 49 ->setName($this->renderThread($thread, $policy_objects)); ··· 72 57 73 58 $uri = '/'.$thread->getMonogram(); 74 59 $data = $thread->getDisplayData($user); 75 - $icon = null; 76 - if ($thread->getIsRoom()) { 77 - $icon = id(new PHUIIconView()) 78 - ->addClass('msr') 79 - ->setIconFont($thread->getPolicyIconName($policy_objects)); 80 - } 60 + $icon = id(new PHUIIconView()) 61 + ->addClass('msr') 62 + ->setIconFont($thread->getPolicyIconName($policy_objects)); 81 63 $title = phutil_tag( 82 64 'span', 83 65 array(), ··· 141 123 142 124 $create_item = id(new PHUIListItemView()) 143 125 ->setType(PHUIListItemView::TYPE_LINK) 144 - ->setHref('/conpherence/room/new/') 126 + ->setHref('/conpherence/new/') 145 127 ->setWorkflow(true) 146 128 ->setName(pht('Create a Room')); 147 129 $menu->addMenuItem($create_item); ··· 153 135 return $menu; 154 136 } 155 137 156 - private function addMessagesToMenu( 157 - PHUIListView $menu, 158 - array $conpherences) { 159 - 160 - $header = $this->renderMenuItemHeader( 161 - pht('Messages'), 162 - 'conpherence-message-list-header'); 163 - $menu->addMenuItem($header); 164 - 165 - if (empty($conpherences)) { 166 - $menu->addMenuItem($this->getNoMessagesMenuItem()); 167 - return $menu; 168 - } 169 - 170 - $this->addThreadsToMenu($menu, $conpherences, array()); 171 - 172 - return $menu; 173 - } 174 - 175 138 private function addThreadsToMenu( 176 139 PHUIListView $menu, 177 140 array $threads, ··· 187 150 $more_threads = array_slice($threads, self::SEE_MORE_LIMIT); 188 151 } 189 152 190 - $is_room = false; 191 153 foreach ($show_threads as $thread) { 192 154 $item = $this->renderThreadItem($thread, $policy_objects); 193 155 $menu->addMenuItem($item); 194 - $is_room = $thread->getIsRoom(); 195 156 } 196 157 197 158 if ($more_threads) { 198 - if ($is_room) { 199 - $search_uri = '/conpherence/search/query/participant/'; 200 - $sigil = 'more-room'; 201 - } else { 202 - $search_uri = '/conpherence/search/query/messages/'; 203 - $sigil = 'more-message'; 204 - } 159 + $search_uri = '/conpherence/search/query/participant/'; 160 + $sigil = 'more-room'; 205 161 206 162 $more_item = id(new PHUIListItemView()) 207 163 ->setType(PHUIListItemView::TYPE_LINK) ··· 249 205 ->setName($title) 250 206 ->addClass($class); 251 207 return $item; 252 - } 253 - 254 - private function getNoMessagesMenuItem() { 255 - $message = phutil_tag( 256 - 'div', 257 - array( 258 - 'class' => 'no-conpherences-menu-item', 259 - ), 260 - pht('No Messages')); 261 - 262 - return id(new PHUIListItemView()) 263 - ->setType(PHUIListItemView::TYPE_CUSTOM) 264 - ->setName($message); 265 208 } 266 209 267 210 private function getNoRoomsMenuItem() {
+2 -1
src/applications/people/controller/PhabricatorPeopleProfileController.php
··· 136 136 137 137 $class = 'PhabricatorConpherenceApplication'; 138 138 if (PhabricatorApplication::isClassInstalledForViewer($class, $viewer)) { 139 - $href = '/conpherence/new/?participant='.$user->getPHID(); 139 + $href = id(new PhutilURI('/conpherence/new/')) 140 + ->setQueryParam('participant', $user->getPHID()); 140 141 $image = id(new PHUIIconView()) 141 142 ->setIconFont('fa-comments'); 142 143 $button = id(new PHUIButtonView())
+19 -2
webroot/rsrc/js/application/conpherence/behavior-widget-pane.js
··· 321 321 }); 322 322 } 323 323 }); 324 + 324 325 threadManager.syncWorkflow(workflow, 'submit'); 325 326 } 326 327 ); ··· 331 332 function (e) { 332 333 var href = config.widgetBaseUpdateURI + _loadedWidgetsID + '/'; 333 334 var data = e.getNodeData('remove-person'); 334 - // we end up re-directing to conpherence home 335 + 336 + // While the user is removing themselves, disable the notification 337 + // update behavior. If we don't do this, the user can get an error 338 + // when they remove themselves about permissions as the notification 339 + // code tries to load what jist happened. 340 + var threadManager = JX.ConpherenceThreadManager.getInstance(); 341 + var loadedPhid = threadManager.getLoadedThreadPHID(); 342 + threadManager.setLoadedThreadPHID(null); 343 + 335 344 new JX.Workflow(href, data) 336 - .start(); 345 + .setCloseHandler(function() { 346 + threadManager.setLoadedThreadPHID(loadedPhid); 347 + }) 348 + // we re-direct to conpherence home so the thread manager will 349 + // fix itself there 350 + .setHandler(function(r) { 351 + JX.$U(r.href).go(); 352 + }) 353 + .start(); 337 354 } 338 355 ); 339 356