* Added "Size" column to list view of uploaded files. The size will be use 'pretty' view (kB, MB, etc).

* Added delete button to thumbs view of uploaded files.

* All instances of "file length" in public views renamed to "file name length". The latter makes more sense.
This commit is contained in:
Bobby Wibowo 2018-03-24 23:45:51 +07:00
parent 20f8fd4957
commit 83f3b36f15
No known key found for this signature in database
GPG Key ID: 51C3A1E1E22D26CF
12 changed files with 142 additions and 77 deletions

View File

@ -97,17 +97,17 @@ authController.getFileLengthConfig = async (req, res, next) => {
authController.changeFileLength = async (req, res, next) => {
if (config.uploads.fileLength.userChangeable === false) {
return res.json({ success: false, description: 'Changing file length is disabled at the moment.' })
return res.json({ success: false, description: 'Changing file name length is disabled at the moment.' })
}
const user = await utils.authorize(req, res)
let fileLength = parseInt(req.body.fileLength)
if (fileLength === undefined) return res.json({ success: false, description: 'No file length provided.' })
if (isNaN(fileLength)) return res.json({ success: false, description: 'File length is not a valid number.' })
if (fileLength === undefined) return res.json({ success: false, description: 'No file name length provided.' })
if (isNaN(fileLength)) return res.json({ success: false, description: 'File name length is not a valid number.' })
if (fileLength < config.uploads.fileLength.min || fileLength > config.uploads.fileLength.max) {
return res.json({ success: false, description: `File length must be ${config.uploads.fileLength.min} to ${config.uploads.fileLength.max} characters` })
return res.json({ success: false, description: `File name length must be ${config.uploads.fileLength.min} to ${config.uploads.fileLength.max} characters` })
}
if (fileLength === user.fileLength) {

View File

@ -259,7 +259,7 @@ uploadsController.list = async (req, res) => {
.orderBy('id', 'DESC')
.limit(25)
.offset(25 * offset)
.select('id', 'albumid', 'timestamp', 'name', 'userid')
.select('id', 'albumid', 'timestamp', 'name', 'userid', 'size')
const albums = await db.table('albums')
let basedomain = config.domain
@ -269,6 +269,7 @@ uploadsController.list = async (req, res) => {
file.file = `${basedomain}/${file.name}`
file.date = new Date(file.timestamp * 1000)
file.date = utils.getPrettyDate(file.date)
file.size = utils.getPrettyBytes(parseInt(file.size))
file.album = ''

View File

@ -5,6 +5,8 @@ const gm = require('gm')
const ffmpeg = require('fluent-ffmpeg')
const db = require('knex')(config.database)
const units = ['B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
const utilsController = {}
utilsController.imageExtensions = ['.jpg', '.jpeg', '.bmp', '.gif', '.png']
utilsController.videoExtensions = ['.webm', '.mp4', '.wmv', '.avi', '.mov']
@ -21,6 +23,22 @@ utilsController.getPrettyDate = function (date) {
date.getSeconds()
}
utilsController.getPrettyBytes = function (num) {
// MIT License
// Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
if (!Number.isFinite(num)) return num
const neg = num < 0
if (neg) num = -num
if (num < 1) return (neg ? '-' : '') + num + ' B'
const exponent = Math.min(Math.floor(Math.log10(num) / 3), units.length - 1)
const numStr = Number((num / Math.pow(1000, exponent)).toPrecision(3))
const unit = units[exponent]
return (neg ? '-' : '') + numStr + ' ' + unit
}
utilsController.authorize = async (req, res) => {
const token = req.headers.token
if (token === undefined) return res.status(401).json({ success: false, description: 'No token provided.' })

View File

@ -11,7 +11,7 @@
<!-- Stylesheets and scripts -->
<link rel="stylesheet" type="text/css" href="libs/bulma/bulma.min.css?v=V2RnA3Mwhh">
<link rel="stylesheet" type="text/css" href="css/style.css?v=ugMWEbHDxs">
<link rel="stylesheet" type="text/css" href="css/style.css?v=XcTZuW9fFV">
<script type="text/javascript" src="libs/sweetalert/sweetalert.min.js?v=V2RnA3Mwhh"></script>
<script type="text/javascript" src="libs/axios/axios.min.js?v=V2RnA3Mwhh"></script>
<script type="text/javascript" src="js/album.js?v=V2RnA3Mwhh"></script>

View File

@ -12,7 +12,7 @@
<!-- Stylesheets and scripts -->
<link rel="stylesheet" type="text/css" href="libs/bulma/bulma.min.css?v=V2RnA3Mwhh">
<link rel="stylesheet" type="text/css" href="libs/fontello/fontello.css?v=V2RnA3Mwhh">
<link rel="stylesheet" type="text/css" href="css/style.css?v=ugMWEbHDxs">
<link rel="stylesheet" type="text/css" href="css/style.css?v=XcTZuW9fFV">
<script type="text/javascript" src="libs/sweetalert/sweetalert.min.js?v=V2RnA3Mwhh"></script>
<script type="text/javascript" src="libs/axios/axios.min.js?v=V2RnA3Mwhh"></script>
<script type="text/javascript" src="js/auth.js?v=V2RnA3Mwhh"></script>
@ -50,7 +50,10 @@
<meta name="theme-color" content="#232629">
<style>
/** Colors based on KDE Breeze Dark **/
/* ------------------
COLORS BASED ON
KDE BREEZE DARK
------------------ */
section#login {
background-color: #232629;
}

View File

@ -12,11 +12,11 @@
<!-- Stylesheets and scripts -->
<link rel="stylesheet" type="text/css" href="libs/bulma/bulma.min.css?v=V2RnA3Mwhh">
<link rel="stylesheet" type="text/css" href="libs/fontello/fontello.css?v=V2RnA3Mwhh">
<link rel="stylesheet" type="text/css" href="css/style.css?v=ugMWEbHDxs">
<link rel="stylesheet" type="text/css" href="css/dashboard.css?v=V2RnA3Mwhh">
<link rel="stylesheet" type="text/css" href="css/style.css?v=XcTZuW9fFV">
<link rel="stylesheet" type="text/css" href="css/dashboard.css?v=XcTZuW9fFV">
<script type="text/javascript" src="libs/sweetalert/sweetalert.min.js?v=V2RnA3Mwhh"></script>
<script type="text/javascript" src="libs/axios/axios.min.js?v=V2RnA3Mwhh"></script>
<script type="text/javascript" src="js/dashboard.js?v=fna8s7BYGe"></script>
<script type="text/javascript" src="js/dashboard.js?v=XcTZuW9fFV"></script>
<!-- Open Graph tags -->
<meta property="og:type" content="website" />
@ -108,7 +108,7 @@
<p class="menu-label">Administration</p>
<ul class="menu-list">
<li>
<a id="itemFileLength" onclick="panel.changeFileLength()">Preferred file length</a>
<a id="itemFileLength" onclick="panel.changeFileLength()">Preferred file name length</a>
</li>
<li>
<a id="itemTokens" onclick="panel.changeToken()">Manage your token</a>

View File

@ -11,7 +11,7 @@
<!-- Stylesheets and scripts -->
<link rel="stylesheet" type="text/css" href="libs/bulma/bulma.min.css?v=V2RnA3Mwhh">
<link rel="stylesheet" type="text/css" href="css/style.css?v=ugMWEbHDxs">
<link rel="stylesheet" type="text/css" href="css/style.css?v=XcTZuW9fFV">
<!-- Open Graph tags -->
<meta property="og:type" content="website" />
@ -46,7 +46,10 @@
<meta name="theme-color" content="#232629">
<style>
/** Colors based on KDE Breeze Dark **/
/* ------------------
COLORS BASED ON
KDE BREEZE DARK
------------------ */
.message-body {
color: #eff0f1;
background-color: #31363b;
@ -79,7 +82,9 @@
<h2 class='subtitle'>How can I keep track of my uploads?</h2>
<article class="message">
<div class="message-body">
Simply create a user on the site and every upload will be associated with your account, granting you access to your uploaded files through our dashboard.
Simply create a user on the site and every upload will be associated with your account, granting you access to your uploaded files through our dashboard.<br>
<br>
By having an account, you will also be able to set a preferred file name length!
</div>
</article>

View File

@ -11,7 +11,7 @@
<!-- Stylesheets and scripts -->
<link rel="stylesheet" type="text/css" href="libs/bulma/bulma.min.css?v=V2RnA3Mwhh">
<link rel="stylesheet" type="text/css" href="css/style.css?v=ugMWEbHDxs">
<link rel="stylesheet" type="text/css" href="css/style.css?v=XcTZuW9fFV">
<script type="text/javascript" src="libs/sweetalert/sweetalert.min.js?v=V2RnA3Mwhh"></script>
<script type="text/javascript" src="libs/dropzone/dropzone.min.js?v=V2RnA3Mwhh"></script>
<script type="text/javascript" src="libs/axios/axios.min.js?v=V2RnA3Mwhh"></script>

View File

@ -1,4 +1,8 @@
/** Colors based on KDE Breeze Dark **/
/* ------------------
COLORS BASED ON
KDE BREEZE DARK
------------------ */
html {
background-color: #232629;
}
@ -25,7 +29,8 @@ html {
background-color: #2980b9;
}
.button.is-primary.is-hovered, .button.is-primary:hover {
.button.is-primary.is-hovered,
.button.is-primary:hover {
background-color: #2980b9;
}
@ -35,7 +40,9 @@ html {
background-color: #31363b;
}
.pagination-link:hover, .pagination-next:hover, .pagination-previous:hover {
.pagination-link:hover,
.pagination-next:hover,
.pagination-previous:hover {
color: #eff0f1;
border-color: #3daee9;
background-color: #31363b;
@ -50,15 +57,19 @@ html {
background-color: #31363b;
}
.table tr:hover, .table.is-striped tbody tr:nth-child(2n) {
.table tr:hover,
.table.is-striped tbody tr:nth-child(2n) {
background: none;
}
.table.is-striped tbody tr:hover, .table.is-striped tbody tr:nth-child(2n):hover, .tag {
.table.is-striped tbody tr:hover,
.table.is-striped tbody tr:nth-child(2n):hover,
.tag {
background-color: #4d4d4d;
}
.table thead td, .table thead th {
.table thead td,
.table thead th {
color: #eff0f1;
background-color: #ff3860;
}
@ -67,14 +78,57 @@ html {
color: #eff0f1;
}
.table td, .table th {
.table td,
.table th {
border: 0;
}
section#dashboard div#table div.column {
background-color: #31363b;
}
.menu-list li ul {
border-left-color: #898b8d;
}
section#dashboard .table {
font-size: 12px
}
section#dashboard div#table div.column {
display:flex;
/*
width: 200px;
height: 200px;
*/
margin: 9px;
background-color: #31363b;
overflow: hidden;
align-items: center;
}
section#dashboard div#table div.column .title {
width: 200px;
line-height: 200px;
font-weight: normal;
}
section#dashboard div#table div.column a.image {
width: 100%;
}
section#dashboard div#table div.column a.image img {
width:200px;
}
section#dashboard div#table div.column.image-container {
position: relative;
}
section#dashboard div#table div.column a.button {
position: absolute;
top: 10px;
right: 10px;
background-color: #31363b;
}
section#dashboard div#table div.column a.button:hover,
section#dashboard div#table div.column a.button:active {
background-color: #ff3860;
}

View File

@ -78,20 +78,6 @@ section#home div#uploads { margin-bottom: 25px; }
PANEL
------------------ */
/*
section#login input, section#login p.control a.button {
border-left: 0px;
border-top: 0px;
border-right: 0px;
border-radius: 0px;
box-shadow: 0 0 0;
}
section#login p.control a.button { margin-left: 10px; }
section#login p.control a#loginBtn { border-right: 0px; }
section#login p.control a#registerBtn { border-left: 0px; }
*/
section#auth, section#dashboard { display: none }
section#auth input { background: rgba(0, 0, 0, 0); }
section#auth input, section#auth a {
@ -102,17 +88,15 @@ section#auth input, section#auth a {
box-shadow: 0 0 0;
}
section#dashboard .table { font-size: 12px }
section#dashboard div#table div.column { display:flex; /* width: 200px; height: 200px; */ margin: 9px; background: #f9f9f9; overflow: hidden; align-items: center; }
section#dashboard div#table div.column a { width: 100%; }
section#dashboard div#table div.column a img { width:200px; }
.select-wrapper {
text-align: center;
margin-bottom: 10px;
}
/** Colors based on KDE Breeze Dark **/
/* ------------------
COLORS BASED ON
KDE BREEZE DARK
------------------ */
.hero {
background-color: #232629;
@ -157,12 +141,6 @@ hr {
overflow-x: auto;
}
/*
.textarea, .input {
border-width: 2px;
}
*/
#login .input {
border-top: 0;
border-right: 0;
@ -176,7 +154,14 @@ hr {
border-radius: 0;
}
.input.is-active, .input.is-focused, .input:active, .input:focus, .textarea.is-active, .textarea.is-focused, .textarea:active, .textarea:focus {
.input.is-active,
.input.is-focused,
.input:active,
.input:focus,
.textarea.is-active,
.textarea.is-focused,
.textarea:active,
.textarea:focus {
border-color: #2980b9;
}
@ -184,30 +169,20 @@ hr {
background-color: #da4453;
}
.button.is-danger.is-hovered, .button.is-danger:hover {
.button.is-danger.is-hovered,
.button.is-danger:hover {
background-color: #3daee9;
}
/*
.table.is-striped tbody tr:not(.is-selected):nth-child(2n) {
background-color: #383c41;
}
*/
.table.is-hoverable tbody tr:not(.is-selected):hover {
background-color: #4d4d4d;
}
.table td, .table th {
.table td,
.table th {
vertical-align: middle;
}
section#dashboard div#table div.column .title {
width: 200px;
line-height: 200px;
font-weight: normal;
}
.help {
color: #7f8c8d;
}

View File

@ -118,7 +118,7 @@ panel.getUploads = function (album = undefined, page = undefined) {
<i class="fa icon-list-bullet"></i>
</span>
</a>
<a class="button is-small is-outlined is-danger" title="List view" onclick="panel.setFilesView('thumbs', ${album}, ${page})">
<a class="button is-small is-outlined is-danger" title="Thumbs view" onclick="panel.setFilesView('thumbs', ${album}, ${page})">
<span class="icon is-small">
<i class="fa icon-th-large"></i>
</span>
@ -143,12 +143,19 @@ panel.getUploads = function (album = undefined, page = undefined) {
for (item of response.data.files) {
var div = document.createElement('div')
div.className = 'column is-narrow'
div.className = 'image-container column is-narrow'
if (item.thumb !== undefined) {
div.innerHTML = `<a href="${item.file}" target="_blank"><img src="${item.thumb}"/></a>`
div.innerHTML = `<a class="image" href="${item.file}" target="_blank"><img src="${item.thumb}"/></a>`
} else {
div.innerHTML = `<a href="${item.file}" target="_blank"><h1 class="title">.${item.file.split('.').pop()}</h1></a>`
div.innerHTML = `<a class="image" href="${item.file}" target="_blank"><h1 class="title">.${item.file.split('.').pop()}</h1></a>`
}
div.innerHTML += `
<a class="button is-small is-danger is-outlined" title="Delete album" onclick="panel.deleteFile(${item.id})">
<span class="icon is-small">
<i class="fa icon-trash"></i>
</span>
</a>
`
table.appendChild(div)
}
} else {
@ -165,6 +172,7 @@ panel.getUploads = function (album = undefined, page = undefined) {
<tr>
<th>File</th>
<th>${albumOrUser}</th>
<th>Size</th>
<th>Date</th>
<th></th>
</tr>
@ -193,6 +201,7 @@ panel.getUploads = function (album = undefined, page = undefined) {
<tr>
<th><a href="${item.file}" target="_blank">${item.file}</a></th>
<th>${displayAlbumOrUser}</th>
<td>${item.size}</td>
<td>${item.date}</td>
<td>
<a class="button is-small is-danger is-outlined" title="Delete album" onclick="panel.deleteFile(${item.id})">
@ -475,19 +484,19 @@ panel.changeFileLength = function () {
}
panel.page.innerHTML = `
<h2 class="subtitle">Preferred file length</h2>
<h2 class="subtitle">Preferred file name length</h2>
<div class="field">
<label class="label">Your current file length:</label>
<label class="label">Your current file name length:</label>
<div class="field has-addons">
<div class="control is-expanded">
<input id="fileLength" class="input" type="text" placeholder="Your file length" value="${response.data.fileLength ? Math.min(Math.max(response.data.fileLength, response.data.config.min), response.data.config.max) : response.data.config.default}">
</div>
<div class="control">
<a id="setFileLength" class="button is-primary">Set file length</a>
<a id="setFileLength" class="button is-primary">Set file name length</a>
</div>
</div>
<p class="help">Default file length is <b>${response.data.config.default}</b> characters. ${response.data.config.userChangeable ? `Range allowed for user is <b>${response.data.config.min}</b> to <b>${response.data.config.max}</b> characters.` : 'Changing file length is disabled at the moment.'}</p>
<p class="help">Default file name length is <b>${response.data.config.default}</b> characters. ${response.data.config.userChangeable ? `Range allowed for user is <b>${response.data.config.min}</b> to <b>${response.data.config.max}</b> characters.` : 'Changing file name length is disabled at the moment.'}</p>
</div>
`

View File

@ -11,7 +11,7 @@
<!-- Stylesheets and scripts -->
<link rel="stylesheet" type="text/css" href="../libs/bulma/bulma.min.css?v=V2RnA3Mwhh">
<link rel="stylesheet" type="text/css" href="../css/style.css?v=ugMWEbHDxs">
<link rel="stylesheet" type="text/css" href="../css/style.css?v=XcTZuW9fFV">
<script type="text/javascript" src="../libs/sweetalert/sweetalert.min.js?v=V2RnA3Mwhh"></script>
<script type="text/javascript" src="../libs/axios/axios.min.js?v=V2RnA3Mwhh"></script>