Merge branch 'typescript'
This commit is contained in:
@@ -1,95 +0,0 @@
|
||||
/* Beforehand i'd like to tell you to not forget to add a width and height attribute to the canvas element, this can be styled with css for the prettyness, but to keep the responsiveness a width of 800 is nice with a height of 640 (if you want it to be a landscape styled right now, in any case a rectangle (not a squire) should be have 1 of the 2 attributes 4/5 like 80/100 or 640/800*/
|
||||
|
||||
/* Global variables */
|
||||
var lastUpdate = Date.now();
|
||||
var myInterval = setInterval(tick, 16.333333333);
|
||||
var config = {
|
||||
images: {
|
||||
width: 40, /* The size the image will be scaled to, dont see this as a must, but as a nicer way because you can remove this if you also remove the 2 parameters from the render function */
|
||||
height: 60,
|
||||
},
|
||||
speed: {
|
||||
x: 5.6, /* A lil tricky because here we define the speed it travels with, but this can be either negative or postive value, so we determine possibility that on the image creation, by adding a * -1 or * 1 ;3 */
|
||||
y: 7 /* Just the speed it travels with vertically, not as tricky as the "x" value */
|
||||
}
|
||||
};
|
||||
|
||||
/* Load in items trough ajax call (in case you keep em in a database, if not you can use it like this as well */
|
||||
|
||||
var img_format = '.png'; /* Use the format you desire */
|
||||
var items = {
|
||||
add: function (img_source) {
|
||||
var img = new Image();
|
||||
img.src = 'img_' + this.length + img_format;
|
||||
|
||||
e.direction = Math.random() < 0.5 ? 1 : -1; /* This is used to know if it's going left or right */
|
||||
e.curX = Math.random() * canvas.width();
|
||||
e.curY = canvas.height();
|
||||
this.push(img);
|
||||
}
|
||||
}
|
||||
|
||||
items.add('your_image_path_plus_name');
|
||||
/*_________*/
|
||||
|
||||
/* The preffered way */
|
||||
var items = {};
|
||||
$.ajax({
|
||||
url: 'your_api_call',
|
||||
success: function (response) {
|
||||
if (typeof {response: 1}) {
|
||||
response.forEach(function (element, index, array) {
|
||||
items.push(element);
|
||||
});
|
||||
|
||||
items.forEach(function (e, i, a) {
|
||||
e.direction = Math.random() < 0.5 ? 1 : -1; /* This is used to know if it's going left or right */
|
||||
e.curX = Math.random() * canvas.width();
|
||||
e.curY = canvas.height();
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (items.length === 0) {
|
||||
console.log(items); /* In possible debug scenario that something went wrong with the add function */
|
||||
console.log('Perhaps you did something wrong with the add functionality therefor no items are being found');
|
||||
}
|
||||
|
||||
/* Lets get the loop going */
|
||||
items.forEach(function (e, i, a) { /* You should know by now that e == element, i == index, a == array
|
||||
e.start_location = Math.random() * canvas.width(); /* This will add its starter location, this could also be defined in either the image loop or the ajax call, but im lazy and i will not write this shit twice */
|
||||
});
|
||||
|
||||
/* The simplest of simple looping skills */
|
||||
function tick() {
|
||||
var now = Date.now();
|
||||
var dt = now - lastUpdate;
|
||||
lastUpdate = now;
|
||||
|
||||
update(dt);
|
||||
render();
|
||||
}
|
||||
|
||||
function update(dt) {
|
||||
/* If game loop does not work, which i guess, take a look at "http://goo.gl/f8sQRD" */
|
||||
items.forEach(function (e, i, a) {
|
||||
e.curX += config.speed.x;
|
||||
e.curY += config.speed.y;
|
||||
|
||||
/* Simple reset the shitty image */
|
||||
if ((e.curX > canvas.width()) || (e.curX + config.images.width < 0)) {
|
||||
e.curX = Math.random() * canvas.width();
|
||||
e.curY = canvas.height();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function render() {
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
/* Render the images based on the updated data in the function "update()" */
|
||||
items.forEach(function (e, i, a) {
|
||||
ctx.drawImage(e, e.curX + config.speed.x * e.direction, e.curY - config.speed.y, config.image.width, config.images.height); /* this can be either said in update() or in render(), i prefer render, because i allways want to do the moving after the update, which verifies the speed and such please use "http://goo.gl/2HQbFy" for more information*/
|
||||
});
|
||||
/* get fucked nooblord, just go on with yer life why are you even looking at this if you're not the dev */
|
||||
}
|
@@ -1,73 +0,0 @@
|
||||
/*\
|
||||
|*|
|
||||
|*| :: cookies.js ::
|
||||
|*|
|
||||
|*| A complete cookies reader/writer framework with full unicode support.
|
||||
|*|
|
||||
|*| Revision #3 - July 13th, 2017
|
||||
|*|
|
||||
|*| https://developer.mozilla.org/en-US/docs/Web/API/document.cookie
|
||||
|*| https://developer.mozilla.org/User:fusionchess
|
||||
|*| https://github.com/madmurphy/cookies.js
|
||||
|*|
|
||||
|*| This framework is released under the GNU Public License, version 3 or later.
|
||||
|*| http://www.gnu.org/licenses/gpl-3.0-standalone.html
|
||||
|*|
|
||||
|*| Syntaxes:
|
||||
|*|
|
||||
|*| * docCookies.setItem(name, value[, end[, path[, domain[, secure]]]])
|
||||
|*| * docCookies.getItem(name)
|
||||
|*| * docCookies.removeItem(name[, path[, domain]])
|
||||
|*| * docCookies.hasItem(name)
|
||||
|*| * docCookies.keys()
|
||||
|*|
|
||||
\*/
|
||||
|
||||
var Cookie = {
|
||||
get: function (sKey) {
|
||||
if (!sKey) { return null; }
|
||||
return decodeURIComponent(document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*" + encodeURIComponent(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*([^;]*).*$)|^.*$"), "$1")) || null;
|
||||
},
|
||||
set: function (sKey, sValue, vEnd, sPath, sDomain, bSecure) {
|
||||
if (!sKey || /^(?:expires|max\-age|path|domain|secure)$/i.test(sKey)) { return false; }
|
||||
var sExpires = "";
|
||||
if (vEnd) {
|
||||
switch (vEnd.constructor) {
|
||||
case Number:
|
||||
sExpires = vEnd === Infinity ? "; expires=Fri, 31 Dec 9999 23:59:59 GMT" : "; max-age=" + vEnd;
|
||||
/*
|
||||
Note: Despite officially defined in RFC 6265, the use of `max-age` is not compatible with any
|
||||
version of Internet Explorer, Edge and some mobile browsers. Therefore passing a number to
|
||||
the end parameter might not work as expected. A possible solution might be to convert the the
|
||||
relative time to an absolute time. For instance, replacing the previous line with:
|
||||
*/
|
||||
/*
|
||||
sExpires = vEnd === Infinity ? "; expires=Fri, 31 Dec 9999 23:59:59 GMT" : "; expires=" + (new Date(vEnd * 1e3 + Date.now())).toUTCString();
|
||||
*/
|
||||
break;
|
||||
case String:
|
||||
sExpires = "; expires=" + vEnd;
|
||||
break;
|
||||
case Date:
|
||||
sExpires = "; expires=" + vEnd.toUTCString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
document.cookie = encodeURIComponent(sKey) + "=" + encodeURIComponent(sValue) + sExpires + (sDomain ? "; domain=" + sDomain : "") + (sPath ? "; path=" + sPath : "") + (bSecure ? "; secure" : "");
|
||||
return true;
|
||||
},
|
||||
remove: function (sKey, sPath, sDomain) {
|
||||
if (!this.hasItem(sKey)) { return false; }
|
||||
document.cookie = encodeURIComponent(sKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT" + (sDomain ? "; domain=" + sDomain : "") + (sPath ? "; path=" + sPath : "");
|
||||
return true;
|
||||
},
|
||||
has: function (sKey) {
|
||||
if (!sKey || /^(?:expires|max\-age|path|domain|secure)$/i.test(sKey)) { return false; }
|
||||
return (new RegExp("(?:^|;\\s*)" + encodeURIComponent(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=")).test(document.cookie);
|
||||
},
|
||||
keys: function () {
|
||||
var aKeys = document.cookie.replace(/((?:^|\s*;)[^\=]+)(?=;|$)|^\s*|\s*(?:\=[^;]*)?(?:\1|$)/g, "").split(/\s*(?:\=[^;]*)?;\s*/);
|
||||
for (var nLen = aKeys.length, nIdx = 0; nIdx < nLen; nIdx++) { aKeys[nIdx] = decodeURIComponent(aKeys[nIdx]); }
|
||||
return aKeys;
|
||||
}
|
||||
};
|
4
res/static/res/script/compiled/README
Normal file
4
res/static/res/script/compiled/README
Normal file
@@ -0,0 +1,4 @@
|
||||
All files in this directory are compiled typescript files. You can find the
|
||||
sources in /res/typescript.
|
||||
|
||||
Have fun typing!
|
215
res/static/res/script/compiled/home.js
Normal file
215
res/static/res/script/compiled/home.js
Normal file
@@ -0,0 +1,215 @@
|
||||
var uploader = null;
|
||||
var finishedUploads = new Array();
|
||||
var totalUploads = 0;
|
||||
var UploadProgressBar = /** @class */ (function () {
|
||||
function UploadProgressBar(file) {
|
||||
this.file = file;
|
||||
this.name = file.name;
|
||||
this.queueNum = totalUploads;
|
||||
totalUploads++;
|
||||
this.uploadDiv = document.createElement("a");
|
||||
this.uploadDiv.setAttribute("class", "file_button");
|
||||
this.uploadDiv.innerText = "Queued\n" + this.file.name;
|
||||
this.uploadDivJQ = $(this.uploadDiv);
|
||||
$("#uploads_queue").append(this.uploadDivJQ.hide().fadeIn('slow'));
|
||||
}
|
||||
UploadProgressBar.prototype.onProgress = function (progress) {
|
||||
this.uploadDiv.innerText = "Uploading... " + Math.round(progress * 1000) / 10 + "%\n" + this.file.name;
|
||||
this.uploadDiv.setAttribute('style', 'background: linear-gradient('
|
||||
+ 'to right, '
|
||||
+ '#111 0%, '
|
||||
+ 'var(--highlight_color) ' + ((progress * 100)) + '%, '
|
||||
+ '#111 ' + ((progress * 100) + 1) + '%)');
|
||||
};
|
||||
UploadProgressBar.prototype.onFinished = function (id) {
|
||||
finishedUploads[this.queueNum] = id;
|
||||
this.uploadDiv.setAttribute('style', 'background: #111');
|
||||
this.uploadDiv.setAttribute('href', '/u/' + id);
|
||||
this.uploadDiv.setAttribute("target", "_blank");
|
||||
this.uploadDivJQ.html('<img src="/api/file/' + id + '/thumbnail" alt="' + this.file.name + '"/>'
|
||||
+ this.file.name + '<br/>'
|
||||
+ '<span style="color: var(--highlight_color);">' + window.location.hostname + '/u/' + id + '</span>');
|
||||
};
|
||||
UploadProgressBar.prototype.onFailure = function (response, error) {
|
||||
this.uploadDiv.setAttribute('style', 'background: #821C40');
|
||||
this.uploadDivJQ.html(this.file.name + '<br/>'
|
||||
+ 'Upload failed after three tries!');
|
||||
};
|
||||
return UploadProgressBar;
|
||||
}());
|
||||
function handleUploads(files) {
|
||||
if (uploader === null) {
|
||||
uploader = new UploadManager();
|
||||
$("#uploads_queue").animate({ "height": "340px" }, { "duration": 2000, queue: false });
|
||||
}
|
||||
for (var i = 0; i < files.length; i++) {
|
||||
uploader.uploadFile(new UploadProgressBar(files.item(i)));
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Form upload handlers
|
||||
*/
|
||||
// Relay click event to hidden file field
|
||||
$("#select_file_button").click(function () { $("#file_input_field").click(); });
|
||||
$("#file_input_field").change(function (evt) {
|
||||
handleUploads(evt.target.files);
|
||||
// This resets the file input field
|
||||
// http://stackoverflow.com/questions/1043957/clearing-input-type-file-using-jquery
|
||||
$('#file_name').html("");
|
||||
$("#file_upload_button").css("visibility", "hidden");
|
||||
$("#file_input_field").wrap("<form>").closest("form").get(0).reset();
|
||||
$("#file_input_field").unwrap();
|
||||
});
|
||||
/*
|
||||
* Drag 'n Drop upload handlers
|
||||
*/
|
||||
$(document).on('dragover', function (e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
});
|
||||
$(document).on('dragenter', function (e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
});
|
||||
document.addEventListener('drop', function (e) {
|
||||
if (e.dataTransfer && e.dataTransfer.files.length > 0) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
handleUploads(e.dataTransfer.files);
|
||||
}
|
||||
});
|
||||
var Cookie;
|
||||
(function (Cookie) {
|
||||
function read(name) {
|
||||
var result = new RegExp('(?:^|; )' + encodeURIComponent(name) + '=([^;]*)').exec(document.cookie);
|
||||
return result ? result[1] : null;
|
||||
}
|
||||
Cookie.read = read;
|
||||
function write(name, value, days) {
|
||||
if (!days) {
|
||||
days = 365 * 20;
|
||||
}
|
||||
var date = new Date();
|
||||
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
|
||||
var expires = "; expires=" + date.toUTCString();
|
||||
document.cookie = name + "=" + value + expires + "; path=/";
|
||||
}
|
||||
Cookie.write = write;
|
||||
function remove(name) {
|
||||
write(name, "", -1);
|
||||
}
|
||||
Cookie.remove = remove;
|
||||
})(Cookie || (Cookie = {}));
|
||||
var UploadManager = /** @class */ (function () {
|
||||
function UploadManager() {
|
||||
this.uploadQueue = new Array();
|
||||
this.uploadThreads = new Array();
|
||||
this.maxThreads = 3;
|
||||
}
|
||||
UploadManager.prototype.uploadFile = function (file) {
|
||||
console.debug("Adding upload to queue");
|
||||
this.uploadQueue.push(file);
|
||||
if (this.uploadThreads.length < this.maxThreads) {
|
||||
console.debug("Starting upload thread");
|
||||
var thread_1 = new UploadWorker(this);
|
||||
this.uploadThreads.push(thread_1);
|
||||
setTimeout(function () { thread_1.start(); }, 0); // Start a new upload thread
|
||||
}
|
||||
else {
|
||||
for (var i = 0; i < this.uploadThreads.length; i++) {
|
||||
this.uploadThreads[i].start();
|
||||
}
|
||||
}
|
||||
};
|
||||
UploadManager.prototype.grabFile = function () {
|
||||
if (this.uploadQueue.length > 0) {
|
||||
return this.uploadQueue.shift();
|
||||
}
|
||||
else {
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
return UploadManager;
|
||||
}());
|
||||
var UploadWorker = /** @class */ (function () {
|
||||
function UploadWorker(manager) {
|
||||
this.tries = 0;
|
||||
this.uploading = false;
|
||||
this.manager = manager;
|
||||
}
|
||||
UploadWorker.prototype.start = function () {
|
||||
if (!this.uploading) {
|
||||
this.newFile();
|
||||
}
|
||||
};
|
||||
UploadWorker.prototype.newFile = function () {
|
||||
var file = this.manager.grabFile();
|
||||
if (file === undefined) {
|
||||
this.uploading = false;
|
||||
console.debug("No files left in queue");
|
||||
return; // Stop the thread
|
||||
}
|
||||
this.uploading = true;
|
||||
this.tries = 0;
|
||||
this.upload(file);
|
||||
};
|
||||
UploadWorker.prototype.upload = function (file) {
|
||||
console.debug("Starting upload of " + file.name);
|
||||
var formData = new FormData();
|
||||
formData.append('file', file.file);
|
||||
formData.append("name", file.name);
|
||||
var that = this; // jquery changes the definiton of "this"
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: "/api/file",
|
||||
data: formData,
|
||||
timeout: 7200000,
|
||||
cache: false,
|
||||
async: true,
|
||||
crossDomain: false,
|
||||
contentType: false,
|
||||
processData: false,
|
||||
xhr: function () {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.upload.addEventListener("progress", function (evt) {
|
||||
if (evt.lengthComputable) {
|
||||
file.onProgress(evt.loaded / evt.total);
|
||||
}
|
||||
}, false);
|
||||
return xhr;
|
||||
},
|
||||
success: function (data) {
|
||||
file.onFinished(data.id);
|
||||
that.setHistoryCookie(data.id);
|
||||
console.log("Done: " + data.id);
|
||||
that.newFile(); // Continue uploading on this thread
|
||||
},
|
||||
error: function (xhr, status, error) {
|
||||
console.log("status: " + status + " error: " + error);
|
||||
if (that.tries === 3) {
|
||||
alert("Upload failed: " + status);
|
||||
file.onFailure(status, error);
|
||||
setTimeout(function () { that.newFile(); }, 2000); // Try to continue
|
||||
return; // Upload failed
|
||||
}
|
||||
// Try again
|
||||
that.tries++;
|
||||
setTimeout(function () { that.upload(file); }, that.tries * 3000);
|
||||
}
|
||||
});
|
||||
};
|
||||
UploadWorker.prototype.setHistoryCookie = function (id) {
|
||||
var uc = Cookie.read("pduploads");
|
||||
// First upload in this browser
|
||||
if (uc === null) {
|
||||
Cookie.write("pduploads", id + ".", undefined);
|
||||
return;
|
||||
}
|
||||
if (uc.length > 2000) {
|
||||
// Cookie is becoming too long, drop the oldest two files
|
||||
uc = uc.substring(uc.indexOf(".") + 1).substring(uc.indexOf(".") + 1);
|
||||
}
|
||||
Cookie.write("pduploads", uc + id + ".", undefined);
|
||||
};
|
||||
return UploadWorker;
|
||||
}());
|
187
res/static/res/script/compiled/textupload.js
Normal file
187
res/static/res/script/compiled/textupload.js
Normal file
@@ -0,0 +1,187 @@
|
||||
var uploader = null;
|
||||
var TextUpload = /** @class */ (function () {
|
||||
function TextUpload(file, name) {
|
||||
this.file = file;
|
||||
this.name = name;
|
||||
}
|
||||
TextUpload.prototype.onProgress = function (progress) { return; };
|
||||
TextUpload.prototype.onFinished = function (id) {
|
||||
setTimeout(window.location.href = "/u/" + id, 100);
|
||||
};
|
||||
TextUpload.prototype.onFailure = function (response, error) {
|
||||
alert("File upload failed! The server told us this: " + response);
|
||||
};
|
||||
return TextUpload;
|
||||
}());
|
||||
function uploadText() {
|
||||
var text = $("#textarea").val();
|
||||
var blob = new Blob([text], { type: "text/plain" });
|
||||
var filename = prompt("What do you want to call this piece of textual art?\n\n"
|
||||
+ "Please add your own file extension, if you want.", "Pixeldrain_Text_File.txt");
|
||||
if (filename === null) {
|
||||
return;
|
||||
}
|
||||
if (uploader === null) {
|
||||
uploader = new UploadManager();
|
||||
}
|
||||
uploader.uploadFile(new TextUpload(blob, filename));
|
||||
}
|
||||
/**
|
||||
* Prevent the Tab key from moving the cursor outside of the text area
|
||||
*/
|
||||
$(document).delegate('#textarea', 'keydown', function (e) {
|
||||
var keyCode = e.keyCode || e.which;
|
||||
if (keyCode === 9) {
|
||||
e.preventDefault();
|
||||
var start = $(this).get(0).selectionStart;
|
||||
var end = $(this).get(0).selectionEnd;
|
||||
// set textarea value to: text before caret + tab + text after caret
|
||||
$(this).val($(this).val().substring(0, start)
|
||||
+ "\t"
|
||||
+ $(this).val().substring(end));
|
||||
// put caret at right position again
|
||||
$(this).get(0).selectionStart =
|
||||
$(this).get(0).selectionEnd = start + 1;
|
||||
}
|
||||
});
|
||||
// Upload the file when ctrl + s is pressed
|
||||
$(document).bind('keydown', function (e) {
|
||||
if (e.ctrlKey && (e.which === 83)) {
|
||||
e.preventDefault();
|
||||
uploadText();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
var Cookie;
|
||||
(function (Cookie) {
|
||||
function read(name) {
|
||||
var result = new RegExp('(?:^|; )' + encodeURIComponent(name) + '=([^;]*)').exec(document.cookie);
|
||||
return result ? result[1] : null;
|
||||
}
|
||||
Cookie.read = read;
|
||||
function write(name, value, days) {
|
||||
if (!days) {
|
||||
days = 365 * 20;
|
||||
}
|
||||
var date = new Date();
|
||||
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
|
||||
var expires = "; expires=" + date.toUTCString();
|
||||
document.cookie = name + "=" + value + expires + "; path=/";
|
||||
}
|
||||
Cookie.write = write;
|
||||
function remove(name) {
|
||||
write(name, "", -1);
|
||||
}
|
||||
Cookie.remove = remove;
|
||||
})(Cookie || (Cookie = {}));
|
||||
var UploadManager = /** @class */ (function () {
|
||||
function UploadManager() {
|
||||
this.uploadQueue = new Array();
|
||||
this.uploadThreads = new Array();
|
||||
this.maxThreads = 3;
|
||||
}
|
||||
UploadManager.prototype.uploadFile = function (file) {
|
||||
console.debug("Adding upload to queue");
|
||||
this.uploadQueue.push(file);
|
||||
if (this.uploadThreads.length < this.maxThreads) {
|
||||
console.debug("Starting upload thread");
|
||||
var thread_1 = new UploadWorker(this);
|
||||
this.uploadThreads.push(thread_1);
|
||||
setTimeout(function () { thread_1.start(); }, 0); // Start a new upload thread
|
||||
}
|
||||
else {
|
||||
for (var i = 0; i < this.uploadThreads.length; i++) {
|
||||
this.uploadThreads[i].start();
|
||||
}
|
||||
}
|
||||
};
|
||||
UploadManager.prototype.grabFile = function () {
|
||||
if (this.uploadQueue.length > 0) {
|
||||
return this.uploadQueue.shift();
|
||||
}
|
||||
else {
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
return UploadManager;
|
||||
}());
|
||||
var UploadWorker = /** @class */ (function () {
|
||||
function UploadWorker(manager) {
|
||||
this.tries = 0;
|
||||
this.uploading = false;
|
||||
this.manager = manager;
|
||||
}
|
||||
UploadWorker.prototype.start = function () {
|
||||
if (!this.uploading) {
|
||||
this.newFile();
|
||||
}
|
||||
};
|
||||
UploadWorker.prototype.newFile = function () {
|
||||
var file = this.manager.grabFile();
|
||||
if (file === undefined) {
|
||||
this.uploading = false;
|
||||
console.debug("No files left in queue");
|
||||
return; // Stop the thread
|
||||
}
|
||||
this.uploading = true;
|
||||
this.tries = 0;
|
||||
this.upload(file);
|
||||
};
|
||||
UploadWorker.prototype.upload = function (file) {
|
||||
console.debug("Starting upload of " + file.name);
|
||||
var formData = new FormData();
|
||||
formData.append('file', file.file);
|
||||
formData.append("name", file.name);
|
||||
var that = this; // jquery changes the definiton of "this"
|
||||
$.ajax({
|
||||
url: "/api/file",
|
||||
data: formData,
|
||||
cache: false,
|
||||
crossDomain: false,
|
||||
contentType: false,
|
||||
processData: false,
|
||||
type: 'POST',
|
||||
xhr: function () {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.upload.addEventListener("progress", function (evt) {
|
||||
if (evt.lengthComputable) {
|
||||
file.onProgress(evt.loaded / evt.total);
|
||||
}
|
||||
}, false);
|
||||
return xhr;
|
||||
},
|
||||
success: function (data) {
|
||||
file.onFinished(data.id);
|
||||
that.setHistoryCookie(data.id);
|
||||
console.log("Done: " + data.id);
|
||||
that.newFile(); // Continue uploading on this thread
|
||||
},
|
||||
error: function (xhr, status, error) {
|
||||
console.log("status: " + status + " error: " + error);
|
||||
if (that.tries === 3) {
|
||||
alert("Upload failed: " + status);
|
||||
file.onFailure(status, error);
|
||||
setTimeout(function () { that.newFile(); }, 2000); // Try to continue
|
||||
return; // Upload failed
|
||||
}
|
||||
// Try again
|
||||
that.tries++;
|
||||
setTimeout(function () { that.upload(file); }, that.tries * 3000);
|
||||
}
|
||||
});
|
||||
};
|
||||
UploadWorker.prototype.setHistoryCookie = function (id) {
|
||||
var uc = Cookie.read("pduploads");
|
||||
// First upload in this browser
|
||||
if (uc === null) {
|
||||
Cookie.write("pduploads", id + ".", undefined);
|
||||
return;
|
||||
}
|
||||
if (uc.length > 2000) {
|
||||
// Cookie is becoming too long, drop the oldest two files
|
||||
uc = uc.substring(uc.indexOf(".") + 1).substring(uc.indexOf(".") + 1);
|
||||
}
|
||||
Cookie.write("pduploads", uc + id + ".", undefined);
|
||||
};
|
||||
return UploadWorker;
|
||||
}());
|
@@ -38,10 +38,9 @@ $(document).ready(function () {
|
||||
|
||||
function historyAddItem(json) {
|
||||
if(!json.success){
|
||||
var uploadItem = "<div class=\"uploadItem\" >"
|
||||
var uploadItem = "<div class=\"file_button\" >"
|
||||
+ "<img src=\"/res/img/cross.png\" "
|
||||
+ "alt=\"File has expired\" "
|
||||
+ "class=\"uploadItemImage\" />"
|
||||
+ "alt=\"File has expired\" />"
|
||||
+ "File has expired"
|
||||
+ "</div>";
|
||||
|
||||
@@ -52,16 +51,13 @@ function historyAddItem(json) {
|
||||
|
||||
var date = new Date(json.date_upload * 1000);
|
||||
|
||||
var uploadItem = "<div class=\"uploadItem\" >"
|
||||
+ "<a href=\"/u/" + json.id + "\" target=\"_blank\">"
|
||||
+ "<img src=\"" + APIURL + json.thumbnail_href + "\" "
|
||||
+ "alt=\"" + json.file_name + "\" "
|
||||
+ "class=\"uploadItemImage\" />"
|
||||
+ json.file_name
|
||||
+ "</a>"
|
||||
var uploadItem = '<a href="/u/'+ json.id +'" target="_blank" class="file_button">'
|
||||
+ '<img src="'+ APIURL + json.thumbnail_href + '"'
|
||||
+ "alt=\"" + json.file_name + "\" />"
|
||||
+ '<span style="color: var(--highlight_color);">'+json.file_name+'</span>'
|
||||
+ "<br/>"
|
||||
+ date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate()
|
||||
+ "</div>";
|
||||
+ "</a>";
|
||||
|
||||
$("#uploadedFiles").append($(uploadItem).hide().fadeIn(400));
|
||||
}
|
@@ -1,194 +0,0 @@
|
||||
/*
|
||||
* Made by Fornax for PixelDrain
|
||||
* Use if you want
|
||||
*
|
||||
* I'll clean up this baby some time in the future too
|
||||
*/
|
||||
|
||||
/*
|
||||
* Form upload handlers
|
||||
*/
|
||||
|
||||
|
||||
/* global API_URL */
|
||||
|
||||
$("#selectFileButton").click(function(event){
|
||||
$("#fileInputField").click();
|
||||
});
|
||||
|
||||
$("#fileInputField").change(function(){
|
||||
pushUploads($("#fileInputField")[0].files);
|
||||
|
||||
// This resets the file input field
|
||||
// http://stackoverflow.com/questions/1043957/clearing-input-type-file-using-jquery
|
||||
$('#fileName').html("");
|
||||
$("#fileUploadButton").css("visibility", "hidden");
|
||||
$("#fileInputField").wrap("<form>").closest("form").get(0).reset();
|
||||
$("#fileInputField").unwrap();
|
||||
});
|
||||
|
||||
/*
|
||||
* Drag 'n Drop upload handlers
|
||||
*/
|
||||
$(document).on('dragover', function (e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
});
|
||||
$(document).on('dragenter', function (e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
});
|
||||
$(document).on('drop', function (e) {
|
||||
if (e.originalEvent.dataTransfer) {
|
||||
var len = e.originalEvent.dataTransfer.files.length;
|
||||
|
||||
if (len) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
pushUploads(e.originalEvent.dataTransfer.files);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/*
|
||||
* Upload functions
|
||||
*/
|
||||
function pushUploads(array){
|
||||
var len = array.length;
|
||||
|
||||
for(i = 0; i < len; i++){
|
||||
uploadQueue.push(array[i]);
|
||||
}
|
||||
|
||||
startFileUpload();
|
||||
}
|
||||
|
||||
var isFirstUpload = true;
|
||||
var uploadQueue = new Array();
|
||||
var isUploading = false;
|
||||
|
||||
function startFileUpload() {
|
||||
if(isUploading){
|
||||
return;
|
||||
}
|
||||
var file = uploadQueue.shift();
|
||||
|
||||
if(file === null){
|
||||
return;
|
||||
}
|
||||
|
||||
if(isFirstUpload){
|
||||
isFirstUpload = false;
|
||||
$("#uploads-completed").animate(
|
||||
{"height": "340px"},
|
||||
{"duration": 2000, queue: false}
|
||||
);
|
||||
$("#progress-bar").animate(
|
||||
{"height": "20px"},
|
||||
{"duration": 1000, queue: false}
|
||||
);
|
||||
}
|
||||
|
||||
isUploading = true;
|
||||
formData = new FormData();
|
||||
formData.append('file', file);
|
||||
formData.append("name", file.name);
|
||||
|
||||
jQuery.ajax({
|
||||
url: API_URL + "/file",
|
||||
data: formData,
|
||||
cache: false,
|
||||
crossDomain: false,
|
||||
contentType: false,
|
||||
processData: false,
|
||||
type: 'POST',
|
||||
xhr: function () {
|
||||
var xhr = new window.XMLHttpRequest();
|
||||
xhr.upload.addEventListener("progress", function (evt) {
|
||||
if (evt.lengthComputable) {
|
||||
percentComplete = (evt.loaded / evt.total) * 100;
|
||||
|
||||
$("#upload-progress").animate(
|
||||
{"width": percentComplete + "%"},
|
||||
{"duration": 200, queue: false}
|
||||
);
|
||||
|
||||
$(".progress-text").html("Uploading... "
|
||||
+ evt.loaded + " / " + evt.total + " Bytes "
|
||||
+ "(" + uploadQueue.length + " files in queue)"
|
||||
);
|
||||
}
|
||||
}, false);
|
||||
|
||||
return xhr;
|
||||
},
|
||||
success: function (data) {
|
||||
isUploading = false;
|
||||
if(uploadQueue.length > 0){
|
||||
startFileUpload();
|
||||
}else{
|
||||
$(".progress-text").html("Done! File link is available below");
|
||||
}
|
||||
|
||||
fileUploadComplete(data);
|
||||
},
|
||||
error: function (xhr, status, error){
|
||||
console.log(status);
|
||||
console.log(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function fileUploadComplete(json) {
|
||||
if (json.success) {
|
||||
setHistoryCookie(json.id)
|
||||
|
||||
resultString = "<div class=\"uploadItem\">Upload successful!<br/>"
|
||||
+ "Your file URL:<br/>"
|
||||
+ "<a href=\"/u/"+json.id+"\" target=\"_blank\">"+window.location.hostname+"/u/"+json.id+"</a>"
|
||||
+ "</div>";
|
||||
|
||||
$('#uploads-completed').prepend(
|
||||
$(resultString).hide().fadeIn('slow')
|
||||
);
|
||||
|
||||
addToList(json.id, "");
|
||||
} else {
|
||||
resultString = "<div class=\"uploadItem\">Something went wrong! "
|
||||
+ "The server responded with this:<br/>\"" + json.message
|
||||
+ "\"</div>";
|
||||
|
||||
$('#uploads-completed').prepend(
|
||||
$(resultString).hide().fadeIn('slow')
|
||||
);
|
||||
|
||||
$(".progressText").html(json.message);
|
||||
}
|
||||
}
|
||||
|
||||
function setHistoryCookie(id){
|
||||
uc = Cookie.get("pduploads");
|
||||
|
||||
// First upload in this browser
|
||||
if (uc === null) {
|
||||
Cookie.set("pduploads", id + ".");
|
||||
return;
|
||||
}
|
||||
|
||||
if (uc.length > 2000){
|
||||
// Cookie is becoming too long, drop the oldest two files
|
||||
uc = uc.substring(
|
||||
uc.indexOf(".") + 1
|
||||
).substring(
|
||||
uc.indexOf(".") + 1
|
||||
);
|
||||
}
|
||||
|
||||
Cookie.set("pduploads", uc + id + ".");
|
||||
}
|
||||
|
||||
$("#btnClearHistory").click(function(){
|
||||
$('#uploads-container').html("");
|
||||
listItems = new Array();
|
||||
});
|
@@ -1,23 +1,22 @@
|
||||
|
||||
var listItems = new Array();
|
||||
|
||||
$("#btnCreateList").click(function (evt) {
|
||||
$("#btn_create_list").click(function (evt) {
|
||||
createList();
|
||||
});
|
||||
|
||||
function addToList(id, desc){
|
||||
var listEntry = {id: id, desc: desc};
|
||||
|
||||
listItems.push(listEntry);
|
||||
}
|
||||
|
||||
function createList(){
|
||||
let listfiles = new Array()
|
||||
for (var i = 0; i < finishedUploads.length; i++) {
|
||||
if (finishedUploads[i] === undefined) {
|
||||
continue;
|
||||
}
|
||||
listfiles.push(finishedUploads[i]);
|
||||
}
|
||||
|
||||
var url = "/api/list";
|
||||
|
||||
var postData = {};
|
||||
|
||||
var title = prompt(
|
||||
"You are creating a list containing " + listItems.length + " files.\n"
|
||||
"You are creating a list containing " + listfiles.length + " files.\n"
|
||||
+ "What do you want to call it?", "My New Album"
|
||||
);
|
||||
|
||||
@@ -31,12 +30,10 @@ function createList(){
|
||||
"files": new Array()
|
||||
};
|
||||
|
||||
var arrayLength = listItems.length;
|
||||
for (var i = 0; i < arrayLength; i++) {
|
||||
postData.files[i] = {
|
||||
"id": listItems[i]["id"],
|
||||
"description": listItems[i]["desc"]
|
||||
};
|
||||
for (var i = 0; i < listfiles.length; i++) {
|
||||
postData.files.push({
|
||||
"id": listfiles[i]
|
||||
});
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
@@ -52,21 +49,22 @@ function createList(){
|
||||
|
||||
function listCreated(response){
|
||||
if(response.success){
|
||||
resultString = "<div class=\"uploadItem\">List creation finished!<br/>"
|
||||
resultString = "<div class=\"file_button\">List creation finished!<br/>"
|
||||
+ "Your List URL: <br/>"
|
||||
+ "<a href=\"/l/" + response.id + "\" target=\"_blank\" style=\"font-weight: bold;\">"+window.location.hostname+"/l/" + response.id + "</a>"
|
||||
+ "</div>";
|
||||
|
||||
$('#uploads-completed').prepend(
|
||||
$('#uploads_queue').prepend(
|
||||
$(resultString).hide().fadeIn('slow')
|
||||
);
|
||||
window.open('/l/'+response.id, '_blank');
|
||||
}else{
|
||||
resultString = "<div class=\"uploadItem\">List creation failed<br/>"
|
||||
resultString = "<div class=\"file_button\">List creation failed<br/>"
|
||||
+ "The server responded with this: <br/>"
|
||||
+ response.type + ": " + response.value
|
||||
+ "</div>";
|
||||
|
||||
$('#uploads-completed').prepend(
|
||||
$('#uploads_queue').prepend(
|
||||
$(resultString).hide().fadeIn('slow')
|
||||
);
|
||||
}
|
||||
|
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
Created on : Dec 1, 2015, 9:54:01 PM
|
||||
Author : Fornax
|
||||
*/
|
||||
|
||||
.progress-bar{
|
||||
position: relative;
|
||||
margin: 3px;
|
||||
height: 20px;
|
||||
background-color: #555;
|
||||
border: #999 groove 2px;
|
||||
overflow: hidden;
|
||||
color: #eeeeee;
|
||||
z-index: 100;
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.progress-bar div{
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 0%;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
background-color: #9FCF6C;
|
||||
overflow: hidden;
|
||||
color: #000;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.progress-bar span,
|
||||
.progress-bar div span {
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
white-space: nowrap;
|
||||
}
|
@@ -1,32 +0,0 @@
|
||||
.uploadedFiles{
|
||||
position: relative;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
height: auto;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.uploadItem{
|
||||
position: relative;
|
||||
width: 238px;
|
||||
max-width: 90%;
|
||||
height: 60px;
|
||||
float: left;
|
||||
margin: 3px;
|
||||
padding: 0;
|
||||
border: 1px #555 solid;
|
||||
overflow: hidden;
|
||||
background-color: #111;
|
||||
word-break: break-all;
|
||||
text-align: left;
|
||||
line-height: 120%;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.uploadItemImage{
|
||||
max-height: 60px;
|
||||
max-width: 120px;
|
||||
margin-right: 5px;
|
||||
float: left;
|
||||
display: block;
|
||||
}
|
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
Created on : Jun 3, 2015, 9:33:11 AM
|
||||
Author : Fornax
|
||||
*/
|
||||
|
||||
.progress-bar{
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 0;
|
||||
background-color: #555;
|
||||
overflow: hidden;
|
||||
color: #eeeeee;
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.progressbar-inner{
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 0%;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
background-color: var(--highlight_color);;
|
||||
overflow: hidden;
|
||||
color: #000;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.progress-text{
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
white-space: nowrap;
|
||||
}
|
@@ -3,6 +3,10 @@
|
||||
Author : Fornax
|
||||
*/
|
||||
|
||||
:root {
|
||||
--highlight_border: inset 0px 0px 5px 1px var(--highlight_color), 0px 0px 1px 0px var(--highlight_color);
|
||||
}
|
||||
|
||||
body{
|
||||
background-color: #111;
|
||||
background-repeat: repeat;
|
||||
@@ -20,7 +24,7 @@ html{
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* HEAD */
|
||||
/* Page layout elements */
|
||||
|
||||
#header{
|
||||
position: relative;
|
||||
@@ -35,23 +39,12 @@ html{
|
||||
border-bottom: #606060 solid 1px;
|
||||
}
|
||||
|
||||
#header-image{
|
||||
#header_image{
|
||||
width: 100%;
|
||||
max-width: 1000px;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
#uploads-completed{
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 0;
|
||||
overflow-x: hidden;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
|
||||
/* Layout elements */
|
||||
|
||||
.body{
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
@@ -84,7 +77,7 @@ html{
|
||||
}
|
||||
.navigation a:hover {
|
||||
background: linear-gradient(var(--highlight_color), var(--highlight_color_dark));
|
||||
box-shadow: 2px 2px 8px #000000;
|
||||
box-shadow: var(--highlight_border), 2px 2px 8px #000000;
|
||||
color: #000000;
|
||||
text-decoration: none;
|
||||
}
|
||||
@@ -178,7 +171,7 @@ a:hover{
|
||||
line-height: 8px;
|
||||
}
|
||||
|
||||
.progress-bar{
|
||||
.progress_bar{
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 0;
|
||||
@@ -188,7 +181,7 @@ a:hover{
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.progressbar-inner{
|
||||
.progressbar_inner{
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 0%;
|
||||
@@ -199,12 +192,53 @@ a:hover{
|
||||
color: #000;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.progress-text{
|
||||
.progress_text{
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.uploads_queue{
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 0;
|
||||
overflow-x: hidden;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
.files_container{
|
||||
position: relative;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
height: auto;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.file_button, .file_button:hover{
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
width: 316px;
|
||||
max-width: 90%;
|
||||
height: 60px;
|
||||
float: left;
|
||||
margin: 6px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
box-shadow: 0px 0px 5px 2px #111;
|
||||
background-color: #111;
|
||||
color: var(--text_color);
|
||||
word-break: break-all;
|
||||
text-align: left;
|
||||
line-height: 120%;
|
||||
display: block;
|
||||
}
|
||||
.file_button > img{
|
||||
max-height: 60px;
|
||||
max-width: 120px;
|
||||
margin-right: 5px;
|
||||
float: left;
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* Form fields */
|
||||
|
||||
/* BUTTONS */
|
||||
@@ -214,10 +248,10 @@ input[type="button"],
|
||||
input[type="color"],
|
||||
select{
|
||||
border-radius: 4px;
|
||||
border: 1px hidden transparent;
|
||||
border: none;
|
||||
margin: 2px;
|
||||
background: linear-gradient(#606060, #404040);
|
||||
padding: 6px 10px 6px 10px;
|
||||
margin: 2px;
|
||||
box-shadow: 2px 2px 8px #000000;
|
||||
font-weight: bold;
|
||||
color: #FFFFFF;
|
||||
@@ -235,16 +269,13 @@ input[type="submit"]:focus,
|
||||
input[type="button"]:focus,
|
||||
input[type="color"]:focus,
|
||||
select:focus{
|
||||
border: 1px solid var(--highlight_color);
|
||||
margin: 1px;
|
||||
box-shadow: var(--highlight_border), 2px 2px 8px #000000;
|
||||
}
|
||||
button:active,
|
||||
input[type="submit"]:active,
|
||||
input[type="button"]:active,
|
||||
input[type="color"]:active,
|
||||
select:active{
|
||||
border: 1px solid var(--highlight_color);
|
||||
margin: 1px;
|
||||
background: linear-gradient(#404040, #606060);
|
||||
box-shadow: inset 3px 3px 6px #000000;
|
||||
padding: 8px 8px 4px 12px;
|
||||
@@ -290,8 +321,7 @@ input[type="text"]:focus,
|
||||
input[type="password"]:focus,
|
||||
input[type="email"]:focus,
|
||||
input[type="number"]:focus{
|
||||
border: 1px solid var(--highlight_color);
|
||||
padding: 3px 4px;
|
||||
box-shadow: var(--highlight_border), inset 3px 3px 6px #000000;
|
||||
}
|
||||
|
||||
input[type=file]{
|
||||
|
112
res/static/res/typescript/home/home.ts
Normal file
112
res/static/res/typescript/home/home.ts
Normal file
@@ -0,0 +1,112 @@
|
||||
var uploader: UploadManager|null = null;
|
||||
var finishedUploads: Array<string> = new Array()
|
||||
var totalUploads: number = 0
|
||||
|
||||
class UploadProgressBar implements FileUpload {
|
||||
private uploadDiv: HTMLAnchorElement
|
||||
private uploadDivJQ: JQuery<HTMLElement>
|
||||
private queueNum: number
|
||||
|
||||
constructor(file: File){
|
||||
this.file = file
|
||||
this.name = file.name
|
||||
this.queueNum = totalUploads
|
||||
totalUploads++
|
||||
|
||||
this.uploadDiv = document.createElement("a");
|
||||
this.uploadDiv.setAttribute("class", "file_button");
|
||||
this.uploadDiv.innerText = "Queued\n" + this.file.name
|
||||
this.uploadDivJQ = $(this.uploadDiv)
|
||||
|
||||
$("#uploads_queue").append(
|
||||
this.uploadDivJQ.hide().fadeIn('slow')
|
||||
)
|
||||
}
|
||||
|
||||
// Interface stuff
|
||||
public file: File;
|
||||
public name: string
|
||||
public onProgress(progress: number){
|
||||
this.uploadDiv.innerText = "Uploading... " + Math.round(progress*1000)/10 + "%\n" + this.file.name
|
||||
this.uploadDiv.setAttribute(
|
||||
'style',
|
||||
'background: linear-gradient('
|
||||
+'to right, '
|
||||
+'#111 0%, '
|
||||
+'var(--highlight_color) '+ ((progress*100)) +'%, '
|
||||
+'#111 '+ ((progress*100)+1) +'%)'
|
||||
)
|
||||
}
|
||||
public onFinished(id: string){
|
||||
finishedUploads[this.queueNum] = id
|
||||
|
||||
this.uploadDiv.setAttribute('style', 'background: #111')
|
||||
this.uploadDiv.setAttribute('href', '/u/'+id)
|
||||
this.uploadDiv.setAttribute("target", "_blank");
|
||||
this.uploadDivJQ.html(
|
||||
'<img src="/api/file/'+id+'/thumbnail" alt="'+this.file.name+'"/>'
|
||||
+ this.file.name+'<br/>'
|
||||
+ '<span style="color: var(--highlight_color);">'+window.location.hostname+'/u/'+id+'</span>'
|
||||
)
|
||||
}
|
||||
public onFailure(response: JQuery.Ajax.ErrorTextStatus, error: string) {
|
||||
this.uploadDiv.setAttribute('style', 'background: #821C40')
|
||||
this.uploadDivJQ.html(
|
||||
this.file.name+'<br/>'
|
||||
+ 'Upload failed after three tries!'
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
function handleUploads(files: FileList) {
|
||||
if (uploader === null){
|
||||
uploader = new UploadManager()
|
||||
|
||||
$("#uploads_queue").animate(
|
||||
{"height": "340px"},
|
||||
{"duration": 2000, queue: false}
|
||||
);
|
||||
}
|
||||
|
||||
for (var i = 0; i < files.length; i++) {
|
||||
uploader.uploadFile(new UploadProgressBar(files.item(i)))
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Form upload handlers
|
||||
*/
|
||||
|
||||
// Relay click event to hidden file field
|
||||
$("#select_file_button").click(function(){$("#file_input_field").click()})
|
||||
|
||||
$("#file_input_field").change(function(evt){
|
||||
handleUploads((<HTMLInputElement>evt.target).files)
|
||||
|
||||
// This resets the file input field
|
||||
// http://stackoverflow.com/questions/1043957/clearing-input-type-file-using-jquery
|
||||
$('#file_name').html("")
|
||||
$("#file_upload_button").css("visibility", "hidden");
|
||||
(<HTMLFormElement>$("#file_input_field").wrap("<form>").closest("form").get(0)).reset()
|
||||
$("#file_input_field").unwrap()
|
||||
})
|
||||
|
||||
/*
|
||||
* Drag 'n Drop upload handlers
|
||||
*/
|
||||
$(document).on('dragover', function (e) {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
})
|
||||
$(document).on('dragenter', function (e) {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
})
|
||||
document.addEventListener('drop', function(e: DragEvent){
|
||||
if (e.dataTransfer && e.dataTransfer.files.length > 0) {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
|
||||
handleUploads(e.dataTransfer.files)
|
||||
}
|
||||
})
|
11
res/static/res/typescript/home/tsconfig.json
Normal file
11
res/static/res/typescript/home/tsconfig.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"outFile": "../../script/compiled/home.js"
|
||||
},
|
||||
"files": [
|
||||
"home.ts",
|
||||
"../lib/cookie.ts",
|
||||
"../lib/jquery.d.ts",
|
||||
"../lib/uploader.ts"
|
||||
]
|
||||
}
|
23
res/static/res/typescript/lib/cookie.ts
Normal file
23
res/static/res/typescript/lib/cookie.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
module Cookie {
|
||||
export function read(name: string) {
|
||||
var result = new RegExp('(?:^|; )' + encodeURIComponent(name) + '=([^;]*)').exec(document.cookie);
|
||||
return result ? result[1] : null;
|
||||
}
|
||||
|
||||
export function write(name: string, value: string, days?: number) {
|
||||
if (!days) {
|
||||
days = 365 * 20;
|
||||
}
|
||||
|
||||
var date = new Date();
|
||||
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
|
||||
|
||||
var expires = "; expires=" + date.toUTCString();
|
||||
|
||||
document.cookie = name + "=" + value + expires + "; path=/";
|
||||
}
|
||||
|
||||
export function remove(name: string) {
|
||||
write(name, "", -1);
|
||||
}
|
||||
}
|
8027
res/static/res/typescript/lib/jquery.d.ts
vendored
Normal file
8027
res/static/res/typescript/lib/jquery.d.ts
vendored
Normal file
File diff suppressed because it is too large
Load Diff
138
res/static/res/typescript/lib/uploader.ts
Normal file
138
res/static/res/typescript/lib/uploader.ts
Normal file
@@ -0,0 +1,138 @@
|
||||
interface FileUpload {
|
||||
file: Blob
|
||||
name: string
|
||||
onProgress(progress: number)
|
||||
onFinished(id: string)
|
||||
onFailure(response: JQuery.Ajax.ErrorTextStatus, error: string)
|
||||
}
|
||||
|
||||
class UploadManager {
|
||||
private uploadQueue: Array<FileUpload> = new Array();
|
||||
private uploadThreads: Array<UploadWorker> = new Array();
|
||||
private maxThreads: number = 3;
|
||||
|
||||
public uploadFile(file: FileUpload) {
|
||||
console.debug("Adding upload to queue")
|
||||
this.uploadQueue.push(file);
|
||||
|
||||
if (this.uploadThreads.length < this.maxThreads) {
|
||||
console.debug("Starting upload thread")
|
||||
let thread = new UploadWorker(this)
|
||||
this.uploadThreads.push(thread)
|
||||
setTimeout(function(){thread.start()}, 0) // Start a new upload thread
|
||||
} else {
|
||||
for (var i = 0; i < this.uploadThreads.length; i++) {
|
||||
this.uploadThreads[i].start()
|
||||
}
|
||||
}
|
||||
}
|
||||
public grabFile(): FileUpload | undefined {
|
||||
if (this.uploadQueue.length > 0) {
|
||||
return this.uploadQueue.shift()
|
||||
} else {
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class UploadWorker {
|
||||
private manager: UploadManager
|
||||
private tries: number = 0
|
||||
private uploading: boolean = false
|
||||
|
||||
constructor(manager: UploadManager) {
|
||||
this.manager = manager
|
||||
}
|
||||
public start(){
|
||||
if (!this.uploading) {
|
||||
this.newFile()
|
||||
}
|
||||
}
|
||||
|
||||
private newFile() {
|
||||
var file = this.manager.grabFile()
|
||||
if (file === undefined) {
|
||||
this.uploading = false
|
||||
console.debug("No files left in queue")
|
||||
return // Stop the thread
|
||||
}
|
||||
|
||||
this.uploading = true
|
||||
this.tries = 0
|
||||
this.upload(<FileUpload>file)
|
||||
}
|
||||
|
||||
private upload(file: FileUpload){
|
||||
console.debug("Starting upload of " + file.name)
|
||||
|
||||
var formData = new FormData()
|
||||
formData.append('file', file.file)
|
||||
formData.append("name", file.name)
|
||||
|
||||
var that = this // jquery changes the definiton of "this"
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: "/api/file",
|
||||
data: formData,
|
||||
timeout: 7200000, // 2 hours
|
||||
cache: false,
|
||||
async: true,
|
||||
crossDomain: false,
|
||||
contentType: false,
|
||||
processData: false,
|
||||
xhr: function () {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.upload.addEventListener("progress", function (evt) {
|
||||
if (evt.lengthComputable) {
|
||||
file.onProgress(evt.loaded / evt.total)
|
||||
}
|
||||
}, false);
|
||||
return xhr;
|
||||
},
|
||||
success: function (data) {
|
||||
file.onFinished(data.id)
|
||||
that.setHistoryCookie(data.id)
|
||||
console.log("Done: " + data.id)
|
||||
|
||||
that.newFile() // Continue uploading on this thread
|
||||
},
|
||||
error: function (xhr, status, error){
|
||||
console.log("status: "+status+" error: "+error)
|
||||
|
||||
if (that.tries === 3) {
|
||||
alert("Upload failed: " + status);
|
||||
file.onFailure(status, error)
|
||||
|
||||
setTimeout(function(){that.newFile()}, 2000) // Try to continue
|
||||
return; // Upload failed
|
||||
}
|
||||
|
||||
// Try again
|
||||
that.tries++
|
||||
setTimeout(function(){that.upload(file)}, that.tries*3000)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private setHistoryCookie(id: string){
|
||||
var uc = Cookie.read("pduploads")
|
||||
|
||||
// First upload in this browser
|
||||
if (uc === null) {
|
||||
Cookie.write("pduploads", id + ".", undefined)
|
||||
return
|
||||
}
|
||||
|
||||
if (uc.length > 2000){
|
||||
// Cookie is becoming too long, drop the oldest two files
|
||||
uc = uc.substring(
|
||||
uc.indexOf(".") + 1
|
||||
).substring(
|
||||
uc.indexOf(".") + 1
|
||||
)
|
||||
}
|
||||
|
||||
Cookie.write("pduploads", uc + id + ".", undefined)
|
||||
}
|
||||
}
|
69
res/static/res/typescript/textupload/text.ts
Normal file
69
res/static/res/typescript/textupload/text.ts
Normal file
@@ -0,0 +1,69 @@
|
||||
var uploader: UploadManager|null = null
|
||||
|
||||
class TextUpload implements FileUpload {
|
||||
constructor(file: Blob, name: string){
|
||||
this.file = file
|
||||
this.name = name
|
||||
}
|
||||
|
||||
// Interface stuff
|
||||
public file: Blob;
|
||||
public name: string
|
||||
public onProgress(progress: number){return}
|
||||
public onFinished(id: string){
|
||||
setTimeout(window.location.href = "/u/" + id, 100);
|
||||
}
|
||||
public onFailure(response: JQuery.Ajax.ErrorTextStatus, error: string) {
|
||||
alert("File upload failed! The server told us this: " + response);
|
||||
}
|
||||
}
|
||||
|
||||
function uploadText() {
|
||||
var text = $("#textarea").val();
|
||||
var blob = new Blob([text], {type: "text/plain"});
|
||||
var filename = prompt("What do you want to call this piece of textual art?\n\n"
|
||||
+ "Please add your own file extension, if you want.",
|
||||
"Pixeldrain_Text_File.txt");
|
||||
|
||||
if(filename === null){
|
||||
return;
|
||||
}
|
||||
|
||||
if (uploader === null){
|
||||
uploader = new UploadManager()
|
||||
}
|
||||
|
||||
uploader.uploadFile(new TextUpload(blob, filename))
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Prevent the Tab key from moving the cursor outside of the text area
|
||||
*/
|
||||
$(document).delegate('#textarea', 'keydown', function (e) {
|
||||
var keyCode = e.keyCode || e.which;
|
||||
|
||||
if (keyCode === 9) {
|
||||
e.preventDefault();
|
||||
var start = (<HTMLTextAreaElement>$(this).get(0)).selectionStart;
|
||||
var end = (<HTMLTextAreaElement>$(this).get(0)).selectionEnd;
|
||||
|
||||
// set textarea value to: text before caret + tab + text after caret
|
||||
$(this).val((<string>$(this).val()).substring(0, start)
|
||||
+ "\t"
|
||||
+ (<string>$(this).val()).substring(end));
|
||||
|
||||
// put caret at right position again
|
||||
(<HTMLTextAreaElement>$(this).get(0)).selectionStart =
|
||||
(<HTMLTextAreaElement>$(this).get(0)).selectionEnd = start + 1;
|
||||
}
|
||||
});
|
||||
|
||||
// Upload the file when ctrl + s is pressed
|
||||
$(document).bind('keydown', function (e) {
|
||||
if (e.ctrlKey && (e.which === 83)) {
|
||||
e.preventDefault();
|
||||
uploadText();
|
||||
return false;
|
||||
}
|
||||
});
|
11
res/static/res/typescript/textupload/tsconfig.json
Normal file
11
res/static/res/typescript/textupload/tsconfig.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"outFile": "../../script/compiled/textupload.js"
|
||||
},
|
||||
"files": [
|
||||
"text.ts",
|
||||
"../lib/cookie.ts",
|
||||
"../lib/jquery.d.ts",
|
||||
"../lib/uploader.ts"
|
||||
]
|
||||
}
|
@@ -7,7 +7,6 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<link rel="stylesheet" href="/global.css"/>
|
||||
<link rel="stylesheet" href="/res/style/layout.css"/>
|
||||
<link rel="stylesheet" href="/res/style/history.css"/>
|
||||
<link href='https://fonts.googleapis.com/css?family=Ubuntu' rel='stylesheet' type='text/css'/>
|
||||
<link href="https://fonts.googleapis.com/css?family=Lato:100" rel="stylesheet" type="text/css"/>
|
||||
<link rel="shortcut icon" href="/res/img/tray32.png"/>
|
||||
@@ -44,7 +43,7 @@
|
||||
This data is saved locally in your web browser and gets updated every time you upload a file through your current browser.
|
||||
<br/><br/>
|
||||
|
||||
<div id="uploadedFiles" class="uploadedFiles"></div>
|
||||
<div id="uploadedFiles" class="files_container"></div>
|
||||
{{template "footer"}}
|
||||
</div>
|
||||
<script src="/res/script/history.js"></script>
|
||||
|
@@ -6,9 +6,7 @@
|
||||
<meta charset="UTF-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<link rel="stylesheet" href="/global.css"/>
|
||||
<link rel="stylesheet" href="/res/style/home.css"/>
|
||||
<link rel="stylesheet" href="/res/style/layout.css"/>
|
||||
<link rel="stylesheet" href="/res/style/history.css"/>
|
||||
<link href='https://fonts.googleapis.com/css?family=Ubuntu' rel='stylesheet' type='text/css'/>
|
||||
<link href="https://fonts.googleapis.com/css?family=Lato:100" rel="stylesheet" type="text/css"/>
|
||||
<link rel="shortcut icon" href="/res/img/tray32.png"/>
|
||||
@@ -39,21 +37,14 @@
|
||||
<div id="body" class="body">
|
||||
{{template "menu"}}
|
||||
<div class="highlight_middle border-bottom">
|
||||
<input id="fileInputField" type="file" name="file" multiple='multiple'/>
|
||||
<button id="selectFileButton" class="big_button button_highlight">Upload Files</button>
|
||||
<button id="textButton" class="big_button button_highlight" onClick="window.location.href = '/t/'">Upload Text</button><br/>
|
||||
<input id="file_input_field" type="file" name="file" multiple="multiple"/>
|
||||
<button id="select_file_button" class="big_button button_highlight">Upload Files</button>
|
||||
<button id="text_button" class="big_button button_highlight" onClick="window.location.href = '/t/'">Upload Text</button><br/>
|
||||
|
||||
<div id="progress-bar" class="progress-bar">
|
||||
<span class="progress-text"></span>
|
||||
<div id="upload-progress" class="progressbar-inner">
|
||||
<span class="progress-text"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="uploads-completed"></div>
|
||||
<div id="uploads_queue" class="uploads_queue"></div>
|
||||
</div>
|
||||
<div class="highlight_dark border-bottom">
|
||||
<button id="btnCreateList">Create list with uploaded files</button>
|
||||
<button id="btn_create_list">Create list with uploaded files</button>
|
||||
</div>
|
||||
|
||||
<h1>Pixeldrain Public Beta<img src="/res/img/sia.png" style="height: 40px;"/></h1>
|
||||
@@ -144,9 +135,8 @@
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">var API_URL = "/api";</script>
|
||||
<script src="/res/script/Cookie.js"></script>
|
||||
<script src="/res/script/home.js"></script>
|
||||
<script src="/res/script/listmaker.js"></script>
|
||||
<script src="/res/script/compiled/home.js"></script>
|
||||
{{template "analytics"}}
|
||||
</body>
|
||||
</html>
|
||||
|
@@ -55,26 +55,8 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="/res/script/Cookie.js"></script>
|
||||
<script src="/res/script/paste.js"></script>
|
||||
|
||||
<!-- Google Analytics Tracking code -->
|
||||
<script>
|
||||
(function (i, s, o, g, r, a, m) {
|
||||
i['GoogleAnalyticsObject'] = r;
|
||||
i[r] = i[r] || function () {
|
||||
(i[r].q = i[r].q || []).push(arguments)
|
||||
}, i[r].l = 1 * new Date();
|
||||
a = s.createElement(o),
|
||||
m = s.getElementsByTagName(o)[0];
|
||||
a.async = 1;
|
||||
a.src = g;
|
||||
m.parentNode.insertBefore(a, m)
|
||||
})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');
|
||||
|
||||
ga('create', 'UA-24463738-4', 'auto');
|
||||
ga('send', 'pageview');
|
||||
</script>
|
||||
<script src="/res/script/compiled/textupload.js"></script>
|
||||
{{template "analytics"}}
|
||||
</body>
|
||||
</html>
|
||||
{{end}}
|
Reference in New Issue
Block a user