Conpherence -- finish off the "show older" functionality
Summary: Fixes T2956. Ref T2399. Test Plan: set message limit to 2 and verified "show older" showed up, and that clicking it again and again and again showed the right stuff, ultimately not showing a "show older" UI anymore. Reviewers: epriestley, chad Reviewed By: epriestley CC: aran, Korvin Maniphest Tasks: T2399, T2956 Differential Revision: https://secure.phabricator.com/D5721
This commit is contained in:
		@@ -141,6 +141,15 @@ abstract class ConpherenceController extends PhabricatorController {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    $user = $this->getRequest()->getUser();
 | 
					    $user = $this->getRequest()->getUser();
 | 
				
			||||||
    $transactions = $conpherence->getTransactions();
 | 
					    $transactions = $conpherence->getTransactions();
 | 
				
			||||||
 | 
					    $oldest_transaction_id = 0;
 | 
				
			||||||
 | 
					    $too_many = ConpherenceThreadQuery::TRANSACTION_LIMIT + 1;
 | 
				
			||||||
 | 
					    if (count($transactions) == $too_many) {
 | 
				
			||||||
 | 
					      $last_transaction = end($transactions);
 | 
				
			||||||
 | 
					      unset($transactions[$last_transaction->getID()]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    $transactions = array_reverse($transactions);
 | 
				
			||||||
 | 
					    $oldest_transaction = reset($transactions);
 | 
				
			||||||
 | 
					    $oldest_transaction_id = $oldest_transaction->getID();
 | 
				
			||||||
    $handles = $conpherence->getHandles();
 | 
					    $handles = $conpherence->getHandles();
 | 
				
			||||||
    $rendered_transactions = array();
 | 
					    $rendered_transactions = array();
 | 
				
			||||||
    $engine = id(new PhabricatorMarkupEngine())
 | 
					    $engine = id(new PhabricatorMarkupEngine())
 | 
				
			||||||
@@ -166,11 +175,11 @@ abstract class ConpherenceController extends PhabricatorController {
 | 
				
			|||||||
        ->render();
 | 
					        ->render();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    $latest_transaction_id = $transaction->getID();
 | 
					    $latest_transaction_id = $transaction->getID();
 | 
				
			||||||
    $rendered_transactions = phutil_implode_html(' ', $rendered_transactions);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return array(
 | 
					    return array(
 | 
				
			||||||
      'transactions' => $rendered_transactions,
 | 
					      'transactions' => $rendered_transactions,
 | 
				
			||||||
      'latest_transaction_id' => $latest_transaction_id
 | 
					      'latest_transaction_id' => $latest_transaction_id,
 | 
				
			||||||
 | 
					      'oldest_transaction_id' => $oldest_transaction_id
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -345,7 +345,7 @@ final class ConpherenceUpdateController
 | 
				
			|||||||
    $user = $this->getRequest()->getUser();
 | 
					    $user = $this->getRequest()->getUser();
 | 
				
			||||||
    $conpherence = id(new ConpherenceThreadQuery())
 | 
					    $conpherence = id(new ConpherenceThreadQuery())
 | 
				
			||||||
      ->setViewer($user)
 | 
					      ->setViewer($user)
 | 
				
			||||||
      ->setAfterMessageID($latest_transaction_id)
 | 
					      ->setAfterTransactionID($latest_transaction_id)
 | 
				
			||||||
      ->needHeaderPics($need_header_pics)
 | 
					      ->needHeaderPics($need_header_pics)
 | 
				
			||||||
      ->needWidgetData($need_widget_data)
 | 
					      ->needWidgetData($need_widget_data)
 | 
				
			||||||
      ->needTransactions($need_transactions)
 | 
					      ->needTransactions($need_transactions)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -37,12 +37,19 @@ final class ConpherenceViewController extends
 | 
				
			|||||||
    if (!$conpherence_id) {
 | 
					    if (!$conpherence_id) {
 | 
				
			||||||
      return new Aphront404Response();
 | 
					      return new Aphront404Response();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    $conpherence = id(new ConpherenceThreadQuery())
 | 
					    $query = id(new ConpherenceThreadQuery())
 | 
				
			||||||
      ->setViewer($user)
 | 
					      ->setViewer($user)
 | 
				
			||||||
      ->withIDs(array($conpherence_id))
 | 
					      ->withIDs(array($conpherence_id))
 | 
				
			||||||
      ->needHeaderPics(true)
 | 
					      ->needHeaderPics(true)
 | 
				
			||||||
 | 
					      ->needParticipantCache(true)
 | 
				
			||||||
      ->needTransactions(true)
 | 
					      ->needTransactions(true)
 | 
				
			||||||
      ->executeOne();
 | 
					      ->setTransactionLimit(ConpherenceThreadQuery::TRANSACTION_LIMIT);
 | 
				
			||||||
 | 
					    $before_transaction_id = $request->getInt('oldest_transaction_id');
 | 
				
			||||||
 | 
					    if ($before_transaction_id) {
 | 
				
			||||||
 | 
					      $query
 | 
				
			||||||
 | 
					        ->setBeforeTransactionID($before_transaction_id);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    $conpherence = $query->executeOne();
 | 
				
			||||||
    $this->setConpherence($conpherence);
 | 
					    $this->setConpherence($conpherence);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $participant = $conpherence->getParticipant($user->getPHID());
 | 
					    $participant = $conpherence->getParticipant($user->getPHID());
 | 
				
			||||||
@@ -52,9 +59,23 @@ final class ConpherenceViewController extends
 | 
				
			|||||||
    $participant->markUpToDate($conpherence, $latest_transaction);
 | 
					    $participant->markUpToDate($conpherence, $latest_transaction);
 | 
				
			||||||
    unset($write_guard);
 | 
					    unset($write_guard);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $header = $this->renderHeaderPaneContent();
 | 
					    $data = $this->renderConpherenceTransactions($conpherence);
 | 
				
			||||||
    $messages = $this->renderMessagePaneContent();
 | 
					    $messages = $this->renderMessagePaneContent(
 | 
				
			||||||
    $content = $header + $messages;
 | 
					      $data['transactions'],
 | 
				
			||||||
 | 
					      $data['oldest_transaction_id']);
 | 
				
			||||||
 | 
					    if ($before_transaction_id) {
 | 
				
			||||||
 | 
					      $header = null;
 | 
				
			||||||
 | 
					      $form = null;
 | 
				
			||||||
 | 
					      $content = array('messages' => $messages);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      $header = $this->renderHeaderPaneContent();
 | 
				
			||||||
 | 
					      $form = $this->renderFormContent($data['latest_transaction_id']);
 | 
				
			||||||
 | 
					      $content = array(
 | 
				
			||||||
 | 
					        'header' => $header,
 | 
				
			||||||
 | 
					        'messages' => $messages,
 | 
				
			||||||
 | 
					        'form' => $form
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if ($request->isAjax()) {
 | 
					    if ($request->isAjax()) {
 | 
				
			||||||
      return id(new AphrontAjaxResponse())->setContent($content);
 | 
					      return id(new AphrontAjaxResponse())->setContent($content);
 | 
				
			||||||
@@ -64,8 +85,8 @@ final class ConpherenceViewController extends
 | 
				
			|||||||
      ->setBaseURI($this->getApplicationURI())
 | 
					      ->setBaseURI($this->getApplicationURI())
 | 
				
			||||||
      ->setThread($conpherence)
 | 
					      ->setThread($conpherence)
 | 
				
			||||||
      ->setHeader($header)
 | 
					      ->setHeader($header)
 | 
				
			||||||
      ->setMessages($messages['messages'])
 | 
					      ->setMessages($messages)
 | 
				
			||||||
      ->setReplyForm($messages['form'])
 | 
					      ->setReplyForm($form)
 | 
				
			||||||
      ->setRole('thread');
 | 
					      ->setRole('thread');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return $this->buildApplicationPage(
 | 
					    return $this->buildApplicationPage(
 | 
				
			||||||
@@ -80,19 +101,39 @@ final class ConpherenceViewController extends
 | 
				
			|||||||
    require_celerity_resource('conpherence-header-pane-css');
 | 
					    require_celerity_resource('conpherence-header-pane-css');
 | 
				
			||||||
    $conpherence = $this->getConpherence();
 | 
					    $conpherence = $this->getConpherence();
 | 
				
			||||||
    $header = $this->buildHeaderPaneContent($conpherence);
 | 
					    $header = $this->buildHeaderPaneContent($conpherence);
 | 
				
			||||||
    return array('header' => hsprintf('%s', $header));
 | 
					    return hsprintf('%s', $header);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private function renderMessagePaneContent() {
 | 
					  private function renderMessagePaneContent(
 | 
				
			||||||
 | 
					    array $transactions,
 | 
				
			||||||
 | 
					    $oldest_transaction_id) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    require_celerity_resource('conpherence-message-pane-css');
 | 
					    require_celerity_resource('conpherence-message-pane-css');
 | 
				
			||||||
    $user = $this->getRequest()->getUser();
 | 
					
 | 
				
			||||||
 | 
					    $scrollbutton = '';
 | 
				
			||||||
 | 
					    if ($oldest_transaction_id) {
 | 
				
			||||||
 | 
					      $scrollbutton = javelin_tag(
 | 
				
			||||||
 | 
					        'a',
 | 
				
			||||||
 | 
					        array(
 | 
				
			||||||
 | 
					          'href' => '#',
 | 
				
			||||||
 | 
					          'mustcapture' => true,
 | 
				
			||||||
 | 
					          'sigil' => 'show-older-messages',
 | 
				
			||||||
 | 
					          'class' => 'conpherence-show-older-messages',
 | 
				
			||||||
 | 
					          'meta' => array(
 | 
				
			||||||
 | 
					            'oldest_transaction_id' => $oldest_transaction_id
 | 
				
			||||||
 | 
					          )
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        pht('Show Older Messages'));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return hsprintf('%s%s', $scrollbutton, $transactions);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private function renderFormContent($latest_transaction_id) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $conpherence = $this->getConpherence();
 | 
					    $conpherence = $this->getConpherence();
 | 
				
			||||||
 | 
					    $user = $this->getRequest()->getUser();
 | 
				
			||||||
    $data = $this->renderConpherenceTransactions($conpherence);
 | 
					 | 
				
			||||||
    $latest_transaction_id = $data['latest_transaction_id'];
 | 
					 | 
				
			||||||
    $transactions = $data['transactions'];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    $update_uri = $this->getApplicationURI('update/'.$conpherence->getID().'/');
 | 
					    $update_uri = $this->getApplicationURI('update/'.$conpherence->getID().'/');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Javelin::initBehavior('conpherence-pontificate');
 | 
					    Javelin::initBehavior('conpherence-pontificate');
 | 
				
			||||||
@@ -127,21 +168,7 @@ final class ConpherenceViewController extends
 | 
				
			|||||||
        ''))
 | 
					        ''))
 | 
				
			||||||
      ->render();
 | 
					      ->render();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $scrollbutton = javelin_tag(
 | 
					    return $form;
 | 
				
			||||||
      'a',
 | 
					 | 
				
			||||||
      array(
 | 
					 | 
				
			||||||
        'href' => '#',
 | 
					 | 
				
			||||||
        'mustcapture' => true,
 | 
					 | 
				
			||||||
        'sigil' => 'show-older-messages',
 | 
					 | 
				
			||||||
        'class' => 'conpherence-show-older-messages',
 | 
					 | 
				
			||||||
      ),
 | 
					 | 
				
			||||||
      pht('Show Older Messages'));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return array(
 | 
					 | 
				
			||||||
      'messages' => hsprintf('%s%s', $scrollbutton, $transactions),
 | 
					 | 
				
			||||||
      'form' => $form
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,6 +6,8 @@
 | 
				
			|||||||
final class ConpherenceThreadQuery
 | 
					final class ConpherenceThreadQuery
 | 
				
			||||||
  extends PhabricatorCursorPagedPolicyAwareQuery {
 | 
					  extends PhabricatorCursorPagedPolicyAwareQuery {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const TRANSACTION_LIMIT = 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private $phids;
 | 
					  private $phids;
 | 
				
			||||||
  private $ids;
 | 
					  private $ids;
 | 
				
			||||||
  private $needWidgetData;
 | 
					  private $needWidgetData;
 | 
				
			||||||
@@ -14,7 +16,9 @@ final class ConpherenceThreadQuery
 | 
				
			|||||||
  private $needTransactions;
 | 
					  private $needTransactions;
 | 
				
			||||||
  private $needParticipantCache;
 | 
					  private $needParticipantCache;
 | 
				
			||||||
  private $needFilePHIDs;
 | 
					  private $needFilePHIDs;
 | 
				
			||||||
  private $afterMessageID;
 | 
					  private $afterTransactionID;
 | 
				
			||||||
 | 
					  private $beforeTransactionID;
 | 
				
			||||||
 | 
					  private $transactionLimit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public function needFilePHIDs($need_file_phids) {
 | 
					  public function needFilePHIDs($need_file_phids) {
 | 
				
			||||||
    $this->needFilePHIDs = $need_file_phids;
 | 
					    $this->needFilePHIDs = $need_file_phids;
 | 
				
			||||||
@@ -56,12 +60,25 @@ final class ConpherenceThreadQuery
 | 
				
			|||||||
    return $this;
 | 
					    return $this;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // TODO: This is pretty hacky!!!!~~
 | 
					  public function setAfterTransactionID($id) {
 | 
				
			||||||
  public function setAfterMessageID($id) {
 | 
					    $this->afterTransactionID = $id;
 | 
				
			||||||
    $this->afterMessageID = $id;
 | 
					 | 
				
			||||||
    return $this;
 | 
					    return $this;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public function setBeforeTransactionID($id) {
 | 
				
			||||||
 | 
					    $this->beforeTransactionID = $id;
 | 
				
			||||||
 | 
					    return $this;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public function setTransactionLimit($transaction_limit) {
 | 
				
			||||||
 | 
					    $this->transactionLimit = $transaction_limit;
 | 
				
			||||||
 | 
					    return $this;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public function getTransactionLimit() {
 | 
				
			||||||
 | 
					    return $this->transactionLimit;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  protected function loadPage() {
 | 
					  protected function loadPage() {
 | 
				
			||||||
    $table = new ConpherenceThread();
 | 
					    $table = new ConpherenceThread();
 | 
				
			||||||
    $conn_r = $table->establishConnection('r');
 | 
					    $conn_r = $table->establishConnection('r');
 | 
				
			||||||
@@ -164,13 +181,23 @@ final class ConpherenceThreadQuery
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private function loadTransactionsAndHandles(array $conpherences) {
 | 
					  private function loadTransactionsAndHandles(array $conpherences) {
 | 
				
			||||||
    $transactions = id(new ConpherenceTransactionQuery())
 | 
					    $query = id(new ConpherenceTransactionQuery())
 | 
				
			||||||
      ->setViewer($this->getViewer())
 | 
					      ->setViewer($this->getViewer())
 | 
				
			||||||
      ->withObjectPHIDs(array_keys($conpherences))
 | 
					      ->withObjectPHIDs(array_keys($conpherences))
 | 
				
			||||||
      ->needHandles(true)
 | 
					      ->needHandles(true);
 | 
				
			||||||
      ->setAfterID($this->afterMessageID)
 | 
					 | 
				
			||||||
      ->execute();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // We have to flip these for the underyling query class. The semantics of
 | 
				
			||||||
 | 
					    // paging are tricky business.
 | 
				
			||||||
 | 
					    if ($this->afterTransactionID) {
 | 
				
			||||||
 | 
					      $query->setBeforeID($this->afterTransactionID);
 | 
				
			||||||
 | 
					    } else if ($this->beforeTransactionID) {
 | 
				
			||||||
 | 
					      $query->setAfterID($this->beforeTransactionID);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if ($this->getTransactionLimit()) {
 | 
				
			||||||
 | 
					      // fetch an extra for "show older" scenarios
 | 
				
			||||||
 | 
					      $query->setLimit($this->getTransactionLimit() + 1);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    $transactions = $query->execute();
 | 
				
			||||||
    $transactions = mgroup($transactions, 'getObjectPHID');
 | 
					    $transactions = mgroup($transactions, 'getObjectPHID');
 | 
				
			||||||
    foreach ($conpherences as $phid => $conpherence) {
 | 
					    foreach ($conpherences as $phid => $conpherence) {
 | 
				
			||||||
      $current_transactions = $transactions[$phid];
 | 
					      $current_transactions = $transactions[$phid];
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,4 +10,9 @@ final class ConpherenceTransactionQuery
 | 
				
			|||||||
    return new ConpherenceTransaction();
 | 
					    return new ConpherenceTransaction();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected function getReversePaging() {
 | 
				
			||||||
 | 
					    return false;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -35,11 +35,19 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery
 | 
				
			|||||||
    return $this;
 | 
					    return $this;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  final protected function getAfterID() {
 | 
				
			||||||
 | 
					    return $this->afterID;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  final public function setBeforeID($object_id) {
 | 
					  final public function setBeforeID($object_id) {
 | 
				
			||||||
    $this->beforeID = $object_id;
 | 
					    $this->beforeID = $object_id;
 | 
				
			||||||
    return $this;
 | 
					    return $this;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  final protected function getBeforeID() {
 | 
				
			||||||
 | 
					    return $this->beforeID;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  final protected function buildLimitClause(AphrontDatabaseConnection $conn_r) {
 | 
					  final protected function buildLimitClause(AphrontDatabaseConnection $conn_r) {
 | 
				
			||||||
    if ($this->getRawResultLimit()) {
 | 
					    if ($this->getRawResultLimit()) {
 | 
				
			||||||
      return qsprintf($conn_r, 'LIMIT %d', $this->getRawResultLimit());
 | 
					      return qsprintf($conn_r, 'LIMIT %d', $this->getRawResultLimit());
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -235,16 +235,18 @@ JX.behavior('conpherence-menu', function(config) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  JX.Stratcom.listen('click', 'show-older-messages', function(e) {
 | 
					  JX.Stratcom.listen('click', 'show-older-messages', function(e) {
 | 
				
			||||||
    e.kill();
 | 
					    e.kill();
 | 
				
			||||||
    var last_offset = e.getNodeData('show-older-messages').offset;
 | 
					    var data = e.getNodeData('show-older-messages');
 | 
				
			||||||
    var conf_id = e.getNodeData('show-older-messages').ID;
 | 
					    var oldest_transaction_id = data.oldest_transaction_id;
 | 
				
			||||||
 | 
					    var conf_id = thread.selected;
 | 
				
			||||||
    JX.DOM.remove(e.getNode('show-older-messages'));
 | 
					    JX.DOM.remove(e.getNode('show-older-messages'));
 | 
				
			||||||
    var root = JX.DOM.find(document, 'div', 'conpherence-layout');
 | 
					    var root = JX.DOM.find(document, 'div', 'conpherence-layout');
 | 
				
			||||||
    var messages_root = JX.DOM.find(root, 'div', 'conpherence-messages');
 | 
					    var messages_root = JX.DOM.find(root, 'div', 'conpherence-messages');
 | 
				
			||||||
    new JX.Request(config.base_uri + conf_id + '/', function(r) {
 | 
					    new JX.Request(config.base_uri + conf_id + '/', function(r) {
 | 
				
			||||||
      var messages = JX.$H(r.messages);
 | 
					      var messages = JX.$H(r.messages);
 | 
				
			||||||
      JX.DOM.prependContent(messages_root,
 | 
					      JX.DOM.prependContent(
 | 
				
			||||||
      JX.$H(messages));
 | 
					        messages_root,
 | 
				
			||||||
    }).setData({ offset: last_offset+1 }).send();
 | 
					        JX.$H(messages));
 | 
				
			||||||
 | 
					    }).setData({ oldest_transaction_id : oldest_transaction_id }).send();
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user