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