Frontend done

This commit is contained in:
kanadeko 2017-01-14 05:50:18 -03:00
parent 7b01e7b40c
commit a246fc8365
9 changed files with 215 additions and 105 deletions

View File

@ -1,5 +1,13 @@
module.exports = {
/*
NOTES:
All folders specified on this file will be created automagically.
Most options shouldn't be touched, and the service should run straight up.
*/
// Port on which to run the server
port: 9999,
@ -12,7 +20,8 @@ module.exports = {
// If not, which IP's should be able to access?
IPs: [
'::1',
'127.0.0.1'
'127.0.0.1',
'186.19.241.189'
]
},
@ -23,20 +32,24 @@ module.exports = {
folder: 'uploads',
// Max file size allowed
maxsize: '512MB'
maxsize: '512MB',
// The length of the random generated name for the uploaded files
fileLength: 4,
// Prefix before linking an uploaded file. Ex: your-domain.com/prefix/k4n4.png
// Leave blank for no prefix
prefix: ''
},
// Folder where to store logs
logsFolder: 'logs',
// The length of the random generated name for the uploaded files
fileLength: 4,
// The following values shouldn't be touched
database: {
client: 'sqlite3',
connection: {
filename: './db'
filename: './database/db'
},
useNullAsDefault: true
}

View File

@ -11,7 +11,7 @@ const storage = multer.diskStorage({
cb(null, './' + config.uploads.folder + '/')
},
filename: function (req, file, cb) {
cb(null, randomstring.generate(config.fileLength) + path.extname(file.originalname))
cb(null, randomstring.generate(config.uploads.fileLength) + path.extname(file.originalname))
}
})

19
database/db.js Normal file
View File

@ -0,0 +1,19 @@
let init = function(db){
// Create the tables we need to store galleries and files
db.schema.createTableIfNotExists('gallery', function (table) {
table.increments()
table.string('name')
table.timestamps()
}).then(() => {})
db.schema.createTableIfNotExists('files', function (table) {
table.increments()
table.string('file')
table.integer('galleryid')
}).then(() => {})
}
module.exports = init

View File

@ -1,17 +1,22 @@
const config = require('./config.js')
const routes = require('./routes.js')
const routes = require('./routes/routes.js')
const express = require('express')
const db = require('knex')(config.database)
const fs = require('fs')
const safe = express()
require('./database/db.js')(db)
fs.existsSync('./' + config.uploads.folder) || fs.mkdirSync('./' + config.uploads.folder)
fs.existsSync('./' + config.logsFolder) || fs.mkdirSync('./' + config.logsFolder)
fs.existsSync('db') || fs.writeFile('db', '')
safe.enable('trust proxy')
safe.use('/', express.static('./uploads'))
let prefix = config.uploads.prefix
if( prefix !== '' )
prefix = prefix + '/'
safe.use('/' + prefix, express.static('./uploads'))
safe.use('/', express.static('./public'))
safe.use('/api' , routes)
@ -25,17 +30,4 @@ safe.use(function (err, req, res, next) {
res.status(500).end()
})
// Create the tables we need to store galleries and files
db.schema.createTableIfNotExists('gallery', function (table) {
table.increments()
table.string('name')
table.timestamps()
}).then(() => {})
db.schema.createTableIfNotExists('files', function (table) {
table.increments()
table.string('file')
table.integer('galleryid')
}).then(() => {})
safe.listen(config.port, () => console.log(`loli-safe started on port ${config.port}`))

75
public/css/style.css Normal file
View File

