diff --git a/.eslintrc.json b/.eslintrc.json index e7581e9a05..f976bbbe0c 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -26,6 +26,7 @@ "object-curly-newline": ["error", {"multiline": true, "consistent": true}], "one-var-declaration-per-line": "error", "quotes": ["error", "single", {"avoidEscape": true}], + "radix": "error", "semi": "error", "semi-spacing": "error", "space-before-blocks": "error", diff --git a/public/css/style.css b/public/css/style.css index 33d4164ad4..b3a032b55d 100644 --- a/public/css/style.css +++ b/public/css/style.css @@ -776,6 +776,14 @@ input { display:none; } +#stream-pagination { + text-align: center; +} + +#stream-pagination li { + display: inline; +} + #fullscreen-entry { display:none; } diff --git a/public/js/selfoss-base.js b/public/js/selfoss-base.js index 48a402503d..3fa53a9d24 100644 --- a/public/js/selfoss-base.js +++ b/public/js/selfoss-base.js @@ -500,7 +500,7 @@ var selfoss = { if (ids.length === 0 && selfoss.filter.type == 'unread') { $('.entry').remove(); if (selfoss.filter.type == 'unread' && - parseInt($('.unread-count .count').html()) > 0) { + parseInt($('.unread-count .count').html(), 10) > 0) { selfoss.db.reloadList(); } else { selfoss.ui.refreshStreamButtons(true); @@ -517,7 +517,7 @@ var selfoss = { selfoss.ui.beforeReloadList(true); - var unreadstats = parseInt($('.nav-filter-unread span.count').html()) - + var unreadstats = parseInt($('.nav-filter-unread span.count').html(), 10) - ids.length; var displayed = false; var displayNextUnread = function() { diff --git a/public/js/selfoss-db.js b/public/js/selfoss-db.js index bf26469722..9316bda2c8 100644 --- a/public/js/selfoss-db.js +++ b/public/js/selfoss-db.js @@ -204,7 +204,7 @@ selfoss.dbOnline = { unreadCount = data.stats.unread; } else { unreadCount = parseInt($('.unread-count .count') - .html()); + .html(), 10); } if (unreadCount > $('.entry.unread').length) { $('.stream-more').show(); @@ -392,7 +392,7 @@ selfoss.dbOffline = { .then(function() { var offlineDays = window.localStorage.getItem('offlineDays'); if (offlineDays !== null) { - selfoss.dbOffline.offlineDays = parseInt(offlineDays); + selfoss.dbOffline.offlineDays = parseInt(offlineDays, 10); } // The newest garbage collected entry is either what's already // in the offline db or if more recent the entry older than @@ -559,19 +559,27 @@ selfoss.dbOffline = { var isMore = false; var alwaysInDb = selfoss.filter.type === 'starred' || selfoss.filter.type === 'unread'; + var offset = selfoss.filter.offset; entries.filter(function(entry) { + var keepEntry = false; + if (selfoss.filter.extraIds.indexOf(entry.id) > -1) { return true; } if (selfoss.filter.type == 'starred') { - return entry.starred; + keepEntry = entry.starred; } else if (selfoss.filter.type == 'unread') { - return entry.unread; + keepEntry = entry.unread; + } + + if (keepEntry && offset > 0) { + offset = offset - 1; + return false; } - return true; + return keepEntry; }).until(function(entry) { // stop iteration if enough entries have been shown // go one further to assess if has more @@ -679,7 +687,7 @@ selfoss.dbOffline = { var d = new Date().toISOString(); statuses.forEach(function(newStatus) { newQueuedStatuses.push({ - entryId: parseInt(newStatus.entryId), + entryId: parseInt(newStatus.entryId, 10), name: newStatus.name, value: newStatus.value, datetime: d @@ -758,7 +766,7 @@ selfoss.dbOffline = { } }); - var id = parseInt(itemStatus.id); + var id = parseInt(itemStatus.id, 10); selfoss.db.storage.entries.get(id).then(function() { selfoss.db.storage.entries.update(id, newStatus); }, function() { diff --git a/public/js/selfoss-events-entries.js b/public/js/selfoss-events-entries.js index 6bcbff9e70..481bb1d3b7 100644 --- a/public/js/selfoss-events-entries.js +++ b/public/js/selfoss-events-entries.js @@ -169,6 +169,13 @@ selfoss.events.entries = function() { }); } + // stream pagination buttons + $('#stream-pagination button').unbind('click').click(function() { + var pageNumber = parseInt($(this).html(), 10); + selfoss.filter.offset = (pageNumber - 1) * selfoss.filter.itemsPerPage; + selfoss.db.reloadList(); + }); + // click a tag if (selfoss.isSmartphone() == false) { $('.entry-tags-tag').unbind('click').click(function() { diff --git a/public/js/selfoss-events-entriestoolbar.js b/public/js/selfoss-events-entriestoolbar.js index fca7688212..b2e443ea5c 100644 --- a/public/js/selfoss-events-entriestoolbar.js +++ b/public/js/selfoss-events-entriestoolbar.js @@ -80,7 +80,7 @@ selfoss.events.entriesToolbar = function(parent) { // update statistics in main menue var updateStats = function(starr) { - var starred = parseInt($('.nav-filter-starred span.count').html()); + var starred = parseInt($('.nav-filter-starred span.count').html(), 10); if (starr) { starred++; } else { @@ -128,7 +128,7 @@ selfoss.events.entriesToolbar = function(parent) { // update statistics in main menue and the currently active tag var updateStats = function(unread) { // update all unread counters - var unreadstats = parseInt($('.nav-filter-unread span.count').html()); + var unreadstats = parseInt($('.nav-filter-unread span.count').html(), 10); var diff = unread ? -1 : 1; selfoss.refreshUnread(unreadstats + diff); diff --git a/public/js/selfoss-events.js b/public/js/selfoss-events.js index 60f198b51d..ba3a80df68 100644 --- a/public/js/selfoss-events.js +++ b/public/js/selfoss-events.js @@ -112,7 +112,7 @@ selfoss.events = { + '/' + selfoss.events.subsection; var entryId = null; - if (hashPath.length > 2 && (entryId = parseInt(hashPath[2]))) { + if (hashPath.length > 2 && (entryId = parseInt(hashPath[2], 10))) { selfoss.events.entryId = entryId; } else { selfoss.events.entryId = null; @@ -168,7 +168,7 @@ selfoss.events = { if (selfoss.events.subsection.substr(0, 4) == 'tag-') { selfoss.filter.tag = selfoss.events.subsection.substr(4); } else if (selfoss.events.subsection.substr(0, 7) == 'source-') { - var sourceId = parseInt(selfoss.events.subsection.substr(7)); + var sourceId = parseInt(selfoss.events.subsection.substr(7), 10); if (sourceId) { selfoss.filter.source = sourceId; selfoss.filter.sourcesNav = true; diff --git a/public/js/selfoss-ui.js b/public/js/selfoss-ui.js index 4fbd5d4001..9f8fac4222 100644 --- a/public/js/selfoss-ui.js +++ b/public/js/selfoss-ui.js @@ -34,7 +34,7 @@ selfoss.ui = { refreshTitle: function(unread) { - unread = (typeof unread !== 'undefined') ? unread : parseInt($('.unread-count .count').html()); + unread = (typeof unread !== 'undefined') ? unread : parseInt($('.unread-count .count').html(), 10); if (unread > 0) { $(document).attr('title', selfoss.htmlTitle + ' (' + unread + ')'); @@ -129,6 +129,7 @@ selfoss.ui = { hasMore = (typeof hasMore !== 'undefined') ? hasMore : false; $('.stream-button, .stream-empty').css('display', 'block').hide(); + $('#stream-pagination').hide(); if (entries) { if ($('.entry').not('.fullscreen').length > 0) { $('.stream-empty').hide(); @@ -138,6 +139,10 @@ selfoss.ui = { if (hasMore) { $('.stream-more').show(); } + + if ($('#config').data('auto_stream_more') == 0) { + selfoss.ui.refreshStreamPagination(); + } } else { $('.stream-empty').show(); if (selfoss.isSmartphone()) { @@ -148,6 +153,39 @@ selfoss.ui = { }, + refreshStreamPagination: function() { + var streamPagination = $('#stream-pagination').empty(); + + var pageButtonsAmount = 5; + var count = parseInt($('.nav-filter-' + selfoss.filter.type + + ' span.count').html(), 10); + var currentPage = selfoss.filter.offset / selfoss.filter.itemsPerPage + 1; + var lastPage = count / selfoss.filter.itemsPerPage; + var maxPageDistance = pageButtonsAmount / 2; + + for (var pageNumber = 1; pageNumber <= lastPage; pageNumber++) { + var currentPageDistance = Math.abs(pageNumber - currentPage); + if (pageNumber == 1 || pageNumber == lastPage || + currentPageDistance < maxPageDistance) { + + var currentAttr = ''; + var current = ''; + if (pageNumber == currentPage) { + currentAttr = ' aria-current="true"'; + current = ' (' + selfoss.ui._('page_current') + ')'; + } + streamPagination.append('
  • '); + } else if (pageNumber == 2) { + streamPagination.append('
  • ...
  • '); + } else if (pageNumber == lastPage - 1) { + streamPagination.append('
  • ...
  • '); + } + } + + $('#stream-pagination').show(); + }, + + beforeReloadList: function(clear) { clear = (typeof clear !== 'undefined') ? clear : true; @@ -226,7 +264,7 @@ selfoss.ui = { case ',': if (placeholder) { if (state == 'index') { - placeholder.index = parseInt(buffer.trim()); + placeholder.index = parseInt(buffer.trim(), 10); placeholder.value = params[placeholder.index]; buffer = ''; } else if (state == 'type') { @@ -398,7 +436,7 @@ selfoss.ui = { var unreadCount = 0; if (diff) { if (tagsCountEl.html() != '') { - unreadCount = parseInt(tagsCountEl.html()); + unreadCount = parseInt(tagsCountEl.html(), 10); } unreadCount = unreadCount + tagCount.count; } else { @@ -420,7 +458,7 @@ selfoss.ui = { var unreadCount = 0; if (diff) { if (sourcesCountEl.html() != '') { - unreadCount = parseInt(sourcesCountEl.html()); + unreadCount = parseInt(sourcesCountEl.html(), 10); } unreadCount = unreadCount + sourceCount.count; } else { @@ -450,12 +488,12 @@ selfoss.ui = { var offlineWidget = $('span.offline-count', widget); if (offlineCounts[ck] == 'keep') { - offlineCounts[ck] = parseInt(offlineWidget.html()); + offlineCounts[ck] = parseInt(offlineWidget.html(), 10); } else { offlineWidget.html(offlineCounts[ck]); } - if (parseInt($('span.count', widget).html()) != + if (parseInt($('span.count', widget).html(), 10) != offlineCounts[ck]) { offlineWidget.addClass('diff'); } else { diff --git a/public/lang/en.json b/public/lang/en.json index 9f4c0bf921..e5d6eafaae 100644 --- a/public/lang/en.json +++ b/public/lang/en.json @@ -50,6 +50,8 @@ "lang_source_refresh": "Refresh this source", "lang_no_entries": "No entries found", "lang_more": "More", + "lang_page_current": "current", + "lang_page_goto": "Goto page {0}", "lang_login": "Log in", "lang_login_username": "Username", "lang_login_password": "Password", diff --git a/public/lang/fr.json b/public/lang/fr.json index d41529489d..95008f6a31 100644 --- a/public/lang/fr.json +++ b/public/lang/fr.json @@ -49,6 +49,8 @@ "lang_source_refresh": "Rafraîchir cette source", "lang_no_entries": "Aucun article à consulter", "lang_more": "Plus", + "lang_page_current": "celle-ci", + "lang_page_goto": "Aller à la page {0}", "lang_login": "Connexion", "lang_login_username": "Identifiant", "lang_login_password": "Mot de passe", diff --git a/templates/home.phtml b/templates/home.phtml index c3fe1d5be3..d48fc6d2d0 100644 --- a/templates/home.phtml +++ b/templates/home.phtml @@ -89,7 +89,9 @@ data-error_invalid_subsection="" data-seconds="" data-minutes="" - data-hours=""> + data-hours="" + data-page_current="" + data-page_goto=""> +