2023-11-09 09:44:04 +00:00
|
|
|
const m = require('mithril')
|
|
|
|
const Authentication = require('./authentication')
|
|
|
|
const api = require('./api')
|
2023-11-14 07:27:04 +00:00
|
|
|
const Input = require('./input')
|
2023-11-20 07:12:08 +00:00
|
|
|
const lang = require('./lang')
|
|
|
|
const videos = require('./videos')
|
2023-11-09 09:44:04 +00:00
|
|
|
|
2023-11-14 07:27:04 +00:00
|
|
|
const Upload = {
|
2023-11-09 09:44:04 +00:00
|
|
|
oninit: function(vnode) {
|
2023-11-14 07:27:04 +00:00
|
|
|
Authentication.requiresLogin()
|
2023-11-09 09:44:04 +00:00
|
|
|
this.error = ''
|
2023-11-15 04:43:05 +00:00
|
|
|
let d = new Date()
|
|
|
|
d.setDate(d.getDate() - d.getDay())
|
|
|
|
d.setHours(11)
|
|
|
|
d.setMinutes(0)
|
|
|
|
d.setSeconds(0)
|
|
|
|
d.setMilliseconds(0)
|
|
|
|
|
2023-11-29 19:19:41 +00:00
|
|
|
this.cacheVideo = null
|
|
|
|
this.cacheImage = null
|
2023-11-20 07:12:08 +00:00
|
|
|
this.uploading = null
|
2023-12-05 22:57:59 +00:00
|
|
|
this.bannerStatus = null
|
2023-11-14 07:27:04 +00:00
|
|
|
this.form = {
|
2023-11-20 07:12:08 +00:00
|
|
|
title: 'Sunnudagssamkoma',
|
2023-11-15 04:43:05 +00:00
|
|
|
date: d,
|
2023-11-09 09:44:04 +00:00
|
|
|
file: null,
|
2023-11-29 19:19:41 +00:00
|
|
|
banner: null,
|
2023-11-20 07:12:08 +00:00
|
|
|
metadata: {
|
|
|
|
speaker: '',
|
|
|
|
},
|
2023-11-09 09:44:04 +00:00
|
|
|
}
|
|
|
|
},
|
2023-11-14 07:27:04 +00:00
|
|
|
|
|
|
|
uploadvideo: function(vnode, e) {
|
2023-11-20 07:12:08 +00:00
|
|
|
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
|
2023-11-30 04:14:42 +00:00
|
|
|
if (!this.form.file) this.error = lang.upload_missing_file // Video file missing
|
|
|
|
if (!this.form.banner) this.error = lang.upload_missing_banner // Poster image missing
|
2023-11-20 07:12:08 +00:00
|
|
|
|
|
|
|
if (this.error) return false
|
|
|
|
|
|
|
|
api.sendRequest({
|
|
|
|
method: 'GET',
|
|
|
|
url: '/api/auth/uploadToken',
|
|
|
|
})
|
|
|
|
.then(res => {
|
2023-11-29 19:19:41 +00:00
|
|
|
if (this.cacheImage?.file === this.form.banner) {
|
|
|
|
return this.cacheImage
|
|
|
|
}
|
|
|
|
|
2023-12-05 22:57:59 +00:00
|
|
|
return api.uploadBanner(this.form.banner, res, (status) => {
|
|
|
|
this.bannerStatus = status
|
|
|
|
m.redraw()
|
|
|
|
})
|
2023-11-30 04:14:42 +00:00
|
|
|
.then(imageData => {
|
|
|
|
this.cacheImage = imageData
|
2023-11-29 19:19:41 +00:00
|
|
|
return res
|
|
|
|
})
|
|
|
|
})
|
|
|
|
.then(res => {
|
|
|
|
if (this.cacheVideo?.file === this.form.file) {
|
|
|
|
return this.cacheVideo
|
2023-11-20 07:12:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return api.uploadFileProgress({
|
|
|
|
url: res.path + '?token=' + res.token,
|
|
|
|
}, this.form.file, (xhr, progress, perSecond) => {
|
|
|
|
this.uploading = {
|
|
|
|
progress,
|
|
|
|
xhr,
|
|
|
|
perSecond
|
|
|
|
}
|
|
|
|
m.redraw()
|
|
|
|
})
|
|
|
|
})
|
|
|
|
.then(res => {
|
2023-11-29 19:19:41 +00:00
|
|
|
this.cacheVideo = {
|
2023-11-20 07:12:08 +00:00
|
|
|
file: this.form.file,
|
|
|
|
filename: res.filename,
|
|
|
|
path: res.path,
|
|
|
|
}
|
|
|
|
this.uploading = null
|
|
|
|
|
|
|
|
return api.sendRequest({
|
|
|
|
method: 'PUT',
|
|
|
|
url: '/api/auth/articles/0',
|
|
|
|
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: {
|
|
|
|
filename: res.filename,
|
|
|
|
path: res.path,
|
2023-11-29 19:19:41 +00:00
|
|
|
type: this.form.file.type,
|
2023-11-20 07:12:08 +00:00
|
|
|
size: this.form.file.size,
|
2023-11-29 19:19:41 +00:00
|
|
|
},
|
|
|
|
banner: {
|
|
|
|
filename: this.cacheImage.medium.filename,
|
|
|
|
path: this.cacheImage.medium.path,
|
|
|
|
type: 'image/avif',
|
2023-11-30 04:14:42 +00:00
|
|
|
size: this.cacheImage.size,
|
2023-11-29 19:19:41 +00:00
|
|
|
preview: {
|
|
|
|
base64: this.cacheImage.preview.base64,
|
|
|
|
},
|
|
|
|
},
|
2023-11-20 07:12:08 +00:00
|
|
|
},
|
|
|
|
})
|
|
|
|
})
|
|
|
|
.then(res => {
|
|
|
|
videos.refreshTree()
|
2023-11-30 04:14:42 +00:00
|
|
|
m.route.set('/')
|
2023-11-20 07:12:08 +00:00
|
|
|
})
|
|
|
|
.catch((error) => {
|
2023-12-05 22:57:59 +00:00
|
|
|
this.bannerStatus = null
|
2023-11-20 07:12:08 +00:00
|
|
|
this.uploading = null
|
|
|
|
if (!error) return
|
|
|
|
|
|
|
|
this.error = lang.format(lang.upload_error, error.message) // Error while uploading:
|
|
|
|
})
|
|
|
|
|
|
|
|
return false
|
|
|
|
},
|
|
|
|
|
|
|
|
cancelUpload(e) {
|
|
|
|
e.stopPropagation()
|
|
|
|
this.uploading.xhr.abortRequest()
|
|
|
|
this.uploading = null
|
2023-11-15 04:43:05 +00:00
|
|
|
return false
|
2023-11-09 09:44:04 +00:00
|
|
|
},
|
|
|
|
|
2023-11-30 04:14:42 +00:00
|
|
|
filechanged(file) {
|
|
|
|
if (!file || !file.name) return
|
|
|
|
|
|
|
|
let matches = /^(\d{4})-(\d\d)-(\d\d)_(\d\d)-(\d\d)/.exec(file.name)
|
|
|
|
if (!matches) return
|
|
|
|
|
|
|
|
var date = new Date(matches.slice(1, 4).join('-') + 'T' + matches.slice(4,6).join(':') + ':00')
|
|
|
|
if (isNaN(date.getTime())) return
|
|
|
|
|
|
|
|
if (date.getMinutes() >= 30 || date.getHours() === 10) {
|
|
|
|
date.setHours(date.getHours() + 1)
|
|
|
|
}
|
|
|
|
date.setMinutes(0)
|
|
|
|
this.form.date = date
|
|
|
|
},
|
|
|
|
|
2023-11-09 09:44:04 +00:00
|
|
|
view: function(vnode) {
|
|
|
|
return [
|
2023-11-14 07:27:04 +00:00
|
|
|
m('div.page.page-upload', [
|
|
|
|
m('div.modal', [
|
|
|
|
m('form', {
|
|
|
|
onsubmit: this.uploadvideo.bind(this, vnode),
|
|
|
|
}, [
|
|
|
|
m('h3', 'Upload new video'),
|
|
|
|
this.error ? m('p.error', this.error) : null,
|
|
|
|
m(Input, {
|
|
|
|
label: 'Title',
|
|
|
|
form: this.form,
|
|
|
|
formKey: 'title',
|
|
|
|
}),
|
|
|
|
m(Input, {
|
2023-11-20 07:12:08 +00:00
|
|
|
label: 'Date (dd.mm.yyyy)',
|
2023-11-15 04:43:05 +00:00
|
|
|
type: 'text',
|
|
|
|
utility: 'datetime',
|
2023-11-14 07:27:04 +00:00
|
|
|
form: this.form,
|
|
|
|
formKey: 'date',
|
|
|
|
}),
|
2023-11-20 07:12:08 +00:00
|
|
|
m(Input, {
|
|
|
|
label: 'Video',
|
|
|
|
type: 'file',
|
|
|
|
accept: '.webm',
|
|
|
|
utility: 'file',
|
|
|
|
button: 'fa-video',
|
|
|
|
form: this.form,
|
|
|
|
formKey: 'file',
|
2023-11-30 04:14:42 +00:00
|
|
|
oninput: (file) => this.filechanged(file),
|
2023-11-20 07:12:08 +00:00
|
|
|
}),
|
2023-11-29 19:19:41 +00:00
|
|
|
m(Input, {
|
|
|
|
label: 'Mynd',
|
|
|
|
type: 'file',
|
|
|
|
accept: 'image/*',
|
|
|
|
utility: 'image',
|
|
|
|
form: this.form,
|
|
|
|
formKey: 'banner',
|
|
|
|
}),
|
2023-11-20 07:12:08 +00:00
|
|
|
m('p.separator', 'Optional'),
|
|
|
|
m(Input, {
|
|
|
|
label: 'Speaker',
|
|
|
|
form: this.form.metadata,
|
|
|
|
formKey: 'speaker',
|
|
|
|
}),
|
2023-11-14 07:27:04 +00:00
|
|
|
m('input.spinner', {
|
|
|
|
hidden: api.loading,
|
|
|
|
type: 'submit',
|
2023-11-15 04:43:05 +00:00
|
|
|
value: 'Begin upload',
|
2023-11-14 07:27:04 +00:00
|
|
|
}),
|
|
|
|
api.loading ? m('div.loading-spinner') : null,
|
2023-12-05 22:57:59 +00:00
|
|
|
this.bannerStatus ? [
|
|
|
|
m('p', this.bannerStatus),
|
|
|
|
m('.loading-bar', { style: `--progress: 0%` }),
|
|
|
|
] : null,
|
2023-11-20 07:12:08 +00:00
|
|
|
this.uploading ? [
|
|
|
|
m('p', `${Math.floor(this.uploading.progress)}% (${this.uploading.perSecond}/s)`),
|
|
|
|
m('.loading-bar', { style: `--progress: ${this.uploading.progress}%` }),
|
|
|
|
m('button.button.button-alert', {
|
|
|
|
onclick: this.cancelUpload.bind(this),
|
|
|
|
}, 'Cancel upload'),
|
|
|
|
] : null,
|
2023-11-14 07:27:04 +00:00
|
|
|
]),
|
2023-11-09 09:44:04 +00:00
|
|
|
]),
|
2023-11-20 07:12:08 +00:00
|
|
|
m('footer', lang.mformat(
|
|
|
|
lang.unsplash, // Photo by X on Y
|
2023-11-30 04:14:42 +00:00
|
|
|
m('a', { href: 'https://unsplash.com/@franhotchin?utm_content=creditCopyText&utm_medium=referral&utm_source=unsplash', target: '_blank' }, 'Francesca Hotchin'),
|
|
|
|
m('a', { href: 'https://unsplash.com/photos/landscape-photo-of-mountain-covered-with-snow-FN-cedy6NHA?utm_content=creditCopyText&utm_medium=referral&utm_source=unsplash', target: '_blank' }, 'Unsplash'),
|
2023-11-20 07:12:08 +00:00
|
|
|
)),
|
2023-11-09 09:44:04 +00:00
|
|
|
]),
|
|
|
|
]
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2023-11-14 07:27:04 +00:00
|
|
|
module.exports = Upload
|