@ -0,0 +1,75 @@
/* ------------------
HOME
------------------ */
#b {
-webkit-animation-delay: 0.5s;
animation-delay: 0.5s;
-webkit-animation-duration: 1.5s;
animation-duration: 1.5s;
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
-webkit-animation-name: floatUp;
animation-name: floatUp;
-webkit-animation-timing-function: cubic-bezier(0, 0.71, 0.29, 1);
animation-timing-function: cubic-bezier(0, 0.71, 0.29, 1);
border-radius: 24px;
display: inline-block;
height: 240px;
margin-bottom: 40px;
position: relative;
vertical-align: top;
width: 240px;
box-shadow: 0 20px 60px rgba(10, 10, 10, 0.05), 0 5px 10px rgba(10, 10, 10, 0.1), 0 1px 1px rgba(10, 10, 10, 0.2);
}
div#dropzone {
border: 1px solid #dbdbdb;
background-color: rgba(0, 0, 0, 0);
border-color: #ff3860;
color: #ff3860;
display: flex;
width: 100%;
border-radius: 3px;
box-shadow: none;
height: 2.5em;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
user-select: none;
justify-content: center;
padding-left: .75em;
padding-right: .75em;
text-align: center;
cursor: pointer;
}
div#dropzone:hover {
background-color: #ff3860;
border-color: #ff3860;
color: #fff;
}
img.logo { height: 200px; margin-top: 20px; }
.dz-preview .dz-details { display: flex; }
.dz-preview .dz-details .dz-size, .dz-preview .dz-details .dz-filename { flex: 1 }
.dz-preview img, .dz-preview .dz-success-mark, .dz-preview .dz-error-mark { display: none }
@keyframes floatUp {
0% {
opacity: 0;
box-shadow: 0 0 0 rgba(10, 10, 10, 0), 0 0 0 rgba(10, 10, 10, 0), 0 0 0 rgba(10, 10, 10, 0);
-webkit-transform: scale(0.86);
transform: scale(0.86);
}
25% { opacity: 100; }
67% {
box-shadow: 0 0 0 rgba(10, 10, 10, 0), 0 5px 10px rgba(10, 10, 10, 0.1), 0 1px 1px rgba(10, 10, 10, 0.2);
-webkit-transform: scale(1);
transform: scale(1);
}
100% {
box-shadow: 0 20px 60px rgba(10, 10, 10, 0.05), 0 5px 10px rgba(10, 10, 10, 0.1), 0 1px 1px rgba(10, 10, 10, 0.2);
-webkit-transform: scale(1);
transform: scale(1);
}
}

View File

@ -1 +1,47 @@
404
<!DOCTYPE html>
<html>
<head>
<title>loli-safe</title>
<link href='//fonts.googleapis.com/css?family=Lato:100' rel='stylesheet' type='text/css'>
<style>
html, body {
height: 100%;
}
body {
margin: 0;
padding: 0;
width: 100%;
color: #B0BEC5;
display: table;
font-weight: 100;
font-family: 'Lato';
}
.container {
text-align: center;
display: table-cell;
vertical-align: middle;
}
.content {
text-align: center;
display: inline-block;
}
.title {
font-size: 72px;
margin-bottom: 40px;
}
</style>
</head>
<body>
<div class="container">
<div class="content">
<div class="title">Page not found.</div>
</div>
</div>
</body>
</html>

View File

