diff --git a/src/render/articles.js b/src/render/articles.js index bfd5a658..0b2bdecd 100644 --- a/src/render/articles.js +++ b/src/render/articles.js @@ -1,6 +1,8 @@ const React = require('react') const Article = require('../core/Article') +const ArticleComponent = require('../components/Article') const ArticleCardList = require('../components/ArticleCardList') +const {render} = require('../lib/render') const timestamp = require('../lib/date').timestamp const ImageArtifactType = require('../core/ImageArtifactType') const {sortBy} = require('../utils/sort') @@ -9,6 +11,32 @@ const sortArticleByDate = sortBy( x => timestamp(new Date(x.date)) ) +function getMeta(article) { + const types = [ + ImageArtifactType.FACEBOOK, + ImageArtifactType.MEDIUM, + ImageArtifactType.BIG, + ImageArtifactType.ORIGIN, + ] + const meta = { + title: article.title, + } + + if (article.preview) { + try { + const artifact = article.preview.findArtifact(types) + meta.image = artifact.url + meta.imageWidth = artifact.width + meta.imageHeight = artifact.height + } catch (error) { + meta.image = 'https://art.shlisselburg.org/entrance.jpg' + meta.imageWidth = 1200 + meta.imageHeight = 630 + } + } + return meta +} + async function findArticlesNin(nin, skip, limit, sort) { const query = { _id: {$nin: nin} @@ -65,4 +93,36 @@ async function createArticleCardList(page, pageSize) { ) } +async function renderArticles(path, page, pageSize) { + const articles = await createArticleCardList(page, pageSize) + + const Component = ( +
+ {articles} +
+ ) + + return render(path, Component, getMeta({title: `Статьи`})) +} + +async function renderArticle(id) { + const article = await Article.findById(id) + if (!article) return null + + const Component = ( +
+ +
+ ) + + return render(article.url, Component, getMeta(article), {commentsEnabled: true}) +} + exports.createArticleCardList = createArticleCardList +exports.renderArticles = renderArticles +exports.renderArticle = renderArticle diff --git a/src/routes/articles.js b/src/routes/articles.js index 32f6f8e6..081608cf 100644 --- a/src/routes/articles.js +++ b/src/routes/articles.js @@ -1,120 +1,9 @@ -const React = require('react') const {get} = require('koa-route') -const {c} = require('../core/db') const Article = require('../components/Article') -const ArticleList = require('../components/ArticleList') -const Paginator = require('../components/Paginator') -const {render} = require('../lib/render') +const {renderArticles, renderArticle} = require('../render/articles') const getPathWithNoTrailingSlash = require('../lib/url').getPathWithNoTrailingSlash -const timestamp = require('../lib/date').timestamp -const ImageArtifactType = require('../core/ImageArtifactType') -const Image = require('../core/Image') -const {sortBy} = require('../utils/sort') const accepts = require('./index').accepts -const sortArticleByDate = sortBy( - i => timestamp(new Date(i.date)) -) - -const articleUrl = article => `/article/${article.id}` - -async function findArticle(id) { - return c('articles').findOne({id: id}) -} - -async function findArticlesNin(nin, skip, limit, sort) { - return c('articles') - .find({ - _id: {$nin: nin} - }) - .sort(sort) - .skip(skip) - .limit(limit) - .toArray() -} - -async function totalArticles() { - return c('articles') - .find({}) - .count() -} - -async function findPinned(page) { - const now = new Date() - return page !== 1 - ? [] - : await c('articles') - .find({until: {$gte: now}}) - .sort({date: -1}) - .toArray() -} - -async function getArticleListComponent(path, page, pageSize) { - path = getPathWithNoTrailingSlash(path) - - const limit = pageSize - const skip = (page - 1) * pageSize - - const pinnedArticles = await findPinned(page) - const total = await totalArticles() - const totalPages = total / pageSize - - const id = i => i._id - const pinnedIds = pinnedArticles.map(id) - const articles = await findArticlesNin(pinnedIds, skip, limit, {date: -1}) - - const prevPage = page > 1 - ? page - 1 - : null - - const nextPage = page < totalPages - ? page + 1 - : null - - const content = [ - ...pinnedArticles.sort(sortArticleByDate), - ...articles - ] - .map(article => ({ - ...article, - url: articleUrl(article), - })) - - return ( - - ) -} - -function getMeta(article) { - const types = [ - ImageArtifactType.FACEBOOK, - ImageArtifactType.MEDIUM, - ImageArtifactType.BIG, - ImageArtifactType.ORIGIN, - ] - const meta = { - title: article.title, - } - - if (article.preview) { - try { - const artifact = article.preview.findArtifact(types) - meta.image = artifact.url - meta.imageWidth = artifact.width - meta.imageHeight = artifact.height - } catch (error) { - meta.image = 'https://art.shlisselburg.org/entrance.jpg' - meta.imageWidth = 1200 - meta.imageHeight = 630 - } - } - return meta -} - function getArticles(pageSize) { return get('/articles/:page?', async (ctx, page) => { page = parseInt(page) || 1 @@ -124,14 +13,7 @@ function getArticles(pageSize) { } else { const path = getPathWithNoTrailingSlash(ctx.path) - const articles = await getArticleListComponent(path, page, pageSize) - const Component = ( -
- {articles} -
- ) - - ctx.body = await render(path, Component, getMeta({title: `Статьи`})) + ctx.body = await renderArticles(path, page, pageSize) } }) } @@ -139,34 +21,17 @@ function getArticles(pageSize) { function getArticle() { return get('/article/:id', accepts({ 'text/html': async (ctx, id) => { - const path = getPathWithNoTrailingSlash(ctx.path) - const article = await findArticle(id) - - if (article) { - const previewId = article.preview - ? article.preview - : article.images[0] - article.preview = await Image.findById(previewId) - - const Component = ( -
-
-
- ) + const body = await renderArticle(id) + if (body) { ctx.type = 'text/html' - ctx.body = await render(path, Component, getMeta(article), {commentsEnabled: true}) + ctx.body = body } else { ctx.status = 404 } }, 'application/json': async (ctx, id) => { - const article = await findArticle(id) + const article = await Article.findById(id) if (article) { ctx.body = article @@ -177,6 +42,5 @@ function getArticle() { })) } -exports.getArticleListComponent = getArticleListComponent exports.getArticles = getArticles exports.getArticle = getArticle