Page MenuHomePhabricator

D17749.diff
No OneTemporary

D17749.diff

diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -1724,6 +1724,7 @@
'PHUIListItemView' => 'view/phui/PHUIListItemView.php',
'PHUIListView' => 'view/phui/PHUIListView.php',
'PHUIListViewTestCase' => 'view/layout/__tests__/PHUIListViewTestCase.php',
+ 'PHUINextPrevView' => 'view/phui/PHUINextPrevView.php',
'PHUIObjectBoxView' => 'view/phui/PHUIObjectBoxView.php',
'PHUIObjectItemListExample' => 'applications/uiexample/examples/PHUIObjectItemListExample.php',
'PHUIObjectItemListView' => 'view/phui/PHUIObjectItemListView.php',
@@ -6730,6 +6731,7 @@
'PHUIListItemView' => 'AphrontTagView',
'PHUIListView' => 'AphrontTagView',
'PHUIListViewTestCase' => 'PhabricatorTestCase',
+ 'PHUINextPrevView' => 'AphrontView',
'PHUIObjectBoxView' => 'AphrontTagView',
'PHUIObjectItemListExample' => 'PhabricatorUIExample',
'PHUIObjectItemListView' => 'AphrontTagView',
diff --git a/src/applications/phriction/controller/PhrictionDocumentController.php b/src/applications/phriction/controller/PhrictionDocumentController.php
--- a/src/applications/phriction/controller/PhrictionDocumentController.php
+++ b/src/applications/phriction/controller/PhrictionDocumentController.php
@@ -220,6 +220,26 @@
}
$prop_list = phutil_tag_div('phui-document-view-pro-box', $prop_list);
+ $pager = new PHUINextPrevView();
+ if ($request->getInt('v') != null) {
+ $pager->setOffset($request->getInt('v'));
+ } else {
+ // In Phriction, v=0 points to the last version
+ // We must handle this and set offset manually
+ // to prevent the NEXT button from appearing
+ $content = id(new PhrictionContent())->load($document->getContentID());
+ $pager->setOffset($content->getVersion());
+ }
+ $pager->setURI($request->getRequestURI(), 'v');
+
+ $next_prev_version = id(new PhrictionContent())->loadAllWhere(
+ 'documentID = %d ORDER BY version LIMIT %d,%d',
+ $document->getID(),
+ max(0, $pager->getOffset() - 1),
+ $pager->getPageSize() + 1);
+
+ $next_prev_version = $pager->sliceResults($next_prev_version);
+
$page_content = id(new PHUIDocumentViewPro())
->setHeader($header)
->setToc($toc)
@@ -228,6 +248,7 @@
$version_note,
$move_notice,
$core_content,
+ $pager,
));
return $this->newPage()
diff --git a/src/view/phui/PHUINextPrevView.php b/src/view/phui/PHUINextPrevView.php
new file mode 100644
--- /dev/null
+++ b/src/view/phui/PHUINextPrevView.php
@@ -0,0 +1,212 @@
+<?php
+
+final class PHUINextPrevView extends AphrontView {
+
+ private $offset;
+ private $pageSize = 1;
+
+ private $count;
+ private $hasMorePages;
+
+ private $uri;
+ private $pagingParameter;
+ private $surroundingPages = 0;
+ private $enableKeyboardShortcuts;
+
+ public function setOffset($offset) {
+ $this->offset = max(0, $offset);
+ return $this;
+ }
+
+ public function getOffset() {
+ return $this->offset;
+ }
+
+ public function getPageSize() {
+ return $this->pageSize;
+ }
+
+ public function setCount($count) {
+ $this->count = $count;
+ return $this;
+ }
+
+ public function setHasMorePages($has_more) {
+ $this->hasMorePages = $has_more;
+ return $this;
+ }
+
+ public function setURI(PhutilURI $uri, $paging_parameter) {
+ $this->uri = $uri;
+ $this->pagingParameter = $paging_parameter;
+ return $this;
+ }
+
+ public function readFromRequest(AphrontRequest $request) {
+ $this->uri = $request->getRequestURI();
+ $this->pagingParameter = 'offset';
+ $this->offset = $request->getInt($this->pagingParameter);
+ return $this;
+ }
+
+ public function willShowPagingControls() {
+ return $this->hasMorePages || $this->getOffset();
+ }
+
+ public function getHasMorePages() {
+ return $this->hasMorePages;
+ }
+
+ private function computeCount() {
+ if ($this->count !== null) {
+ return $this->count;
+ }
+ return $this->getOffset()
+ + $this->getPageSize()
+ + ($this->hasMorePages ? 1 : 0);
+ }
+
+ private function isExactCountKnown() {
+ return $this->count !== null;
+ }
+
+ /**
+ * A common paging strategy is to select one extra record and use that to
+ * indicate that there's an additional page (this doesn't give you a
+ * complete page count but is often faster than counting the total number
+ * of items). This method will take a result array, slice it down to the
+ * page size if necessary, and call setHasMorePages() if there are more than
+ * one page of results.
+ *
+ * $results = queryfx_all(
+ * $conn,
+ * 'SELECT ... LIMIT %d, %d',
+ * $pager->getOffset(),
+ * $pager->getPageSize() + 1);
+ * $results = $pager->sliceResults($results);
+ *
+ * @param list Result array.
+ * @return list One page of results.
+ */
+ public function sliceResults(array $results) {
+ if (count($results) > $this->getPageSize()) {
+ $results = array_slice($results, 0, $this->getPageSize(), true);
+ $this->setHasMorePages(true);
+ }
+ return $results;
+ }
+
+ public function setEnableKeyboardShortcuts($enable) {
+ $this->enableKeyboardShortcuts = $enable;
+ return $this;
+ }
+
+ public function render() {
+ if (!$this->uri) {
+ throw new PhutilInvalidStateException('setURI');
+ }
+
+ require_celerity_resource('phui-pager-css');
+
+ $page = (int)floor($this->getOffset() / $this->getPageSize());
+ $last = ((int)ceil($this->computeCount() / $this->getPageSize())) - 1;
+ $near = $this->surroundingPages;
+
+ $min = $page - $near;
+ $max = $page + $near;
+
+ // Limit the window size to no larger than the number of available pages.
+ if ($max - $min > $last) {
+ $max = $min + $last;
+ if ($max == $min) {
+ return phutil_tag('div', array('class' => 'phui-pager-view'), '');
+ }
+ }
+
+ // Slide the window so it is entirely over displayable pages.
+ if ($min < 0) {
+ $max += 0 - $min;
+ $min += 0 - $min;
+ }
+
+ if ($max > $last) {
+ $min -= $max - $last;
+ $max -= $max - $last;
+ }
+
+
+ // Build up a list of <index, label, css-class> tuples which describe the
+ // links we'll display, then render them all at once.
+
+ $links = array();
+
+ $prev_index = null;
+ $next_index = null;
+
+ if ($page > 0) {
+ $links[] = array($page - 1, pht('Prev'), null);
+ $prev_index = $page - 1;
+ }
+
+ if ($page < $last && $last > 0) {
+ $links[] = array($page + 1, pht('Next'), null);
+ $next_index = $page + 1;
+ }
+
+ $base_uri = $this->uri;
+ $parameter = $this->pagingParameter;
+
+ if ($this->enableKeyboardShortcuts) {
+ $pager_links = array();
+ $pager_index = array(
+ 'prev' => $prev_index,
+ 'next' => $next_index,
+ );
+ foreach ($pager_index as $key => $index) {
+ if ($index !== null) {
+ $display_index = $this->getDisplayIndex($index);
+ $pager_links[$key] = (string)$base_uri->alter(
+ $parameter,
+ $display_index);
+ }
+ }
+ Javelin::initBehavior('phabricator-keyboard-pager', $pager_links);
+ }
+
+ // Convert tuples into rendered nodes.
+ $rendered_links = array();
+ foreach ($links as $link) {
+ list($index, $label, $class) = $link;
+ $display_index = $this->getDisplayIndex($index);
+ $link = $base_uri->alter($parameter, $display_index);
+ $rendered_links[] = id(new PHUIButtonView())
+ ->setTag('a')
+ ->setHref($link)
+ ->setColor(PHUIButtonView::GREY)
+ ->addClass('mml')
+ ->addClass($class)
+ ->setText($label);
+ }
+
+ return phutil_tag(
+ 'div',
+ array(
+ 'class' => 'phui-pager-view',
+ ),
+ $rendered_links);
+ }
+
+ private function getDisplayIndex($page_index) {
+ $page_size = $this->getPageSize();
+ // Use a 1-based sequence for display so that the number in the URI is
+ // the same as the page number you're on.
+ if ($page_index == 0) {
+ // No need for the first page to say page=1.
+ $display_index = null;
+ } else {
+ $display_index = $page_index * $page_size;
+ }
+ return $display_index;
+ }
+
+}

File Metadata

Mime Type
text/plain
Expires
Sat, Apr 12, 5:55 PM (3 w, 6 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7580850
Default Alt Text
D17749.diff (8 KB)

Event Timeline