Begin implementing a reporting mechanism

This commit is contained in:
Danny Coates
2020-07-13 10:21:28 -07:00
parent ccbcb69666
commit 9891d1f0ba
37 changed files with 762 additions and 183 deletions
+28 -2
View File
@@ -482,6 +482,11 @@ module.exports.empty = function(state, emit) {
>
${state.translate('addFilesButton')}
</label>
<p
class="font-normal text-sm text-grey-50 dark:text-grey-40 my-6 mx-12 text-center max-w-sm leading-loose"
>
${state.translate('trustWarningMessage')}
</p>
${upsell}
</send-upload-area>
`;
@@ -517,13 +522,27 @@ module.exports.preview = function(state, emit) {
`;
return html`
<send-archive
class="flex flex-col max-h-full bg-white p-4 w-full md:w-128 dark:bg-grey-90"
class="flex flex-col max-h-full bg-white w-full dark:bg-grey-90"
>
<div class="border rounded py-3 px-6 dark:border-grey-70">
<div class="border rounded py-3 px-4 dark:border-grey-70">
${archiveInfo(archive)} ${details}
</div>
<div class="checkbox inline-block mt-6 mx-auto">
<input
id="trust-download"
type="checkbox"
autocomplete="off"
onchange="${toggleDownloadEnabled}"
/>
<label for="trust-download">
${state.translate('downloadTrustCheckbox', {
count: archive.manifest.files.length
})}
</label>
</div>
<button
id="download-btn"
disabled
class="btn rounded-lg mt-4 w-full flex-shrink-0 focus:outline"
title="${state.translate('downloadButtonLabel')}"
onclick=${download}
@@ -533,6 +552,13 @@ module.exports.preview = function(state, emit) {
</send-archive>
`;
function toggleDownloadEnabled(event) {
event.stopPropagation();
const checked = event.target.checked;
const btn = document.getElementById('download-btn');
btn.disabled = !checked;
}
function download(event) {
event.preventDefault();
event.target.disabled = true;
+2 -4
View File
@@ -10,11 +10,9 @@ module.exports = function(name, url) {
<h1 class="text-3xl font-bold my-4">
${state.translate('notifyUploadEncryptDone')}
</h1>
<p
class="font-normal leading-normal text-grey-80 word-break-all dark:text-grey-40"
>
<p class="font-normal leading-normal text-grey-80 dark:text-grey-40">
${state.translate('copyLinkDescription')} <br />
${name}
<span class="word-break-all">${name}</span>
</p>
<input
type="text"
+42 -10
View File
@@ -1,5 +1,6 @@
/* global downloadMetadata */
const html = require('choo/html');
const assets = require('../../common/assets');
const archiveTile = require('./archiveTile');
const modal = require('./modal');
const noStreams = require('./noStreams');
@@ -31,22 +32,53 @@ function downloading(state, emit) {
}
function preview(state, emit) {
if (state.fileInfo.flagged) {
return html`
<div
class="flex flex-col w-full max-w-md h-full mx-auto items-center justify-center"
>
<h1 class="text-xl font-bold">${state.translate('downloadFlagged')}</h1>
</div>
`;
}
if (!state.capabilities.streamDownload && state.fileInfo.size > BIG_SIZE) {
return noStreams(state, emit);
}
return html`
<div
class="flex flex-col w-full max-w-md h-full mx-auto items-center justify-center"
class="w-full overflow-hidden md:flex md:flex-row items-stretch md:flex-1"
>
<h1 class="text-3xl font-bold mb-4">
${state.translate('downloadTitle')}
</h1>
<p
class="w-full text-grey-80 text-center leading-normal dark:text-grey-40"
<div
class="px-2 w-full md:px-0 flex-half md:flex md:flex-col mt-12 md:pr-8 pb-4"
>
${state.translate('downloadDescription')}
</p>
${archiveTile.preview(state, emit)}
<h1 class="text-3xl font-bold mb-4 text-center md:text-left">
${state.translate('downloadTitle')}
</h1>
<p
class="text-grey-80 leading-normal dark:text-grey-40 mb-4 text-center md:text-left"
>
${state.translate('downloadDescription')}
</p>
<p
class="text-grey-80 leading-normal dark:text-grey-40 font-semibold text-center md:mb-8 md:text-left"
>
${state.translate('downloadConfirmDescription')}
</p>
<img
class="hidden md:block dl-bg w-full"
src="${assets.get('intro.svg')}"
/>
</div>
<div
class="w-full flex-half flex-half md:flex md:flex-col md:justify-center"
>
${archiveTile.preview(state, emit)}
<a href="/report" class="link-blue mt-4 text-center block"
>${state.translate('reportFile', {
count: state.fileInfo.manifest.files.length
})}</a
>
</div>
</div>
`;
}
@@ -83,7 +115,7 @@ module.exports = function(state, emit) {
<main class="main">
${state.modal && modal(state, emit)}
<section
class="relative h-full w-full p-6 md:p-8 md:rounded-xl md:shadow-big"
class="relative h-full w-full p-6 md:p-8 md:rounded-xl md:shadow-big md:flex md:flex-col"
>
${content}
</section>
+4 -1
View File
@@ -10,7 +10,7 @@ module.exports = function(state) {
<h1 class="text-center text-3xl font-bold my-2">
${state.translate('downloadFinish')}
</h1>
<img src="${assets.get('completed.svg')}" class="my-12 h-48" />
<img src="${assets.get('completed.svg')}" class="my-8 h-48" />
<p class="text-grey-80 leading-normal dark:text-grey-40">
${state.translate('trySendDescription')}
</p>
@@ -19,6 +19,9 @@ module.exports = function(state) {
>${state.translate('sendYourFilesLink')}</a
>
</p>
<p class="">
<a href="/report" class="link-blue">${state.translate('reportFile')}</a>
</p>
</div>
`;
};
+58
View File
@@ -0,0 +1,58 @@
const html = require('choo/html');
module.exports = function() {
return function(state, emit, close) {
const archive = state.fileInfo;
return html`
<send-download-dialog
class="flex flex-col w-full max-w-sm h-full mx-auto items-center justify-center"
>
<h1 class="text-3xl font-bold mb-4">
${state.translate('downloadConfirmTitle')}
</h1>
<p
class="w-full text-grey-80 text-center leading-normal dark:text-grey-40 mb-8"
>
${state.translate('downloadConfirmDescription')}
</p>
<div class="checkbox inline-block mr-3 mb-8">
<input
id="trust-download"
type="checkbox"
autocomplete="off"
onchange="${toggleDownloadEnabled}"
/>
<label for="trust-download">
${state.translate('downloadTrustCheckbox')}
</label>
</div>
<button
id="download-btn"
disabled
class="btn rounded-lg w-full flex-shrink-0"
onclick="${download}"
title="${state.translate('downloadButtonLabel')}"
>
${state.translate('downloadButtonLabel')}
</button>
<a href="/report" class="link-blue mt-8"
>${state.translate('reportFile')}</a
>
</send-download-dialog>
`;
function toggleDownloadEnabled(event) {
event.stopPropagation();
const checked = event.target.checked;
const btn = document.getElementById('download-btn');
btn.disabled = !checked;
}
function download(event) {
event.preventDefault();
close();
event.target.disabled = true;
emit('download', archive);
}
};
};
-15
View File
@@ -1,7 +1,5 @@
const html = require('choo/html');
const Component = require('choo/component');
const version = require('../../package.json').version;
const { browserName } = require('../utils');
class Footer extends Component {
constructor(name, state) {
@@ -15,8 +13,6 @@ class Footer extends Component {
createElement() {
const translate = this.state.translate;
const browser = browserName();
const feedbackUrl = `https://qsurvey.mozilla.com/s3/Firefox-Send-Product-Feedback?ver=${version}&browser=${browser}`;
return html`
<footer
class="flex flex-col md:flex-row items-start w-full flex-none self-start p-6 md:p-8 font-medium text-xs text-grey-60 dark:text-grey-40 md:items-center justify-between"
@@ -43,17 +39,6 @@ class Footer extends Component {
<li class="m-2">
<a href="https://github.com/mozilla/send">GitHub </a>
</li>
<li class="m-2">
<a
href="${feedbackUrl}"
rel="noreferrer noopener"
class="feedback-link"
alt="Feedback"
target="_blank"
>
${translate('siteFeedback')}
</a>
</li>
</ul>
</footer>
`;
+5
View File
@@ -21,6 +21,11 @@ module.exports = function(state, emit) {
>${state.translate('sendYourFilesLink')}</a
>
</p>
<p class="">
<a href="/report" class="link-blue"
>${state.translate('reportFile')}</a
>
</p>
</section>
</main>
`;
+132
View File
@@ -0,0 +1,132 @@
const html = require('choo/html');
const raw = require('choo/html/raw');
const assets = require('../../common/assets');
const REPORTABLES = ['Malware', 'Pii', 'Abuse'];
module.exports = function(state, emit) {
let submitting = false;
const file = state.fileInfo;
if (!file) {
return html`
<main class="main">
<section
class="flex flex-col items-center justify-center h-full w-full p-6 md:p-8 overflow-hidden md:rounded-xl md:shadow-big"
>
<p class="mb-4 leading-normal">
${state.translate('reportUnknownDescription')}
</p>
</section>
</main>
`;
}
if (file.reported) {
return html`
<main class="main">
<section
class="flex flex-col items-center justify-center h-full w-full p-6 md:p-8 overflow-hidden md:rounded-xl md:shadow-big"
>
<h1 class="text-center text-3xl font-bold my-2">
${state.translate('reportedTitle')}
</h1>
<p class="max-w-md text-center text-grey-80 leading-normal">
${state.translate('reportedDescription')}
</p>
<img src="${assets.get('notFound.svg')}" class="my-12" />
<p class="my-5">
<a href="/" class="btn rounded-lg flex items-center" role="button"
>${state.translate('okButton')}</a
>
</p>
</section>
</main>
`;
}
return html`
<main class="main">
<section
class="relative h-full w-full p-6 md:p-8 md:rounded-xl md:shadow-big"
>
<div
class="flex flex-col w-full max-w-sm h-full mx-auto items-center justify-center"
>
<h1 class="text-2xl font-bold mb-4">
${state.translate('reportFile')}
</h1>
<p class="mb-4 leading-normal font-semibold">
${state.translate('reportDescription')}
</p>
<form onsubmit="${report}" data-no-csrf>
<fieldset onchange="${optionChanged}">
<ul
class="list-none p-4 mb-6 rounded-sm bg-grey-10 dark:bg-black"
>
${REPORTABLES.map(
reportable =>
html`
<li class="mb-2 leading-normal">
<label
for="${reportable.toLowerCase()}"
class="flex items-center"
>
<input
type="radio"
name="reason"
id="${reportable.toLowerCase()}"
value="${reportable.toLowerCase()}"
class="mr-2 my-2 w-4 h-4"
/>
${state.translate(`reportReason${reportable}`)}
</label>
</li>
`
)}
<li class="mt-4 mb-2 leading-normal">
${raw(
replaceLinks(state.translate('reportReasonCopyright'), [
'https://www.mozilla.org/about/legal/report-infringement/'
])
)}
</li>
</ul>
</fieldset>
<input
type="submit"
disabled
class="btn rounded-lg w-full flex-shrink-0 focus:outline"
title="${state.translate('reportButton')}"
value="${state.translate('reportButton')}"
/>
</form>
</div>
</section>
</main>
`;
function optionChanged(event) {
event.stopPropagation();
const button = event.currentTarget.nextElementSibling;
button.disabled = false;
}
function report(event) {
event.stopPropagation();
event.preventDefault();
if (submitting) {
return;
}
submitting = true;
state.fileInfo.reported = true;
const form = event.target;
emit('report', { reason: form.reason.value });
}
function replaceLinks(str, urls) {
let i = 0;
const s = str.replace(
/<a>([^<]+)<\/a>/g,
(m, v) => `<a class="text-blue" href="${urls[i++]}">${v}</a>`
);
return `<p>${s}</p>`;
}
};
+2 -4
View File
@@ -9,11 +9,9 @@ module.exports = function(name, url) {
<h1 class="text-3xl font-bold my-4">
${state.translate('notifyUploadEncryptDone')}
</h1>
<p
class="font-normal leading-normal text-grey-80 word-break-all dark:text-grey-40"
>
<p class="font-normal leading-normal text-grey-80 dark:text-grey-40">
${state.translate('shareLinkDescription')}<br />
${name}
<span class="word-break-all">${name}</span>
</p>
<input
type="text"