Jonatan Nilsson
6565409e52
nfp_moe: Complete re-thinking of all loading. Smarter loading and lighter site. Better user experience among other things.
326 lines
11 KiB
JavaScript
326 lines
11 KiB
JavaScript
const m = require('mithril')
|
|
const api = require('./api')
|
|
const PageTree = require('./page_tree')
|
|
const Paginator = require('./paginator')
|
|
// const Authentication = require('./authentication')
|
|
const Article = require('./article')
|
|
const Articleslim = require('./article_slim')
|
|
const media = require('./media')
|
|
const EditorBlock = require('./editorblock')
|
|
const NotFoundView = require('./site_404')
|
|
|
|
const ArticlesPerPage = 10
|
|
|
|
const SitePage = {
|
|
oninit: function(vnode) {
|
|
this.error = ''
|
|
this.loading = false
|
|
this.treePage = null
|
|
this.data = {
|
|
page: null,
|
|
articles: [],
|
|
total_articles: 0,
|
|
featured: null,
|
|
}
|
|
this.picture = null
|
|
this.children = []
|
|
this.currentPage = Number(m.route.param('page')) || 1
|
|
|
|
if (window.__nfpdata) {
|
|
this.path = m.route.param('id')
|
|
this.lastpage = this.currentPage
|
|
|
|
this.data = window.__nfpdata
|
|
window.__nfpdata = null
|
|
|
|
this.children = PageTree.Tree
|
|
if (this.path) {
|
|
this.children = PageTree.TreeMap.get(this.path)
|
|
this.children = this.children && this.children.children || []
|
|
}
|
|
this.afterData()
|
|
} 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')
|
|
|
|
this.loading = true
|
|
|
|
if (this.path) {
|
|
this.treePage = PageTree.TreeMap.get(this.path)
|
|
this.children = this.treePage && this.treePage.children || []
|
|
} else {
|
|
this.treePage = { has_banner: true, has_media: true }
|
|
this.children = PageTree.Tree
|
|
}
|
|
|
|
api.sendRequest({
|
|
method: 'GET',
|
|
url: '/api/' + (this.path ? 'pages/' + this.path : 'frontpage') + '?page=' + (this.lastpage || 1),
|
|
})
|
|
.then((result) => {
|
|
this.data = result
|
|
this.afterData()
|
|
}, (err) => {
|
|
this.error = err.message
|
|
})
|
|
.then(() => {
|
|
this.loading = false
|
|
m.redraw()
|
|
})
|
|
},
|
|
|
|
afterData: function() {
|
|
if (!this.data.page && this.path) {
|
|
this.error = 'Page not found'
|
|
return
|
|
}
|
|
|
|
let title = 'Page not found - NFP Moe - Anime/Manga translation group'
|
|
if (this.data.page) {
|
|
title = this.data.page.name + ' - NFP Moe'
|
|
} else if (!this.path) {
|
|
title = 'NFP Moe - Anime/Manga translation group'
|
|
}
|
|
|
|
this.picture = media.generatePictureSource(this.data.page,
|
|
'(max-width: 1280px) calc(100vw - 2rem), '
|
|
+ '1248px')
|
|
|
|
if (this.lastpage !== 1) {
|
|
document.title = 'Page ' + this.lastpage + ' - ' + title
|
|
} else {
|
|
document.title = title
|
|
}
|
|
},
|
|
|
|
view: function(vnode) {
|
|
let page = this.data.page
|
|
let featuredBanner = media.getBannerImage(this.data.featured, '/article/')
|
|
let pageBanner = media.getBannerImage(this.data.page, '/page/')
|
|
|
|
return ([
|
|
this.loading
|
|
? [
|
|
this.treePage.has_banner
|
|
? m('div.page-banner.lb')
|
|
: null,
|
|
this.path
|
|
? m('div.inside.vertical', [
|
|
m('div.actions', m('div.lb-link')),
|
|
m('h2.title', m('div.lb-main.lb--long')),
|
|
])
|
|
: null,
|
|
m('div.inside', [
|
|
this.children.length
|
|
? m('aside', [
|
|
m('h5', m('div.lb-main')),
|
|
m('div.lb-link'),
|
|
m('ul', [
|
|
m('li', m('div.lb-link')),
|
|
m('li', m('div.lb-link')),
|
|
m('li', m('div.lb-link')),
|
|
]),
|
|
m('div.lb-link'),
|
|
m('ul', [
|
|
m('li', m('div.lb-link')),
|
|
m('li', m('div.lb-link')),
|
|
m('li', m('div.lb-link')),
|
|
]),
|
|
])
|
|
: null,
|
|
!this.path
|
|
? m('div.container', [
|
|
m('article', [
|
|
m('h2.title', m('div.lb-main.lb--long')),
|
|
m('div.row', [
|
|
m('div.lb-main.lb--imgmini'),
|
|
m('div', [
|
|
m('div', m.trust(' ')),
|
|
m('div.lb-main.lb--long'),
|
|
m('div.lb-main'),
|
|
m('div.lb-main.lb--medium'),
|
|
m('div.lb-main.lb--medium'),
|
|
m('div.lb-main'),
|
|
]),
|
|
]),
|
|
]),
|
|
m('article', [
|
|
m('h2.title', m('div.lb-main.lb--long')),
|
|
m('div.row', [
|
|
m('div.lb-main.lb--imgmini'),
|
|
m('div', [
|
|
m('div', m.trust(' ')),
|
|
m('div.lb-main.lb--long'),
|
|
m('div.lb-main'),
|
|
m('div.lb-main.lb--medium'),
|
|
m('div.lb-main.lb--medium'),
|
|
m('div.lb-main'),
|
|
]),
|
|
]),
|
|
]),
|
|
])
|
|
: null,
|
|
this.path
|
|
? m('div.container', [
|
|
this.treePage.has_media
|
|
? m('div.cover', m('picture.lb.nobg'))
|
|
: null,
|
|
m('h5', m('div.lb-main.lb--long')),
|
|
m('articleslim', [
|
|
m('a.cover.nobg.lb'),
|
|
m('div', [
|
|
m('div', m('div.lb-link.lb--long')),
|
|
m('div.lb-main.lb--longest.lb--slim'),
|
|
]),
|
|
]),
|
|
m('articleslim', [
|
|
m('a.cover.nobg.lb'),
|
|
m('div', [
|
|
m('div', m('div.lb-link.lb--long')),
|
|
m('div.lb-main.lb--longest.lb--slim'),
|
|
]),
|
|
]),
|
|
m('articleslim', [
|
|
m('a.cover.nobg.lb'),
|
|
m('div', [
|
|
m('div', m('div.lb-link.lb--long')),
|
|
m('div.lb-main.lb--longest.lb--slim'),
|
|
]),
|
|
]),
|
|
m('articleslim', [
|
|
m('a.cover.nobg.lb'),
|
|
m('div', [
|
|
m('div', m('div.lb-link.lb--long')),
|
|
m('div.lb-main.lb--longest.lb--slim'),
|
|
]),
|
|
]),
|
|
])
|
|
: null,
|
|
]),
|
|
]
|
|
: [
|
|
this.error === 'Page not found'
|
|
? NotFoundView.view()
|
|
: null,
|
|
this.error && this.error !== 'Page not found'
|
|
? m('div.wrapper', m('div.error', {
|
|
onclick: () => {
|
|
this.error = ''
|
|
this.fetchPage(vnode)
|
|
},
|
|
}, 'Page error: ' + this.error + '. Click here to try again'))
|
|
: null,
|
|
(featuredBanner
|
|
? m(m.route.Link, {
|
|
class: 'page-banner',
|
|
href: featuredBanner.path,
|
|
style: { 'background-image': 'url("' + featuredBanner.preview + '")' },
|
|
}, [
|
|
m('div.page-banner-real', {
|
|
style: { 'background-image': 'url("' + featuredBanner.banner + '")' },
|
|
}, m('div.inside', m('div.page-banner-title', featuredBanner.name))),
|
|
]
|
|
)
|
|
: null),
|
|
(!featuredBanner && pageBanner
|
|
? m('a.page-banner', {
|
|
href: pageBanner.original,
|
|
target: '_blank',
|
|
style: { 'background-image': 'url("' + pageBanner.preview + '")' },
|
|
},
|
|
m('div.page-banner-real', {
|
|
style: { 'background-image': 'url("' + pageBanner.banner + '")' },
|
|
})
|
|
)
|
|
: null),
|
|
(page
|
|
? m('.inside.vertical', [
|
|
m('div.actions', [
|
|
'« ',
|
|
m(m.route.Link, {
|
|
href: page.parent_path
|
|
? '/page/' + page.parent_path
|
|
: '/'
|
|
}, page.parent_name || 'Home'),
|
|
Authentication.currentUser
|
|
? [
|
|
m('div.filler'),
|
|
'Actions:',
|
|
m(m.route.Link, { href: '/admin/pages/' + page.id }, 'Edit page'),
|
|
]
|
|
: null,
|
|
]),
|
|
m('h2.title', page.name)
|
|
])
|
|
: null),
|
|
(page || this.data.articles.length
|
|
? m('.inside', [
|
|
this.children.length
|
|
? m('aside', { class: page ? '' : 'frontpage' }, [
|
|
m('h5', page ? 'View ' + page.name + ':' : 'Categories'),
|
|
this.children.map((page) => {
|
|
return [
|
|
m(m.route.Link, { class: 'root', href: '/page/' + page.path }, page.name),
|
|
(page.children && page.children.length
|
|
? m('ul', page.children.map(function(subpage) {
|
|
return m('li', m(m.route.Link, { class: 'child', href: '/page/' + subpage.path }, subpage.name))
|
|
}))
|
|
: null),
|
|
]
|
|
}),
|
|
!page
|
|
? m('div.asuna.spritesheet')
|
|
: null,
|
|
])
|
|
: null,
|
|
m('div.container', [
|
|
(page
|
|
? media.getArticlePicture(this.picture, false, page.media_path, 'Image for page ' + page.name)
|
|
: null),
|
|
(page && page.content
|
|
? m('div.content', page.content.blocks.map(block => {
|
|
return m(EditorBlock, { block: block })
|
|
}))
|
|
: null),
|
|
(page && this.data.articles.length
|
|
? [
|
|
m('h5', 'Latest posts under ' + page.name + ':'),
|
|
this.data.articles.map(function(article) {
|
|
return m(Articleslim, { article: article })
|
|
}),
|
|
]
|
|
: null),
|
|
(!page && this.data.articles.length
|
|
? this.data.articles.map(function(article) {
|
|
return m(Article, { article: article })
|
|
})
|
|
: null),
|
|
m(Paginator, {
|
|
base: page ? '/page/' + page.path : '/',
|
|
page: this.currentPage,
|
|
perPage: ArticlesPerPage,
|
|
total: this.data.total_articles,
|
|
}),
|
|
]),
|
|
])
|
|
: null),
|
|
],
|
|
])
|
|
},
|
|
}
|
|
|
|
module.exports = SitePage
|