Skip to content
This repository has been archived by the owner on May 22, 2021. It is now read-only.

Testpilot ga #268

Merged
merged 12 commits into from
Jul 21, 2017
Merged

Testpilot ga #268

merged 12 commits into from
Jul 21, 2017

Conversation

abhinadduri
Copy link
Collaborator

@abhinadduri abhinadduri commented Jul 20, 2017

Finished adding in all metrics.

One issue is that a user can click on Try Firefox Send without completing a download, something that we don't account for in our metrics guidelines for the restarted event.

for (let i = 0; i < localStorage.length; i++) {
const id = localStorage.key(i);
//check if file exists before adding to list
checkExistence(id, true);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit confused here... We're looping over localStorage and checking each key to see if the file exists. But now we're injecting more things into localStorage, such as referrer, etc.

Should we be filtering out ids against a regexp before calling setExistence()? Or should we possibly refactor the files into a specific key (such as localStorage.files which is an array/Object of all the non-expired files?

Copy link
Collaborator Author

@abhinadduri abhinadduri Jul 20, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Further down in the code, checkExistence does a check to ignore the injected elements. We can move that up here if necessary.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... Because I notice we have code like this in ~4 places currently:

+          if (id !== 'totalUploads' && 
+              id !== 'totalDownloads' &&
+              id !== 'referrer') {
+            // ...
+          }

Maybe we need some utility function isFile(id) {} helper.

function isFile(id) {
  return !['referrer', 'totalDownloads', 'totalUploads'].contains(id); // optionally validate `id` against a RegExp.
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would be a handy function to have! I'll go ahead and add it into utils.js.

cm5: localStorage.getItem('totalUploads'),
cm6: unexpiredFiles,
cm7: totalDownloads,
cd1: event.type === 'drop' ? 'drop' : 'click',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any way the event.type could not be "drop" or "click"?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only way for the event.type to not be drop is if the user doesn't drag and drop the file. I'm not sure the onChange property of the input tag can be changed with anything other than a click or a drag for a file upload.

// delete file
$popupText.find('.del-file').click(e => {
FileSender.delete(file.fileId, file.deleteToken).then(() => {
$(e.target).parents('tr').remove();
localStorage.removeItem(file.fileId);
const timeToExpiry = 86400000 - (new Date().getTime() - file.creationDate.getTime());
Copy link
Collaborator

@pdehaan pdehaan Jul 20, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if we want to convert the magic 86400000 number to a const. For example:

const timeToExpiry = ONE_DAY_IN_MS - Date.now() - file.creationDate.getTime();

Or better yet, extract into helper function since I think we do this in at least 2 places.

case 'https://testpilot.firefox.com/privacy':
return 'privacy';
case 'https://testpilot.firefox.com/terms':
return 'terms';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re: #260
Not sure what "privacy" and "terms" means here, or if we need to try clarifying to disambiguate between Send Privacy/Terms and TestPilot Privacy/Terms. Or not, I have no idea what I'm talking about.
/cc @chuckharmston @clouserw

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They're intended to be the footer links. If there are additional link destinations I missed, feel free to disambiguate or add to the list as appropriate as long as you update the docs; I pieced this together from the mocks.

$('#link').attr('disabled', false);
$copyBtn.attr('data-l10n-id', 'copyUrlFormButton');

if (localStorage.length === 0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

with the new keys this check is no longer a valid way to determine whether to show the file list header

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed by adding in a new function in utils.js.

server/server.js Outdated
sizeInBytes: contentLength,
timeToExpiry: timeToExpiry,
trackerId: conf.analytics_id,
dsn: conf.sentry_id
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

trackerId and dsn should not need to be in this response anymore

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed.

fileSender.on('encrypting', isStillEncrypting => {
// The file is being encrypted
if (isStillEncrypting) {
console.log('Encrypting');
} else {
console.log('Finished encrypting');
uploadStart = new Date().getTime();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Date.now() is the preferred way to do this

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed all instances of new Date().getTime() to Date.now().

const filename = $('#dl-filename').html();
const bytelength = $('#dl-bytelength').html();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be .text() and converted to Number. same for timeToExpiry

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed to const bytelength = Number($('#dl-bytelength').text());, and the same for timeToExpiry.


let totalDownloads = 0;
if (localStorage.hasOwnProperty('totalDownloads')) {
totalDownloads = localStorage.getItem('totalDownloads');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should be consistent with the type of totalDownloads and others. localStorage stores everything as a string so helper functions to convert for us will mean less repetition:

function getTotalDownloads() {
  return Number(localStorage.getItem('totalDownloads'))
}

@@ -200,7 +345,9 @@ $(document).ready(function() {
populateFileList(localStorage.getItem(id));
}
} else if (xhr.status === 404) {
localStorage.removeItem(id);
if (isFile(id)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we shouldn't even be calling checkExistence on non-file ids. move this up a level

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

checkExistence is no longer called if an id is not a file.

let totalUploads = 0;
if (storage.has('totalUploads')) {
totalUploads = storage.totalUploads;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we've got two blocks with this pattern. this is initialization code so i suggest moving them into the Storage constructor. Also check that they're necessary at all because I think the getters (as implemented) will return 0 when it's not already set.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed by removing the check.

window.analytics
.sendEvent('recipient', 'download-stopped', {
cm1: bytelength,
cm5: totalUploads,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: lets use storage.totalUploads directly and remove the local var

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in all cases.

}
}
return length;
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks mostly similar to get files() {...} above (with the obvious exception of returning a count instead of an array). Not sure if it's worth it just to return this.files.length, or if that is too 'expensive' due to the JSON.parse() calls.

This would probably be a lot easier if we just had a localStorage key named files which was a JSON encoded array/object of files, instead of storing everything at the root level and having to loop/filter. 🤷‍♀️

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I avoided calling length because of the parsing calls. I'm not sure if it's worth it or not to just go with this.files.length.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can revisit the internals of this later. for now im just glad it's factored into it's own module

@@ -41,6 +43,6 @@
<img src="/resources/illustration_expired.svg" id="expired-img" data-l10n-id="linkExpiredAlt"/>
</div>
<div class="expired-description" data-l10n-id="uploadPageExplainer"></div>
<a class="send-new" data-l10n-id="sendYourFilesLink"></a>
<a class="send-new" id = "expired-send-new" data-l10n-id="sendYourFilesLink"></a>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: remove spaces around =.


if (!storage.has('totalDownloads')) {
storage.totalDownloads = 0;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

delete me

@abhinadduri abhinadduri merged commit 7243a10 into master Jul 21, 2017
@dannycoates dannycoates deleted the testpilotGA branch July 31, 2017 21:39
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants