265 lines
7.8 KiB
JavaScript
265 lines
7.8 KiB
JavaScript
const m = require('mithril')
|
|
const api = require('./api')
|
|
const Authentication = require('./authentication')
|
|
const Input = require('./input')
|
|
const lang = require('./lang')
|
|
const videos = require('./videos')
|
|
const HoldButton = require('./holdbutton')
|
|
|
|
const Article = {
|
|
oninit: function(vnode) {
|
|
this.error = ''
|
|
this.path = ''
|
|
this.data = null
|
|
this.editing = false
|
|
this.cacheImage = null
|
|
this.form = {
|
|
title: 'Sunnudagssamkoma',
|
|
date: new Date(),
|
|
banner: null,
|
|
metadata: {
|
|
speaker: '',
|
|
},
|
|
}
|
|
this.onbeforeupdate(vnode)
|
|
},
|
|
|
|
onbeforeupdate: function(vnode) {
|
|
let path = m.route.param('year').padStart(4, '0')
|
|
+ '-' + m.route.param('month').padStart(2, '0')
|
|
+ '-' + m.route.param('path')
|
|
if (this.path === path) return
|
|
|
|
this.fetchArticle(vnode, path)
|
|
},
|
|
|
|
fetchArticle: function(vnode, path) {
|
|
this.error = ''
|
|
this.data = null
|
|
this.path = path
|
|
this.cacheImage = null
|
|
this.editing = false
|
|
|
|
api.sendRequest({
|
|
method: 'GET',
|
|
url: '/api/articles/' + this.path,
|
|
})
|
|
.then((result) => {
|
|
this.data = result.article
|
|
this.gotArticle(vnode)
|
|
}, (err) => {
|
|
this.error = err.message
|
|
})
|
|
},
|
|
|
|
gotArticle: function(vnode) {
|
|
if (!this.data) {
|
|
return this.error = 'Article not found'
|
|
}
|
|
this.form.title = this.data.name
|
|
this.form.date = new Date(this.data.publish_at)
|
|
this.form.banner = this.data.banner_path
|
|
this.form.metadata.speaker = this.data.content.speaker
|
|
},
|
|
|
|
updatevideo: function(vnode, e) {
|
|
this.error = ''
|
|
|
|
if (!this.form.title) this.error = lang.upload_missing_title // Title is missing
|
|
if (!this.form.date) this.error = lang.upload_missing_date // Date is missing
|
|
if (this.error) return false
|
|
|
|
let promise = Promise.resolve()
|
|
|
|
if (Authentication.currentUser && (typeof(this.form.banner) !== 'string' && this.cacheImage?.file !== this.form.banner)) {
|
|
promise = api.sendRequest({
|
|
method: 'GET',
|
|
url: '/api/auth/uploadToken',
|
|
})
|
|
.then(res => {
|
|
return api.uploadBanner(this.form.banner, res)
|
|
.then(imageData => {
|
|
this.cacheImage = imageData
|
|
|
|
if (this.data.banner_path) {
|
|
api.sendRequest({
|
|
method: 'DELETE',
|
|
url: res.delete + this.data.banner_path.slice(this.data.banner_path.lastIndexOf('/') + 1) + '?token=' + res.token,
|
|
}).catch(err => console.error(err))
|
|
}
|
|
|
|
return res
|
|
})
|
|
})
|
|
}
|
|
|
|
promise.then(() => {
|
|
return api.sendRequest({
|
|
method: 'PUT',
|
|
url: '/api/auth/articles/' + this.data.id,
|
|
body: {
|
|
name: this.form.title,
|
|
page_id: 'null',
|
|
path: this.form.date.toISOString().replace('T', '_').replace(/:/g, '').split('.')[0],
|
|
content: JSON.stringify(this.form.metadata),
|
|
publish_at: this.form.date,
|
|
admin_id: Authentication.getTokenDecoded().user_id,
|
|
is_featured: false,
|
|
media: null,
|
|
banner: this.cacheImage ? {
|
|
filename: this.cacheImage.medium.filename,
|
|
path: this.cacheImage.medium.path,
|
|
type: 'image/avif',
|
|
size: this.cacheImage.size,
|
|
preview: {
|
|
base64: this.cacheImage.preview.base64,
|
|
},
|
|
} : null,
|
|
},
|
|
})
|
|
})
|
|
.then(res => {
|
|
this.fetchArticle(vnode, this.path)
|
|
})
|
|
.catch((error) => {
|
|
console.error(error)
|
|
this.error = lang.format(lang.article_error, error.message) // Error while saving:
|
|
})
|
|
|
|
|
|
return false
|
|
},
|
|
|
|
deletevideo: function(vnode) {
|
|
api.sendRequest({
|
|
method: 'GET',
|
|
url: '/api/auth/uploadToken',
|
|
body: this.form,
|
|
})
|
|
.then(res => {
|
|
return Promise.all([
|
|
this.data.banner_path ? api.sendRequest({
|
|
method: 'DELETE',
|
|
url: res.delete + this.data.banner_path.slice(this.data.banner_path.lastIndexOf('/') + 1) + '?token=' + res.token,
|
|
}).catch(err => console.error(err)) : Promise.resolve(),
|
|
this.data.media_path ? api.sendRequest({
|
|
method: 'DELETE',
|
|
url: res.delete + this.data.media_path.slice(this.data.media_path.lastIndexOf('/') + 1) + '?token=' + res.token,
|
|
}).catch(err => console.error(err)) : Promise.resolve(),
|
|
])
|
|
})
|
|
.then(() => {
|
|
return api.sendRequest({
|
|
method: 'DELETE',
|
|
url: '/api/auth/articles/' + this.data.id,
|
|
})
|
|
})
|
|
.then(res => {
|
|
videos.removeArticle(this.data.id)
|
|
m.route.set('/')
|
|
})
|
|
.catch((error) => {
|
|
if (!error) return
|
|
|
|
this.error = lang.format(lang.delete_error, error.message) // Error while uploading:
|
|
})
|
|
},
|
|
|
|
view: function(vnode) {
|
|
return [
|
|
api.loading && !this.data ? m('div.loading-spinner') : null,
|
|
this.data ? [
|
|
this.data.media_path
|
|
? [
|
|
m('.player', [
|
|
m('video', {
|
|
crossorigin: '',
|
|
controls: true,
|
|
preload: 'none',
|
|
poster: this.data.banner_path || '/assets/placeholder.avif',
|
|
}, [
|
|
m('source', {
|
|
src: this.data.media_path
|
|
})
|
|
]),
|
|
]),
|
|
]
|
|
: null,
|
|
this.editing
|
|
? m('form.article', {
|
|
onsubmit: this.updatevideo.bind(this, vnode),
|
|
}, [
|
|
m('div.form-row', [
|
|
m('div.form-columns', [
|
|
m(Input, {
|
|
label: '',
|
|
type: 'file',
|
|
accept: 'image/*',
|
|
utility: 'image',
|
|
form: this.form,
|
|
formKey: 'banner',
|
|
}),
|
|
]),
|
|
m('div.form-columns.article-name', [
|
|
m(Input, {
|
|
label: 'Title',
|
|
form: this.form,
|
|
formKey: 'title',
|
|
}),
|
|
m(Input, {
|
|
label: 'Date (dd.mm.yyyy)',
|
|
type: 'text',
|
|
utility: 'datetime',
|
|
form: this.form,
|
|
formKey: 'date',
|
|
}),
|
|
]),
|
|
]),
|
|
m('p.separator', 'Optional'),
|
|
m(Input, {
|
|
label: 'Speaker',
|
|
form: this.form.metadata,
|
|
formKey: 'speaker',
|
|
}),
|
|
this.error ? m('div.full-error', this.error) : null,
|
|
m('div.row', [
|
|
m('input.spinner', {
|
|
hidden: api.loading,
|
|
type: 'submit',
|
|
value: lang.edit,
|
|
}),
|
|
m('div.filler', {
|
|
hidden: api.loading,
|
|
}),
|
|
api.loading ? m('div.loading-spinner') : null,
|
|
m(HoldButton, {
|
|
class: 'button spinner',
|
|
onclick: () => this.deletevideo(vnode),
|
|
hidden: api.loading,
|
|
text: lang.delete,
|
|
}),
|
|
]),
|
|
])
|
|
: m('div.article', [
|
|
m('h1', this.data.name),
|
|
m('p', [
|
|
lang.printdate(this.form.date),
|
|
]),
|
|
m('div.table', [
|
|
m('div.table-row', [
|
|
m('div.table-item', lang.article_speaker),
|
|
m('div.table-item', this.data.content.speaker || '...'),
|
|
]),
|
|
]),
|
|
Authentication.currentUser?.rank >= 10
|
|
? m('button.button', { onclick: () => this.editing = true },lang.edit)
|
|
: null,
|
|
]),
|
|
] : [
|
|
this.error ? m('div.full-error', this.error) : null,
|
|
],
|
|
]
|
|
},
|
|
}
|
|
|
|
module.exports = Article
|