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

Merge branch 'master' into redesign-2015

+395 -751
+15 -15
resources/celerity/map.php
··· 341 341 'rsrc/js/application/conpherence/behavior-menu.js' => 'd3782c93', 342 342 'rsrc/js/application/conpherence/behavior-pontificate.js' => '21ba5861', 343 343 'rsrc/js/application/conpherence/behavior-quicksand-blacklist.js' => '7927a7d3', 344 - 'rsrc/js/application/conpherence/behavior-widget-pane.js' => '93568464', 344 + 'rsrc/js/application/conpherence/behavior-widget-pane.js' => 'cafc59ab', 345 345 'rsrc/js/application/countdown/timer.js' => 'e4cc26b3', 346 346 'rsrc/js/application/daemon/behavior-bulk-job-reload.js' => 'edf8a145', 347 347 'rsrc/js/application/dashboard/behavior-dashboard-async-panel.js' => '469c0d9e', ··· 548 548 'javelin-behavior-conpherence-drag-and-drop-photo' => 'cf86d16a', 549 549 'javelin-behavior-conpherence-menu' => 'd3782c93', 550 550 'javelin-behavior-conpherence-pontificate' => '21ba5861', 551 - 'javelin-behavior-conpherence-widget-pane' => '93568464', 551 + 'javelin-behavior-conpherence-widget-pane' => 'cafc59ab', 552 552 'javelin-behavior-countdown-timer' => 'e4cc26b3', 553 553 'javelin-behavior-dark-console' => 'f411b6ae', 554 554 'javelin-behavior-dashboard-async-panel' => '469c0d9e', ··· 1511 1511 'javelin-dom', 1512 1512 'javelin-stratcom', 1513 1513 ), 1514 - 93568464 => array( 1515 - 'javelin-behavior', 1516 - 'javelin-dom', 1517 - 'javelin-stratcom', 1518 - 'javelin-workflow', 1519 - 'javelin-util', 1520 - 'phabricator-notification', 1521 - 'javelin-behavior-device', 1522 - 'phuix-dropdown-menu', 1523 - 'phuix-action-list-view', 1524 - 'phuix-action-view', 1525 - 'conpherence-thread-manager', 1526 - ), 1527 1514 '93d0c9e3' => array( 1528 1515 'javelin-behavior', 1529 1516 'javelin-stratcom', ··· 1770 1757 'javelin-dom', 1771 1758 'javelin-stratcom', 1772 1759 'phabricator-phtize', 1760 + ), 1761 + 'cafc59ab' => array( 1762 + 'javelin-behavior', 1763 + 'javelin-dom', 1764 + 'javelin-stratcom', 1765 + 'javelin-workflow', 1766 + 'javelin-util', 1767 + 'phabricator-notification', 1768 + 'javelin-behavior-device', 1769 + 'phuix-dropdown-menu', 1770 + 'phuix-action-list-view', 1771 + 'phuix-action-view', 1772 + 'conpherence-thread-manager', 1773 1773 ), 1774 1774 'ccf1cbf8' => array( 1775 1775 '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
··· 241 241 'ConpherenceLayoutView' => 'applications/conpherence/view/ConpherenceLayoutView.php', 242 242 'ConpherenceListController' => 'applications/conpherence/controller/ConpherenceListController.php', 243 243 'ConpherenceMenuItemView' => 'applications/conpherence/view/ConpherenceMenuItemView.php', 244 - 'ConpherenceNewController' => 'applications/conpherence/controller/ConpherenceNewController.php', 245 244 'ConpherenceNewRoomController' => 'applications/conpherence/controller/ConpherenceNewRoomController.php', 246 245 'ConpherenceNotificationPanelController' => 'applications/conpherence/controller/ConpherenceNotificationPanelController.php', 247 246 'ConpherenceParticipant' => 'applications/conpherence/storage/ConpherenceParticipant.php', ··· 266 265 'ConpherenceThreadQuery' => 'applications/conpherence/query/ConpherenceThreadQuery.php', 267 266 'ConpherenceThreadRemarkupRule' => 'applications/conpherence/remarkup/ConpherenceThreadRemarkupRule.php', 268 267 'ConpherenceThreadSearchEngine' => 'applications/conpherence/query/ConpherenceThreadSearchEngine.php', 269 - 'ConpherenceThreadTestCase' => 'applications/conpherence/__tests__/ConpherenceThreadTestCase.php', 270 268 'ConpherenceTransaction' => 'applications/conpherence/storage/ConpherenceTransaction.php', 271 269 'ConpherenceTransactionComment' => 'applications/conpherence/storage/ConpherenceTransactionComment.php', 272 270 'ConpherenceTransactionQuery' => 'applications/conpherence/query/ConpherenceTransactionQuery.php', ··· 3614 3612 'ConpherenceLayoutView' => 'AphrontView', 3615 3613 'ConpherenceListController' => 'ConpherenceController', 3616 3614 'ConpherenceMenuItemView' => 'AphrontTagView', 3617 - 'ConpherenceNewController' => 'ConpherenceController', 3618 3615 'ConpherenceNewRoomController' => 'ConpherenceController', 3619 3616 'ConpherenceNotificationPanelController' => 'ConpherenceController', 3620 3617 'ConpherenceParticipant' => 'ConpherenceDAO', ··· 3645 3642 'ConpherenceThreadQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 3646 3643 'ConpherenceThreadRemarkupRule' => 'PhabricatorObjectRemarkupRule', 3647 3644 'ConpherenceThreadSearchEngine' => 'PhabricatorApplicationSearchEngine', 3648 - 'ConpherenceThreadTestCase' => 'ConpherenceTestCase', 3649 3645 'ConpherenceTransaction' => 'PhabricatorApplicationTransaction', 3650 3646 'ConpherenceTransactionComment' => 'PhabricatorApplicationTransactionComment', 3651 3647 '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( ··· 50 50 ->addAction( 51 51 id(new PHUIListItemView()) 52 52 ->setName(pht('New Room')) 53 - ->setHref($this->getApplicationURI('room/new/')) 53 + ->setHref($this->getApplicationURI('new/')) 54 54 ->setIcon('fa-plus-square') 55 55 ->setWorkflow(true)); 56 56 } else { 57 57 $crumbs 58 58 ->addAction( 59 59 id(new PHUIListItemView()) 60 - ->setName(pht('New Message')) 60 + ->setName(pht('New Room')) 61 61 ->setHref($this->getApplicationURI('new/')) 62 62 ->setIcon('fa-plus-square') 63 63 ->setWorkflow(true)) 64 64 ->addAction( 65 65 id(new PHUIListItemView()) 66 - ->setName(pht('Thread')) 66 + ->setName(pht('Room')) 67 67 ->setHref('#') 68 68 ->setIcon('fa-bars') 69 69 ->setStyle('display: none;') ··· 80 80 81 81 $crumbs = $this->buildApplicationCrumbs(); 82 82 $data = $conpherence->getDisplayData($this->getViewer()); 83 - if ($conpherence->getID() && $conpherence->getIsRoom()) { 84 - $icon = $conpherence->getPolicyIconName($policy_objects); 85 - } else { 86 - $icon = null; 87 - } 88 83 $crumbs->addCrumb( 89 84 id(new PHUICrumbView()) 90 - ->setIcon($icon) 91 85 ->setName($data['title']) 92 86 ->setHref($this->getApplicationURI('update/'.$conpherence->getID().'/')) 93 87 ->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()) ··· 258 221 $result->setNoDataString(pht('No threads found.')); 259 222 260 223 return $result; 261 - } 262 - 263 - private function getTypeOptions() { 264 - return array( 265 - 'rooms' => pht('Rooms'), 266 - 'messages' => pht('Messages'), 267 - 'both' => pht('Both'), 268 - ); 269 224 } 270 225 271 226 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
··· 118 118 'quicksandConfig' => $this->getQuicksandConfig(), 119 119 )); 120 120 121 - $policies = array(); 122 - $conpherences = $this->getConpherences(); 123 - foreach ($conpherences as $conpherence) { 124 - if (!$conpherence->getIsRoom()) { 125 - continue; 126 - } 127 - $policies[] = $conpherence->getViewPolicy(); 128 - } 129 - $policy_objects = array(); 130 - if ($policies) { 131 - $policy_objects = id(new PhabricatorPolicyQuery()) 132 - ->setViewer($this->getUser()) 133 - ->withPHIDs($policies) 134 - ->execute(); 135 - } 121 + $policy_objects = ConpherenceThread::loadViewPolicyObjects( 122 + $this->getUser(), 123 + $this->getConpherences()); 136 124 $this->setPolicyObjects($policy_objects); 137 125 138 126 $classes = array(); ··· 223 211 224 212 assert_instances_of($policy_objects, 'PhabricatorPolicy'); 225 213 226 - $icon = null; 227 - if ($conpherence->getIsRoom()) { 228 - $icon = $conpherence->getPolicyIconName($policy_objects); 229 - $icon = id(new PHUIIconView()) 230 - ->addClass('mmr') 231 - ->setIconFont($icon); 232 - } 214 + $icon = $conpherence->getPolicyIconName($policy_objects); 215 + $icon = id(new PHUIIconView()) 216 + ->addClass('mmr') 217 + ->setIconFont($icon); 233 218 return $icon; 234 219 } 235 220 ··· 390 375 } 391 376 392 377 private function getHeaderActionsConfig(ConpherenceThread $conpherence) { 393 - if ($conpherence->getIsRoom()) { 394 - $rename_label = pht('Edit Room'); 395 - } else { 396 - $rename_label = pht('Rename Thread'); 397 - } 398 378 $can_edit = PhabricatorPolicyFilter::hasCapability( 399 379 $this->getUser(), 400 380 $conpherence, ··· 409 389 'key' => ConpherenceUpdateActions::ADD_PERSON, 410 390 ), 411 391 array( 412 - 'name' => $rename_label, 392 + 'name' => pht('Edit Room'), 413 393 'disabled' => !$can_edit, 414 394 'href' => '/conpherence/update/'.$conpherence->getID().'/?nopic', 415 395 'icon' => 'fa-pencil', ··· 444 424 array( 445 425 'class' => 'mmb', 446 426 ), 447 - pht('You do not have any messages yet.')), 427 + pht('You are not in any rooms yet.')), 448 428 javelin_tag( 449 429 'a', 450 430 array( ··· 452 432 'class' => 'button grey', 453 433 'sigil' => 'workflow', 454 434 ), 455 - pht('Send a Message')), 435 + pht('Create a Room')), 456 436 ); 457 437 } 458 438
+2 -2
src/applications/conpherence/view/ConpherenceLayoutView.php
··· 137 137 array( 138 138 'class' => 'text', 139 139 ), 140 - pht('You do not have any messages yet.')), 140 + pht('You are not in any rooms yet.')), 141 141 javelin_tag( 142 142 'a', 143 143 array( ··· 145 145 'class' => 'button grey', 146 146 'sigil' => 'workflow', 147 147 ), 148 - pht('Send a Message')), 148 + pht('Create a Room')), 149 149 )), 150 150 javelin_tag( 151 151 '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() {
+3 -1
src/applications/people/controller/PhabricatorPeopleProfileController.php
··· 64 64 65 65 $class = 'PhabricatorConpherenceApplication'; 66 66 if (PhabricatorApplication::isClassInstalledForViewer($class, $viewer)) { 67 - $href = '/conpherence/new/?participant='.$user->getPHID(); 67 + $href = id(new PhutilURI('/conpherence/new/')) 68 + ->setQueryParam('participant', $user->getPHID()); 69 + 68 70 $actions->addAction( 69 71 id(new PhabricatorActionView()) 70 72 ->setIcon('fa-comments')
+3 -16
src/docs/user/installation_guide.diviner
··· 167 167 168 168 ..to "/etc/php.d/apc.ini" or the "php.ini" file indicated by "php -i". 169 169 170 - = Updating Phabricator = 171 - 172 - Since Phabricator is under active development, you should update frequently. To 173 - update Phabricator: 174 - 175 - - Stop the webserver (including `php-fpm`, if you use it). 176 - - Run `git pull` in `libphutil/`, `arcanist/` and `phabricator/`. 177 - - Run `phabricator/bin/storage upgrade`. 178 - - Restart the webserver (and `php-fpm`, if you stopped it earlier). 179 - 180 - For more details, see @{article:Configuration Guide}. You can use a script 181 - similar to this one to automate the process: 182 - 183 - http://www.phabricator.com/rsrc/install/update_phabricator.sh 184 - 185 170 = Next Steps = 186 171 187 172 Continue by: 188 173 189 - - configuring Phabricator with the @{article:Configuration Guide}. 174 + - configuring Phabricator with the @{article:Configuration Guide}; or 175 + - learning how to keep Phabricator up to date with 176 + @{article:Upgrading Phabricator}.
+130
src/docs/user/upgrading.diviner
··· 1 + @title Upgrading Phabricator 2 + @group intro 3 + 4 + This document contains instructions for keeping Phabricator up to date. 5 + 6 + Overview 7 + ======== 8 + 9 + Phabricator is under active development, and new features are released 10 + continuously. Staying up to date will keep your install secure. 11 + 12 + We recommend installs upgrade regularly (every 1-2 weeks). Upgrades usually go 13 + smoothly and complete in a few minutes. If you put off upgrades for a long 14 + time, it may take a lot more work to bring things up to date if you want access 15 + to a useful new feature or an important security change. 16 + 17 + 18 + Staying On Top of Changes 19 + ========================= 20 + 21 + We release a weekly [[https://secure.phabricator.com/w/changelog | Changelog]], 22 + which describes changes in the previous week. You can look at the changelogs 23 + for an idea of what new features are available, upcoming changes, security 24 + information, and warnings about compatibility issues or migrations. 25 + 26 + 27 + Stable Branch 28 + ============= 29 + 30 + You can either run the `master` or `stable` branch of Phabricator. The `stable` 31 + branch is run in the [[ https://phacility.com | Phacility Cluster ]], and lags 32 + about a week behind `master`. 33 + 34 + The `stable` branch is a little more stable than `master`, and may be helpful 35 + if you administrate a larger install. 36 + 37 + We promote `master` to `stable` about once a week, then publish the changelog 38 + and deploy the cluster. During the week, major bugfixes are cherry-picked to 39 + the `stable` branch. The changelog lists the `stable` hashes for that week, 40 + as well as any fixes which were cherry-picked. 41 + 42 + To switch to `stable`, check the branch out in each working copy: 43 + 44 + phabricator/ $ git checkout stable 45 + arcanist/ $ git checkout stable 46 + libphutil/ $ git checkout stable 47 + 48 + You can now follow the upgrade process normally. 49 + 50 + 51 + Upgrade Process 52 + =============== 53 + 54 + IMPORTANT: You **MUST** restart Apache or PHP-FPM after upgrading. 55 + 56 + Phabricator runs on many different systems, with many different webservers. 57 + Given this diversity, we don't currently maintain a comprehensive upgrade 58 + script which can work on any system. However, the general steps are the same 59 + on every system: 60 + 61 + - Stop the webserver (including `php-fpm`, if you use it). 62 + - Stop the daemons, with `phabricator/bin/phd stop`. 63 + - Run `git pull` in `libphutil/`, `arcanist/` and `phabricator/`. 64 + - Run `phabricator/bin/storage upgrade`. 65 + - Start the daemons, with `phabricator/bin/phd start`. 66 + - Restart the webserver (and `php-fpm`, if you stopped it earlier). 67 + 68 + For some more discussion details, see @{article:Configuration Guide}. 69 + 70 + This template script roughly outlines the steps required to upgrade Phabricator. 71 + You'll need to adjust paths and commands a bit for your particular system: 72 + 73 + ```lang=sh 74 + #!/bin/sh 75 + 76 + set -e 77 + set -x 78 + 79 + # This is an example script for updating Phabricator, similar to the one used to 80 + # update <https://secure.phabricator.com/>. It might not work perfectly on your 81 + # system, but hopefully it should be easy to adapt. This script is not intended 82 + # to work without modifications. 83 + 84 + # NOTE: This script assumes you are running it from a directory which contains 85 + # arcanist/, libphutil/, and phabricator/. 86 + 87 + ROOT=`pwd` # You can hard-code the path here instead. 88 + 89 + ### UPDATE WORKING COPIES ###################################################### 90 + 91 + cd $ROOT/libphutil 92 + git pull 93 + 94 + cd $ROOT/arcanist 95 + git pull 96 + 97 + cd $ROOT/phabricator 98 + git pull 99 + 100 + 101 + ### CYCLE WEB SERVER AND DAEMONS ############################################### 102 + 103 + # Stop daemons. 104 + $ROOT/phabricator/bin/phd stop 105 + 106 + # If running the notification server, stop it. 107 + # $ROOT/phabricator/bin/aphlict stop 108 + 109 + # Stop the webserver (apache, nginx, lighttpd, etc). This command will differ 110 + # depending on which system and webserver you are running: replace it with an 111 + # appropriate command for your system. 112 + # NOTE: If you're running php-fpm, you should stop it here too. 113 + 114 + sudo /etc/init.d/httpd stop 115 + 116 + 117 + # Upgrade the database schema. You may want to add the "--force" flag to allow 118 + # this script to run noninteractively. 119 + $ROOT/phabricator/bin/storage upgrade 120 + 121 + # Restart the webserver. As above, this depends on your system and webserver. 122 + # NOTE: If you're running php-fpm, restart it here too. 123 + sudo /etc/init.d/httpd start 124 + 125 + # Restart daemons. 126 + $ROOT/phabricator/bin/phd start 127 + 128 + # If running the notification server, start it. 129 + # $ROOT/phabricator/bin/aphlict start 130 + ```
+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