diff --git a/src/applications/conpherence/conduit/ConpherenceQueryThreadConduitAPIMethod.php b/src/applications/conpherence/conduit/ConpherenceQueryThreadConduitAPIMethod.php index fd602058a3..0d177e502c 100644 --- a/src/applications/conpherence/conduit/ConpherenceQueryThreadConduitAPIMethod.php +++ b/src/applications/conpherence/conduit/ConpherenceQueryThreadConduitAPIMethod.php @@ -1,80 +1,79 @@ 'optional array', 'phids' => 'optional array', 'limit' => 'optional int', 'offset' => 'optional int', ); } protected function defineReturnType() { return 'nonempty dict'; } protected function execute(ConduitAPIRequest $request) { $user = $request->getUser(); $ids = $request->getValue('ids', array()); $phids = $request->getValue('phids', array()); $limit = $request->getValue('limit'); $offset = $request->getValue('offset'); $query = id(new ConpherenceThreadQuery()) - ->setViewer($user) - ->needParticipantCache(true); + ->setViewer($user); if ($ids) { $conpherences = $query ->withIDs($ids) ->setLimit($limit) ->setOffset($offset) ->execute(); } else if ($phids) { $conpherences = $query ->withPHIDs($phids) ->setLimit($limit) ->setOffset($offset) ->execute(); } else { $participation = id(new ConpherenceParticipantQuery()) ->withParticipantPHIDs(array($user->getPHID())) ->setLimit($limit) ->setOffset($offset) ->execute(); - $conpherence_phids = array_keys($participation); + $conpherence_phids = mpull($participation, 'getConpherencePHID'); $query->withPHIDs($conpherence_phids); $conpherences = $query->execute(); $conpherences = array_select_keys($conpherences, $conpherence_phids); } $data = array(); foreach ($conpherences as $conpherence) { $id = $conpherence->getID(); $data[$id] = array( 'conpherenceID' => $id, 'conpherencePHID' => $conpherence->getPHID(), 'conpherenceTitle' => $conpherence->getTitle(), 'messageCount' => $conpherence->getMessageCount(), 'conpherenceURI' => $this->getConpherenceURI($conpherence), ); } return $data; } } diff --git a/src/applications/conpherence/controller/ConpherenceListController.php b/src/applications/conpherence/controller/ConpherenceListController.php index 6f50d2b37a..fc73d98341 100644 --- a/src/applications/conpherence/controller/ConpherenceListController.php +++ b/src/applications/conpherence/controller/ConpherenceListController.php @@ -1,178 +1,179 @@ / - SELECTED_MODE * * UNSELECTED_MODE is not an Ajax request while the other two are Ajax * requests. */ private function determineMode() { $request = $this->getRequest(); $mode = self::UNSELECTED_MODE; if ($request->isAjax()) { $mode = self::SELECTED_MODE; } return $mode; } public function shouldAllowPublic() { return true; } public function handleRequest(AphrontRequest $request) { $user = $request->getUser(); $title = pht('Conpherence'); $conpherence = null; $limit = ConpherenceThreadListView::SEE_ALL_LIMIT + 1; $all_participation = array(); $mode = $this->determineMode(); switch ($mode) { case self::SELECTED_MODE: $conpherence_id = $request->getURIData('id'); $conpherence = id(new ConpherenceThreadQuery()) ->setViewer($user) ->withIDs(array($conpherence_id)) ->executeOne(); if (!$conpherence) { return new Aphront404Response(); } if ($conpherence->getTitle()) { $title = $conpherence->getTitle(); } $cursor = $conpherence->getParticipantIfExists($user->getPHID()); $data = $this->loadDefaultParticipation($limit); $all_participation = $data['all_participation']; if (!$cursor) { $menu_participation = id(new ConpherenceParticipant()) ->makeEphemeral() ->setConpherencePHID($conpherence->getPHID()) ->setParticipantPHID($user->getPHID()); } else { $menu_participation = $cursor; } // check to see if the loaded conpherence is going to show up // within the SEE_ALL_LIMIT amount of conpherences. // If its not there, then we just pre-pend it as the "first" // conpherence so folks have a navigation item in the menu. $count = 0; $found = false; foreach ($all_participation as $phid => $curr_participation) { if ($conpherence->getPHID() == $phid) { $found = true; break; } $count++; if ($count > ConpherenceThreadListView::SEE_ALL_LIMIT) { break; } } if (!$found) { $all_participation = array($conpherence->getPHID() => $menu_participation) + $all_participation; } break; case self::UNSELECTED_MODE: default: $data = $this->loadDefaultParticipation($limit); $all_participation = $data['all_participation']; $conpherence_id = head($all_participation)->getConpherencePHID(); $conpherence = id(new ConpherenceThreadQuery()) ->setViewer($user) ->withPHIDs(array($conpherence_id)) ->needProfileImage(true) ->executeOne(); // If $conpherence is null, NUX state will render break; } $threads = $this->loadConpherenceThreadData($all_participation); $thread_view = id(new ConpherenceThreadListView()) ->setUser($user) ->setBaseURI($this->getApplicationURI()) ->setThreads($threads); switch ($mode) { case self::SELECTED_MODE: $response = id(new AphrontAjaxResponse())->setContent($thread_view); break; case self::UNSELECTED_MODE: default: $layout = id(new ConpherenceLayoutView()) ->setUser($user) ->setBaseURI($this->getApplicationURI()) ->setThreadView($thread_view) ->setRole('list'); if ($conpherence) { $layout->setThread($conpherence); } else { // make a dummy conpherence so we can render something $conpherence = ConpherenceThread::initializeNewRoom($user); $conpherence->attachHandles(array()); $conpherence->attachTransactions(array()); $conpherence->makeEphemeral(); } $policy_objects = id(new PhabricatorPolicyQuery()) ->setViewer($user) ->setObject($conpherence) ->execute(); $layout->setHeader($this->buildHeaderPaneContent( $conpherence, $policy_objects)); $response = $this->newPage() ->setTitle($title) ->appendChild($layout); break; } return $response; } private function loadDefaultParticipation($limit) { $viewer = $this->getRequest()->getUser(); $all_participation = id(new ConpherenceParticipantQuery()) ->withParticipantPHIDs(array($viewer->getPHID())) ->setLimit($limit) ->execute(); + $all_participation = mpull($all_participation, null, 'getConpherencePHID'); return array( 'all_participation' => $all_participation, ); } private function loadConpherenceThreadData($participation) { $user = $this->getRequest()->getUser(); $conpherence_phids = array_keys($participation); $conpherences = array(); if ($conpherence_phids) { $conpherences = id(new ConpherenceThreadQuery()) ->setViewer($user) ->withPHIDs($conpherence_phids) ->needProfileImage(true) ->execute(); // this will re-sort by participation data $conpherences = array_select_keys($conpherences, $conpherence_phids); } return $conpherences; } } diff --git a/src/applications/conpherence/controller/ConpherenceNotificationPanelController.php b/src/applications/conpherence/controller/ConpherenceNotificationPanelController.php index 3dda87b1b4..8458a9d5c4 100644 --- a/src/applications/conpherence/controller/ConpherenceNotificationPanelController.php +++ b/src/applications/conpherence/controller/ConpherenceNotificationPanelController.php @@ -1,137 +1,138 @@ getUser(); $conpherences = array(); require_celerity_resource('conpherence-notification-css'); $participant_data = id(new ConpherenceParticipantQuery()) ->withParticipantPHIDs(array($user->getPHID())) ->setLimit(5) ->execute(); + $participant_data = mpull($participant_data, null, 'getConpherencePHID'); if ($participant_data) { $conpherences = id(new ConpherenceThreadQuery()) ->setViewer($user) ->withPHIDs(array_keys($participant_data)) ->needProfileImage(true) ->needTransactions(true) ->setTransactionLimit(100) ->execute(); } if ($conpherences) { // re-order the conpherences based on participation data $conpherences = array_select_keys( $conpherences, array_keys($participant_data)); $view = new AphrontNullView(); foreach ($conpherences as $conpherence) { $p_data = $participant_data[$conpherence->getPHID()]; $d_data = $conpherence->getDisplayData($user); $classes = array( 'phabricator-notification', 'conpherence-notification', ); if (!$p_data->isUpToDate($conpherence)) { $classes[] = 'phabricator-notification-unread'; } $uri = $this->getApplicationURI($conpherence->getID().'/'); $title = $d_data['title']; $subtitle = $d_data['subtitle']; $unread_count = $d_data['unread_count']; $epoch = $d_data['epoch']; $image = $d_data['image']; $msg_view = id(new ConpherenceMenuItemView()) ->setUser($user) ->setTitle($title) ->setSubtitle($subtitle) ->setHref($uri) ->setEpoch($epoch) ->setImageURI($image) ->setUnreadCount($unread_count); $view->appendChild(javelin_tag( 'div', array( 'class' => implode(' ', $classes), 'sigil' => 'notification', 'meta' => array( 'href' => $uri, ), ), $msg_view)); } $content = $view->render(); } else { $rooms_uri = phutil_tag( 'a', array( 'href' => '/conpherence/', 'class' => 'no-room-notification', ), pht('You have joined no rooms.')); $content = phutil_tag_div( 'phabricator-notification no-notifications', $rooms_uri); } $content = hsprintf( '
%s%s
'. '%s', phutil_tag( 'a', array( 'href' => '/conpherence/', ), pht('Rooms')), $this->renderPersistentOption(), $content); $unread = id(new ConpherenceParticipantCountQuery()) ->withParticipantPHIDs(array($user->getPHID())) ->withUnread(true) ->execute(); $unread_count = idx($unread, $user->getPHID(), 0); $json = array( 'content' => $content, 'number' => (int)$unread_count, ); return id(new AphrontAjaxResponse())->setContent($json); } private function renderPersistentOption() { $viewer = $this->getViewer(); $column_key = PhabricatorConpherenceColumnVisibleSetting::SETTINGKEY; $show = (bool)$viewer->getUserSetting($column_key, false); $view = phutil_tag( 'div', array( 'class' => 'persistent-option', ), array( javelin_tag( 'input', array( 'type' => 'checkbox', 'checked' => ($show) ? 'checked' : null, 'value' => !$show, 'sigil' => 'conpherence-persist-column', )), phutil_tag( 'span', array(), pht('Persistent Chat')), )); return $view; } } diff --git a/src/applications/conpherence/query/ConpherenceParticipantQuery.php b/src/applications/conpherence/query/ConpherenceParticipantQuery.php index e538ded2c2..fb4c3eff0f 100644 --- a/src/applications/conpherence/query/ConpherenceParticipantQuery.php +++ b/src/applications/conpherence/query/ConpherenceParticipantQuery.php @@ -1,65 +1,50 @@ participantPHIDs = $phids; return $this; } public function execute() { $table = new ConpherenceParticipant(); $thread = new ConpherenceThread(); $conn = $table->establishConnection('r'); $data = queryfx_all( $conn, 'SELECT * FROM %T participant JOIN %T thread ON participant.conpherencePHID = thread.phid %Q %Q %Q', $table->getTableName(), $thread->getTableName(), $this->buildWhereClause($conn), $this->buildOrderClause($conn), $this->buildLimitClause($conn)); - $participants = $table->loadAllFromArray($data); - - // TODO: Fix this, it's bogus. - if ('garbage') { - if (count($this->participantPHIDs) !== 1) { - throw new Exception( - pht( - 'This query only works when querying for exactly one participant '. - 'PHID!')); - } - // This will throw results away if we aren't doing a query for exactly - // one participant PHID. - $participants = mpull($participants, null, 'getConpherencePHID'); - } - - return $participants; + return $table->loadAllFromArray($data); } protected function buildWhereClause(AphrontDatabaseConnection $conn) { $where = array(); if ($this->participantPHIDs !== null) { $where[] = qsprintf( $conn, 'participantPHID IN (%Ls)', $this->participantPHIDs); } return $this->formatWhereClause($where); } private function buildOrderClause(AphrontDatabaseConnection $conn) { return qsprintf( $conn, 'ORDER BY thread.dateModified DESC, thread.id DESC, participant.id DESC'); } }