big refactor
This commit is contained in:
parent
dd448cb3ed
commit
565e47aef8
37 changed files with 1095 additions and 943 deletions
|
@ -1,51 +1,15 @@
|
|||
/* global EXPIRE_SECONDS */
|
||||
import FileSender from './fileSender';
|
||||
import FileReceiver from './fileReceiver';
|
||||
import { copyToClipboard, delay, fadeOut, percent } from './utils';
|
||||
import {
|
||||
copyToClipboard,
|
||||
delay,
|
||||
fadeOut,
|
||||
openLinksInNewTab,
|
||||
percent,
|
||||
saveFile
|
||||
} from './utils';
|
||||
import * as metrics from './metrics';
|
||||
|
||||
function saveFile(file) {
|
||||
const dataView = new DataView(file.plaintext);
|
||||
const blob = new Blob([dataView], { type: file.type });
|
||||
const downloadUrl = URL.createObjectURL(blob);
|
||||
|
||||
if (window.navigator.msSaveBlob) {
|
||||
return window.navigator.msSaveBlob(blob, file.name);
|
||||
}
|
||||
const a = document.createElement('a');
|
||||
a.href = downloadUrl;
|
||||
a.download = file.name;
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
URL.revokeObjectURL(downloadUrl);
|
||||
}
|
||||
|
||||
function openLinksInNewTab(links, should = true) {
|
||||
links = links || Array.from(document.querySelectorAll('a:not([target])'));
|
||||
if (should) {
|
||||
links.forEach(l => {
|
||||
l.setAttribute('target', '_blank');
|
||||
l.setAttribute('rel', 'noopener noreferrer');
|
||||
});
|
||||
} else {
|
||||
links.forEach(l => {
|
||||
l.removeAttribute('target');
|
||||
l.removeAttribute('rel');
|
||||
});
|
||||
}
|
||||
return links;
|
||||
}
|
||||
|
||||
async function getDLCounts(file) {
|
||||
const url = `/api/metadata/${file.id}`;
|
||||
const receiver = new FileReceiver(url, file);
|
||||
try {
|
||||
await receiver.getMetadata(file.nonce);
|
||||
return receiver.file;
|
||||
} catch (e) {
|
||||
if (e.message === '404') return false;
|
||||
}
|
||||
}
|
||||
export default function(state, emitter) {
|
||||
let lastRender = 0;
|
||||
let updateTitle = false;
|
||||
|
@ -60,14 +24,11 @@ export default function(state, emitter) {
|
|||
for (const file of files) {
|
||||
const oldLimit = file.dlimit;
|
||||
const oldTotal = file.dtotal;
|
||||
const receivedFile = await getDLCounts(file);
|
||||
if (!receivedFile) {
|
||||
await file.updateDownloadCount();
|
||||
if (file.dtotal === file.dlimit) {
|
||||
state.storage.remove(file.id);
|
||||
rerender = true;
|
||||
} else if (
|
||||
oldLimit !== receivedFile.dlimit ||
|
||||
oldTotal !== receivedFile.dtotal
|
||||
) {
|
||||
} else if (oldLimit !== file.dlimit || oldTotal !== file.dtotal) {
|
||||
rerender = true;
|
||||
}
|
||||
}
|
||||
|
@ -92,16 +53,15 @@ export default function(state, emitter) {
|
|||
checkFiles();
|
||||
});
|
||||
|
||||
emitter.on('navigate', checkFiles);
|
||||
// emitter.on('navigate', checkFiles);
|
||||
|
||||
emitter.on('render', () => {
|
||||
lastRender = Date.now();
|
||||
});
|
||||
|
||||
emitter.on('changeLimit', async ({ file, value }) => {
|
||||
await FileSender.changeLimit(file.id, file.ownerToken, value);
|
||||
file.dlimit = value;
|
||||
state.storage.writeFiles();
|
||||
await file.changeLimit(value);
|
||||
state.storage.writeFile(file);
|
||||
metrics.changedDownloadLimit(file);
|
||||
});
|
||||
|
||||
|
@ -116,11 +76,10 @@ export default function(state, emitter) {
|
|||
location
|
||||
});
|
||||
state.storage.remove(file.id);
|
||||
await FileSender.delete(file.id, file.ownerToken);
|
||||
await file.del();
|
||||
} catch (e) {
|
||||
state.raven.captureException(e);
|
||||
}
|
||||
state.fileInfo = null;
|
||||
});
|
||||
|
||||
emitter.on('cancel', () => {
|
||||
|
@ -134,32 +93,24 @@ export default function(state, emitter) {
|
|||
sender.on('encrypting', render);
|
||||
state.transfer = sender;
|
||||
render();
|
||||
|
||||
const links = openLinksInNewTab();
|
||||
await delay(200);
|
||||
try {
|
||||
const start = Date.now();
|
||||
metrics.startedUpload({ size, type });
|
||||
const info = await sender.upload();
|
||||
const time = Date.now() - start;
|
||||
const speed = size / (time / 1000);
|
||||
metrics.completedUpload({ size, time, speed, type });
|
||||
const ownedFile = await sender.upload(state.storage);
|
||||
state.storage.totalUploads += 1;
|
||||
metrics.completedUpload(ownedFile);
|
||||
|
||||
state.storage.addFile(ownedFile);
|
||||
|
||||
document.getElementById('cancel-upload').hidden = 'hidden';
|
||||
await delay(1000);
|
||||
await fadeOut('upload-progress');
|
||||
info.name = file.name;
|
||||
info.size = size;
|
||||
info.type = type;
|
||||
info.time = time;
|
||||
info.speed = speed;
|
||||
info.createdAt = Date.now();
|
||||
info.url = `${info.url}#${info.secretKey}`;
|
||||
info.expiresAt = Date.now() + EXPIRE_SECONDS * 1000;
|
||||
state.fileInfo = info;
|
||||
state.storage.addFile(state.fileInfo);
|
||||
openLinksInNewTab(links, false);
|
||||
state.transfer = null;
|
||||
state.storage.totalUploads += 1;
|
||||
emitter.emit('pushState', `/share/${info.id}`);
|
||||
|
||||
emitter.emit('pushState', `/share/${ownedFile.id}`);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
state.transfer = null;
|
||||
|
@ -174,31 +125,29 @@ export default function(state, emitter) {
|
|||
}
|
||||
});
|
||||
|
||||
emitter.on('password', async ({ existingPassword, password, file }) => {
|
||||
emitter.on('password', async ({ password, file }) => {
|
||||
try {
|
||||
await FileSender.setPassword(existingPassword, password, file);
|
||||
await file.setPassword(password);
|
||||
state.storage.writeFile(file);
|
||||
metrics.addedPassword({ size: file.size });
|
||||
file.password = password;
|
||||
state.storage.writeFiles();
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
render();
|
||||
});
|
||||
|
||||
emitter.on('preview', async () => {
|
||||
emitter.on('getMetadata', async () => {
|
||||
const file = state.fileInfo;
|
||||
const url = `/api/download/${file.id}`;
|
||||
const receiver = new FileReceiver(url, file);
|
||||
receiver.on('progress', updateProgress);
|
||||
receiver.on('decrypting', render);
|
||||
state.transfer = receiver;
|
||||
const receiver = new FileReceiver(file);
|
||||
try {
|
||||
await receiver.getMetadata(file.nonce);
|
||||
await receiver.getMetadata();
|
||||
receiver.on('progress', updateProgress);
|
||||
receiver.on('decrypting', render);
|
||||
state.transfer = receiver;
|
||||
} catch (e) {
|
||||
if (e.message === '401') {
|
||||
file.password = null;
|
||||
if (!file.pwd) {
|
||||
if (!file.requiresPassword) {
|
||||
return emitter.emit('pushState', '/404');
|
||||
}
|
||||
}
|
||||
|
@ -214,7 +163,7 @@ export default function(state, emitter) {
|
|||
try {
|
||||
const start = Date.now();
|
||||
metrics.startedDownload({ size: file.size, ttl: file.ttl });
|
||||
const f = await state.transfer.download(file.nonce);
|
||||
const f = await state.transfer.download();
|
||||
const time = Date.now() - start;
|
||||
const speed = size / (time / 1000);
|
||||
await delay(1000);
|
||||
|
@ -225,8 +174,11 @@ export default function(state, emitter) {
|
|||
metrics.completedDownload({ size, time, speed });
|
||||
emitter.emit('pushState', '/completed');
|
||||
} catch (err) {
|
||||
if (err.message === '0') {
|
||||
// download cancelled
|
||||
return render();
|
||||
}
|
||||
console.error(err);
|
||||
// TODO cancelled download
|
||||
const location = err.message === 'notfound' ? '/404' : '/error';
|
||||
if (location === '/error') {
|
||||
state.raven.captureException(err);
|
||||
|
@ -244,6 +196,14 @@ export default function(state, emitter) {
|
|||
metrics.copiedLink({ location });
|
||||
});
|
||||
|
||||
setInterval(() => {
|
||||
// poll for updates of the download counts
|
||||
// TODO something for the share page: || state.route === '/share/:id'
|
||||
if (state.route === '/') {
|
||||
checkFiles();
|
||||
}
|
||||
}, 2 * 60 * 1000);
|
||||
|
||||
setInterval(() => {
|
||||
// poll for rerendering the file list countdown timers
|
||||
if (
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue