forked from kaverti/website
133 lines
3.0 KiB
JavaScript
133 lines
3.0 KiB
JavaScript
let urlSlug = require('url-slug')
|
|
const { Op } = require("sequelize");
|
|
|
|
module.exports = (sequelize, DataTypes) => {
|
|
let Thread = sequelize.define('Thread', {
|
|
title: {
|
|
type: DataTypes.TEXT,
|
|
set (val) {
|
|
this.setDataValue('name', val)
|
|
if(val) {
|
|
this.setDataValue(
|
|
'slug',
|
|
//if you don't covert to lowercase it doesn't
|
|
//correctly slugify diacritics, e.g. thrËad
|
|
//becomes 'thr-ead' not 'thread'
|
|
urlSlug(val.toString().toLowerCase() || '') || '_'
|
|
)
|
|
}
|
|
},
|
|
allowNull: false,
|
|
validate: {
|
|
notEmpty: {
|
|
msg: 'Did you forget something?'
|
|
},
|
|
len: {
|
|
args: [4, 50],
|
|
msg: 'The title must be between 4 and 50 characters'
|
|
},
|
|
isString (val) {
|
|
if(typeof val !== 'string') {
|
|
throw new sequelize.ValidationError('The title must be a string')
|
|
}
|
|
}
|
|
}
|
|
},
|
|
content: DataTypes.TEXT,
|
|
replies: {
|
|
type: DataTypes.BIGINT,
|
|
defaultValue: 0
|
|
},
|
|
views: {
|
|
type: DataTypes.BIGINT
|
|
},
|
|
locked: {
|
|
type: DataTypes.BOOLEAN,
|
|
defaultValue: false
|
|
},
|
|
pages: {
|
|
type: DataTypes.BIGINT
|
|
},
|
|
messages: {
|
|
type: DataTypes.BIGINT
|
|
}
|
|
})
|
|
Thread.associate = function (models) {
|
|
Thread.belongsTo(models.User)
|
|
Thread.belongsTo(models.Category)
|
|
Thread.hasMany(models.Post, { foreignKeyConstraint: true, onDelete: 'CASCADE' })
|
|
}
|
|
Thread.includeOptions = function (from, limit) {
|
|
let models = sequelize.models
|
|
|
|
return [
|
|
{ model: models.User, attributes: ['username', 'createdAt'] },
|
|
models.Category,
|
|
{
|
|
model: models.Post,
|
|
where: { postNumber: { [Op.gte]: from } },
|
|
order: [['id', 'ASC']],
|
|
limit,
|
|
include: [
|
|
{ model: models.User, attributes: ['username', 'createdAt'] }
|
|
]
|
|
}
|
|
]
|
|
}
|
|
Thread.prototype.getMeta = function (limit) {
|
|
let meta = {}
|
|
|
|
let posts = this.Posts
|
|
let firstPost = posts[0]
|
|
let lastPost = posts.slice(-1)[0]
|
|
|
|
//next url
|
|
if(!lastPost || lastPost.postNumber+1 === this.postsCount) {
|
|
meta.nextURL = null
|
|
} else {
|
|
meta.nextURL =
|
|
`/api/v1/forums/thread/${this.id}?limit=${limit}&from=${lastPost.postNumber + 1}`
|
|
}
|
|
|
|
//previous url
|
|
if(!firstPost || firstPost.postNumber === 0) {
|
|
meta.previousURL = null
|
|
} else if(firstPost.postNumber - limit < 0) {
|
|
meta.previousURL =
|
|
`/api/v1/forums/thread/${this.id}?limit=${firstPost.postNumber}&from=0`
|
|
} else {
|
|
meta.previousURL =
|
|
`/api/v1/forums/thread/${this.id}?limit=${limit}&from=${firstPost.postNumber - limit}`
|
|
}
|
|
|
|
//remaining posts
|
|
if(lastPost === undefined) {
|
|
meta.nextPostsCount = 0
|
|
meta.previousPostsCount = 0
|
|
meta.postsRemaining = 0
|
|
} else {
|
|
let postsRemaining =
|
|
this.postsCount - lastPost.postNumber - 1
|
|
|
|
meta.postsRemaining = postsRemaining
|
|
|
|
if(postsRemaining < limit) {
|
|
meta.nextPostsCount = postsRemaining
|
|
} else {
|
|
meta.nextPostsCount = limit
|
|
}
|
|
|
|
if(firstPost.postNumber === 0) {
|
|
meta.previousPostsCount = 0
|
|
} else if(firstPost.postNumber - limit < 0) {
|
|
meta.previousPostsCount = firstPost.postNumber
|
|
} else {
|
|
meta.previousPostsCount = limit
|
|
}
|
|
}
|
|
|
|
return meta
|
|
}
|
|
return Thread
|
|
}
|