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