forked from sam/fedifeed
add infinite-scroll, and strictly follow boost and reply options
This commit is contained in:
parent
71edc0a4e5
commit
98d2192463
9 changed files with 3216 additions and 26 deletions
4
index.js
4
index.js
|
@ -55,7 +55,7 @@ app.get('/api/feed',function(req,res){
|
|||
opts.boosts = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
opts.replies = true;
|
||||
if (req.query.replies){
|
||||
if (req.query.replies.toLowerCase() == 'no' || req.query.replies.toLowerCase() == 'false'){
|
||||
|
@ -64,6 +64,8 @@ app.get('/api/feed',function(req,res){
|
|||
opts.replies = true;
|
||||
}
|
||||
}
|
||||
opts.feedUrl = feedUrl;
|
||||
opts.mastofeedUrl = req.url;
|
||||
|
||||
var req = request.get(feedUrl);
|
||||
convert(req,opts,function(er,data){
|
||||
|
|
|
@ -180,7 +180,37 @@ function buildUp(jsonObj,opts){
|
|||
item.cw = item.summary;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// get a pagination ID for an entry
|
||||
item.paginationId = false;
|
||||
if (item['atom:link']){
|
||||
var links = item['atom:link'];
|
||||
if (!isArray(links) && typeof links == 'object'){
|
||||
links = [links];
|
||||
}else if (!isArray(links)){
|
||||
links = [];
|
||||
}
|
||||
links.forEach((link)=>{
|
||||
if (!link['@']){return}
|
||||
if (link['@']['rel']=='self'){
|
||||
// parse out the pagination id
|
||||
// href looks like this in mastodon: https://octodon.social/users/fenwick67/updates/732275.atom
|
||||
// href looks like this in pleroma (and we should ignore): https://social.fenwick.pizza/objects/1e2fa906-378c-43f8-98fa-271aae455758
|
||||
var href = link['@']['href'];
|
||||
if (!href){return}
|
||||
var match = href.match(/\/\d+.atom/);
|
||||
if(!match){return}
|
||||
var id = match[0].replace(/\D/g,'');
|
||||
if (id){
|
||||
item.paginationId = id;
|
||||
}else{
|
||||
return;
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
});
|
||||
|
@ -197,9 +227,51 @@ function buildUp(jsonObj,opts){
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
// get next page
|
||||
jsonObj.feedUrl = opts.feedUrl;
|
||||
jsonObj.isIndex = (opts.feedUrl.indexOf('?') == -1);
|
||||
|
||||
// prefer link(rel=next)
|
||||
var nextPageFeedUrl = '';
|
||||
var links = jsonObj.meta['atom:link'];
|
||||
if (links){
|
||||
if (!isArray(links) && typeof links == 'object'){
|
||||
links = [links];
|
||||
}else if (!isArray(links)){
|
||||
links = [];
|
||||
}
|
||||
links.forEach(function(link){
|
||||
if (link['@'] && link['@']['rel'] == 'next' && link['@']['href']){
|
||||
nextPageFeedUrl = link['@']['href'];
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (!nextPageFeedUrl){
|
||||
// alternative: try to get the oldest entry id on this page
|
||||
var lowestId = Infinity;
|
||||
jsonObj.items.forEach(function(item){
|
||||
var id = Number(item.paginationId);
|
||||
if ( id < lowestId ){
|
||||
lowestId = id;
|
||||
}
|
||||
});
|
||||
|
||||
if (lowestId < Infinity && opts.feedUrl){
|
||||
nextPageFeedUrl = opts.feedUrl.replace(/\?.+/g,'') + '?max_id='+lowestId;
|
||||
}
|
||||
}
|
||||
|
||||
if(nextPageFeedUrl){
|
||||
jsonObj.nextPageLink = opts.mastofeedUrl.replace(encodeURIComponent(opts.feedUrl),encodeURIComponent(nextPageFeedUrl));
|
||||
console.log(jsonObj.nextPageLink);
|
||||
}
|
||||
return template(jsonObj);
|
||||
}
|
||||
|
||||
// utilities below
|
||||
|
||||
|
||||
// get obj[key]['#'] or ''
|
||||
function getH(obj,key){
|
||||
|
|
|
@ -37,12 +37,10 @@
|
|||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
|
||||
<div class="container">
|
||||
|
||||
<% var filtered = items.filter(function(item){return !((item.isBoost && !opts.boosts) || (item.isReply && !opts.replies)) })%>
|
||||
<% if (filtered.length < 2){
|
||||
filtered = items;// show all items if it was pared down too much
|
||||
} %>
|
||||
<% filtered.forEach(function(item){ %>
|
||||
<div class="item">
|
||||
<% if (item.isBoost) { %>
|
||||
|
@ -78,7 +76,48 @@
|
|||
<div class="date"><%= item.stringDate %></div>
|
||||
</div>
|
||||
<% }); %>
|
||||
<% if (nextPageLink) %>
|
||||
<div class="item hidden">
|
||||
<a class="hacky_link" href="<%- nextPageLink %>">More</a>
|
||||
</div>
|
||||
<% %>
|
||||
</div> <!-- end item container -->
|
||||
<div class="pagination">
|
||||
<a class="button" href="<%- nextPageLink %>">Load More</a>
|
||||
</div>
|
||||
|
||||
<% if ( isIndex ){ %>
|
||||
<script src="/infinite-scroll.js"></script>
|
||||
<script type="text/javascript">
|
||||
|
||||
var lastPageLoaded = null;
|
||||
var infScroll = new InfiniteScroll( '.container', {
|
||||
// options
|
||||
hideNav:'.pagination',
|
||||
append: '.item',
|
||||
history:false,
|
||||
prefill:true,
|
||||
path: function(){
|
||||
// need to query this DOM my damn self
|
||||
var pageLinks = document.querySelectorAll('.hacky_link');
|
||||
if (!pageLinks || pageLinks.length == 0){
|
||||
console.log ('next page link could not be found');
|
||||
return false;
|
||||
}else{
|
||||
var finalLink = pageLinks[pageLinks.length-1].href;
|
||||
// make sure we don't load the same page twice
|
||||
if (finalLink == lastPageLoaded){
|
||||
console.log('this was the last page');
|
||||
return false;
|
||||
}else{
|
||||
return finalLink;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<% } %>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
|
3020
package-lock.json
generated
Normal file
3020
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
42
package.json
42
package.json
|
@ -1,21 +1,21 @@
|
|||
{
|
||||
"dependencies": {
|
||||
"ejs": "^2.5.6",
|
||||
"express": "^4.15.2",
|
||||
"feedparser": "^2.2.0",
|
||||
"request": "^2.81.0",
|
||||
"serve-static": "^1.12.2",
|
||||
"timeago.js": "^3.0.1",
|
||||
"pug":"2.0.0-rc.3"
|
||||
},
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"start": "node index.js",
|
||||
"build-styles": "node build-styles.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"metalsmith": "^2.3.0",
|
||||
"metalsmith-sass": "^1.4.0",
|
||||
"node-sass": "^4.5.2"
|
||||
}
|
||||
}
|
||||
{
|
||||
"dependencies": {
|
||||
"ejs": "^2.5.6",
|
||||
"express": "^4.15.2",
|
||||
"feedparser": "^2.2.0",
|
||||
"request": "^2.81.0",
|
||||
"serve-static": "^1.12.2",
|
||||
"timeago.js": "^3.0.1",
|
||||
"pug": "2.0.0-rc.3"
|
||||
},
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"start": "node index.js",
|
||||
"build-styles": "node build-styles.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"metalsmith": "^2.3.0",
|
||||
"metalsmith-sass": "^1.4.0",
|
||||
"node-sass": "^4.9.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ a * {
|
|||
position: relative;
|
||||
top: calc(50% - 3rem); }
|
||||
.header .header-right {
|
||||
flex-grow: 1;
|
||||
font-size: 0.9rem;
|
||||
padding: 0.9rem;
|
||||
background: rgba(40, 44, 55, 0.85); }
|
||||
|
@ -110,3 +111,17 @@ a * {
|
|||
|
||||
.meta .title {
|
||||
font-weight: bold; }
|
||||
|
||||
.hidden {
|
||||
display: none; }
|
||||
|
||||
.button {
|
||||
padding: 0.5rem 1rem;
|
||||
border: none;
|
||||
margin: 1rem;
|
||||
border-radius: 0.5rem;
|
||||
display: inline-block;
|
||||
text-decoration: none;
|
||||
background: #2b90d9;
|
||||
color: #ffffff;
|
||||
font-weight: 400; }
|
||||
|
|
12
static/infinite-scroll.js
Normal file
12
static/infinite-scroll.js
Normal file
File diff suppressed because one or more lines are too long
|
@ -36,6 +36,7 @@ a * {
|
|||
position: relative;
|
||||
top: calc(50% - 3rem); }
|
||||
.header .header-right {
|
||||
flex-grow: 1;
|
||||
font-size: 0.9rem;
|
||||
padding: 0.9rem;
|
||||
background: rgba(255, 255, 255, 0.85); }
|
||||
|
@ -111,6 +112,20 @@ a * {
|
|||
.meta .title {
|
||||
font-weight: bold; }
|
||||
|
||||
.hidden {
|
||||
display: none; }
|
||||
|
||||
.button {
|
||||
padding: 0.5rem 1rem;
|
||||
border: none;
|
||||
margin: 1rem;
|
||||
border-radius: 0.5rem;
|
||||
display: inline-block;
|
||||
text-decoration: none;
|
||||
background: #2b90d9;
|
||||
color: #282c37;
|
||||
font-weight: 400; }
|
||||
|
||||
.item-content,
|
||||
.description,
|
||||
.title,
|
||||
|
|
|
@ -51,6 +51,7 @@ a * {
|
|||
}
|
||||
}
|
||||
.header-right{
|
||||
flex-grow:1;
|
||||
font-size:0.9rem;
|
||||
padding:0.9rem;
|
||||
background:transparentize($bg,0.15);
|
||||
|
@ -140,3 +141,17 @@ a * {
|
|||
.meta .title{
|
||||
font-weight:bold;
|
||||
}
|
||||
.hidden{
|
||||
display:none;
|
||||
}
|
||||
.button{
|
||||
padding: 0.5rem 1rem;
|
||||
border: none;
|
||||
margin: 1rem;
|
||||
border-radius: 0.5rem;
|
||||
display: inline-block;
|
||||
text-decoration: none;
|
||||
background:$link;
|
||||
color:$fg;
|
||||
font-weight:400;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue