Prechádzať zdrojové kódy

Use simplified pagination system based on ordinal post number

sbkwgh 8 rokov pred
rodič
commit
8d3b208cb0
5 zmenil súbory, kde vykonal 39 pridanie a 101 odobranie
  1. 8 9
      lib/pagination.js
  2. 4 14
      models/thread.js
  3. 2 2
      routes/post.js
  4. 20 69
      routes/thread.js
  5. 5 7
      test/thread_post.js

+ 8 - 9
lib/pagination.js

@@ -32,24 +32,23 @@ async function getPreviousId(Model, where, items, limit) {
 
 
 function getPaginationProps(query) {
-	let lastId = 0
-	let previousId = null
+	let from = 0
 	let limit = 10
 
-	if(+query.lastId > 0) lastId = +query.lastId
+	if(+query.from > 0) from = +query.from
 	if(+query.limit > 0) limit = +query.limit
 
-	if(query.previousId) {
-		lastId = null
+	if(+query.postNumber > 0) {
+		let lowerFrom = +query.postNumber - Math.floor(limit / 2) + 1
 
-		if(+query.previousId > 0) {
-			previousId = +query.previousId
+		if(lowerFrom < 0) {
+			from = 0
 		} else {
-			previousId = 0
+			from = lowerFrom
 		}
 	}
 
-	return { lastId, limit, previousId }
+	return { from, limit }
 }
 
 module.exports = {

+ 4 - 14
models/thread.js

@@ -21,27 +21,17 @@ module.exports = (sequelize, DataTypes) => {
 				Thread.belongsTo(models.Category)
 				Thread.hasMany(models.Post)
 			},
-			includeOptions (lastId, limit, previousId) {
+			includeOptions (from, limit) {
 				let models = sequelize.models
 
-				let where = {}
-				let order = [['id', 'ASC']]
-
-				if(lastId !== null) {
-					where.id = { $gt: lastId }
-				} else {
-					where.id = { $lt: previousId }
-					order = [['id', 'DESC']]
-				}
-
 				return [
 					{ model: models.User, attributes: ['username', 'createdAt', 'color', 'updatedAt', 'id'] }, 
 					models.Category,
 					{ 
 						model: models.Post, 
-						where,
-						order,
-						limit: limit,
+						where: { postNumber: { $gte: from } },
+						order: [['id', 'ASC']],
+						limit,
 						include: [
 							{ model: models.Thread, attributes: ['slug'] }, 
 							{ model: models.User, attributes: ['username', 'createdAt', 'id', 'color'] }, 

+ 2 - 2
routes/post.js

@@ -75,13 +75,13 @@ router.post('/', async (req, res) => {
 			} else if(replyingToPost.Thread.id !== thread.id) {
 				throw Errors.invalidParameter('replyingToId', 'replies must be in same thread')
 			} else {
-				post = await Post.create({ content: req.body.content, postNumber: thread.postsCount+1 })
+				post = await Post.create({ content: req.body.content, postNumber: thread.postsCount })
 
 				await post.setReplyingTo(replyingToPost)
 				await replyingToPost.addReplies(post)
 			}
 		} else {
-			post = await Post.create({ content: req.body.content, postNumber: thread.postsCount+1 })
+			post = await Post.create({ content: req.body.content, postNumber: thread.postsCount })
 		}
 
 		await post.setUser(user)

+ 20 - 69
routes/thread.js

@@ -7,85 +7,36 @@ let pagination = require('../lib/pagination.js')
 
 router.get('/:thread_id', async (req, res) => {
 	try {
-		let { lastId, limit, previousId } = pagination.getPaginationProps(req.query)
+		let { from, limit } = pagination.getPaginationProps(req.query)
 		let thread, resThread
+	
+		thread = await Thread.findById(req.params.thread_id, {
+			include: Thread.includeOptions(from, limit)
+		})
 
-		if(+req.query.postId) {
-			let findObj = {
-				limit: Math.floor(limit / 2),
-				order: [['id', 'ASC']],
-				include: Post.includeOptions()
-			}
-
-			thread = await Thread.findById(req.params.thread_id, {
-				include: [
-					{ model: User, attributes: ['username', 'createdAt', 'color', 'updatedAt', 'id'] }, 
-					Category,
-				]
-			})
-			if(!thread) throw Errors.invalidParameter('id', 'thread does not exist')
-			resThread = thread.toJSON()
-
-			let postsAfter = await Post.findAll(Object.assign({}, findObj, {
-				where: {
-					id: { $gt: +req.query.postId },
-					threadId: req.params.thread_id,
-				},
-			}))
-
-			let postsBefore = await Post.findAll(Object.assign({}, findObj, {
-				where: {
-					id: { $lte: +req.query.postId },
-					threadId: req.params.thread_id,
-				},
-				order: [['id', 'DESC']],
-			}))
-
-			resThread.Posts = postsBefore
-				.concat(postsAfter)
-				.map(p => p.toJSON())
-				.sort((a, b) => a.id - b.id)
-
-		} else {
-			thread = await Thread.findById(req.params.thread_id, {
-				include: Thread.includeOptions(lastId, limit, previousId)
-			})
-
-			if(!thread) throw Errors.invalidParameter('id', 'thread does not exist')
-			resThread = thread.toJSON()
-
-			if(previousId) {
-				resThread.Posts = resThread.Posts.sort((a, b) => a.id - b.id)
-			}
-		}
+		if(!thread) throw Errors.invalidParameter('id', 'thread does not exist')
+		resThread = thread.toJSON()
 
 		resThread.meta = {}
 	
-		let nextId = await pagination.getNextId(
-			Post,
-			{ threadId: +req.params.thread_id },
-			resThread.Posts
-		)
-
-		let beforeId = await pagination.getPreviousId(
-			Post,
-			{ threadId: +req.params.thread_id },
-			resThread.Posts,
-			limit
-		)
-
-		if(nextId) {
-			resThread.meta.nextURL =
-				`/api/v1/thread/${thread.id}?limit=${limit}&lastId=${nextId}`
-		} else {
+		let lastPost = thread.Posts.slice(-1)[0]
+		let firstPost = thread.Posts[0]
+
+		if(!lastPost || lastPost.postNumber+1 === thread.postsCount) {
 			resThread.meta.nextURL = null
+		} else {
+			resThread.meta.nextURL =
+				`/api/v1/thread/${thread.id}?limit=${limit}&from=${lastPost.postNumber + 1}`
 		}
 
-		if(beforeId) {
+		if(!firstPost || firstPost.postNumber === 0) {
+			resThread.meta.previousURL = null
+		} else if(firstPost.postNumber - limit < 0) {
 			resThread.meta.previousURL =
-				`/api/v1/thread/${thread.id}?limit=${limit}&previousId=${beforeId}`
+				`/api/v1/thread/${thread.id}?limit=${firstPost.postNumber}&from=0`
 		} else {
-			resThread.meta.previousURL = null
+			resThread.meta.previousURL =
+				`/api/v1/thread/${thread.id}?limit=${limit}&from=${firstPost.postNumber - limit}`
 		}
 
 		res.json(resThread)

+ 5 - 7
test/thread_post.js

@@ -9,7 +9,6 @@ let { sequelize } = require('../models')
 
 const Errors = require('../lib/errors.js')
 let PAGINATION_THREAD_ID
-let MID_PAGINATION_POST_ID
 
 chai.use(require('chai-http'))
 chai.use(require('chai-things'))
@@ -178,7 +177,7 @@ describe('Thread and post', () => {
 			res.should.be.json
 			res.should.have.status(200)
 			res.body.should.have.property('content', '<p>content</p>\n')
-			res.body.should.have.property('postNumber', 1)
+			res.body.should.have.property('postNumber', 0)
 			res.body.should.have.deep.property('User.username', 'username')
 			res.body.should.have.deep.property('Thread.name', 'thread')
 			res.body.should.have.deep.property('Thread.postsCount', 1)
@@ -281,7 +280,7 @@ describe('Thread and post', () => {
 
 			res.should.be.json
 			res.should.have.status(200)
-			res.body.should.have.property('postNumber', 2)
+			res.body.should.have.property('postNumber', 1)
 			res.body.should.have.property('content', '<p>another post</p>\n')
 			res.body.should.have.deep.property('User.username', 'username1')
 			res.body.should.have.deep.property('Thread.name', 'thread')
@@ -391,14 +390,12 @@ describe('Thread and post', () => {
 						.set('content-type', 'application/json')
 						.send({ threadId: threadOther.body.id, content: `POST OTHER ${i}` })
 				}
-
-				if(i === 15) MID_PAGINATION_POST_ID = post.body.id
 			}
 
 			let pageOne = await userAgent.get('/api/v1/thread/' + thread.body.id)
 			let pageTwo = await userAgent.get(pageOne.body.meta.nextURL)
 			let pageThree = await userAgent.get(pageTwo.body.meta.nextURL)
-			let pageInvalid = await userAgent.get('/api/v1/thread/' + thread.body.id + '?lastId=' + 100)
+			let pageInvalid = await userAgent.get('/api/v1/thread/' + thread.body.id + '?from=' + 100)
 
 			pageOne.body.Posts.should.have.length(10)
 			pageOne.body.meta.should.have.property('previousURL', null)
@@ -418,7 +415,8 @@ describe('Thread and post', () => {
 		it('should allow you to get an individual and surrounding posts', async () => {
 			let http = chai.request(server)
 			
-			let pageOne = await http.get(`/api/v1/thread/${PAGINATION_THREAD_ID}?postId=${MID_PAGINATION_POST_ID}`)
+			let pageOne = await http.get(`/api/v1/thread/${PAGINATION_THREAD_ID}?postNumber=15`)
+
 			let pageZero = await http.get(pageOne.body.meta.previousURL)
 			let pageTwo = await http.get(pageOne.body.meta.nextURL)