added survey dialog. closes #1307

This commit is contained in:
Danny Coates 2019-04-26 13:30:33 -07:00
parent ce4157ac08
commit 20b9279eec
14 changed files with 113 additions and 32 deletions

View File

@ -1,5 +1,5 @@
/* global AUTH_CONFIG LOCALE */
import { browserName } from './utils';
/* global AUTH_CONFIG */
import { browserName, locale } from './utils';
async function checkCrypto() {
try {
@ -91,7 +91,7 @@ export default async function getCapabilities() {
account = false;
}
const share =
typeof navigator.share === 'function' && LOCALE.startsWith('en'); // en until strings merge
typeof navigator.share === 'function' && locale().startsWith('en'); // en until strings merge
const standalone =
window.matchMedia('(display-mode: standalone)').matches ||

View File

@ -2,11 +2,12 @@ import FileSender from './fileSender';
import FileReceiver from './fileReceiver';
import { copyToClipboard, delay, openLinksInNewTab, percent } from './utils';
import * as metrics from './metrics';
import { bytes } from './utils';
import { bytes, locale } from './utils';
import okDialog from './ui/okDialog';
import copyDialog from './ui/copyDialog';
import shareDialog from './ui/shareDialog';
import signupDialog from './ui/signupDialog';
import surveyDialog from './ui/surveyDialog';
export default function(state, emitter) {
let lastRender = 0;
@ -281,6 +282,22 @@ export default function(state, emitter) {
// metrics.copiedLink({ location });
});
emitter.on('closeModal', () => {
if (
state.PREFS.surveyUrl &&
['copy', 'share'].includes(state.modal.type) &&
locale().startsWith('en') &&
(state.storage.totalUploads > 1 || state.storage.totalDownloads > 0) &&
!state.user.surveyed
) {
state.user.surveyed = true;
state.modal = surveyDialog();
} else {
state.modal = null;
}
render();
});
setInterval(() => {
// poll for updates of the upload list
if (!state.modal && state.route === '/') {

View File

@ -1,4 +1,4 @@
/* global DEFAULTS LIMITS LOCALE */
/* global DEFAULTS LIMITS PREFS */
import 'core-js';
import 'fast-text-encoding'; // MS Edge support
import 'fluent-intl-polyfill';
@ -17,7 +17,7 @@ import './main.css';
import User from './user';
import { getTranslator } from './locale';
import Archive from './archive';
import { setTranslate } from './utils';
import { setTranslate, locale } from './utils';
if (navigator.doNotTrack !== '1' && window.RAVEN_CONFIG) {
Raven.config(window.SENTRY_ID, window.RAVEN_CONFIG).install();
@ -45,11 +45,12 @@ if (process.env.NODE_ENV === 'production') {
}
}
const translate = await getTranslator(LOCALE);
const translate = await getTranslator(locale());
setTranslate(translate);
window.initialState = {
LIMITS,
DEFAULTS,
PREFS,
archive: new Archive([], DEFAULTS.EXPIRE_SECONDS),
capabilities,
translate,

View File

@ -1,5 +1,5 @@
import storage from './storage';
import { platform } from './utils';
import { platform, locale } from './utils';
import { sendMetrics } from './api';
let appState = null;
@ -7,7 +7,7 @@ let appState = null;
const HOUR = 1000 * 60 * 60;
const events = [];
let session_id = Date.now();
const lang = document.querySelector('html').lang;
const lang = locale();
export default function initialize(state, emitter) {
appState = state;

View File

@ -2,7 +2,7 @@ const html = require('choo/html');
const { copyToClipboard } = require('../utils');
module.exports = function(name, url) {
return function(state, emit, close) {
const dialog = function(state, emit, close) {
return html`
<send-copy-dialog
class="flex flex-col items-center text-center p-4 max-w-sm m-auto"
@ -45,4 +45,6 @@ module.exports = function(name, url) {
setTimeout(close, 1000);
}
};
dialog.type = 'copy';
return dialog;
};

View File

@ -21,7 +21,6 @@ module.exports = function(state, emit) {
event.preventDefault();
event.stopPropagation();
}
state.modal = null;
emit('render');
emit('closeModal');
}
};

View File

@ -1,13 +1,7 @@
const html = require('choo/html');
/* Possible strings for l10n
shareLinkDescription = Share the link to your file:
shareLinkButton = Share link
shareMessage = Download "{ $name }" with { -send-brand }: simple, safe file sharing
*/
module.exports = function(name, url) {
return function(state, emit, close) {
const dialog = function(state, emit, close) {
return html`
<send-share-dialog
class="flex flex-col items-center text-center p-4 max-w-sm m-auto"
@ -16,7 +10,7 @@ module.exports = function(name, url) {
${state.translate('notifyUploadEncryptDone')}
</h1>
<p class="font-normal leading-normal text-grey-darkest word-break-all">
Share the link to your file:<br />
${state.translate('shareLinkDescription')}<br />
${name}
</p>
<input
@ -29,9 +23,9 @@ module.exports = function(name, url) {
<button
class="btn rounded-lg w-full flex-no-shrink focus:outline"
onclick="${share}"
title="Share link"
title="${state.translate('shareLinkButton')}"
>
Share link
${state.translate('shareLinkButton')}
</button>
<button
class="text-blue-dark hover:text-blue-darker focus:text-blue-darker my-4 font-medium cursor-pointer focus:outline"
@ -48,8 +42,7 @@ module.exports = function(name, url) {
try {
await navigator.share({
title: state.translate('-send-brand'),
text: `Download "${name}" with Firefox Send: simple, safe file sharing`,
//state.translate('shareMessage', { name }),
text: state.translate('shareMessage', { name }),
url
});
} catch (e) {
@ -61,4 +54,6 @@ module.exports = function(name, url) {
close();
}
};
dialog.type = 'share';
return dialog;
};

42
app/ui/surveyDialog.js Normal file
View File

@ -0,0 +1,42 @@
const html = require('choo/html');
const version = require('../../package.json').version;
const { browserName } = require('../utils');
module.exports = function() {
return function(state, emit, close) {
const surveyUrl = `${
state.PREFS.surveyUrl
}?ver=${version}&browser=${browserName()}&anon=${
state.user.loggedIn
}&active_count=${state.storage.files.length}`;
return html`
<send-survey-dialog
class="flex flex-col items-center text-center p-4 max-w-sm m-auto"
>
<h1 class="font-bold my-4">
Tell us what you think.
</h1>
<p class="font-normal leading-normal text-grey-darkest px-4">
Love Firefox Send? Take a quick survey to let us know how we can make
it better.
</p>
<a
class="btn rounded-lg w-full flex-no-shrink focus:outline my-5"
onclick="${() => emit('closeModal')}"
title="Give feedback"
href="${surveyUrl}"
target="_blank"
>
Give feedback
</a>
<button
class="text-blue-dark hover:text-blue-darker focus:text-blue-darker font-medium cursor-pointer focus:outline"
onclick="${close}"
title="Skip"
>
Skip
</button>
</send-survey-dialog>
`;
};
};

View File

@ -44,6 +44,14 @@ export default class User {
this.storage.set('firstAction', action);
}
get surveyed() {
return this.storage.get('surveyed');
}
set surveyed(yes) {
this.storage.set('surveyed', yes);
}
get avatar() {
const defaultAvatar = assets.get('user.svg');
if (this.info.avatarDefault) {

View File

@ -14,6 +14,10 @@ function b64ToArray(str) {
return b64.toByteArray(str + '==='.slice((str.length + 3) % 4));
}
function locale() {
return document.querySelector('html').lang;
}
function loadShim(polyfill) {
return new Promise((resolve, reject) => {
const shim = document.createElement('script');
@ -67,8 +71,7 @@ function bytes(num) {
let nStr = n.toFixed(decimalDigits);
if (LOCALIZE_NUMBERS) {
try {
const locale = document.querySelector('html').lang;
nStr = n.toLocaleString(locale, {
nStr = n.toLocaleString(locale(), {
minimumFractionDigits: decimalDigits,
maximumFractionDigits: decimalDigits
});
@ -85,8 +88,7 @@ function bytes(num) {
function percent(ratio) {
if (LOCALIZE_NUMBERS) {
try {
const locale = document.querySelector('html').lang;
return ratio.toLocaleString(locale, { style: 'percent' });
return ratio.toLocaleString(locale(), { style: 'percent' });
} catch (e) {
// fall through
}
@ -96,8 +98,7 @@ function percent(ratio) {
function number(n) {
if (LOCALIZE_NUMBERS) {
const locale = document.querySelector('html').lang;
return n.toLocaleString(locale);
return n.toLocaleString(locale());
}
return n.toString();
}
@ -267,6 +268,7 @@ function setTranslate(t) {
}
module.exports = {
locale,
fadeOut,
delay,
allowedCopy,

View File

@ -138,3 +138,8 @@ noStreamsOptionCopy = Copy the link to open in another browser
noStreamsOptionFirefox = Try our favorite browser
noStreamsOptionDownload = Continue with this browser
downloadFirefoxPromo = { -send-short-brand } is brought to you by the all-new { -firefox }.
# the next line after the colon contains a file name
shareLinkDescription = Share the link to your file:
shareLinkButton = Share link
# $name is the name of the file
shareMessage = Download “{ $name }” with { -send-brand }: simple, safe file sharing

View File

@ -144,6 +144,11 @@ const conf = convict({
format: String,
default: 'https://identity.mozilla.com/apps/send',
env: 'FXA_KEY_SCOPE'
},
survey_url: {
format: String,
default: '',
env: 'SURVEY_URL'
}
});

View File

@ -47,8 +47,8 @@ module.exports = function(state) {
var LIMITS = ${JSON.stringify(clientConstants.LIMITS)};
var DEFAULTS = ${JSON.stringify(clientConstants.DEFAULTS)};
const LOCALE = '${state.locale}';
const downloadMetadata = ${
var PREFS = ${JSON.stringify(state.prefs)};
var downloadMetadata = ${
state.downloadMetadata ? raw(JSON.stringify(state.downloadMetadata)) : '{}'
};
${authConfig};

View File

@ -19,6 +19,10 @@ module.exports = async function(req) {
// continue without accounts
}
}
const prefs = {};
if (config.survey_url) {
prefs.surveyUrl = config.survey_url;
}
return {
archive: {
numFiles: 0
@ -39,6 +43,7 @@ module.exports = async function(req) {
user: { avatar: assets.get('user.svg'), loggedIn: false },
robots,
authConfig,
prefs,
layout
};
};