@ -3,62 +3,8 @@
<head>
<title>loli-safe - A self hosted upload service</title>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.3.0/css/bulma.min.css">
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/dropzone/4.3.0/min/dropzone.min.css">
<link rel="stylesheet" type="text/css" href="/css/style.css">
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/dropzone/4.3.0/min/dropzone.min.js"></script>
<style type="text/css">
#b {
-webkit-animation-delay: 0.5s;
animation-delay: 0.5s;
-webkit-animation-duration: 1.5s;
animation-duration: 1.5s;
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
-webkit-animation-name: floatUp;
animation-name: floatUp;
-webkit-animation-timing-function: cubic-bezier(0, 0.71, 0.29, 1);
animation-timing-function: cubic-bezier(0, 0.71, 0.29, 1);
border-radius: 24px;
display: inline-block;
height: 240px;
margin-bottom: 40px;
position: relative;
vertical-align: top;
width: 240px;
box-shadow: 0 20px 60px rgba(10, 10, 10, 0.05), 0 5px 10px rgba(10, 10, 10, 0.1), 0 1px 1px rgba(10, 10, 10, 0.2);
}
img.logo {
height: 200px;
margin-top: 20px;
}
.dz-preview .dz-details { display: flex; }
.dz-preview .dz-details .dz-size, .dz-preview .dz-details .dz-filename { flex: 1 }
.dz-preview img, .dz-preview .dz-success-mark, .dz-preview .dz-error-mark { display: none }
@keyframes floatUp {
0% {
opacity: 0;
box-shadow: 0 0 0 rgba(10, 10, 10, 0), 0 0 0 rgba(10, 10, 10, 0), 0 0 0 rgba(10, 10, 10, 0);
-webkit-transform: scale(0.86);
transform: scale(0.86);
}
25% {
opacity: 100;
}
67% {
box-shadow: 0 0 0 rgba(10, 10, 10, 0), 0 5px 10px rgba(10, 10, 10, 0.1), 0 1px 1px rgba(10, 10, 10, 0.2);
-webkit-transform: scale(1);
transform: scale(1);
}
100% {
box-shadow: 0 20px 60px rgba(10, 10, 10, 0.05), 0 5px 10px rgba(10, 10, 10, 0.1), 0 1px 1px rgba(10, 10, 10, 0.2);
-webkit-transform: scale(1);
transform: scale(1);
}
}
</style>
</head>
<body>
@ -78,15 +24,7 @@
<div class="columns">
<div class="column"></div>
<div class="column">
<a class="button is-danger is-outlined is-fullwidth" id="upload-button">Upload files</a>
</div>
<div class="column"></div>
</div>
<div class="columns">
<div class="column"></div>
<div class="column">
<div class="notification" id="dropzone">Or drag and drop files here</div>
<div id="dropzone">Click here or drag and drop files</div>
</div>
<div class="column"></div>
</div>
@ -112,7 +50,25 @@
</section>
<script type="text/javascript">
var maxSize = '512';
var urlPrefix = '';
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == XMLHttpRequest.DONE) {
if(xhr.responseText.maxFileSize)
maxSize = xhr.responseText.maxFileSize
if(xhr.responseText.urlPrefix)
urlPrefix = xhr.responseText.urlPrefix + '/'
}
}
xhr.open('GET', '/api/info', true);
xhr.send(null);
window.onload = function () {
var previewNode = document.querySelector("#template");
previewNode.id = "";
var previewTemplate = previewNode.parentNode.innerHTML;
@ -121,7 +77,7 @@
var dropzone = new Dropzone('div#dropzone', {
url: '/api/upload',
paramName: 'file',
maxFilesize: 512,
maxFilesize: maxSize,
parallelUploads: 2,
uploadMultiple: false,
previewsContainer: 'div#uploads',
@ -137,14 +93,15 @@
});
dropzone.on("success", function(file, response) {
// Handle the responseText here. For example, add the text to the preview element:
a = document.createElement('a');
a.href = 'https://i.kanacchi.moe/' + response.filename;
a.innerHTML = response.filename;
// Handle the responseText here. For example, add the text to the preview element:
a = document.createElement('a');
a.href = window.location.origin + '/' + urlPrefix + response.filename;
a.target = '_blank';
a.innerHTML = response.filename;
file.previewTemplate.querySelector(".progress").style.display = 'none';
file.previewTemplate.querySelector(".link").appendChild(a);
});
file.previewTemplate.querySelector(".progress").style.display = 'none';
file.previewTemplate.querySelector(".link").appendChild(a);
});
};
</script>

View File

@ -1,9 +0,0 @@
const routes = require('express').Router()
const uploadController = require('./controllers/uploadController')
const galleryController = require('./controllers/galleryController')
routes.post ('/upload', (req, res, next) => uploadController.upload(req, res, next))
routes.get ('/gallery', (req, res, next) => galleryController.list(req, res, next))
routes.get ('/gallery/test', (req, res, next) => galleryController.test(req, res, next))
module.exports = routes

17
routes/routes.js Normal file
View File

@ -0,0 +1,17 @@
const config = require('../config.js')
const routes = require('express').Router()
const uploadController = require('../controllers/uploadController')
const galleryController = require('../controllers/galleryController')
routes.get ('/info', (req, res, next) => {
res.json({
maxFileSize: config.uploads.maxsize.slice(0, -2),
urlPrefix: config.uploads.prefix
})
})
routes.post ('/upload', (req, res, next) => uploadController.upload(req, res, next))
routes.get ('/gallery', (req, res, next) => galleryController.list(req, res, next))
routes.get ('/gallery/test', (req, res, next) => galleryController.test(req, res, next))
module.exports = routes