refactored localStorage into storage module for frontend

This commit is contained in:
Abhinav Adduri 2017-07-21 12:44:55 -07:00
parent cb0d69c5cd
commit d660eda64c
4 changed files with 134 additions and 96 deletions

View File

@ -1,12 +1,14 @@
const FileReceiver = require('./fileReceiver'); const FileReceiver = require('./fileReceiver');
const { notify, findMetric, isFile } = require('./utils'); const { notify, findMetric } = require('./utils');
const Storage = require('./storage');
const storage = new Storage(localStorage);
const $ = require('jquery'); const $ = require('jquery');
require('jquery-circle-progress'); require('jquery-circle-progress');
const Raven = window.Raven; const Raven = window.Raven;
if (!localStorage.hasOwnProperty('totalDownloads')) { if (!storage.has('totalDownloads')) {
localStorage.setItem('totalDownloads', 0); storage.totalDownloads = 0;
} }
$(document).ready(function() { $(document).ready(function() {
@ -40,14 +42,14 @@ $(document).ready(function() {
}) })
$('#expired-send-new').click(function() { $('#expired-send-new').click(function() {
localStorage.setItem('referrer', 'errored-download'); storage.referrer = 'errored-download';
}) })
} }
const filename = $('#dl-filename').html(); const filename = $('#dl-filename').html();
const bytelength = $('#dl-bytelength').html(); const bytelength = Number($('#dl-bytelength').text());
const timeToExpiry = $('#dl-ttl').html(); const timeToExpiry = Number($('#dl-ttl').text());
//initiate progress bar //initiate progress bar
$('#dl-progress').circleProgress({ $('#dl-progress').circleProgress({
@ -59,35 +61,27 @@ $(document).ready(function() {
}); });
$('#download-btn').click(download); $('#download-btn').click(download);
function download() { function download() {
const totalDownloads = localStorage.getItem('totalDownloads'); storage.totalDownloads += 1;
localStorage.setItem('totalDownloads', Number(totalDownloads) + 1);
const fileReceiver = new FileReceiver(); const fileReceiver = new FileReceiver();
let unexpiredFiles = 0;
for (let i = 0; i < localStorage.length; i++) {
const id = localStorage.key(i);
if (isFile(id)) {
unexpiredFiles += 1;
}
}
const unexpiredFiles = storage.numFiles;
let totalUploads = 0; let totalUploads = 0;
if (localStorage.hasOwnProperty('totalUploads')) { if (storage.has('totalUploads')) {
totalUploads = localStorage.getItem('totalUploads'); totalUploads = storage.totalUploads;
} }
fileReceiver.on('progress', progress => { fileReceiver.on('progress', progress => {
window.onunload = function() { window.onunload = function() {
localStorage.setItem('referrer', 'cancelled-download'); storage.referrer = 'cancelled-download';
// record download-stopped (cancelled by tab close or reload) // record download-stopped (cancelled by tab close or reload)
window.analytics window.analytics
.sendEvent('recipient', 'download-stopped', { .sendEvent('recipient', 'download-stopped', {
cm1: bytelength, cm1: bytelength,
cm5: totalUploads, cm5: totalUploads,
cm6: unexpiredFiles, cm6: unexpiredFiles,
cm7: localStorage.getItem('totalDownloads'), cm7: storage.totalDownloads,
cd2: 'cancelled' cd2: 'cancelled'
}) })
} }
@ -131,7 +125,7 @@ $(document).ready(function() {
console.log('Decrypting'); console.log('Decrypting');
} else { } else {
console.log('Done decrypting'); console.log('Done decrypting');
downloadEnd = new Date().getTime(); downloadEnd = Date.now();
} }
}); });
@ -144,7 +138,7 @@ $(document).ready(function() {
} }
}); });
const startTime = new Date().getTime(); const startTime = Date.now();
// record download-started by recipient // record download-started by recipient
window.analytics window.analytics
@ -153,7 +147,7 @@ $(document).ready(function() {
cm4: timeToExpiry, cm4: timeToExpiry,
cm5: totalUploads, cm5: totalUploads,
cm6: unexpiredFiles, cm6: unexpiredFiles,
cm7: localStorage.getItem('totalDownloads') cm7: storage.totalDownloads
}); });
fileReceiver fileReceiver
@ -165,7 +159,7 @@ $(document).ready(function() {
cm1: bytelength, cm1: bytelength,
cm5: totalUploads, cm5: totalUploads,
cm6: unexpiredFiles, cm6: unexpiredFiles,
cm7: localStorage.getItem('totalDownloads'), cm7: storage.totalDownloads,
cd2: 'errored', cd2: 'errored',
cd6: err cd6: err
}); });
@ -180,12 +174,12 @@ $(document).ready(function() {
return; return;
}) })
.then(([decrypted, fname]) => { .then(([decrypted, fname]) => {
const endTime = new Date().getTime(); const endTime = Date.now();
const totalTime = endTime - startTime; const totalTime = endTime - startTime;
const downloadTime = endTime - downloadEnd; const downloadTime = endTime - downloadEnd;
const downloadSpeed = bytelength / (downloadTime / 1000); const downloadSpeed = bytelength / (downloadTime / 1000);
localStorage.setItem('referrer', 'completed-download'); storage.referrer = 'completed-download';
// record download-stopped (completed) by recipient // record download-stopped (completed) by recipient
window.analytics window.analytics
.sendEvent('recipient', 'download-stopped', { .sendEvent('recipient', 'download-stopped', {
@ -194,7 +188,7 @@ $(document).ready(function() {
cm3: downloadSpeed, cm3: downloadSpeed,
cm5: totalUploads, cm5: totalUploads,
cm6: unexpiredFiles, cm6: unexpiredFiles,
cm7: localStorage.getItem('totalDownloads'), cm7: storage.totalDownloads,
cd2: 'completed' cd2: 'completed'
}); });

66
frontend/src/storage.js Normal file
View File

@ -0,0 +1,66 @@
const { isFile } = require('./utils');
class Storage {
constructor(engine) {
this.engine = engine
}
get totalDownloads() {
return Number(this.engine.getItem('totalDownloads'));
}
set totalDownloads(n) {
this.engine.setItem('totalDownloads', n);
}
get totalUploads() {
return Number(this.engine.getItem('totalUploads'));
}
set totalUploads(n) {
this.engine.setItem('totalUploads', n);
}
get referrer() {
return this.engine.getItem('referrer');
}
set referrer(str) {
this.engine.setItem('referrer', str);
}
get files() {
const fs = [];
for (let i = 0; i < this.engine.length; i++) {
const k = this.engine.key(i);
if (isFile(k)) {
fs.push(JSON.parse(this.engine.getItem(k))); // parse or whatever else
}
}
return fs;
}
get numFiles() {
let length = 0;
for (let i = 0; i < this.engine.length; i++) {
const k = this.engine.key(i);
if (isFile(k)) {
length += 1;
}
}
return length;
}
getFileById(id) {
return this.engine.getItem(id);
}
has(property) {
return this.engine.hasOwnProperty(property);
}
remove(property) {
this.engine.removeItem(property);
}
addFile(id, file) {
this.engine.setItem(id, JSON.stringify(file));
}
}
module.exports = Storage;

View File

@ -1,17 +1,19 @@
const FileSender = require('./fileSender'); const FileSender = require('./fileSender');
const { notify, gcmCompliant, findMetric, isFile, ONE_DAY_IN_MS } = require('./utils'); const { notify, gcmCompliant, findMetric, ONE_DAY_IN_MS } = require('./utils');
const Storage = require('./storage');
const storage = new Storage(localStorage);
const $ = require('jquery'); const $ = require('jquery');
require('jquery-circle-progress'); require('jquery-circle-progress');
const Raven = window.Raven; const Raven = window.Raven;
if (!localStorage.hasOwnProperty('totalUploads')) { if (!storage.has('totalUploads')) {
localStorage.setItem('totalUploads', 0); storage.totalUploads = 0;
} }
if (localStorage.hasOwnProperty('referrer')) { if (storage.has('referrer')) {
window.referrer = localStorage.getItem('referrer'); window.referrer = storage.referrer;
localStorage.removeItem('referrer'); storage.remove('referrer');
} else { } else {
window.referrer = 'external'; window.referrer = 'external';
} }
@ -52,7 +54,7 @@ $(document).ready(function() {
cd2: 'completed' cd2: 'completed'
}) })
.then(() => { .then(() => {
localStorage.setItem('referrer', 'completed-upload'); storage.referrer = 'completed-upload';
location.href = target.currentTarget.href; location.href = target.currentTarget.href;
}); });
}) })
@ -65,7 +67,7 @@ $(document).ready(function() {
cd2: 'errored' cd2: 'errored'
}) })
.then(() => { .then(() => {
localStorage.setItem('referrer', 'errored-upload'); storage.referrer = 'errored-upload';
location.href = target.currentTarget.href; location.href = target.currentTarget.href;
}); });
}) })
@ -77,13 +79,14 @@ $(document).ready(function() {
$('#link').attr('disabled', false); $('#link').attr('disabled', false);
$copyBtn.attr('data-l10n-id', 'copyUrlFormButton'); $copyBtn.attr('data-l10n-id', 'copyUrlFormButton');
if (localStorage.length === 0) { const files = storage.files;
if (files.length === 0) {
toggleHeader(); toggleHeader();
} else { } else {
for (let i = 0; i < localStorage.length; i++) { for (const index in files) {
const id = localStorage.key(i); const id = files[index].fileId;
//check if file exists before adding to list //check if file still exists before adding to list
checkExistence(id, true); checkExistence(id, files[index], true);
} }
} }
@ -134,8 +137,7 @@ $(document).ready(function() {
function onUpload(event) { function onUpload(event) {
event.preventDefault(); event.preventDefault();
const totalUploads = localStorage.getItem('totalUploads'); storage.totalUploads += 1;
localStorage.setItem('totalUploads', Number(totalUploads) + 1);
let file = ''; let file = '';
if (event.type === 'drop') { if (event.type === 'drop') {
@ -167,13 +169,13 @@ $(document).ready(function() {
.then(str => { .then(str => {
notify(str); notify(str);
}); });
localStorage.setItem('referrer', 'cancelled-upload'); storage.referrer = 'cancelled-upload';
// record upload-stopped (cancelled) by sender // record upload-stopped (cancelled) by sender
window.analytics window.analytics
.sendEvent('sender', 'upload-stopped', { .sendEvent('sender', 'upload-stopped', {
cm1: file.size, cm1: file.size,
cm5: localStorage.getItem('totalUploads'), cm5: storage.totalUploads,
cm6: unexpiredFiles, cm6: unexpiredFiles,
cm7: totalDownloads, cm7: totalDownloads,
cd1: event.type === 'drop' ? 'drop' : 'click', cd1: event.type === 'drop' ? 'drop' : 'click',
@ -228,32 +230,25 @@ $(document).ready(function() {
console.log('Encrypting'); console.log('Encrypting');
} else { } else {
console.log('Finished encrypting'); console.log('Finished encrypting');
uploadStart = new Date().getTime(); uploadStart = Date.now();
} }
}); });
let t; let t;
const startTime = new Date().getTime(); const startTime = Date.now();
let unexpiredFiles = 1; const unexpiredFiles = storage.numFiles + 1;
for (let i = 0; i < localStorage.length; i++) {
const id = localStorage.key(i);
if (isFile(id)) {
unexpiredFiles += 1;
}
}
let totalDownloads = 0; let totalDownloads = 0;
if (localStorage.hasOwnProperty('totalDownloads')) { if (storage.has('totalDownloads')) {
totalDownloads = localStorage.getItem('totalDownloads'); totalDownloads = storage.totalDownloads;
} }
// record upload-started event by sender // record upload-started event by sender
window.analytics window.analytics
.sendEvent('sender', 'upload-started', { .sendEvent('sender', 'upload-started', {
cm1: file.size, cm1: file.size,
cm5: localStorage.getItem('totalUploads'), cm5: storage.totalUploads,
cm6: unexpiredFiles, cm6: unexpiredFiles,
cm7: totalDownloads, cm7: totalDownloads,
cd1: event.type === 'drop' ? 'drop' : 'click', cd1: event.type === 'drop' ? 'drop' : 'click',
@ -263,7 +258,7 @@ $(document).ready(function() {
fileSender fileSender
.upload() .upload()
.then(info => { .then(info => {
const endTime = new Date().getTime(); const endTime = Date.now();
const totalTime = endTime - startTime; const totalTime = endTime - startTime;
const uploadTime = endTime - uploadStart; const uploadTime = endTime - uploadStart;
const uploadSpeed = file.size / (uploadTime / 1000); const uploadSpeed = file.size / (uploadTime / 1000);
@ -274,7 +269,7 @@ $(document).ready(function() {
cm1: file.size, cm1: file.size,
cm2: totalTime, cm2: totalTime,
cm3: uploadSpeed, cm3: uploadSpeed,
cm5: localStorage.getItem('totalUploads'), cm5: storage.totalUploads,
cm6: unexpiredFiles, cm6: unexpiredFiles,
cm7: totalDownloads, cm7: totalDownloads,
cd1: event.type === 'drop' ? 'drop' : 'click', cd1: event.type === 'drop' ? 'drop' : 'click',
@ -295,7 +290,7 @@ $(document).ready(function() {
uploadSpeed: uploadSpeed uploadSpeed: uploadSpeed
}; };
localStorage.setItem(info.fileId, JSON.stringify(fileData)); storage.addFile(info.fileId, fileData);
$('#upload-filename').attr('data-l10n-id', 'uploadSuccessConfirmHeader'); $('#upload-filename').attr('data-l10n-id', 'uploadSuccessConfirmHeader');
t = window.setTimeout(() => { t = window.setTimeout(() => {
$('#page-one').attr('hidden', true); $('#page-one').attr('hidden', true);
@ -304,7 +299,7 @@ $(document).ready(function() {
$('#share-link').removeAttr('hidden'); $('#share-link').removeAttr('hidden');
}, 1000); }, 1000);
populateFileList(JSON.stringify(fileData)); populateFileList(fileData);
document.l10n.formatValue('notifyUploadDone') document.l10n.formatValue('notifyUploadDone')
.then(str => { .then(str => {
notify(str); notify(str);
@ -322,7 +317,7 @@ $(document).ready(function() {
window.analytics window.analytics
.sendEvent('sender', 'upload-stopped', { .sendEvent('sender', 'upload-stopped', {
cm1: file.size, cm1: file.size,
cm5: localStorage.getItem('totalUploads'), cm5: storage.totalUploads,
cm6: unexpiredFiles, cm6: unexpiredFiles,
cm7: totalDownloads, cm7: totalDownloads,
cd1: event.type === 'drop' ? 'drop' : 'click', cd1: event.type === 'drop' ? 'drop' : 'click',
@ -336,18 +331,16 @@ $(document).ready(function() {
ev.preventDefault(); ev.preventDefault();
} }
function checkExistence(id, populate) { function checkExistence(id, file, populate) {
const xhr = new XMLHttpRequest(); const xhr = new XMLHttpRequest();
xhr.onreadystatechange = () => { xhr.onreadystatechange = () => {
if (xhr.readyState === XMLHttpRequest.DONE) { if (xhr.readyState === XMLHttpRequest.DONE) {
if (xhr.status === 200) { if (xhr.status === 200) {
if (populate) { if (populate) {
populateFileList(localStorage.getItem(id)); populateFileList(file);
} }
} else if (xhr.status === 404) { } else if (xhr.status === 404) {
if (isFile(id)) { storage.remove(id);
localStorage.removeItem(id);
}
} }
} }
}; };
@ -355,14 +348,8 @@ $(document).ready(function() {
xhr.send(); xhr.send();
} }
//update file table with current files in localStorage //update file table with current files in storage
function populateFileList(file) { function populateFileList(file) {
try {
file = JSON.parse(file);
} catch (e) {
return;
}
const row = document.createElement('tr'); const row = document.createElement('tr');
const name = document.createElement('td'); const name = document.createElement('td');
const link = document.createElement('td'); const link = document.createElement('td');
@ -435,7 +422,7 @@ $(document).ready(function() {
future.setTime(file.creationDate.getTime() + file.expiry); future.setTime(file.creationDate.getTime() + file.expiry);
let countdown = 0; let countdown = 0;
countdown = future.getTime() - new Date().getTime(); countdown = future.getTime() - Date.now();
let minutes = Math.floor(countdown / 1000 / 60); let minutes = Math.floor(countdown / 1000 / 60);
let hours = Math.floor(minutes / 60); let hours = Math.floor(minutes / 60);
let seconds = Math.floor(countdown / 1000 % 60); let seconds = Math.floor(countdown / 1000 % 60);
@ -443,7 +430,7 @@ $(document).ready(function() {
poll(); poll();
function poll() { function poll() {
countdown = future.getTime() - new Date().getTime(); countdown = future.getTime() - Date.now();
minutes = Math.floor(countdown / 1000 / 60); minutes = Math.floor(countdown / 1000 / 60);
hours = Math.floor(minutes / 60); hours = Math.floor(minutes / 60);
seconds = Math.floor(countdown / 1000 % 60); seconds = Math.floor(countdown / 1000 % 60);
@ -462,7 +449,7 @@ $(document).ready(function() {
} }
//remove from list when expired //remove from list when expired
if (countdown <= 0) { if (countdown <= 0) {
localStorage.removeItem(file.fileId); storage.remove(file.fileId);
$(expiry).parents('tr').remove(); $(expiry).parents('tr').remove();
window.clearTimeout(t); window.clearTimeout(t);
toggleHeader(); toggleHeader();
@ -497,25 +484,18 @@ $(document).ready(function() {
row.appendChild(del); row.appendChild(del);
$('tbody').append(row); //add row to table $('tbody').append(row); //add row to table
let unexpiredFiles = 0; const unexpiredFiles = storage.numFiles;
for (let i = 0; i < localStorage.length; i++) {
const id = localStorage.key(i);
if (isFile(id)) {
unexpiredFiles += 1;
}
}
let totalDownloads = 0; let totalDownloads = 0;
if (localStorage.hasOwnProperty('totalDownloads')) { if (storage.has('totalDownloads')) {
totalDownloads = localStorage.getItem('totalDownloads'); totalDownloads = storage.totalDownloads;
} }
// delete file // delete file
$popupText.find('.del-file').click(e => { $popupText.find('.del-file').click(e => {
FileSender.delete(file.fileId, file.deleteToken).then(() => { FileSender.delete(file.fileId, file.deleteToken).then(() => {
$(e.target).parents('tr').remove(); $(e.target).parents('tr').remove();
const timeToExpiry = ONE_DAY_IN_MS - (new Date().getTime() - file.creationDate.getTime()); const timeToExpiry = ONE_DAY_IN_MS - (Date.now() - file.creationDate.getTime());
// record upload-deleted from file list // record upload-deleted from file list
window.analytics window.analytics
.sendEvent('sender', 'upload-deleted', { .sendEvent('sender', 'upload-deleted', {
@ -523,14 +503,14 @@ $(document).ready(function() {
cm2: file.totalTime, cm2: file.totalTime,
cm3: file.uploadSpeed, cm3: file.uploadSpeed,
cm4: timeToExpiry, cm4: timeToExpiry,
cm5: localStorage.getItem('totalUploads'), cm5: storage.totalUploads,
cm6: unexpiredFiles, cm6: unexpiredFiles,
cm7: totalDownloads, cm7: totalDownloads,
cd1: file.typeOfUpload, cd1: file.typeOfUpload,
cd4: 'upload-list' cd4: 'upload-list'
}) })
.then(() => { .then(() => {
localStorage.removeItem(file.fileId); storage.remove(file.fileId);
}) })
toggleHeader(); toggleHeader();
}); });
@ -538,7 +518,7 @@ $(document).ready(function() {
document.getElementById('delete-file').onclick = () => { document.getElementById('delete-file').onclick = () => {
FileSender.delete(file.fileId, file.deleteToken).then(() => { FileSender.delete(file.fileId, file.deleteToken).then(() => {
const timeToExpiry = ONE_DAY_IN_MS - (new Date().getTime() - file.creationDate.getTime()); const timeToExpiry = ONE_DAY_IN_MS - (Date.now() - file.creationDate.getTime());
// record upload-deleted from success screen // record upload-deleted from success screen
window.analytics window.analytics
.sendEvent('sender', 'upload-deleted', { .sendEvent('sender', 'upload-deleted', {
@ -546,14 +526,14 @@ $(document).ready(function() {
cm2: file.totalTime, cm2: file.totalTime,
cm3: file.uploadSpeed, cm3: file.uploadSpeed,
cm4: timeToExpiry, cm4: timeToExpiry,
cm5: localStorage.getItem('totalUploads'), cm5: storage.totalUploads,
cm6: unexpiredFiles, cm6: unexpiredFiles,
cm7: totalDownloads, cm7: totalDownloads,
cd1: file.typeOfUpload, cd1: file.typeOfUpload,
cd4: 'success-screen' cd4: 'success-screen'
}) })
.then(() => { .then(() => {
localStorage.removeItem(file.fileId); storage.remove(file.fileId);
location.reload(); location.reload();
}) })
}); });

View File

@ -114,9 +114,7 @@ app.get('/download/:id', (req, res) => {
filename: decodeURIComponent(filename), filename: decodeURIComponent(filename),
filesize: bytes(contentLength), filesize: bytes(contentLength),
sizeInBytes: contentLength, sizeInBytes: contentLength,
timeToExpiry: timeToExpiry, timeToExpiry: timeToExpiry
trackerId: conf.analytics_id,
dsn: conf.sentry_id
}); });
}) })
}) })