From 37931ee689e11050c0dcaf604e3a54640f560ed6 Mon Sep 17 00:00:00 2001 From: Joel McCoy Date: Sat, 20 Sep 2014 16:38:39 -0400 Subject: [PATCH 1/4] SHOW_BLOCKS PAGINATION - Get total count of blocks in a BlockBatch within showBlocks() - Fetch perPage (500) blocks at a time - Offset blocks fetch based on "?page=" querystring - Pass currentPage and pages[] to templates/show_blocks - pagination.mustache made for inclusion in show-blocks - CSS counters added to style.css for numbering pagination links - pagination.js handles detecting current page and navigating to others - Remove 'theres_more' flag --- blocktogether.js | 27 ++++++++++++++++------ static/pagination.js | 41 ++++++++++++++++++++++++++++++++++ static/style.css | 9 ++++++++ templates/pagination.mustache | 8 +++++++ templates/show-blocks.mustache | 10 ++++----- 5 files changed, 83 insertions(+), 12 deletions(-) create mode 100644 static/pagination.js create mode 100644 templates/pagination.mustache diff --git a/blocktogether.js b/blocktogether.js index dabeab7..ce7a672 100644 --- a/blocktogether.js +++ b/blocktogether.js @@ -466,6 +466,13 @@ function renderHtmlError(message) { function showBlocks(req, res, btUser, ownBlocks) { // The user viewing this page may not be logged in. var logged_in_screen_name = undefined; + // For pagination + // N.B.: currentPage IS 1-INDEXED, NOT ZERO-INDEXED + var currentPage = req.query.page || 1, + perPage = 500; + if (currentPage < 1) { + currentPage = 1; + } if (req.user) { logged_in_screen_name = req.user.screen_name; } @@ -481,8 +488,12 @@ function showBlocks(req, res, btUser, ownBlocks) { if (!blockBatch) { renderHtmlError('No blocks fetched yet. Please try again soon.'); } else { - blockBatch.getBlocks({ - limit: 5000, + Block.findAndCountAll({ + where: { + blockBatchId: blockBatch.id + }, + limit: perPage, + offset: perPage * (currentPage - 1), include: [{ model: TwitterUser, required: false @@ -492,7 +503,9 @@ function showBlocks(req, res, btUser, ownBlocks) { }).success(function(blocks) { // Create a list of users that has at least a uid entry even if the // TwitterUser doesn't yet exist in our DB. - var blockedUsersList = blocks.map(function(block) { + var blocksCount = blocks.count, + blocksRows = blocks.rows; + var blockedUsersList = blocksRows.map(function(block) { if (block.twitterUser) { return block.twitterUser; } else { @@ -507,10 +520,10 @@ function showBlocks(req, res, btUser, ownBlocks) { author_screen_name: btUser.screen_name, // The uid of the user whose blocks we are viewing. author_uid: btUser.uid, - // TODO: We could get the full count even when we are only displaying - // 5000. - block_count: blocks.length, - theres_more: blocks.length === 5000, + block_count: blocksCount, + // 1-indexed array of numbers for use in pagination template. + pages: _.range(1, Math.ceil(blocksCount / perPage) + 1), + currentPage: currentPage, blocked_users: blockedUsersList, own_blocks: ownBlocks }; diff --git a/static/pagination.js b/static/pagination.js new file mode 100644 index 0000000..c2faf6b --- /dev/null +++ b/static/pagination.js @@ -0,0 +1,41 @@ +$(function(){ + /* Specialized from MDN example of querystring reading. */ + function readPageNum() { + return unescape(window.location.search.replace( + /^(?:.*[&\?]page(?:\=([^&]*))?)?.*$/i, '$1' + )); + } + function loadPage(pageNum) { + window.location = window.location.origin + + window.location.pathname + + "?page=" + pageNum; + } + var currentPage = readPageNum() || 1, + pages = $('ol.pagination > li.page'); + + // Keep page number within bounds; disable prev/next buttons as needed. + if (currentPage <= 1) { + currentPage = 1; + $('li.prev-page').addClass('disabled'); + } + if (currentPage >= pages.length) { + currentPage = pages.length; + $('li.next-page').addClass('disabled'); + } + // Display current page as active. + $('ol.pagination > li.page').eq(currentPage - 1).addClass('active'); + + // Assign behaviors to navigation components: + $('.prev-page').click(function(ev) { + ev.preventDefault(); + loadPage(currentPage - 1); + }); + $('.next-page').click(function(ev) { + ev.preventDefault(); + loadPage(currentPage + 1); + }); + $('ol.pagination').on('click', 'li.page', function(ev) { + ev.preventDefault(); + loadPage($(this).index()); + }); +}); diff --git a/static/style.css b/static/style.css index aa04e02..067748d 100644 --- a/static/style.css +++ b/static/style.css @@ -65,3 +65,12 @@ th, td { .screen-name { font-family: serif; } + +/* Numbering for pagination, since our templating is logicless */ +ol.pagination { + counter-reset: page-number +} +ol.pagination > li > a.page-link::before { + counter-increment: page-number; + content: counter(page-number); +} diff --git a/templates/pagination.mustache b/templates/pagination.mustache new file mode 100644 index 0000000..4e674ee --- /dev/null +++ b/templates/pagination.mustache @@ -0,0 +1,8 @@ + +
    +
  1. «
  2. + {{#pages}} +
  3. + {{/pages}} +
  4. »
  5. +
diff --git a/templates/show-blocks.mustache b/templates/show-blocks.mustache index 801e13b..e345a52 100644 --- a/templates/show-blocks.mustache +++ b/templates/show-blocks.mustache @@ -3,13 +3,10 @@ {{^own_blocks}} User @{{author_screen_name}} - is blocking {{block_count}} - {{#theres_more}}+{{/theres_more}} - users on Twitter (updated {{updated}}): + is blocking {{block_count}} users on Twitter (updated {{updated}}): {{/own_blocks}} {{#own_blocks}} - You are blocking {{block_count}} - {{#theres_more}}+{{/theres_more}} users on Twitter (updated {{updated}}): + You are blocking {{block_count}} users on Twitter (updated {{updated}}): {{/own_blocks}} {{! When displaying someone else's blocks, give an option to block all the same ones. }} @@ -23,6 +20,9 @@ {{/own_blocks}} +
+ {{>pagination.mustache}} +
From 896a5a0072f1c41756204777843aeb32d2ece8d1 Mon Sep 17 00:00:00 2001 From: Joel McCoy Date: Sat, 20 Sep 2014 23:15:25 -0400 Subject: [PATCH 2/4] - Remove CSS/JQuery pagination handling - Move pagination bar logic to blocktogether.js - Omit previous/next links instead of disabling them --- blocktogether.js | 21 +++++++++++++----- static/pagination.js | 42 +---------------------------------- static/style.css | 9 -------- templates/pagination.mustache | 16 ++++++++++--- 4 files changed, 30 insertions(+), 58 deletions(-) diff --git a/blocktogether.js b/blocktogether.js index ce7a672..927eaa5 100644 --- a/blocktogether.js +++ b/blocktogether.js @@ -1,6 +1,7 @@ // TODO: Add CSRF protection on POSTs // TODO: Log off using GET allows drive-by logoff, fix that. var express = require('express'), // Web framework + url = require('url'), bodyParser = require('body-parser'), cookieSession = require('cookie-session'), crypto = require('crypto'), @@ -468,7 +469,7 @@ function showBlocks(req, res, btUser, ownBlocks) { var logged_in_screen_name = undefined; // For pagination // N.B.: currentPage IS 1-INDEXED, NOT ZERO-INDEXED - var currentPage = req.query.page || 1, + var currentPage = parseInt(req.query.page, 10) || 1, perPage = 500; if (currentPage < 1) { currentPage = 1; @@ -504,7 +505,8 @@ function showBlocks(req, res, btUser, ownBlocks) { // Create a list of users that has at least a uid entry even if the // TwitterUser doesn't yet exist in our DB. var blocksCount = blocks.count, - blocksRows = blocks.rows; + blocksRows = blocks.rows, + pageCount = Math.ceil(blocksCount / perPage); var blockedUsersList = blocksRows.map(function(block) { if (block.twitterUser) { return block.twitterUser; @@ -521,9 +523,18 @@ function showBlocks(req, res, btUser, ownBlocks) { // The uid of the user whose blocks we are viewing. author_uid: btUser.uid, block_count: blocksCount, - // 1-indexed array of numbers for use in pagination template. - pages: _.range(1, Math.ceil(blocksCount / perPage) + 1), - currentPage: currentPage, + // Array of objects (1-indexed) for use in pagination template. + pages: _.range(1, pageCount + 1).map(function(pageNum) { + return { + page_num: pageNum, + active: pageNum === currentPage + }; + }), + // Previous/next page indices for use in pagination template. + previous_page: currentPage - 1 || false, + next_page: currentPage === pageCount ? false : currentPage + 1, + // Base URL for appending pagination querystring. + path_name: url.parse(req.url).pathname, blocked_users: blockedUsersList, own_blocks: ownBlocks }; diff --git a/static/pagination.js b/static/pagination.js index c2faf6b..8b13789 100644 --- a/static/pagination.js +++ b/static/pagination.js @@ -1,41 +1 @@ -$(function(){ - /* Specialized from MDN example of querystring reading. */ - function readPageNum() { - return unescape(window.location.search.replace( - /^(?:.*[&\?]page(?:\=([^&]*))?)?.*$/i, '$1' - )); - } - function loadPage(pageNum) { - window.location = window.location.origin + - window.location.pathname + - "?page=" + pageNum; - } - var currentPage = readPageNum() || 1, - pages = $('ol.pagination > li.page'); - - // Keep page number within bounds; disable prev/next buttons as needed. - if (currentPage <= 1) { - currentPage = 1; - $('li.prev-page').addClass('disabled'); - } - if (currentPage >= pages.length) { - currentPage = pages.length; - $('li.next-page').addClass('disabled'); - } - // Display current page as active. - $('ol.pagination > li.page').eq(currentPage - 1).addClass('active'); - - // Assign behaviors to navigation components: - $('.prev-page').click(function(ev) { - ev.preventDefault(); - loadPage(currentPage - 1); - }); - $('.next-page').click(function(ev) { - ev.preventDefault(); - loadPage(currentPage + 1); - }); - $('ol.pagination').on('click', 'li.page', function(ev) { - ev.preventDefault(); - loadPage($(this).index()); - }); -}); + diff --git a/static/style.css b/static/style.css index 067748d..aa04e02 100644 --- a/static/style.css +++ b/static/style.css @@ -65,12 +65,3 @@ th, td { .screen-name { font-family: serif; } - -/* Numbering for pagination, since our templating is logicless */ -ol.pagination { - counter-reset: page-number -} -ol.pagination > li > a.page-link::before { - counter-increment: page-number; - content: counter(page-number); -} diff --git a/templates/pagination.mustache b/templates/pagination.mustache index 4e674ee..6ec54dc 100644 --- a/templates/pagination.mustache +++ b/templates/pagination.mustache @@ -1,8 +1,18 @@
    -
  1. «
  2. + {{#previous_page}} +
  3. + « +
  4. + {{/previous_page}} {{#pages}} -
  5. +
  6. + {{page_num}} +
  7. {{/pages}} -
  8. »
  9. + {{#next_page}} +
  10. + » +
  11. + {{/next_page}}
From 69345f1217d2cebdec980a59a3a678ee1f7b8d00 Mon Sep 17 00:00:00 2001 From: Joel McCoy Date: Sat, 20 Sep 2014 23:40:40 -0400 Subject: [PATCH 3/4] - Rename classes for pagination template - More accurately label the "Block All" button for pagination --- templates/pagination.mustache | 10 +++++----- templates/show-blocks.mustache | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/templates/pagination.mustache b/templates/pagination.mustache index 6ec54dc..16f15a1 100644 --- a/templates/pagination.mustache +++ b/templates/pagination.mustache @@ -1,18 +1,18 @@
    {{#previous_page}} -
  1. - « +
  2. {{/previous_page}} {{#pages}} -
  3. +
  4. {{/pages}} {{#next_page}} -
  5. - » +
  6. {{/next_page}}
diff --git a/templates/show-blocks.mustache b/templates/show-blocks.mustache index e345a52..701d753 100644 --- a/templates/show-blocks.mustache +++ b/templates/show-blocks.mustache @@ -9,10 +9,10 @@ You are blocking {{block_count}} users on Twitter (updated {{updated}}): {{/own_blocks}} {{! When displaying someone else's blocks, give an option to block all the - same ones. }} + same ones on this page. }} {{^own_blocks}}
- +
Block Together will now block {{block_count}} users using your account @{{logged_in_screen_name}}. This may take some time. You can check From 208b36bddc7e41bf63e710f4d98a1638e758a2fe Mon Sep 17 00:00:00 2001 From: Joel McCoy Date: Sat, 20 Sep 2014 23:48:05 -0400 Subject: [PATCH 4/4] - Hide pagination if only one page is needed --- blocktogether.js | 1 + templates/show-blocks.mustache | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/blocktogether.js b/blocktogether.js index 927eaa5..aa44b0a 100644 --- a/blocktogether.js +++ b/blocktogether.js @@ -523,6 +523,7 @@ function showBlocks(req, res, btUser, ownBlocks) { // The uid of the user whose blocks we are viewing. author_uid: btUser.uid, block_count: blocksCount, + paginate: pageCount > 1, // Array of objects (1-indexed) for use in pagination template. pages: _.range(1, pageCount + 1).map(function(pageNum) { return { diff --git a/templates/show-blocks.mustache b/templates/show-blocks.mustache index 701d753..9ac003d 100644 --- a/templates/show-blocks.mustache +++ b/templates/show-blocks.mustache @@ -12,7 +12,7 @@ same ones on this page. }} {{^own_blocks}}
- +
Block Together will now block {{block_count}} users using your account @{{logged_in_screen_name}}. This may take some time. You can check @@ -20,9 +20,11 @@
{{/own_blocks}} + {{#paginate}}
{{>pagination.mustache}}
+ {{/paginate}}