Updates
* Added ship waifu renders to homepage. These renders are toggleable since some of them maybe a bit NSFW-ish (state saved to browser's local storage). * Updated lazyload to v10.19.0. * Git commit URL is now have dotted bottom border. * Thumbnail modal (the one that appears when you click display thumbnail button in lists view) now have a "Load original" button. For images it will simply load the original images, but for videos it will show a video player (relies on the browser's support for <video> tag). Thumbs view will now also have the "display thumbnail" button. * Small changes to "add to album" modal. * Small changes to alignment to modals in general.
1
.gitignore
vendored
@ -12,3 +12,4 @@ migrate.js
|
|||||||
yarn.lock
|
yarn.lock
|
||||||
yarn-error.log
|
yarn-error.log
|
||||||
package-lock.json
|
package-lock.json
|
||||||
|
public/render/**/original
|
||||||
|
@ -23,6 +23,10 @@ a {
|
|||||||
color: #3794d2;
|
color: #3794d2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a.is-dotted {
|
||||||
|
border-bottom: 1px dotted #3794d2;
|
||||||
|
}
|
||||||
|
|
||||||
a:hover {
|
a:hover {
|
||||||
color: #60a8dc;
|
color: #60a8dc;
|
||||||
}
|
}
|
||||||
@ -96,3 +100,24 @@ hr {
|
|||||||
border-color: transparent;
|
border-color: transparent;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.render {
|
||||||
|
position: fixed;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
font-size: 1rem;
|
||||||
|
color: #bdc3c7;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.render.button {
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
right: 1%;
|
||||||
|
opacity: .25;
|
||||||
|
transition: opacity .25s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.render.button:hover {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
@ -2,11 +2,19 @@
|
|||||||
background-color: #31363b;
|
background-color: #31363b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.swal-modal .field {
|
||||||
|
text-align: initial;
|
||||||
|
}
|
||||||
|
|
||||||
.swal-title,
|
.swal-title,
|
||||||
.swal-text {
|
.swal-text {
|
||||||
color: #eff0f1;
|
color: #eff0f1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.swal-text {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
.swal-content .label,
|
.swal-content .label,
|
||||||
.swal-content .checkbox,
|
.swal-content .checkbox,
|
||||||
.swal-content .radio {
|
.swal-content .radio {
|
||||||
|
@ -65,6 +65,8 @@ const page = {
|
|||||||
clipboardJS: null,
|
clipboardJS: null,
|
||||||
lazyLoad: null,
|
lazyLoad: null,
|
||||||
|
|
||||||
|
imageExtensions: ['.webp', '.jpg', '.jpeg', '.bmp', '.gif', '.png'],
|
||||||
|
|
||||||
// byte units for getPrettyBytes()
|
// byte units for getPrettyBytes()
|
||||||
byteUnits: ['B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
|
byteUnits: ['B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
|
||||||
}
|
}
|
||||||
@ -360,6 +362,12 @@ page.getUploads = function ({ album, pageNum, all } = {}, element) {
|
|||||||
const selected = page.selected.uploads.includes(upload.id)
|
const selected = page.selected.uploads.includes(upload.id)
|
||||||
if (!selected && allSelected) { allSelected = false }
|
if (!selected && allSelected) { allSelected = false }
|
||||||
|
|
||||||
|
page.cache.uploads[upload.id] = {
|
||||||
|
name: upload.name,
|
||||||
|
thumb: upload.thumb,
|
||||||
|
original: upload.file
|
||||||
|
}
|
||||||
|
|
||||||
// Prettify
|
// Prettify
|
||||||
upload.prettyBytes = page.getPrettyBytes(parseInt(upload.size))
|
upload.prettyBytes = page.getPrettyBytes(parseInt(upload.size))
|
||||||
upload.prettyDate = page.getPrettyDate(new Date(upload.timestamp * 1000))
|
upload.prettyDate = page.getPrettyDate(new Date(upload.timestamp * 1000))
|
||||||
@ -379,6 +387,11 @@ page.getUploads = function ({ album, pageNum, all } = {}, element) {
|
|||||||
div.innerHTML += `
|
div.innerHTML += `
|
||||||
<input type="checkbox" class="checkbox" title="Select this file" data-action="select"${selected ? ' checked' : ''}>
|
<input type="checkbox" class="checkbox" title="Select this file" data-action="select"${selected ? ' checked' : ''}>
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
|
<a class="button is-small is-primary" title="View thumbnail" data-action="display-thumbnail"${upload.thumb ? '' : ' disabled'}>
|
||||||
|
<span class="icon">
|
||||||
|
<i class="icon-picture-1"></i>
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
<a class="button is-small is-info clipboard-js" title="Copy link to clipboard" data-clipboard-text="${upload.file}">
|
<a class="button is-small is-info clipboard-js" title="Copy link to clipboard" data-clipboard-text="${upload.file}">
|
||||||
<span class="icon">
|
<span class="icon">
|
||||||
<i class="icon-clipboard-1"></i>
|
<i class="icon-clipboard-1"></i>
|
||||||
@ -443,7 +456,8 @@ page.getUploads = function ({ album, pageNum, all } = {}, element) {
|
|||||||
|
|
||||||
page.cache.uploads[upload.id] = {
|
page.cache.uploads[upload.id] = {
|
||||||
name: upload.name,
|
name: upload.name,
|
||||||
thumb: upload.thumb
|
thumb: upload.thumb,
|
||||||
|
original: upload.file
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prettify
|
// Prettify
|
||||||
@ -516,13 +530,57 @@ page.setUploadsView = function (view, element) {
|
|||||||
page.displayThumbnail = function (id) {
|
page.displayThumbnail = function (id) {
|
||||||
const file = page.cache.uploads[id]
|
const file = page.cache.uploads[id]
|
||||||
if (!file.thumb) { return }
|
if (!file.thumb) { return }
|
||||||
|
|
||||||
|
const div = document.createElement('div')
|
||||||
|
div.innerHTML = `
|
||||||
|
<div class="field has-text-centered">
|
||||||
|
<label class="label">${file.name}</label>
|
||||||
|
<div class="controls">
|
||||||
|
<img id="swalThumb" src="${file.thumb}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
if (file.original) {
|
||||||
|
div.innerHTML += `
|
||||||
|
<div class="field has-text-centered">
|
||||||
|
<div class="controls">
|
||||||
|
<a id="swalOriginal" type="button" class="button is-breeze" data-original="${file.original}">Load original</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
div.querySelector('#swalOriginal').addEventListener('click', function () {
|
||||||
|
const button = this
|
||||||
|
const original = button.dataset.original
|
||||||
|
button.classList.add('is-loading')
|
||||||
|
|
||||||
|
const thumb = div.querySelector('#swalThumb')
|
||||||
|
const exec = /.[\w]+(\?|$)/.exec(original)
|
||||||
|
const isimage = exec && exec[0] && page.imageExtensions.includes(exec[0].toLowerCase())
|
||||||
|
|
||||||
|
if (isimage) {
|
||||||
|
thumb.src = file.original
|
||||||
|
thumb.onload = function () { button.style.display = 'none' }
|
||||||
|
} else {
|
||||||
|
thumb.style.display = 'none'
|
||||||
|
const video = document.createElement('video')
|
||||||
|
video.id = 'swalVideo'
|
||||||
|
video.controls = true
|
||||||
|
video.src = file.original
|
||||||
|
thumb.insertAdjacentElement('afterend', video)
|
||||||
|
button.style.display = 'none'
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resize currently visible modal
|
||||||
|
document.body.querySelector('.swal-overlay--show-modal .swal-modal').style = 'width: auto; max-width: 90%;'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return swal({
|
return swal({
|
||||||
text: file.name,
|
content: div,
|
||||||
content: {
|
buttons: false
|
||||||
element: 'img',
|
}).then(function () {
|
||||||
attributes: { src: file.thumb }
|
const video = div.querySelector('#swalVideo')
|
||||||
},
|
if (video) { video.remove() }
|
||||||
button: true
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -845,9 +903,11 @@ page.addFilesToAlbum = function (ids, callback) {
|
|||||||
|
|
||||||
const content = document.createElement('div')
|
const content = document.createElement('div')
|
||||||
content.innerHTML = `
|
content.innerHTML = `
|
||||||
<p>You are about to add <b>${count}</b> file${count === 1 ? '' : 's'} to an album.</p>
|
<div class="field has-text-centered">
|
||||||
|
<p>You are about to add <b>${count}</b> file${count === 1 ? '' : 's'} to an album.</p>
|
||||||
|
<p><b>If a file is already in an album, it will be moved.</b></p>
|
||||||
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label class="label">If a file is already in an album, it will be moved.</label>
|
|
||||||
<div class="control">
|
<div class="control">
|
||||||
<div class="select is-fullwidth">
|
<div class="select is-fullwidth">
|
||||||
<select id="swalAlbum" disabled>
|
<select id="swalAlbum" disabled>
|
||||||
@ -860,7 +920,6 @@ page.addFilesToAlbum = function (ids, callback) {
|
|||||||
`
|
`
|
||||||
|
|
||||||
swal({
|
swal({
|
||||||
title: 'Add to album',
|
|
||||||
icon: 'warning',
|
icon: 'warning',
|
||||||
content,
|
content,
|
||||||
buttons: {
|
buttons: {
|
||||||
|
@ -18,10 +18,10 @@ const page = {
|
|||||||
|
|
||||||
dropzone: null,
|
dropzone: null,
|
||||||
clipboardJS: null,
|
clipboardJS: null,
|
||||||
lazyLoad: null
|
lazyLoad: null,
|
||||||
}
|
|
||||||
|
|
||||||
const imageExtensions = ['.webp', '.jpg', '.jpeg', '.bmp', '.gif', '.png']
|
imageExtensions: ['.webp', '.jpg', '.jpeg', '.bmp', '.gif', '.png']
|
||||||
|
}
|
||||||
|
|
||||||
page.checkIfPublic = function () {
|
page.checkIfPublic = function () {
|
||||||
axios.get('api/check').then(function (response) {
|
axios.get('api/check').then(function (response) {
|
||||||
@ -191,10 +191,9 @@ page.prepareDropzone = function () {
|
|||||||
<span>Click here or drag and drop files</span>
|
<span>Click here or drag and drop files</span>
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
|
tabDiv.querySelector('.dz-container').appendChild(div)
|
||||||
|
|
||||||
tabDiv.getElementsByClassName('dz-container')[0].appendChild(div)
|
const previewsContainer = tabDiv.querySelector('#tab-files .field.uploads')
|
||||||
|
|
||||||
const previewsContainer = tabDiv.getElementsByClassName('uploads')[0]
|
|
||||||
page.dropzone = new Dropzone('#dropzone', {
|
page.dropzone = new Dropzone('#dropzone', {
|
||||||
url: 'api/upload',
|
url: 'api/upload',
|
||||||
paramName: 'files[]',
|
paramName: 'files[]',
|
||||||
@ -372,12 +371,12 @@ page.updateTemplate = function (file, response) {
|
|||||||
clipboard.parentElement.style.display = 'block'
|
clipboard.parentElement.style.display = 'block'
|
||||||
|
|
||||||
const exec = /.[\w]+(\?|$)/.exec(response.url)
|
const exec = /.[\w]+(\?|$)/.exec(response.url)
|
||||||
if (exec && exec[0] && imageExtensions.includes(exec[0].toLowerCase())) {
|
if (exec && exec[0] && page.imageExtensions.includes(exec[0].toLowerCase())) {
|
||||||
const img = file.previewElement.querySelector('img')
|
const img = file.previewElement.querySelector('img')
|
||||||
img.setAttribute('alt', response.name || '')
|
img.setAttribute('alt', response.name || '')
|
||||||
img.dataset['src'] = response.url
|
img.dataset['src'] = response.url
|
||||||
img.onerror = function () { this.style.display = 'none' } // hide webp in firefox and ie
|
img.onerror = function () { this.style.display = 'none' } // hide webp in firefox and ie
|
||||||
page.lazyLoad.update(file.previewElement.querySelectorAll('img'))
|
page.lazyLoad.update()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -476,7 +475,9 @@ window.onload = function () {
|
|||||||
return swal('An error occurred!', 'There was an error when trying to copy the link to clipboard, please check the console for more information.', 'error')
|
return swal('An error occurred!', 'There was an error when trying to copy the link to clipboard, please check the console for more information.', 'error')
|
||||||
})
|
})
|
||||||
|
|
||||||
page.lazyLoad = new LazyLoad()
|
page.lazyLoad = new LazyLoad({
|
||||||
|
elements_selector: '.field.uploads img'
|
||||||
|
})
|
||||||
|
|
||||||
document.getElementById('createAlbum').addEventListener('click', function () {
|
document.getElementById('createAlbum').addEventListener('click', function () {
|
||||||
page.createAlbum()
|
page.createAlbum()
|
||||||
|
86
public/js/render.js
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
/* global page, swal */
|
||||||
|
|
||||||
|
page.renderRoot = 'render/al/'
|
||||||
|
page.renderArray = [
|
||||||
|
'atago_1.png',
|
||||||
|
'atago_2.png',
|
||||||
|
'belfast_1.png',
|
||||||
|
'belfast_2.png',
|
||||||
|
'belfast_3.png',
|
||||||
|
'eldridge_1.png',
|
||||||
|
'hammann_1.png',
|
||||||
|
'hammann_2.png',
|
||||||
|
'javelin_1.png',
|
||||||
|
'kaga_1.png',
|
||||||
|
'laffey_1.png',
|
||||||
|
'prinz_eugen_1.png',
|
||||||
|
'prinz_eugen_2.png',
|
||||||
|
'takao_1.png',
|
||||||
|
'takao_2.png',
|
||||||
|
'unicorn_1.png',
|
||||||
|
'unicorn_2.png',
|
||||||
|
'unicorn_3.png',
|
||||||
|
'unicorn_4.png',
|
||||||
|
'unicorn_5.png',
|
||||||
|
'yamashiro_1.png'
|
||||||
|
]
|
||||||
|
page.render = null
|
||||||
|
|
||||||
|
page.doRenderSwal = function () {
|
||||||
|
const div = document.createElement('div')
|
||||||
|
div.innerHTML = `
|
||||||
|
<div class="field">
|
||||||
|
<div class="control">
|
||||||
|
<label class="checkbox">
|
||||||
|
<input id="swalRender" type="checkbox" ${localStorage.render === '0' ? '' : 'checked'}>
|
||||||
|
Enable random render of ship waifu~
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<p class="help">If disabled, you will still be able to see a small button on the bottom right corner of the screen to re-enable it.</p>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
|
||||||
|
swal({
|
||||||
|
content: div,
|
||||||
|
buttons: {
|
||||||
|
confirm: true
|
||||||
|
}
|
||||||
|
}).then(function (value) {
|
||||||
|
if (!value) { return }
|
||||||
|
const newValue = div.querySelector('#swalRender').checked ? '1' : '0'
|
||||||
|
if (newValue !== localStorage.render) {
|
||||||
|
localStorage.render = newValue
|
||||||
|
swal('Success!', `Render is now ${newValue === '1' ? 'enabled' : 'disabled'}.`, 'success')
|
||||||
|
const element = document.querySelector('body > .render')
|
||||||
|
element.remove()
|
||||||
|
page.doRender()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
page.doRender = function () {
|
||||||
|
if (!page.renderRoot || !page.renderArray || !page.renderArray.length) { return }
|
||||||
|
if (localStorage.render === undefined) { localStorage.render = '1' }
|
||||||
|
|
||||||
|
let element
|
||||||
|
if (localStorage.render === '0') {
|
||||||
|
element = document.createElement('a')
|
||||||
|
element.className = 'button is-breeze is-hidden-mobile'
|
||||||
|
element.title = 'ship waifu~'
|
||||||
|
element.innerHTML = '<i class="icon-picture-1"></i>'
|
||||||
|
} else {
|
||||||
|
if (!page.render) {
|
||||||
|
page.render = page.renderArray[Math.floor(Math.random() * page.renderArray.length)]
|
||||||
|
}
|
||||||
|
element = document.createElement('img')
|
||||||
|
element.alt = element.title = 'ship waifu~'
|
||||||
|
element.className = 'is-hidden-mobile'
|
||||||
|
element.src = `${page.renderRoot}${page.render}`
|
||||||
|
}
|
||||||
|
|
||||||
|
element.classList.add('render')
|
||||||
|
element.addEventListener('click', page.doRenderSwal)
|
||||||
|
document.body.appendChild(element)
|
||||||
|
}
|
||||||
|
|
||||||
|
page.doRender()
|
2
public/libs/lazyload/lazyload.min.js
vendored
BIN
public/render/al/atago_1.png
Normal file
After Width: | Height: | Size: 67 KiB |
BIN
public/render/al/atago_2.png
Normal file
After Width: | Height: | Size: 78 KiB |
BIN
public/render/al/belfast_1.png
Normal file
After Width: | Height: | Size: 90 KiB |
BIN
public/render/al/belfast_2.png
Normal file
After Width: | Height: | Size: 103 KiB |
BIN
public/render/al/belfast_3.png
Normal file
After Width: | Height: | Size: 99 KiB |
BIN
public/render/al/eldridge_1.png
Normal file
After Width: | Height: | Size: 101 KiB |
BIN
public/render/al/hammann_1.png
Normal file
After Width: | Height: | Size: 88 KiB |
BIN
public/render/al/hammann_2.png
Normal file
After Width: | Height: | Size: 93 KiB |
BIN
public/render/al/javelin_1.png
Normal file
After Width: | Height: | Size: 74 KiB |
BIN
public/render/al/kaga_1.png
Normal file
After Width: | Height: | Size: 72 KiB |
BIN
public/render/al/laffey_1.png
Normal file
After Width: | Height: | Size: 91 KiB |
BIN
public/render/al/prinz_eugen_1.png
Normal file
After Width: | Height: | Size: 84 KiB |
BIN
public/render/al/prinz_eugen_2.png
Normal file
After Width: | Height: | Size: 81 KiB |
BIN
public/render/al/takao_1.png
Normal file
After Width: | Height: | Size: 81 KiB |
BIN
public/render/al/takao_2.png
Normal file
After Width: | Height: | Size: 63 KiB |
BIN
public/render/al/unicorn_1.png
Normal file
After Width: | Height: | Size: 83 KiB |
BIN
public/render/al/unicorn_2.png
Normal file
After Width: | Height: | Size: 85 KiB |
BIN
public/render/al/unicorn_3.png
Normal file
After Width: | Height: | Size: 82 KiB |
BIN
public/render/al/unicorn_4.png
Normal file
After Width: | Height: | Size: 107 KiB |
BIN
public/render/al/unicorn_5.png
Normal file
After Width: | Height: | Size: 95 KiB |
BIN
public/render/al/yamashiro_1.png
Normal file
After Width: | Height: | Size: 89 KiB |
@ -15,9 +15,9 @@
|
|||||||
v2: Images and config files (manifest.json, browserconfig.xml, etc).
|
v2: Images and config files (manifest.json, browserconfig.xml, etc).
|
||||||
v3: CSS and JS files (libs such as bulma, lazyload, etc).
|
v3: CSS and JS files (libs such as bulma, lazyload, etc).
|
||||||
#}
|
#}
|
||||||
{% set v1 = "6SjzrVGxcS" %}
|
{% set v1 = "6MfcbDZldp" %}
|
||||||
{% set v2 = "Ii3JYKIhb0" %}
|
{% set v2 = "Ii3JYKIhb0" %}
|
||||||
{% set v3 = "4TRCinLWfk" %}
|
{% set v3 = "6MfcbDZldp" %}
|
||||||
|
|
||||||
{#
|
{#
|
||||||
These will be the links in the homepage and the No-JS uploader.
|
These will be the links in the homepage and the No-JS uploader.
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
<script type="text/javascript" src="libs/lazyload/lazyload.min.js?v={{ globals.v3 }}"></script>
|
<script type="text/javascript" src="libs/lazyload/lazyload.min.js?v={{ globals.v3 }}"></script>
|
||||||
<script type="text/javascript" src="js/home.js?v={{ globals.v1 }}"></script>
|
<script type="text/javascript" src="js/home.js?v={{ globals.v1 }}"></script>
|
||||||
<script type="text/javascript" src="js/sharex.js?v={{ globals.v1 }}"></script>
|
<script type="text/javascript" src="js/sharex.js?v={{ globals.v1 }}"></script>
|
||||||
|
<script type="text/javascript" src="js/render.js?v={{ globals.v1 }}"></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
@ -126,7 +127,7 @@
|
|||||||
{% include "_partial/links.njk" %}
|
{% include "_partial/links.njk" %}
|
||||||
|
|
||||||
{% if gitHash -%}
|
{% if gitHash -%}
|
||||||
<p>Git commit: <a href="https://github.com/BobbyWibowo/lolisafe/commit/{{ gitHash }}" target="_blank" rel="noopener">{{ gitHash }}</a></p>
|
<p class="git-commit">Git commit: <a class="is-dotted" href="https://github.com/BobbyWibowo/lolisafe/commit/{{ gitHash }}" target="_blank" rel="noopener">{{ gitHash }}</a></p>
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|