234 lines
8 KiB
JavaScript
234 lines
8 KiB
JavaScript
|
const m = require('mithril')
|
||
|
const ApiPage = require('../api/page.p')
|
||
|
const Article = require('../api/article.p')
|
||
|
const pagination = require('../api/pagination')
|
||
|
const Authentication = require('../authentication')
|
||
|
const Newsentry = require('../widgets/newsentry')
|
||
|
const Pages = require('../widgets/pages')
|
||
|
|
||
|
const Page = {
|
||
|
oninit: function(vnode) {
|
||
|
this.error = ''
|
||
|
this.loading = false
|
||
|
this.showLoading = null
|
||
|
this.data = {
|
||
|
page: null,
|
||
|
articles: [],
|
||
|
total_articles: 0,
|
||
|
featured: null,
|
||
|
}
|
||
|
this.children = []
|
||
|
this.currentPage = Number(m.route.param('page')) || 1
|
||
|
|
||
|
if (window.__nfpdata) {
|
||
|
this.path = m.route.param('id')
|
||
|
this.data = window.__nfpdata
|
||
|
|
||
|
window.__nfpdata = null
|
||
|
window.__nfpsubdata = null
|
||
|
} else {
|
||
|
this.fetchPage(vnode)
|
||
|
}
|
||
|
},
|
||
|
|
||
|
onbeforeupdate: function(vnode) {
|
||
|
this.currentPage = Number(m.route.param('page')) || 1
|
||
|
|
||
|
if (this.path !== m.route.param('id') || this.currentPage !== this.lastpage) {
|
||
|
this.fetchPage(vnode)
|
||
|
}
|
||
|
},
|
||
|
|
||
|
fetchPage: function(vnode) {
|
||
|
this.error = ''
|
||
|
this.lastpage = this.currentPage
|
||
|
this.path = m.route.param('id')
|
||
|
|
||
|
if (this.showLoading) {
|
||
|
clearTimeout(this.showLoading)
|
||
|
}
|
||
|
|
||
|
if (this.data.page) {
|
||
|
this.showLoading = setTimeout(() => {
|
||
|
this.showLoading = null
|
||
|
this.loading = true
|
||
|
m.redraw()
|
||
|
}, 150)
|
||
|
} else {
|
||
|
this.loading = true
|
||
|
}
|
||
|
|
||
|
this.children = ApiPage.TreeMap.get(this.path)
|
||
|
this.children = this.children && this.children.children || []
|
||
|
|
||
|
ApiPage.getPage(this.path, this.lastpage)
|
||
|
.then((result) => {
|
||
|
this.data = result
|
||
|
|
||
|
if (!this.data.page) {
|
||
|
this.error = 'Page not found'
|
||
|
return
|
||
|
}
|
||
|
|
||
|
if (this.data.page.media_alt_prefix) {
|
||
|
this.data.page.pictureFallback = this.data.page.media_alt_prefix + '_small.jpg'
|
||
|
this.data.page.pictureJpeg = this.data.page.media_alt_prefix + '_small.jpg' + ' 720w, '
|
||
|
+ this.data.page.media_alt_prefix + '_medium.jpg' + ' 1300w, '
|
||
|
+ this.data.page.media_alt_prefix + '_large.jpg 1920w'
|
||
|
this.data.page.pictureAvif = this.data.page.media_alt_prefix + '_small.avif' + ' 720w, '
|
||
|
+ this.data.page.media_alt_prefix + '_medium.avif' + ' 1300w, '
|
||
|
+ this.data.page.media_alt_prefix + '_large.avif 1920w'
|
||
|
|
||
|
this.data.page.pictureCover = '(max-width: 840px) calc(100vw - 82px), '
|
||
|
+ '758px'
|
||
|
} else {
|
||
|
this.data.page.pictureFallback = null
|
||
|
this.data.page.pictureJpeg = null
|
||
|
this.data.page.pictureAvif = null
|
||
|
this.data.page.pictureCover = null
|
||
|
}
|
||
|
|
||
|
if (this.lastpage !== 1) {
|
||
|
document.title = 'Page ' + this.lastpage + ' - ' + this.data.page.name + ' - NFP Moe'
|
||
|
} else {
|
||
|
document.title = this.data.page.name + ' - NFP Moe'
|
||
|
}
|
||
|
}, (err) => {
|
||
|
this.error = err.message
|
||
|
})
|
||
|
.then(() => {
|
||
|
clearTimeout(this.showLoading)
|
||
|
this.showLoading = null
|
||
|
this.loading = false
|
||
|
m.redraw()
|
||
|
})
|
||
|
},
|
||
|
|
||
|
view: function(vnode) {
|
||
|
let page = this.data.page
|
||
|
let bannerPath = ''
|
||
|
|
||
|
return ([
|
||
|
this.loading
|
||
|
? m('article.page', m('div.loading-spinner'))
|
||
|
: null,
|
||
|
!this.loading && this.error
|
||
|
? m('div.error-wrapper', m('div.error', {
|
||
|
onclick: function() {
|
||
|
vnode.state.error = ''
|
||
|
vnode.state.fetchPage(vnode)
|
||
|
},
|
||
|
}, 'Page error: ' + this.error))
|
||
|
: null,
|
||
|
!this.loading && !this.error
|
||
|
? m('article.page', [
|
||
|
bannerPath
|
||
|
? m('.div.page-banner', { style: { 'background-image': 'url("' + bannerPath + '")' } } )
|
||
|
: null,
|
||
|
m('div.goback', ['« ', m(m.route.Link, {
|
||
|
href: page.parent_path
|
||
|
? '/page/' + page.parent_path
|
||
|
: '/'
|
||
|
}, page.parent_name || 'Home')]),
|
||
|
m('header', m('h1', page.name)),
|
||
|
m('.container', {
|
||
|
class: this.children.length ? 'multi' : '',
|
||
|
}, [
|
||
|
this.children.length
|
||
|
? m('aside.sidebar', [
|
||
|
m('h4', 'View ' + page.name + ':'),
|
||
|
this.children.map(function(page) {
|
||
|
return m(m.route.Link, { href: '/page/' + page.path }, page.name)
|
||
|
}),
|
||
|
])
|
||
|
: null,
|
||
|
page.content
|
||
|
? m('.fr-view', [
|
||
|
page.pictureFallback
|
||
|
? m('a.cover', {
|
||
|
rel: 'noopener',
|
||
|
href: page.media_path,
|
||
|
}, [
|
||
|
m('picture', [
|
||
|
m('source', {
|
||
|
srcset: page.pictureAvif,
|
||
|
sizes: page.pictureCover,
|
||
|
type: 'image/avif',
|
||
|
}),
|
||
|
m('img', {
|
||
|
srcset: page.pictureJpeg,
|
||
|
sizes: page.pictureCover,
|
||
|
alt: 'Image for news item ' + page.name,
|
||
|
src: page.pictureFallback,
|
||
|
}),
|
||
|
]),
|
||
|
])
|
||
|
: null,
|
||
|
page.content.blocks.map(block => {
|
||
|
return m(EditorBlock, { block: block })
|
||
|
}),
|
||
|
this.data.articles.length && page.content
|
||
|
? m('aside.news', [
|
||
|
m('h4', 'Latest posts under ' + page.name + ':'),
|
||
|
this.data.articles.map(function(article) {
|
||
|
return m(Newsentry, { article: article })
|
||
|
}),
|
||
|
m(Pages, {
|
||
|
base: '/page/' + page.path,
|
||
|
total: this.data.total_articles,
|
||
|
page: this.currentPage,
|
||
|
}),
|
||
|
])
|
||
|
: null,
|
||
|
])
|
||
|
: this.data.articles.length
|
||
|
? m('aside.news.single',
|
||
|
[
|
||
|
page.pictureFallback
|
||
|
? m('a', {
|
||
|
rel: 'noopener',
|
||
|
href: page.media_path,
|
||
|
}, [
|
||
|
m('picture.page-cover', [
|
||
|
m('source', {
|
||
|
srcset: page.pictureAvif,
|
||
|
sizes: page.pictureCover,
|
||
|
type: 'image/avif',
|
||
|
}),
|
||
|
m('img', {
|
||
|
srcset: page.pictureJpeg,
|
||
|
sizes: page.pictureCover,
|
||
|
alt: 'Cover image for ' + page.name,
|
||
|
src: page.pictureFallback,
|
||
|
}),
|
||
|
]),
|
||
|
])
|
||
|
: null,
|
||
|
m('h4', 'Latest posts under ' + page.name + ':'),
|
||
|
this.data.articles.map(function(article) {
|
||
|
return m(Newsentry, { article: article })
|
||
|
}),
|
||
|
m(Pages, {
|
||
|
base: '/page/' + page.path,
|
||
|
total: this.data.total_articles,
|
||
|
page: this.currentPage,
|
||
|
}),
|
||
|
])
|
||
|
: page.media
|
||
|
? m('img.page-cover.single', { src: page.media.medium_url, alt: 'Cover image for ' + page.name } )
|
||
|
: null,
|
||
|
]),
|
||
|
Authentication.currentUser
|
||
|
? m('div.admin-actions', [
|
||
|
m('span', 'Admin controls:'),
|
||
|
m(m.route.Link, { href: '/admin/pages/' + page.path }, 'Edit page'),
|
||
|
])
|
||
|
: null,
|
||
|
])
|
||
|
: null,
|
||
|
])
|
||
|
},
|
||
|
}
|
||
|
|
||
|
module.exports = Page
|