308 lines
11 KiB
JavaScript
308 lines
11 KiB
JavaScript
// vim:set sw=4 ts=4 sts=4 ft=javascript expandtab:
|
|
|
|
function copyToClipboard(el) {
|
|
el = el.previousSibling;
|
|
var textArea = document.createElement('textarea');
|
|
textArea.style.position = 'fixed';
|
|
textArea.style.top = 0;
|
|
textArea.style.left = 0;
|
|
textArea.style.width = '2em';
|
|
textArea.style.height = '2em';
|
|
textArea.style.padding = 0;
|
|
textArea.style.border = 'none';
|
|
textArea.style.outline = 'none';
|
|
textArea.style.boxShadow = 'none';
|
|
textArea.style.background = 'transparent';
|
|
textArea.value = el.value;
|
|
|
|
document.body.appendChild(textArea);
|
|
textArea.select();
|
|
|
|
try {
|
|
var successful = document.execCommand('copy');
|
|
var msg = successful ? 'successful' : 'unsuccessful';
|
|
console.log('Copying text command was ' + msg);
|
|
} catch (err) {
|
|
el.focus();
|
|
var len = el.value.length * 2;
|
|
el.setSelectionRange(0, len);
|
|
alert(i18n.hit);
|
|
}
|
|
|
|
document.body.removeChild(textArea);
|
|
}
|
|
function copyAllToClipboard() {
|
|
var text = new Array();
|
|
var a = document.getElementsByClassName('link-input');
|
|
var i;
|
|
for (i = 0; i < a.length; i++) {
|
|
text.push(a[i].value);
|
|
}
|
|
var textArea = document.createElement('textarea');
|
|
textArea.style.position = 'fixed';
|
|
textArea.style.top = 0;
|
|
textArea.style.left = 0;
|
|
textArea.style.width = '2em';
|
|
textArea.style.height = '2em';
|
|
textArea.style.padding = 0;
|
|
textArea.style.border = 'none';
|
|
textArea.style.outline = 'none';
|
|
textArea.style.boxShadow = 'none';
|
|
textArea.style.background = 'transparent';
|
|
textArea.value = text.join("\n");
|
|
|
|
document.body.appendChild(textArea);
|
|
textArea.select();
|
|
|
|
try {
|
|
var successful = document.execCommand('copy');
|
|
var msg = successful ? 'successful' : 'unsuccessful';
|
|
console.log('Copying text command was ' + msg);
|
|
} catch (err) {
|
|
textArea.style.width = '';
|
|
textArea.style.height = '';
|
|
textArea.style.background = '#FFFFFF';
|
|
alert(i18n.hits);
|
|
}
|
|
|
|
document.body.removeChild(textArea);
|
|
}
|
|
function addItem(name, url, size, del_at_first_view, created_at, delay, short, token) {
|
|
var files = localStorage.getItem('files');
|
|
if (files === null) {
|
|
files = new Array();
|
|
} else {
|
|
files = JSON.parse(files);
|
|
}
|
|
files.push({ name: name, short: short, url: url, size: size, del_at_first_view: del_at_first_view, created_at: created_at, delay: delay, token: token });
|
|
localStorage.setItem('files', JSON.stringify(files));
|
|
}
|
|
|
|
// Start uploading the files (called from <input> and from drop zone)
|
|
function handleFiles(f) {
|
|
window.files = f;
|
|
|
|
var r = document.getElementById('results');
|
|
r.style.display = 'block';
|
|
|
|
var delay = document.getElementById('delete-day');
|
|
var del_at_first_view = document.getElementById('first-view');
|
|
delay.setAttribute('disabled', 'disabled');
|
|
del_at_first_view.setAttribute('disabled', 'disabled');
|
|
|
|
uploadFile(0, delay.value, del_at_first_view.checked);
|
|
}
|
|
|
|
// Create progress bar and call slicing and uploading function
|
|
function uploadFile(i, delay, del_at_first_view) {
|
|
// Prevent exiting page before full upload
|
|
window.addEventListener('onbeforeunload', confirmExit);
|
|
|
|
// Create a random key, different for all files
|
|
var randomkey = sjcl.codec.base64.fromBits(sjcl.random.randomWords(8, 0), 0);
|
|
|
|
// Get the file and properties
|
|
var file = window.files[i];
|
|
var name = file.name;
|
|
var parts = Math.ceil(file.size/window.sliceLength);
|
|
|
|
// Create a progress bar for the file
|
|
var r = document.getElementById('ul-results');
|
|
var w = document.createElement('li');
|
|
w.setAttribute('class', 'list-group-item');
|
|
w.innerHTML='<div><p id="name-'+i+'">'+file.name+'</p></div><div class="progress"><div id="progress-'+i+'" style="width: 0%;" data-key="'+randomkey+'" data-name="'+file.name+'" aria-valuemax="100" aria-valuemin="0" aria-valuenow="0" role="progressbar" class="progress-bar"><span class="sr-only">'+file.name+'0%</span></div></div>';
|
|
r.appendChild(w);
|
|
|
|
sliceAndUpload(randomkey, i, parts, 0, delay, del_at_first_view, null);
|
|
}
|
|
|
|
// Get a slice of file and send it
|
|
function sliceAndUpload(randomkey, i, parts, j, delay, del_at_first_view, short) {
|
|
var file = window.files[i];
|
|
var slice = file.slice(j * window.sliceLength, (j + 1) * window.sliceLength, file.type);
|
|
var fr = new FileReader();
|
|
fr.onloadend = function() {
|
|
// Get the binary result
|
|
var bin = fr.result;
|
|
|
|
// Transform it in base64
|
|
var b = window.btoa(bin);
|
|
|
|
// Encrypt it
|
|
var encrypted = sjcl.encrypt(randomkey, b);
|
|
|
|
// Prepare json
|
|
var data = {
|
|
total: parts,
|
|
part: j,
|
|
size: file.size,
|
|
name: file.name,
|
|
type: file.type,
|
|
delay: delay,
|
|
del_at_first_view: del_at_first_view,
|
|
id: short,
|
|
i: i
|
|
};
|
|
data = JSON.stringify(data);
|
|
|
|
// Verify that we have a websocket and send json
|
|
if (window.ws.readyState === 3) {
|
|
window.ws = spawnWebsocket(function() {
|
|
window.ws.send(data+'XXMOJOXX'+JSON.stringify(encrypted));
|
|
});
|
|
} else {
|
|
window.ws.send(data+'XXMOJOXX'+JSON.stringify(encrypted));
|
|
}
|
|
}
|
|
fr.readAsBinaryString(slice);
|
|
}
|
|
|
|
// Update the progress bar
|
|
function updateProgressBar(data) {
|
|
var i = data.i;
|
|
var j = data.j;
|
|
var parts = data.parts;
|
|
var short = data.short;
|
|
var del_at_first_view = data.del_at_first_view;
|
|
var created_at = data.created_at;
|
|
var delay = data.delay;
|
|
|
|
var dp = document.getElementById('progress-'+i);
|
|
var key = dp.getAttribute('data-key');
|
|
|
|
if (j + 1 === parts) {
|
|
var n = document.getElementById('name-'+i);
|
|
var d = document.createElement('div');
|
|
var baseURL = document.location.href.replace(/#$/, '');
|
|
var url = baseURL+'r/'+short+'#'+key;
|
|
var del_url = baseURL+'d/'+short+'/'+data.token;
|
|
var links = encodeURIComponent('["'+short+'"]');
|
|
n.innerHTML = n.innerHTML+' <a href="'+baseURL+'m?links='+links+'"><span class="icon icon-mail"></span></a>';
|
|
d.innerHTML = '<div class="form-group"><label class="sr-only" for="'
|
|
+short
|
|
+'">'
|
|
+i18n.dlText
|
|
+'</label><div class="input-group"><div class="input-group-addon"><a href="'
|
|
+url
|
|
+'" target="_blank"><span class="icon icon-download" title="'
|
|
+i18n.dlText
|
|
+'"></span></a></div><input id="'
|
|
+short
|
|
+'" class="form-control link-input" value="'
|
|
+url
|
|
+'" readonly="" type="text" style="background-color: #FFF;"><a href="#" onclick="copyToClipboard(this);" class="input-group-addon" title="'
|
|
+i18n.cpText
|
|
+'"><span class="icon icon-clipboard"></span></a></div></div>'
|
|
+'<div class="form-group"><label class="sr-only" for="delete-'
|
|
+short
|
|
+'">'
|
|
+i18n.delText
|
|
+'</label><div class="input-group"><div class="input-group-addon"><a href="'
|
|
+del_url
|
|
+'" target="_blank"><span class="icon icon-trash" title="'
|
|
+i18n.delText
|
|
+'"></span></a></div><input id="delete-'
|
|
+short
|
|
+'" class="form-control" value="'
|
|
+del_url
|
|
+'" readonly="" type="text" style="background-color: #FFF;">';
|
|
|
|
var p2 = dp.parentNode;
|
|
var p1 = p2.parentNode;
|
|
|
|
p2.remove();
|
|
p1.appendChild(d);
|
|
|
|
// Add copy all and mailto buttons
|
|
var misc = document.getElementById('misc');
|
|
if (misc.innerHTML === '') {
|
|
misc.innerHTML = '<a href="#" onclick="copyAllToClipboard();" class="btn btn-info">'+i18n.copyAll+'</a> <a id="mailto" href="'+baseURL+'m?links='+links+'" class="btn btn-info">'+i18n.mailTo+'</a>';
|
|
} else {
|
|
var a = document.getElementsByClassName('link-input');
|
|
var l = new Array();
|
|
var i;
|
|
for (i = 0; i < a.length; i++) {
|
|
l.push(a[i].id);
|
|
}
|
|
var u = baseURL+'m?links='+JSON.stringify(l);
|
|
document.getElementById('mailto').href = u;
|
|
}
|
|
|
|
// Add the file to localStorage
|
|
addItem(data.name, url, data.size, del_at_first_view, created_at, delay, data.short, data.token);
|
|
|
|
i++;
|
|
if (i < window.files.length) {
|
|
uploadFile(i, delay, del_at_first_view);
|
|
} else {
|
|
// We have finished
|
|
window.removeEventListener('onbeforeunload', confirmExit);
|
|
document.getElementById('delete-day').removeAttribute('disabled');
|
|
document.getElementById('first-view').removeAttribute('disabled');
|
|
}
|
|
} else {
|
|
j++;
|
|
// Update progress bar
|
|
var percent = Math.round(100 * j/parts);
|
|
dp.style.width = percent+'%';
|
|
dp.setAttribute('aria-valuenow', percent);
|
|
|
|
// Encrypt and upload next slice
|
|
sliceAndUpload(key, i, parts, j, delay, del_at_first_view, short);
|
|
}
|
|
}
|
|
|
|
// Dropzone events functions
|
|
function handleDrop(evt) {
|
|
evt.stopPropagation();
|
|
evt.preventDefault();
|
|
|
|
var f = evt.dataTransfer.files; // FileList object
|
|
handleFiles(f);
|
|
}
|
|
function handleDragOver(evt) {
|
|
evt.stopPropagation();
|
|
evt.preventDefault();
|
|
evt.dataTransfer.dropEffect = 'copy'; // Explicitly show this is a copy.
|
|
}
|
|
|
|
// Spawn websocket
|
|
function spawnWebsocket(callback) {
|
|
var ws = new WebSocket(ws_url);
|
|
ws.onopen = function() {
|
|
console.log('Connection is established!');
|
|
if (callback !== undefined) {
|
|
callback();
|
|
}
|
|
};
|
|
ws.onclose = function() {
|
|
console.log('Connection is closed.');
|
|
}
|
|
ws.onmessage = function(e) {
|
|
var data = JSON.parse(e.data);
|
|
if (data.success) {
|
|
updateProgressBar(data);
|
|
} else {
|
|
alert(data.msg);
|
|
}
|
|
}
|
|
ws.onerror = function() {
|
|
console.log('error');
|
|
}
|
|
return ws;
|
|
}
|
|
|
|
// When it's ready
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
// Dropzone events binding
|
|
var dropZone = document.getElementById('files');
|
|
dropZone.addEventListener('dragover', handleDragOver, false);
|
|
dropZone.addEventListener('drop', handleDrop, false);
|
|
|
|
// Set websocket
|
|
window.ws = spawnWebsocket();
|
|
|
|
// Use slice of 10MB
|
|
window.sliceLength = 10000000;
|
|
});
|