This commit is contained in:
parent
fad7acd5f7
commit
bdeeff3794
7 changed files with 334 additions and 136 deletions
|
@ -39,11 +39,12 @@ export default class ArticleRoutes extends OriginalArticleRoutes {
|
||||||
ctx.body = {
|
ctx.body = {
|
||||||
token: Client.createJwt({ iss: media.iss }, media.secret),
|
token: Client.createJwt({ iss: media.iss }, media.secret),
|
||||||
path: config.get('media:directFilePath'),
|
path: config.get('media:directFilePath'),
|
||||||
|
resize: config.get('media:path'),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** PUT: /api/auth/articles/:id */
|
/** PUT: /api/auth/articles/:id */
|
||||||
async updateCreateArticle(ctx) {
|
async updateCreateArticle(ctx) {
|
||||||
return this.private_getUpdateArticle(ctx, ctx.req.body, null, ctx.req.body.media)
|
return this.private_getUpdateArticle(ctx, ctx.req.body, ctx.req.body.banner, ctx.req.body.media)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,13 +21,37 @@ const Input = {
|
||||||
this.tempus = null
|
this.tempus = null
|
||||||
this.subscription = null
|
this.subscription = null
|
||||||
this.input = null
|
this.input = null
|
||||||
|
this.preview = null
|
||||||
},
|
},
|
||||||
|
|
||||||
onremove: function(vnode) {
|
onremove: function(vnode) {
|
||||||
if (!this.tempus) return
|
|
||||||
if (this.subscription) this.subscription.unsubscribe()
|
if (this.subscription) this.subscription.unsubscribe()
|
||||||
this.tempus.dispose()
|
if (this.tempus) {
|
||||||
this.tempus = null
|
this.tempus.dispose()
|
||||||
|
this.tempus = null
|
||||||
|
}
|
||||||
|
if (this.preview) {
|
||||||
|
this.preview.clear()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
imageChanged: function(vnode, e) {
|
||||||
|
let file = vnode.attrs.form[vnode.attrs.formKey] = e.currentTarget.files?.[0] || null
|
||||||
|
if (this.preview) {
|
||||||
|
this.preview.clear()
|
||||||
|
this.preview = null
|
||||||
|
}
|
||||||
|
if (!file) return
|
||||||
|
|
||||||
|
if (file.type.startsWith('image')) {
|
||||||
|
this.preview = {
|
||||||
|
file: file,
|
||||||
|
preview: URL.createObjectURL(file),
|
||||||
|
clear: function() {
|
||||||
|
URL.revokeObjectURL(this.preview)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
getInput: function(vnode) {
|
getInput: function(vnode) {
|
||||||
|
@ -67,6 +91,21 @@ const Input = {
|
||||||
onclick: () => { this.tempus.toggle(); return false },
|
onclick: () => { this.tempus.toggle(); return false },
|
||||||
})
|
})
|
||||||
])
|
])
|
||||||
|
case 'image':
|
||||||
|
let imageLink = this.preview && this.preview.preview || vnode.attrs.form[vnode.attrs.formKey]
|
||||||
|
|
||||||
|
return m('div.form-row.image-banner', {
|
||||||
|
style: {
|
||||||
|
'background-image': typeof imageLink === 'string' ? 'url("' + (imageLink) + '")' : null,
|
||||||
|
},
|
||||||
|
}, [
|
||||||
|
m('input.cover', {
|
||||||
|
type: 'file',
|
||||||
|
accept: vnode.attrs.accept,
|
||||||
|
disabled: api.loading,
|
||||||
|
onchange: this.imageChanged.bind(this, vnode),
|
||||||
|
}),
|
||||||
|
])
|
||||||
default:
|
default:
|
||||||
return m('input', {
|
return m('input', {
|
||||||
disabled: api.loading,
|
disabled: api.loading,
|
||||||
|
|
|
@ -39,6 +39,8 @@ const i18n = {
|
||||||
'Dagsetning vantar'],
|
'Dagsetning vantar'],
|
||||||
upload_missing_file: ['Video file missing',
|
upload_missing_file: ['Video file missing',
|
||||||
'Myndaskrá vantar'],
|
'Myndaskrá vantar'],
|
||||||
|
upload_missing_banner: ['Poster image missing',
|
||||||
|
'Mynd vantar'],
|
||||||
upload_error: ['Error while uploading: {0}',
|
upload_error: ['Error while uploading: {0}',
|
||||||
'Villa við að hlaða upp myndefni: {0}'],
|
'Villa við að hlaða upp myndefni: {0}'],
|
||||||
unsplash: ['Photo by {0} on {1}',
|
unsplash: ['Photo by {0} on {1}',
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
const m = require('mithril')
|
const m = require('mithril')
|
||||||
const api = require('./api')
|
const api = require('./api')
|
||||||
const Authentication = require('./authentication')
|
const Authentication = require('./authentication')
|
||||||
|
const Input = require('./input')
|
||||||
const lang = require('./lang')
|
const lang = require('./lang')
|
||||||
|
|
||||||
const Article = {
|
const Article = {
|
||||||
|
@ -9,6 +10,15 @@ const Article = {
|
||||||
this.error = ''
|
this.error = ''
|
||||||
this.path = ''
|
this.path = ''
|
||||||
this.data = null
|
this.data = null
|
||||||
|
this.editing = false
|
||||||
|
this.form = {
|
||||||
|
title: 'Sunnudagssamkoma',
|
||||||
|
date: new Date(),
|
||||||
|
banner: null,
|
||||||
|
metadata: {
|
||||||
|
speaker: '',
|
||||||
|
},
|
||||||
|
}
|
||||||
this.onbeforeupdate(vnode)
|
this.onbeforeupdate(vnode)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -30,16 +40,25 @@ const Article = {
|
||||||
})
|
})
|
||||||
.then((result) => {
|
.then((result) => {
|
||||||
this.data = result.article
|
this.data = result.article
|
||||||
this.afterData()
|
this.gotArticle(vnode)
|
||||||
}, (err) => {
|
}, (err) => {
|
||||||
this.error = err.message
|
this.error = err.message
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
afterData: function() {
|
gotArticle: function(vnode) {
|
||||||
if (!this.data) {
|
if (!this.data) {
|
||||||
this.error = 'Article not found'
|
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.error) return false
|
||||||
},
|
},
|
||||||
|
|
||||||
view: function(vnode) {
|
view: function(vnode) {
|
||||||
|
@ -58,7 +77,7 @@ const Article = {
|
||||||
crossorigin: '',
|
crossorigin: '',
|
||||||
controls: true,
|
controls: true,
|
||||||
preload: 'none',
|
preload: 'none',
|
||||||
poster: '/assets/placeholder.avif',
|
poster: this.data.banner_path || '/assets/placeholder.avif',
|
||||||
}, [
|
}, [
|
||||||
m('source', {
|
m('source', {
|
||||||
src: this.data.media_path
|
src: this.data.media_path
|
||||||
|
@ -67,6 +86,46 @@ const Article = {
|
||||||
]),
|
]),
|
||||||
]
|
]
|
||||||
: null,
|
: null,
|
||||||
|
this.editing
|
||||||
|
? m('form.article', {
|
||||||
|
onsubmit: this.updatevideo.bind(this, vnode),
|
||||||
|
}, [
|
||||||
|
m('div.form-row', [
|
||||||
|
m('div.form-columns', [
|
||||||
|
m(Input, {
|
||||||
|
label: 'Mynd',
|
||||||
|
type: 'file',
|
||||||
|
accept: 'image/*',
|
||||||
|
utility: 'image',
|
||||||
|
form: this.form,
|
||||||
|
formKey: 'banner',
|
||||||
|
}),
|
||||||
|
]),
|
||||||
|
m('div.form-columns', [
|
||||||
|
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',
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
: m('div.article', [
|
||||||
|
m('h1', this.data.name)
|
||||||
|
]),
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,10 @@ const Browse = {
|
||||||
|
|
||||||
mArticles: function(vnode, articles) {
|
mArticles: function(vnode, articles) {
|
||||||
return articles.map(article => {
|
return articles.map(article => {
|
||||||
return m(m.route.Link, { href: ['', article.publish_at.getFullYear(), article.publish_at.getMonth() + 1, article.id].join('/') }, [
|
return m(m.route.Link, {
|
||||||
|
href: ['', article.publish_at.getFullYear(), article.publish_at.getMonth() + 1, article.id].join('/'),
|
||||||
|
style: article.avif_preview ? `background-image: url('${article.avif_preview}')` : null,
|
||||||
|
}, [
|
||||||
m('span', article.publish_at.toUTCString()),
|
m('span', article.publish_at.toUTCString()),
|
||||||
m('span', article.name),
|
m('span', article.name),
|
||||||
])
|
])
|
||||||
|
|
|
@ -16,12 +16,14 @@ const Upload = {
|
||||||
d.setSeconds(0)
|
d.setSeconds(0)
|
||||||
d.setMilliseconds(0)
|
d.setMilliseconds(0)
|
||||||
|
|
||||||
this.cache = null
|
this.cacheVideo = null
|
||||||
|
this.cacheImage = null
|
||||||
this.uploading = null
|
this.uploading = null
|
||||||
this.form = {
|
this.form = {
|
||||||
title: 'Sunnudagssamkoma',
|
title: 'Sunnudagssamkoma',
|
||||||
date: d,
|
date: d,
|
||||||
file: null,
|
file: null,
|
||||||
|
banner: null,
|
||||||
metadata: {
|
metadata: {
|
||||||
speaker: '',
|
speaker: '',
|
||||||
},
|
},
|
||||||
|
@ -33,7 +35,8 @@ const Upload = {
|
||||||
|
|
||||||
if (!this.form.title) this.error = lang.upload_missing_title // Title is missing
|
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.form.date) this.error = lang.upload_missing_date // Date is missing
|
||||||
if (!this.form.file) this.error = lang.upload_missing_file // Video file missing
|
// if (!this.form.file) this.error = lang.upload_missing_file // Video file missing
|
||||||
|
if (!this.form.banner) this.error = lang.upload_missing_banner // Video file missing
|
||||||
|
|
||||||
if (this.error) return false
|
if (this.error) return false
|
||||||
|
|
||||||
|
@ -43,8 +46,69 @@ const Upload = {
|
||||||
body: this.form,
|
body: this.form,
|
||||||
})
|
})
|
||||||
.then(res => {
|
.then(res => {
|
||||||
if (this.cache?.file === this.form.file) {
|
if (this.cacheImage?.file === this.form.banner) {
|
||||||
return this.cache
|
return this.cacheImage
|
||||||
|
}
|
||||||
|
|
||||||
|
var data = new FormData()
|
||||||
|
data.append('file', this.form.banner)
|
||||||
|
data.append('preview', JSON.stringify({
|
||||||
|
"out": "base64",
|
||||||
|
"format": "avif",
|
||||||
|
"resize": {
|
||||||
|
"width": 360,
|
||||||
|
"height": 203,
|
||||||
|
"fit": "cover",
|
||||||
|
"withoutEnlargement": true,
|
||||||
|
"kernel": "mitchell"
|
||||||
|
},
|
||||||
|
"avif": {
|
||||||
|
"quality": 50,
|
||||||
|
"effort": 9
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
data.append('medium', JSON.stringify({
|
||||||
|
"format": "avif",
|
||||||
|
"resize": {
|
||||||
|
"width": 1280,
|
||||||
|
"height": 720,
|
||||||
|
"fit": "cover",
|
||||||
|
"withoutEnlargement": true,
|
||||||
|
"kernel": "mitchell"
|
||||||
|
},
|
||||||
|
"avif": {
|
||||||
|
"quality": 75,
|
||||||
|
"effort": 3
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
|
return api.sendRequest({
|
||||||
|
method: 'POST',
|
||||||
|
url: res.resize + '?token=' + res.token,
|
||||||
|
body: data,
|
||||||
|
})
|
||||||
|
.then(banner => {
|
||||||
|
this.cacheImage = {
|
||||||
|
file: this.form.banner,
|
||||||
|
medium: {
|
||||||
|
filename: banner.medium.filename,
|
||||||
|
path: banner.medium.path,
|
||||||
|
},
|
||||||
|
preview: {
|
||||||
|
base64: banner.preview.base64,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
api.sendRequest({
|
||||||
|
method: 'DELETE',
|
||||||
|
url: res.resize.replace('resize', banner.filename) + '?token=' + res.token,
|
||||||
|
}).catch(err => console.log(err))
|
||||||
|
|
||||||
|
return res
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then(res => {
|
||||||
|
if (this.cacheVideo?.file === this.form.file) {
|
||||||
|
return this.cacheVideo
|
||||||
}
|
}
|
||||||
|
|
||||||
return api.uploadFileProgress({
|
return api.uploadFileProgress({
|
||||||
|
@ -59,7 +123,7 @@ const Upload = {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.then(res => {
|
.then(res => {
|
||||||
this.cache = {
|
this.cacheVideo = {
|
||||||
file: this.form.file,
|
file: this.form.file,
|
||||||
filename: res.filename,
|
filename: res.filename,
|
||||||
path: res.path,
|
path: res.path,
|
||||||
|
@ -79,10 +143,19 @@ const Upload = {
|
||||||
is_featured: false,
|
is_featured: false,
|
||||||
media: {
|
media: {
|
||||||
filename: res.filename,
|
filename: res.filename,
|
||||||
type: this.form.file.type,
|
|
||||||
path: res.path,
|
path: res.path,
|
||||||
|
type: this.form.file.type,
|
||||||
size: this.form.file.size,
|
size: this.form.file.size,
|
||||||
}
|
},
|
||||||
|
banner: {
|
||||||
|
filename: this.cacheImage.medium.filename,
|
||||||
|
path: this.cacheImage.medium.path,
|
||||||
|
type: 'image/avif',
|
||||||
|
size: this.form.file.size,
|
||||||
|
preview: {
|
||||||
|
base64: this.cacheImage.preview.base64,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -138,6 +211,14 @@ const Upload = {
|
||||||
form: this.form,
|
form: this.form,
|
||||||
formKey: 'file',
|
formKey: 'file',
|
||||||
}),
|
}),
|
||||||
|
m(Input, {
|
||||||
|
label: 'Mynd',
|
||||||
|
type: 'file',
|
||||||
|
accept: 'image/*',
|
||||||
|
utility: 'image',
|
||||||
|
form: this.form,
|
||||||
|
formKey: 'banner',
|
||||||
|
}),
|
||||||
m('p.separator', 'Optional'),
|
m('p.separator', 'Optional'),
|
||||||
m(Input, {
|
m(Input, {
|
||||||
label: 'Speaker',
|
label: 'Speaker',
|
||||||
|
|
|
@ -79,104 +79,6 @@ a, a:visited, button {
|
||||||
background: transparent;
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
input[type=text],
|
|
||||||
input[type=password],
|
|
||||||
input[type=datetime] {
|
|
||||||
border: 1px solid var(--main);
|
|
||||||
background: #fff;
|
|
||||||
color: var(--color);
|
|
||||||
border-radius: 0;
|
|
||||||
padding: 0.25rem;
|
|
||||||
line-height: 1rem;
|
|
||||||
outline: none;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type=text]:disabled,
|
|
||||||
input[type=password]:disabled,
|
|
||||||
input[type=datetime]:disabled {
|
|
||||||
background: var(--bg-component);
|
|
||||||
border-color: var(--color-alt);
|
|
||||||
color: var(--color-alt);
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-row input:disabled + button {
|
|
||||||
border-color: var(--color-alt);
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-row {
|
|
||||||
display: flex;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-row input {
|
|
||||||
flex: 2 1 auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-row button {
|
|
||||||
min-width: 30px;
|
|
||||||
text-align: center;
|
|
||||||
border: 1px solid var(--main);
|
|
||||||
border-left: none;
|
|
||||||
background: var(--bg-component);
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-row .cover {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
opacity: 0;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button, input[type=submit] {
|
|
||||||
background: var(--main);
|
|
||||||
color:var(--main-fg);
|
|
||||||
border-radius: 10px;
|
|
||||||
padding: 0.25rem 1rem;
|
|
||||||
border: none;
|
|
||||||
margin: 1rem 0 2rem;
|
|
||||||
align-self: center;
|
|
||||||
cursor: pointer;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button.spinner, input[type=submit].spinner {
|
|
||||||
height: 2rem;
|
|
||||||
margin-top: 2rem;
|
|
||||||
margin-bottom: 1.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button-alert {
|
|
||||||
background: var(--error-bg);
|
|
||||||
color: var(--color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.loading-bar {
|
|
||||||
border: 1px solid var(--main);
|
|
||||||
background: var(--bg-component);
|
|
||||||
}
|
|
||||||
|
|
||||||
.loading-bar::after {
|
|
||||||
height: 1rem;
|
|
||||||
background: var(--main);
|
|
||||||
min-width: 1px;
|
|
||||||
content: '';
|
|
||||||
display: block;
|
|
||||||
width: var(--progress);
|
|
||||||
transition: width 3s;
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type=text]:focus,
|
|
||||||
input[type=password]:focus,
|
|
||||||
input[type=datetime]:focus {
|
|
||||||
outline: 1px solid var(--main);
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
}
|
}
|
||||||
|
@ -206,20 +108,6 @@ h1 {
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
form p, label {
|
|
||||||
font-size: 0.75rem;
|
|
||||||
font-weight: 500;
|
|
||||||
margin: 0.75rem 0 0.5rem 0;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
form p.separator {
|
|
||||||
color: var(--color-alt);
|
|
||||||
margin-top: 1.5rem;
|
|
||||||
padding-bottom: 0.5rem;
|
|
||||||
border-bottom: 1px solid var(--color-alt);
|
|
||||||
}
|
|
||||||
|
|
||||||
.error {
|
.error {
|
||||||
color: var(--error);
|
color: var(--error);
|
||||||
}
|
}
|
||||||
|
@ -266,6 +154,7 @@ form p.separator {
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: center;
|
background-position: center;
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
|
background-image: url('./assets/bg_admin.avif');
|
||||||
}
|
}
|
||||||
|
|
||||||
.page-upload footer {
|
.page-upload footer {
|
||||||
|
@ -277,11 +166,133 @@ form p.separator {
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.avifsupport .page-upload {
|
/* Common components */
|
||||||
background-image: url('./assets/bg_admin.avif');
|
|
||||||
|
input[type=text],
|
||||||
|
input[type=password],
|
||||||
|
input[type=datetime] {
|
||||||
|
border: 1px solid var(--main);
|
||||||
|
background: #fff;
|
||||||
|
color: var(--color);
|
||||||
|
border-radius: 0;
|
||||||
|
padding: 0.25rem;
|
||||||
|
line-height: 1rem;
|
||||||
|
outline: none;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
.jpegonly .page-upload {
|
|
||||||
background-image: url('./assets/bg_admin.jpg');
|
input[type=text]:disabled,
|
||||||
|
input[type=password]:disabled,
|
||||||
|
input[type=datetime]:disabled {
|
||||||
|
background: var(--bg-component);
|
||||||
|
border-color: var(--color-alt);
|
||||||
|
color: var(--color-alt);
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-row input:disabled + button {
|
||||||
|
border-color: var(--color-alt);
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-row {
|
||||||
|
display: flex;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-row input {
|
||||||
|
flex: 2 1 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-row .form-column {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-around;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-row button {
|
||||||
|
min-width: 30px;
|
||||||
|
text-align: center;
|
||||||
|
border: 1px solid var(--main);
|
||||||
|
border-left: none;
|
||||||
|
background: var(--bg-component);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-row.image-banner {
|
||||||
|
background-size: cover;
|
||||||
|
background-color: white;
|
||||||
|
border: 2px dashed var(--main);
|
||||||
|
aspect-ratio: 16 / 9;
|
||||||
|
align-self: center;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 360px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-row .cover {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
opacity: 0;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=text]:focus,
|
||||||
|
input[type=password]:focus,
|
||||||
|
input[type=datetime]:focus {
|
||||||
|
outline: 1px solid var(--main);
|
||||||
|
}
|
||||||
|
|
||||||
|
.button, input[type=submit] {
|
||||||
|
background: var(--main);
|
||||||
|
color:var(--main-fg);
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 0.25rem 1rem;
|
||||||
|
border: none;
|
||||||
|
margin: 1rem 0 2rem;
|
||||||
|
align-self: center;
|
||||||
|
cursor: pointer;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button.spinner, input[type=submit].spinner {
|
||||||
|
height: 2rem;
|
||||||
|
margin-top: 2rem;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-alert {
|
||||||
|
background: var(--error-bg);
|
||||||
|
color: var(--color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-bar {
|
||||||
|
border: 1px solid var(--main);
|
||||||
|
background: var(--bg-component);
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-bar::after {
|
||||||
|
height: 1rem;
|
||||||
|
background: var(--main);
|
||||||
|
min-width: 1px;
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
width: var(--progress);
|
||||||
|
transition: width 3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
form p, label {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
font-weight: 500;
|
||||||
|
margin: 0.75rem 0 0.5rem 0;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
form p.separator {
|
||||||
|
color: var(--color-alt);
|
||||||
|
margin-top: 1.5rem;
|
||||||
|
padding-bottom: 0.5rem;
|
||||||
|
border-bottom: 1px solid var(--color-alt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Nav */
|
/* Nav */
|
||||||
|
@ -463,13 +474,15 @@ footer a {
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
background: url('./assets/placeholder.avif') center no-repeat;
|
background: url('./assets/placeholder.avif') center no-repeat;
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
padding: 1rem;
|
|
||||||
margin: 0 1rem 1rem;
|
margin: 0 1rem 1rem;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
border: 1px solid var(--main);
|
border: 1px solid var(--main);
|
||||||
text-shadow: 2px 0 10px #fffc, -2px 0 10px #fffc, 0 2px 10px #fffc, 0 -2px 10px #fffc,
|
}
|
||||||
1px 1px 10px #fffc, -1px -1px 10px #fffc, 1px -1px 10px #fffc, -1px 1px 10px #fffc;
|
|
||||||
|
|
||||||
|
.gallery .group a span {
|
||||||
|
align-self: stretch;
|
||||||
|
text-align: center;
|
||||||
|
background: #fffb;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Player */
|
/* Player */
|
||||||
|
|
Loading…
Reference in a new issue