* Added "create new album" button at homepage uploader. Due to this, albums list will always be shown even when you don't have any albums (and of course the list will be empty).
Preview: https://i.fiery.me/ITQ5.mp4 (ignore the fact that the prompt says "Edit album", it's been fixed before this commit goes live)

* Refactored various bits of the codes to use async/await instead of Promise.then. This will obviously cause the browser's requirement to raise but hell, it's the modern browsers age.

* Various other code improvements.
This commit is contained in:
Bobby Wibowo 2018-05-06 21:14:57 +07:00
parent 08410faa9a
commit 9e069f5a9a
No known key found for this signature in database
GPG Key ID: 51C3A1E1E22D26CF
8 changed files with 676 additions and 597 deletions

View File

@ -84,7 +84,7 @@ albumsController.create = async (req, res, next) => {
})
if (!identifier) { return }
await db.table('albums').insert({
const ids = await db.table('albums').insert({
name,
enabled: 1,
userid: user.id,
@ -92,11 +92,11 @@ albumsController.create = async (req, res, next) => {
timestamp: Math.floor(Date.now() / 1000),
editedAt: 0,
zipGeneratedAt: 0,
download: 1,
public: 1
download: (req.body.download === false || req.body.download === 0) ? 0 : 1,
public: (req.body.public === false || req.body.public === 0) ? 0 : 1
})
return res.json({ success: true })
return res.json({ success: true, id: ids[0] })
}
albumsController.getUniqueRandomName = () => {

View File

@ -3,32 +3,6 @@
display: none
}
.button.is-breeze {
background-color: #3794d2;
border-color: transparent;
color: #fff;
}
.button.is-breeze.is-hovered,
.button.is-breeze:hover {
background-color: #60a8dc;
border-color: transparent;
color: #fff;
}
.button.is-breeze.is-active,
.button.is-breeze:active {
background-color: #60a8dc;
border-color: transparent;
color: #fff;
}
.button.is-breeze.is-focus,
.button.is-breeze:focus {
border-color: transparent;
color: #fff;
}
html {
background-color: #232629;
}

View File

@ -24,6 +24,7 @@
max-height: 200px;
}
/*
#dropzone {
border: 1px solid #dbdbdb;
background-color: rgba(0, 0, 0, 0);
@ -46,6 +47,7 @@
text-align: center;
cursor: pointer;
}
*/
#dropzone * {
pointer-events: none;
@ -154,7 +156,7 @@
word-break: break-all;
}
.link > a {
.link>a {
word-break: break-all;
}

View File

@ -66,3 +66,29 @@ hr {
.input:-ms-input-placeholder {
color: #7f8c8d;
}
.button.is-breeze {
background-color: #3794d2;
border-color: transparent;
color: #fff;
}
.button.is-breeze.is-hovered,
.button.is-breeze:hover {
background-color: #60a8dc;
border-color: transparent;
color: #fff;
}
.button.is-breeze.is-active,
.button.is-breeze:active {
background-color: #60a8dc;
border-color: transparent;
color: #fff;
}
.button.is-breeze.is-focus,
.button.is-breeze:focus {
border-color: transparent;
color: #fff;
}

File diff suppressed because it is too large Load Diff

View File

@ -13,6 +13,8 @@ const page = {
// store album id that will be used with upload requests
album: null,
albumSelect: null,
dropzone: null,
clipboardJS: null,
lazyLoad: null
@ -20,22 +22,22 @@ const page = {
const imageExtensions = ['.webp', '.jpg', '.jpeg', '.bmp', '.gif', '.png']
page.checkIfPublic = () => {
axios.get('api/check')
.then(response => {
page.private = response.data.private
page.enableUserAccounts = response.data.enableUserAccounts
page.maxFileSize = response.data.maxFileSize
page.chunkedUploads = response.data.chunkedUploads
page.preparePage()
})
page.checkIfPublic = async () => {
const response = await axios.get('api/check')
.catch(error => {
console.log(error)
const button = document.getElementById('loginToUpload')
button.className = button.className.replace(' is-loading', '')
button.classList.remove('is-loading')
button.innerText = 'Error occurred. Reload the page?'
return swal('An error occurred!', 'There was an error with the request, please check the console for more information.', 'error')
})
if (!response) { return }
page.private = response.data.private
page.enableUserAccounts = response.data.enableUserAccounts
page.maxFileSize = response.data.maxFileSize
page.chunkedUploads = response.data.chunkedUploads
page.preparePage()
}
page.preparePage = () => {
@ -45,7 +47,7 @@ page.preparePage = () => {
} else {
const button = document.getElementById('loginToUpload')
button.href = 'auth'
button.className = button.className.replace(' is-loading', '')
button.classList.remove('is-loading')
if (page.enableUserAccounts) {
button.innerText = 'Anonymous upload is disabled. Log in to page.'
@ -58,71 +60,52 @@ page.preparePage = () => {
}
}
page.verifyToken = (token, reloadOnError) => {
page.verifyToken = async (token, reloadOnError) => {
if (reloadOnError === undefined) { reloadOnError = false }
axios.post('api/tokens/verify', { token })
.then(response => {
if (response.data.success === false) {
swal({
title: 'An error occurred!',
text: response.data.description,
icon: 'error'
}).then(() => {
if (reloadOnError) {
localStorage.removeItem('token')
location.reload()
}
})
return
}
localStorage.token = token
page.token = token
return page.prepareUpload()
})
const response = await axios.post('api/tokens/verify', { token })
.catch(error => {
console.log(error)
return swal('An error occurred!', 'There was an error with the request, please check the console for more information.', 'error')
})
if (!response) { return }
if (response.data.success === false) {
await swal({
title: 'An error occurred!',
text: response.data.description,
icon: 'error'
})
if (reloadOnError) {
localStorage.removeItem('token')
location.reload()
}
return
}
localStorage.token = token
page.token = token
return page.prepareUpload()
}
page.prepareUpload = () => {
// I think this fits best here because we need to check for a valid token before we can get the albums
if (page.token) {
const select = document.getElementById('albumSelect')
page.albumSelect = document.getElementById('albumSelect')
select.addEventListener('change', () => {
page.album = parseInt(select.value)
page.albumSelect.addEventListener('change', () => {
page.album = parseInt(page.albumSelect.value)
})
axios.get('api/albums', { headers: { token: page.token } })
.then(res => {
const albums = res.data.albums
page.prepareAlbums()
// If the user doesn't have any albums we don't really need to display
// an album selection
if (albums.length === 0) { return }
// Loop through the albums and create an option for each album
for (const album of albums) {
const opt = document.createElement('option')
opt.value = album.id
opt.innerHTML = album.name
select.appendChild(opt)
}
// Display the album selection
document.getElementById('albumDiv').style.display = 'block'
})
.catch(error => {
console.log(error)
return swal('An error occurred!', 'There was an error with the request, please check the console for more information.', 'error')
})
// Display the album selection
document.getElementById('albumDiv').style.display = 'flex'
}
const div = document.createElement('div')
div.id = 'dropzone'
div.className = 'button is-unselectable'
div.className = 'button is-danger is-unselectable'
div.innerHTML = `
<span class="icon">
<i class="icon-upload-cloud"></i>
@ -143,6 +126,40 @@ page.prepareUpload = () => {
page.prepareDropzone()
}
page.prepareAlbums = async () => {
const option = document.createElement('option')
option.value = ''
option.innerHTML = 'Upload to album'
option.disabled = true
option.selected = true
page.albumSelect.appendChild(option)
const response = await axios.get('api/albums', { headers: { token: page.token } })
.catch(error => {
console.log(error)
return swal('An error occurred!', 'There was an error with the request, please check the console for more information.', 'error')
})
if (!response) { return }
if (response.data.success === false) {
return swal('An error occurred!', response.data.description, 'error')
}
const albums = response.data.albums
// If the user doesn't have any albums we don't really need to display
// an album selection
if (albums.length === 0) { return }
// Loop through the albums and create an option for each album
for (const album of albums) {
const option = document.createElement('option')
option.value = album.id
option.innerHTML = album.name
page.albumSelect.appendChild(option)
}
}
page.prepareDropzone = () => {
const previewNode = document.querySelector('#template')
previewNode.id = ''
@ -169,8 +186,7 @@ page.prepareDropzone = () => {
file.previewElement.querySelector('.progress').innerHTML = '100%'
// The API supports an array of multiple files
const response = await axios.post(
'api/upload/finishchunks',
const response = await axios.post('api/upload/finishchunks',
{
files: [{
uuid: file.upload.uuid,
@ -181,9 +197,7 @@ page.prepareDropzone = () => {
albumid: page.album
}]
},
{
headers: { token: page.token }
})
{ headers: { token: page.token } })
.then(response => response.data)
.catch(error => {
return {
@ -287,6 +301,69 @@ page.prepareShareX = () => {
}
}
page.createAlbum = async () => {
const div = document.createElement('div')
div.innerHTML = `
<div class="field">
<label class="label">Album name</label>
<div class="controls">
<input id="_name" class="input" type="text" placeholder="My super album">
</div>
</div>
<div class="field">
<div class="control">
<label class="checkbox">
<input id="_download" type="checkbox" checked>
Enable download
</label>
</div>
</div>
<div class="field">
<div class="control">
<label class="checkbox">
<input id="_public" type="checkbox" checked>
Enable public link
</label>
</div>
</div>
`
const value = await swal({
title: 'Create new album',
icon: 'info',
content: div,
buttons: {
cancel: true,
confirm: {
closeModal: false
}
}
})
if (!value) { return }
const name = document.getElementById('_name').value
const response = await axios.post('api/albums', {
name,
download: document.getElementById('_download').checked,
public: document.getElementById('_public').checked
}, { headers: { token: page.token } })
.catch(error => {
console.log(error)
return swal('An error occurred!', 'There was an error with the request, please check the console for more information.', 'error')
})
if (!response) { return }
if (response.data.success === false) {
return swal('An error occurred!', response.data.description, 'error')
}
const option = document.createElement('option')
option.value = response.data.id
option.innerHTML = name
page.albumSelect.appendChild(option)
swal('Woohoo!', 'Album was created successfully', 'success')
}
// Handle image paste event
window.addEventListener('paste', event => {
const items = (event.clipboardData || event.originalEvent.clipboardData).items

View File

@ -12,7 +12,7 @@
v1: CSS and JS files.
v2: Images and config files (manifest.json, browserconfig.xml, etcetera).
#}
{% set v1 = "TsCPSS21gd" %}
{% set v1 = "eB7LXsb2eH" %}
{% set v2 = "MSEpgpfFIQ" %}
{#

View File

@ -34,14 +34,17 @@
<div class="column is-hidden-mobile"></div>
<div id="uploadContainer" class="column">
<a id="loginToUpload" class="button is-danger is-loading" style="display: flex"></a>
<div id="albumDiv" class="field" style="display: none">
<p class="control select-wrapper">
<span class="select">
<select id="albumSelect">
<option value="">Upload to album</option>
</select>
</span>
</p>
<div id="albumDiv" class="field has-addons" style="display: none">
<div class="control is-expanded">
<div class="select is-fullwidth">
<select id="albumSelect"></select>
</div>
</div>
<div class="control">
<a class="button is-breeze" title="Create new album" onclick="page.createAlbum()">
<i class="icon-plus"></i>
</a>
</div>
</div>
</div>
<div class="column is-hidden-mobile"></div>