simple feed functionality

This commit is contained in:
Daniel Lugo 2020-06-27 18:25:32 -04:00
parent 75aeb7af42
commit 3c72432dce
3 changed files with 109 additions and 0 deletions

View file

@ -0,0 +1,64 @@
/**
* @format
*/
const Common = require('shock-common')
const isFinite = require('lodash/isFinite')
const shuffle = require('lodash/shuffle')
const R = require('ramda')
const Follows = require('./follows')
const Wall = require('./wall')
/**
* @param {number} page
* @throws {TypeError}
* @throws {RangeError}
* @returns {Promise<Common.SchemaTypes.Post[]>}
*/
const getFeedPage = async page => {
if (!isFinite(page)) {
throw new TypeError(`Please provide an actual number for [page]`)
}
if (page <= 0) {
throw new RangeError(`Please provide only positive numbers for [page]`)
}
const subbedPublicKeys = Object.values(await Follows.currentFollows()).map(
f => f.user
)
if (subbedPublicKeys.length === 0) {
return []
}
// say there are 20 public keys total
// page 1: page 1 from first 10 public keys
// page 2: page 1 from second 10 public keys
// page 3: page 2 from first 10 public keys
// page 4: page 2 from first 10 public keys
// etc
const pagedPublicKeys = R.splitEvery(10, shuffle(subbedPublicKeys))
if (pagedPublicKeys.length === 1) {
const [publicKeys] = pagedPublicKeys
const fetchedPages = await Promise.all(
publicKeys.map(pk => Wall.getWallPage(page, pk))
)
const allPosts = fetchedPages.map(fp => Object.values(fp.posts))
const posts = R.flatten(allPosts)
// @ts-ignore
const sorted = R.sortBy((a, b) => b.date - a.date, posts)
return sorted
}
return []
}
module.exports = {
getFeedPage
}

View file

@ -7,6 +7,7 @@ const Key = require('../key')
const Utils = require('../utils')
const Wall = require('./wall')
const Feed = require('./feed')
/**
* @param {string} pub
@ -94,3 +95,5 @@ module.exports.Follows = require('./follows')
module.exports.getWallPage = Wall.getWallPage
module.exports.getWallTotalPages = Wall.getWallTotalPages
module.exports.getFeedPage = Feed.getFeedPage

View file

@ -1971,6 +1971,48 @@ module.exports = async (
ap.put(`/api/gun/follows/:publicKey`,apiGunFollowsPut)
ap.delete(`/api/gun/follows/:publicKey`, apiGunFollowsDelete)
/**
* @type {RequestHandler<{}>}
*/
const apiGunFeedGet = async (req, res) => {
try {
const { page } = req.query;
if (!isFinite(page)) {
return res.json(401).json({
field: page,
errorMessage: 'page must be a number'
})
}
if (!isFinite(page)) {
return res.json(400).json({
field: page,
errorMessage: 'page must be a number'
})
}
if (page < 1) {
return res.json(400).json({
field: page,
errorMessage: 'page must be a positive number'
})
}
return res.status(200).json({
posts: await GunGetters.getFeedPage(page)
})
} catch (err) {
return res.status(500).json({
errorMessage: err.message || 'Unknown error inside /api/gun/follows/'
})
}
}
ap.get(`/api/gun/feed`, apiGunFeedGet)
/**
* Return app so that it can be used by express.
*/