Compare commits

..

31 Commits

Author SHA1 Message Date
Danny Coates
18216ce430 v3.0.20 2019-10-21 11:33:54 -07:00
Danny Coates
1711a2d1d7 added "te" to production languages 2019-10-21 10:36:34 -07:00
Danny Coates
8b2080a2f0 updated deps 2019-10-21 10:24:07 -07:00
Danny Coates
006ee1d2e6 Merge pull request #1408 from drakkein/master
Strip tracking URL params
2019-10-21 10:13:56 -07:00
Danny Coates
0a7c473965 Merge pull request #1405 from mozilla/dark-mode
Dark theme
2019-10-21 10:07:42 -07:00
Hampus
4e124d174c Pontoon: Update Swedish (sv-SE) localization of Firefox Send
Localization authors:
- Hampus <hampus.bengtsson@gmail.com>
2019-10-19 00:33:34 +00:00
Artem Polivanchuk
524b2a5668 Pontoon: Update Ukrainian (uk) localization of Firefox Send
Localization authors:
- Artem Polivanchuk <artem@mozilla.org.ua>
2019-10-17 08:52:12 +00:00
Marcelo Ghelman
844f036a27 Pontoon: Update Portuguese (Brazil) (pt-BR) localization of Firefox Send
Localization authors:
- Marcelo Ghelman <marcelo.ghelman@gmail.com>
2019-10-16 14:33:03 +00:00
Marcelo Ghelman
7d6c781ea5 Pontoon: Update Portuguese (Brazil) (pt-BR) localization of Firefox Send
Localization authors:
- Marcelo Ghelman <marcelo.ghelman@gmail.com>
2019-10-16 14:12:33 +00:00
Wiktor Furman
ad9577daaf Update package-lock 2019-10-15 15:50:09 +02:00
Wiktor Furman
114068c531 Strip tracking url parameters 2019-10-15 15:29:48 +02:00
Niksend Mizuhara
0daa03e04c Pontoon: Update Chinese (China) (zh-CN) localization of Firefox Send
Localization authors:
- Niksend Mizuhara <i@rhinecho.com>
2019-10-07 01:53:05 +00:00
Danny Coates
63348fd36a updated deps 2019-10-03 23:32:49 -07:00
Danny Coates
c71c246959 Dark theme 2019-10-03 23:10:11 -07:00
Sander Lepik
2b7504e969 Pontoon: Update Estonian (et) localization of Firefox Send
Localization authors:
- Sander Lepik <sander.lepik@eesti.ee>
2019-10-01 05:14:31 +00:00
Selyan Sliman Amiri
b942554c80 Pontoon: Update Kabyle (kab) localization of Firefox Send
Localization authors:
- Selyan Sliman Amiri <selyan.kab@gmail.com>
2019-09-30 09:32:51 +00:00
Juan Sián
1ae227fddd Pontoon: Update Kaqchikel (cak) localization of Firefox Send
Localization authors:
- Juan Sián <ajtzibsyan@yahoo.com>
2019-09-26 23:32:48 +00:00
Jordi Serratosa
a63fe18d15 Pontoon: Update Catalan (ca) localization of Firefox Send
Localization authors:
- Jordi Serratosa <jordis@softcatala.cat>
2019-09-25 09:56:59 +00:00
Danny Coates
ea1ea2aa68 v3.0.19 2019-09-23 09:24:10 -07:00
Danny Coates
90d06d71d3 updated deps 2019-09-23 09:22:22 -07:00
Kim Younggeon
11f2deb7a6 Pontoon: Update Korean (ko) localization of Firefox Send
Localization authors:
- Kim Younggeon <mail@kyg.kr>
2019-09-23 03:52:14 +00:00
Danny Coates
0f5edf023a Merge pull request #1400 from mozilla/task/update-engines
task: update engines in package.json and README to clarify that node 10x is expected.
2019-09-19 11:02:42 -07:00
Rachel Tublitz
3be0621647 task: update engines in package.json and README to clarify that node 10.x is expected 2019-09-19 13:37:05 -04:00
Marcelo Ghelman
fc07bfdb85 Pontoon: Update Portuguese (Brazil) (pt-BR) localization of Firefox Send
Localization authors:
- Marcelo Ghelman <marcelo.ghelman@gmail.com>
2019-09-15 05:17:20 +00:00
صفا الفليج
581a989304 Pontoon: Update Arabic (ar) localization of Firefox Send
Localization authors:
- صفا الفليج <safa1996alfulaij@gmail.com>
2019-09-11 18:34:38 +00:00
ItielMaN
047d6a85ab Pontoon: Update Hebrew (he) localization of Firefox Send
Localization authors:
- ItielMaN <itiel_yn8@walla.com>
2019-09-08 21:12:53 +00:00
Luiz Felipe F M Costa
90f6a07d4a refactored Dockerfile 2019-09-06 20:04:45 -07:00
Arash Mousavi
8f4a53db64 Pontoon: Update Persian (fa) localization of Firefox Send
Localization authors:
- Arash Mousavi <mousavi.arash@gmail.com>
2019-09-06 21:53:28 +00:00
Danny Coates
c2dd51c638 v3.0.18 2019-09-06 10:40:36 -07:00
Danny Coates
cdd98af86a updated deps 2019-09-06 10:39:42 -07:00
Danny Coates
883f2bc0f9 wait until serviceWorker activate to precache 2019-09-05 19:04:03 -07:00
64 changed files with 1832 additions and 1134 deletions

View File

@@ -1,10 +1,8 @@
node_modules .circleci
.git
.tox
.DS_Store
firefox
assets
docs
test
coverage
.nyc_output .nyc_output
.vscode
.DS_Store
coverage
docs
firefox
node_modules

View File

@@ -19,6 +19,7 @@ rules:
node/no-unsupported-features/es-syntax: off node/no-unsupported-features/es-syntax: off
node/no-unsupported-features/node-builtins: off node/no-unsupported-features/node-builtins: off
node/no-unpublished-require: off node/no-unpublished-require: off
node/no-unpublished-import: off
security/detect-non-literal-fs-filename: off security/detect-non-literal-fs-filename: off
security/detect-object-injection: off security/detect-object-injection: off

View File

@@ -1,6 +1,7 @@
Abdalrahman Hwoij Abdalrahman Hwoij
Abhinav Adduri Abhinav Adduri
Adnan Kičin Adnan Kičin
Adolfo Jayme Barrientos
Alberto Castro Alberto Castro
Alexander Slovesnik Alexander Slovesnik
Alfredos-Panagiotis Damkalis Alfredos-Panagiotis Damkalis
@@ -63,6 +64,7 @@ George Raptis
Georgianizator Georgianizator
Gonçalo Matos Gonçalo Matos
Gwenn Gwenn
Hampus
Hugo Hugo
Hugo Abreu Hugo Abreu
Hyeonseok Shin Hyeonseok Shin
@@ -93,6 +95,7 @@ Juraj Cigáň
Kerim Kalamujić Kerim Kalamujić
Khaled Hosny Khaled Hosny
Kim Ludvigsen Kim Ludvigsen
Kim Younggeon
Kohei Yoshino Kohei Yoshino
Lan Glad Lan Glad
Lasse Liehu Lasse Liehu
@@ -101,6 +104,7 @@ Lobodzets
LuFlo LuFlo
Luis A. Sánchez Luis A. Sánchez
Luiz Carlos de Morais Luiz Carlos de Morais
Luiz Felipe F M Costa
Luna Jernberg Luna Jernberg
Mahay Alam Khan Mahay Alam Khan
Marcelo Ghelman Marcelo Ghelman
@@ -110,6 +114,7 @@ Mark Heijl
Mark Liang Mark Liang
Mark Liang (You-Wen) Mark Liang (You-Wen)
Marko Andrejić Marko Andrejić
Martijn Dekker
Marwan Mohamad Marwan Mohamad
Matjaž Horvat Matjaž Horvat
Maykon Chagas Maykon Chagas
@@ -131,6 +136,7 @@ Myungjae Won
Nicholas Skinsacos Nicholas Skinsacos
Nihad Nihad
Nihad Suljić Nihad Suljić
Niksend Mizuhara
Oscar Oscar
Paulius Paulius
Pedro Burlamaqui Bendahan Pedro Burlamaqui Bendahan
@@ -138,7 +144,9 @@ Peter deHaan
Pierre Neter Pierre Neter
Pin-guang Chen Pin-guang Chen
Piotr Drąg Piotr Drąg
Quentí
Quế Tùng Quế Tùng
Rachel Tublitz
Radu Popescu Radu Popescu
Rhoslyn Prys Rhoslyn Prys
RickieES RickieES
@@ -161,6 +169,7 @@ Sara Todaro
Sav22999 Sav22999
Schieck :) Schieck :)
Selim Şumlu Selim Şumlu
Selyan Sliman Amiri
Sidak Singh Aulakh Sidak Singh Aulakh
Slimane Amiri Slimane Amiri
Slimane Selyan AMIRI Slimane Selyan AMIRI
@@ -183,6 +192,7 @@ Victor Bychek
Vimal Raghubir Vimal Raghubir
Vitaliy Krutko Vitaliy Krutko
Weihang Lo Weihang Lo
Wiktor Furman
Wil Clouser Wil Clouser
YFdyh000 YFdyh000
Yassine Aït-El-Mouden Yassine Aït-El-Mouden
@@ -213,9 +223,11 @@ jesferman1993
jlG jlG
josotrix josotrix
jspam jspam
julen
julenx julenx
kenrick95 kenrick95
kumincir kumincir
leo.toneff
m4hdi.pdroid m4hdi.pdroid
mail mail
manxmensch manxmensch

View File

@@ -1,19 +1,59 @@
FROM node:10 AS builder ##
RUN addgroup --gid 10001 app && adduser --disabled-password --gecos '' --gid 10001 --home /app --uid 10001 app # Firefox Send - Mozilla
COPY package*.json /app/ #
WORKDIR /app # License https://github.com/mozilla/send/blob/master/LICENSE
RUN npm install --production ##
FROM node:10-slim
RUN addgroup --gid 10001 app && adduser --disabled-password --gecos '' --gid 10001 --home /app --uid 10001 app # Build project
FROM node:10 AS builder
RUN set -x \
# Add user
&& addgroup --gid 10001 app \
&& adduser --disabled-password \
--gecos '' \
--gid 10001 \
--home /app \
--uid 10001 \
app
COPY --chown=app:app . /app
USER app USER app
WORKDIR /app WORKDIR /app
COPY --chown=app:app --from=builder /app . RUN ls -la
COPY --chown=app:app . . RUN set -x \
# Build
&& npm ci \
&& npm run build
# Main image
FROM node:10-slim
RUN set -x \
# Add user
&& addgroup --gid 10001 app \
&& adduser --disabled-password \
--gecos '' \
--gid 10001 \
--home /app \
--uid 10001 \
app
RUN apt-get update && apt-get -y install git-core
USER app
WORKDIR /app
COPY --chown=app:app package*.json ./
COPY --chown=app:app app app
COPY --chown=app:app common common
COPY --chown=app:app public/locales public/locales
COPY --chown=app:app server server
COPY --chown=app:app --from=builder /app/dist dist
RUN ls -la
RUN npm ci --production && npm cache clean --force
RUN mkdir -p /app/.config/configstore RUN mkdir -p /app/.config/configstore
RUN ln -s dist/version.json version.json RUN ln -s dist/version.json version.json
ENV PORT=1443 ENV PORT=1443
EXPOSE $PORT
EXPOSE ${PORT}
CMD ["node", "server/bin/prod.js"] CMD ["node", "server/bin/prod.js"]

View File

@@ -1,4 +1,4 @@
# [![Firefox Send](./assets/logo.svg)](https://send.firefox.com/) # [![Firefox Send](./assets/icon.svg)](https://send.firefox.com/) Firefox Send
[![CircleCI](https://img.shields.io/circleci/project/github/mozilla/send.svg)](https://circleci.com/gh/mozilla/send) [![CircleCI](https://img.shields.io/circleci/project/github/mozilla/send.svg)](https://circleci.com/gh/mozilla/send)
@@ -30,7 +30,7 @@ A file sharing experiment which allows you to send encrypted files to other user
## Requirements ## Requirements
- [Node.js 10.0+](https://nodejs.org/) - [Node.js 10.x](https://nodejs.org/)
- [Redis server](https://redis.io/) (optional for development) - [Redis server](https://redis.io/) (optional for development)
- [AWS S3](https://aws.amazon.com/s3/) or compatible service. (optional) - [AWS S3](https://aws.amazon.com/s3/) or compatible service. (optional)

View File

@@ -60,9 +60,7 @@ function body(main) {
</a>`; </a>`;
*/ */
return html` return html`
<body <body class="flex flex-col items-center font-sans bg-grey-10 h-screen">
class="flex flex-col items-center font-sans bg-grey-lightest h-screen"
>
${state.cache(Header, 'header').render()} ${main(state, emit)} ${state.cache(Header, 'header').render()} ${main(state, emit)}
</body> </body>
`; `;

View File

@@ -25,7 +25,7 @@ module.exports = function(state, emit) {
let content = ''; let content = '';
let button = html` let button = html`
<div <div
class="bg-blue rounded-full m-4 flex items-center justify-center shadow-lg" class="bg-blue-50 rounded-full m-4 flex items-center justify-center shadow-lg"
style="width: 56px; height: 56px" style="width: 56px; height: 56px"
onclick="${onclick}" onclick="${onclick}"
> >

View File

@@ -39,7 +39,7 @@ body {
} }
.btn { .btn {
@apply bg-blue-dark; @apply bg-blue-60;
@apply text-white; @apply text-white;
@apply cursor-pointer; @apply cursor-pointer;
@apply py-4; @apply py-4;
@@ -48,11 +48,11 @@ body {
} }
.btn:hover { .btn:hover {
@apply bg-blue-darker; @apply bg-blue-70;
} }
.btn:focus { .btn:focus {
@apply bg-blue-darker; @apply bg-blue-70;
} }
.checkbox { .checkbox {
@@ -70,7 +70,7 @@ body {
} }
.checkbox > label::before { .checkbox > label::before {
/* @apply bg-grey-lightest; */ /* @apply bg-grey-10; */
@apply border; @apply border;
@apply rounded-sm; @apply rounded-sm;
@@ -82,16 +82,16 @@ body {
} }
.checkbox > label:hover::before { .checkbox > label:hover::before {
@apply border-blue-dark; @apply border-blue-50;
} }
.checkbox > input:focus + label::before { .checkbox > input:focus + label::before {
@apply border-blue-dark; @apply border-blue-50;
} }
.checkbox > input:checked + label::before { .checkbox > input:checked + label::before {
@apply bg-blue-dark; @apply bg-blue-50;
@apply border-blue-dark; @apply border-blue-50;
background-image: url('../assets/lock.svg'); background-image: url('../assets/lock.svg');
background-position: center; background-position: center;
@@ -104,8 +104,8 @@ body {
} }
.checkbox > input:disabled + label::before { .checkbox > input:disabled + label::before {
@apply bg-blue-dark; @apply bg-blue-50;
@apply border-blue-dark; @apply border-blue-50;
background-image: url('../assets/lock.svg'); background-image: url('../assets/lock.svg');
background-position: center; background-position: center;
@@ -153,9 +153,21 @@ footer li:hover {
white-space: nowrap; white-space: nowrap;
} }
.link-blue {
@apply text-blue-60;
}
.link-blue:hover {
@apply text-blue-70;
}
.link-blue:focus {
@apply text-blue-70;
}
.main-header img { .main-header img {
height: 32px; height: 32px;
width: 170px; width: auto;
} }
.intro { .intro {
@@ -193,14 +205,14 @@ footer li:hover {
} }
progress { progress {
@apply bg-grey-light; @apply bg-grey-30;
@apply rounded-sm; @apply rounded-sm;
@apply w-full; @apply w-full;
@apply h-1; @apply h-1;
} }
progress::-webkit-progress-bar { progress::-webkit-progress-bar {
@apply bg-grey-light; @apply bg-grey-30;
@apply rounded-sm; @apply rounded-sm;
@apply w-full; @apply w-full;
@apply h-1; @apply h-1;
@@ -290,6 +302,55 @@ select {
} }
} }
@screen dark {
body {
@apply text-grey-10;
background-image: unset;
}
.btn {
@apply bg-blue-40;
@apply text-white;
}
.btn:hover {
@apply bg-blue-50;
}
.btn:focus {
@apply bg-blue-50;
}
.link-blue {
@apply text-blue-40;
}
.link-blue:hover {
@apply text-blue-50;
}
.link-blue:focus {
@apply text-blue-50;
}
.main > section {
@apply bg-grey-90;
}
.mozilla-logo {
background-color: white;
border: 1px solid white;
}
@screen md {
.main > section {
@apply border;
@apply border-grey-80;
}
}
}
@tailwind utilities; @tailwind utilities;
@responsive { @responsive {
@@ -325,8 +386,6 @@ select {
.signin:hover, .signin:hover,
.signin:focus { .signin:focus {
@apply shadow-btn;
transform: scale(1.0625); transform: scale(1.0625);
} }
@@ -337,19 +396,19 @@ select {
/* begin signin button color experiment */ /* begin signin button color experiment */
.white-blue { .white-blue {
@apply border-blue-dark; @apply border-blue-60;
@apply border-2; @apply border-2;
@apply text-blue-dark; @apply text-blue-60;
} }
.white-blue:hover, .white-blue:hover,
.white-blue:focus { .white-blue:focus {
@apply bg-blue-dark; @apply bg-blue-60;
@apply text-white; @apply text-white;
} }
.blue { .blue {
@apply bg-blue-dark; @apply bg-blue-60;
@apply text-white; @apply text-white;
} }

View File

@@ -13,12 +13,12 @@ const VERSIONED_ASSET = /\.[A-Fa-f0-9]{8}\.(js|css|png|svg|jpg)$/;
const DOWNLOAD_URL = /\/api\/download\/([A-Fa-f0-9]{4,})/; const DOWNLOAD_URL = /\/api\/download\/([A-Fa-f0-9]{4,})/;
const FONT = /\.woff2?$/; const FONT = /\.woff2?$/;
self.addEventListener('install', event => { self.addEventListener('install', () => {
event.waitUntil(precache()); self.skipWaiting();
}); });
self.addEventListener('activate', event => { self.addEventListener('activate', event => {
event.waitUntil(self.clients.claim().then(cleanCache)); event.waitUntil(self.clients.claim().then(precache));
}); });
async function decryptStream(id) { async function decryptStream(id) {
@@ -84,10 +84,15 @@ async function decryptStream(id) {
} }
async function precache() { async function precache() {
const cache = await caches.open(version); try {
const images = assets.match(IMAGES); await cleanCache();
await cache.addAll(images); const cache = await caches.open(version);
return self.skipWaiting(); const images = assets.match(IMAGES);
await cache.addAll(images);
} catch (e) {
console.error(e);
// cache will get populated on demand
}
} }
async function cleanCache() { async function cleanCache() {

View File

@@ -64,8 +64,7 @@ class Account extends Component {
return html` return html`
<send-account> <send-account>
<button <button
class="px-4 py-2 md:px-8 md:py-4 focus:outline signin ${this class="px-4 py-2 md:px-8 md:py-4 focus:outline signin border-2 link-blue border-blue-60 hover:border-blue-70 dark:border-blue-40 dark:hover:border-blue-50"
.buttonClass}"
onclick="${e => this.login(e)}" onclick="${e => this.login(e)}"
title="${translate('signInOnlyButton')}" title="${translate('signInOnlyButton')}"
> >
@@ -79,19 +78,19 @@ class Account extends Component {
<input <input
type="image" type="image"
alt="${user.email}" alt="${user.email}"
class="w-8 h-8 rounded-full border text-blue md:text-white focus:outline" class="w-8 h-8 rounded-full border text-blue-50 md:text-white focus:outline"
src="${user.avatar}" src="${user.avatar}"
onclick="${e => this.avatarClick(e)}" onclick="${e => this.avatarClick(e)}"
/> />
<ul <ul
id="accountMenu" id="accountMenu"
class="invisible absolute top-0 right-0 mt-10 pt-2 pb-2 bg-white shadow-md whitespace-no-wrap outline-none z-50" class="invisible absolute top-0 right-0 mt-10 pt-2 pb-2 bg-white shadow-md whitespace-no-wrap outline-none z-50 dark:bg-grey-80"
onblur="${e => this.hideMenu(e)}" onblur="${e => this.hideMenu(e)}"
> >
<li class="p-2 text-grey-dark">${user.email}</li> <li class="p-2 text-grey-60 dark:text-grey-50">${user.email}</li>
<li> <li>
<button <button
class="block w-full text-left px-4 py-2 text-grey-darkest hover:bg-blue hover:text-white cursor-pointer focus:outline" class="block w-full text-left px-4 py-2 text-grey-80 dark:text-grey-30 hover:bg-blue-50 hover:text-white cursor-pointer focus:outline"
onclick="${e => this.logout(e)}" onclick="${e => this.logout(e)}"
title="${translate('signOut')}" title="${translate('signOut')}"
> >

View File

@@ -46,7 +46,7 @@ function password(state) {
id="password-input" id="password-input"
class="${state.archive.password class="${state.archive.password
? '' ? ''
: 'invisible'} border rounded focus:border-blue-dark leading-normal my-1 py-1 px-2 h-8" : 'invisible'} border rounded focus:border-blue-60 leading-normal my-1 py-1 px-2 h-8 dark:bg-grey-80"
autocomplete="off" autocomplete="off"
maxlength="${MAX_LENGTH}" maxlength="${MAX_LENGTH}"
type="password" type="password"
@@ -58,7 +58,7 @@ function password(state) {
<label <label
id="password-msg" id="password-msg"
for="password-input" for="password-input"
class="block text-xs text-grey-darker" class="block text-xs text-grey-70"
></label> ></label>
</div> </div>
`; `;
@@ -106,7 +106,9 @@ function password(state) {
function fileInfo(file, action) { function fileInfo(file, action) {
return html` return html`
<send-file class="flex flex-row items-center p-3 w-full"> <send-file class="flex flex-row items-center p-3 w-full">
<img class="h-8" src="${assets.get('blue_file.svg')}"/> <svg class="h-8 w-8 text-white dark:text-grey-90">
<use xlink:href="${assets.get('blue_file.svg')}#icon"/>
</svg>
<p class="ml-4 w-full"> <p class="ml-4 w-full">
<h1 class="text-base font-medium word-break-all">${file.name}</h1> <h1 class="text-base font-medium word-break-all">${file.name}</h1>
<div class="text-sm font-normal opacity-75 pt-1">${bytes( <div class="text-sm font-normal opacity-75 pt-1">${bytes(
@@ -120,7 +122,9 @@ function fileInfo(file, action) {
function archiveInfo(archive, action) { function archiveInfo(archive, action) {
return html` return html`
<p class="w-full flex items-center"> <p class="w-full flex items-center">
<img class="mr-3 flex-shrink-0" src="${assets.get('blue_file.svg')}"/> <svg class="h-8 w-6 mr-3 flex-shrink-0 text-white dark:text-grey-90">
<use xlink:href="${assets.get('blue_file.svg')}#icon"/>
</svg>
<p class="flex-grow"> <p class="flex-grow">
<h1 class="text-base font-medium word-break-all">${archive.name}</h1> <h1 class="text-base font-medium word-break-all">${archive.name}</h1>
<div class="text-sm font-normal opacity-75 pt-1">${bytes( <div class="text-sm font-normal opacity-75 pt-1">${bytes(
@@ -140,7 +144,7 @@ function archiveDetails(translate, archive) {
ontoggle="${toggled}" ontoggle="${toggled}"
> >
<summary <summary
class="flex items-center text-blue-dark text-sm cursor-pointer outline-none" class="flex items-center link-blue text-sm cursor-pointer outline-none"
> >
<svg <svg
class="fill-current w-4 h-4 mr-1" class="fill-current w-4 h-4 mr-1"
@@ -170,20 +174,25 @@ module.exports = function(state, emit, archive) {
state.capabilities.share || platform() === 'android' state.capabilities.share || platform() === 'android'
? html` ? html`
<button <button
class="text-blue-dark hover:text-blue-darker focus:text-blue-darker self-end flex items-end" class="link-blue self-end flex items-start"
onclick=${share} onclick=${share}
title="Share link" title="Share link"
> >
<img src="${assets.get('share-24.svg')}" class="mr-2" />Share link <svg class="h-4 w-4 mr-2">
<use xlink:href="${assets.get('share-24.svg')}#icon" />
</svg>
Share link
</button> </button>
` `
: html` : html`
<button <button
class="text-blue-dark hover:text-blue-darker focus:text-blue-darker focus:outline self-end flex items-center" class="link-blue focus:outline self-end flex items-center"
onclick=${copy} onclick=${copy}
title="${state.translate('copyLinkButton')}" title="${state.translate('copyLinkButton')}"
> >
<img src="${assets.get('copy-16.svg')}" class="mr-2" /> <svg class="h-4 w-4 mr-2">
<use xlink:href="${assets.get('copy-16.svg')}#icon" />
</svg>
${state.translate('copyLinkButton')} ${state.translate('copyLinkButton')}
</button> </button>
`; `;
@@ -191,12 +200,14 @@ module.exports = function(state, emit, archive) {
platform() === 'web' platform() === 'web'
? html` ? html`
<a <a
class="flex items-baseline text-blue-dark hover:text-blue-darker focus:text-blue-darker" class="flex items-baseline link-blue"
href="${archive.url}" href="${archive.url}"
title="${state.translate('downloadButtonLabel')}" title="${state.translate('downloadButtonLabel')}"
tabindex="0" tabindex="0"
> >
<img src="${assets.get('dl.svg')}" class="mr-2" /> <svg class="h-4 w-3 mr-2">
<use xlink:href="${assets.get('dl.svg')}#icon" />
</svg>
${state.translate('downloadButtonLabel')} ${state.translate('downloadButtonLabel')}
</a> </a>
` `
@@ -206,7 +217,7 @@ module.exports = function(state, emit, archive) {
return html` return html`
<send-archive <send-archive
id="archive-${archive.id}" id="archive-${archive.id}"
class="flex flex-col items-start rounded shadow-light bg-white p-4 w-full" class="flex flex-col items-start rounded shadow-light bg-white p-4 w-full dark:bg-grey-90 dark:border dark:border-grey-70"
> >
${archiveInfo( ${archiveInfo(
archive, archive,
@@ -225,7 +236,7 @@ module.exports = function(state, emit, archive) {
${expiryInfo(state.translate, archive)} ${expiryInfo(state.translate, archive)}
</div> </div>
${archiveDetails(state.translate, archive)} ${archiveDetails(state.translate, archive)}
<hr class="w-full border-t my-4" /> <hr class="w-full border-t my-4 dark:border-grey-70" />
<div class="flex justify-between w-full"> <div class="flex justify-between w-full">
${dl} ${copyOrShare} ${dl} ${copyOrShare}
</div> </div>
@@ -269,18 +280,21 @@ module.exports = function(state, emit, archive) {
module.exports.wip = function(state, emit) { module.exports.wip = function(state, emit) {
return html` return html`
<send-upload-area class="flex flex-col bg-white h-full w-full" id="wip"> <send-upload-area
class="flex flex-col bg-white h-full w-full dark:bg-grey-90"
id="wip"
>
${list( ${list(
Array.from(state.archive.files) Array.from(state.archive.files)
.reverse() .reverse()
.map(f => .map(f =>
fileInfo(f, remove(f, state.translate('deleteButtonHover'))) fileInfo(f, remove(f, state.translate('deleteButtonHover')))
), ),
'flex-shrink bg-grey-lightest rounded-t overflow-y-auto px-6 py-4 md:h-full md:max-h-half-screen', 'flex-shrink bg-grey-10 rounded-t overflow-y-auto px-6 py-4 md:h-full md:max-h-half-screen dark:bg-black',
'bg-white px-2 my-2 shadow-light rounded' 'bg-white px-2 my-2 shadow-light rounded dark:bg-grey-90 dark:border dark:border-grey-80'
)} )}
<div <div
class="flex-shrink-0 flex-grow flex items-end p-4 bg-grey-lightest rounded-b mb-1 font-medium" class="flex-shrink-0 flex-grow flex items-end p-4 bg-grey-10 rounded-b mb-1 font-medium dark:bg-grey-90"
> >
<input <input
id="file-upload" id="file-upload"
@@ -300,10 +314,12 @@ module.exports.wip = function(state, emit) {
class="flex items-center cursor-pointer" class="flex items-center cursor-pointer"
title="${state.translate('addFilesButton')}" title="${state.translate('addFilesButton')}"
> >
<img src="${assets.get('addfiles.svg')}" class="w-6 h-6 mr-2" /> <svg class="w-6 h-6 mr-2 link-blue">
<use xlink:href="${assets.get('addfiles.svg')}#plus" />
</svg>
${state.translate('addFilesButton')} ${state.translate('addFilesButton')}
</label> </label>
<div class="font-normal text-sm text-grey-darker"> <div class="font-normal text-sm text-grey-70 dark:text-grey-40">
${state.translate('totalSize', { ${state.translate('totalSize', {
size: bytes(state.archive.size) size: bytes(state.archive.size)
})} })}
@@ -378,22 +394,22 @@ module.exports.uploading = function(state, emit) {
return html` return html`
<send-upload-area <send-upload-area
id="${archive.id}" id="${archive.id}"
class="flex flex-col items-start rounded shadow-light bg-white p-4 w-full" class="flex flex-col items-start rounded shadow-light bg-white p-4 w-full dark:bg-grey-90"
> >
${archiveInfo(archive)} ${archiveInfo(archive)}
<div class="text-xs text-grey-dark w-full mt-2 mb-2"> <div class="text-xs opacity-75 w-full mt-2 mb-2">
${expiryInfo(state.translate, { ${expiryInfo(state.translate, {
dlimit: state.archive.dlimit, dlimit: state.archive.dlimit,
dtotal: 0, dtotal: 0,
expiresAt: Date.now() + 500 + state.archive.timeLimit * 1000 expiresAt: Date.now() + 500 + state.archive.timeLimit * 1000
})} })}
</div> </div>
<div class="text-blue-dark text-sm font-medium mt-2"> <div class="link-blue text-sm font-medium mt-2">
${progressPercent} ${progressPercent}
</div> </div>
<progress class="my-3" value="${progress}">${progressPercent}</progress> <progress class="my-3" value="${progress}">${progressPercent}</progress>
<button <button
class="text-blue-dark hover:text-blue-darker focus:text-blue-darker self-end font-medium" class="link-blue self-end font-medium"
onclick=${cancel} onclick=${cancel}
title="${state.translate('deletePopupCancel')}" title="${state.translate('deletePopupCancel')}"
> >
@@ -415,7 +431,7 @@ module.exports.empty = function(state, emit) {
? '' ? ''
: html` : html`
<button <button
class="center font-medium text-sm text-blue-dark hover:text-blue-darker focus:text-blue-darker mt-4 mb-2" class="center font-medium text-sm link-blue mt-4 mb-2"
onclick="${event => { onclick="${event => {
event.stopPropagation(); event.stopPropagation();
emit('signup-cta', 'drop'); emit('signup-cta', 'drop');
@@ -428,14 +444,16 @@ module.exports.empty = function(state, emit) {
`; `;
return html` return html`
<send-upload-area <send-upload-area
class="flex flex-col items-center justify-center border-2 border-dashed border-grey-transparent rounded px-6 py-16 h-full w-full" class="flex flex-col items-center justify-center border-2 border-dashed border-grey-transparent rounded px-6 py-16 h-full w-full dark:border-grey-60"
onclick="${e => { onclick="${e => {
if (e.target.tagName !== 'LABEL') { if (e.target.tagName !== 'LABEL') {
document.getElementById('file-upload').click(); document.getElementById('file-upload').click();
} }
}}" }}"
> >
<img src="${assets.get('addfiles.svg')}" width="48" height="48" /> <svg class="w-10 h-10 link-blue">
<use xlink:href="/${assets.get('addfiles.svg')}#plus" />
</svg>
<div class="pt-6 pb-2 text-center text-lg font-bold tracking-wide"> <div class="pt-6 pb-2 text-center text-lg font-bold tracking-wide">
${state.translate('dragAndDropFiles')} ${state.translate('dragAndDropFiles')}
</div> </div>
@@ -469,14 +487,11 @@ module.exports.empty = function(state, emit) {
`; `;
function focus(event) { function focus(event) {
event.target.nextElementSibling.classList.add('bg-blue-darker', 'outline'); event.target.nextElementSibling.classList.add('bg-blue-70', 'outline');
} }
function blur(event) { function blur(event) {
event.target.nextElementSibling.classList.remove( event.target.nextElementSibling.classList.remove('bg-blue-70', 'outline');
'bg-blue-darker',
'outline'
);
} }
function add(event) { function add(event) {
@@ -501,8 +516,10 @@ module.exports.preview = function(state, emit) {
</div> </div>
`; `;
return html` return html`
<send-archive class="flex flex-col max-h-full bg-white p-4 w-full md:w-128"> <send-archive
<div class="border rounded py-3 px-6"> class="flex flex-col max-h-full bg-white p-4 w-full md:w-128 dark:bg-grey-90"
>
<div class="border rounded py-3 px-6 dark:border-grey-70">
${archiveInfo(archive)} ${details} ${archiveInfo(archive)} ${details}
</div> </div>
<button <button
@@ -529,10 +546,10 @@ module.exports.downloading = function(state) {
const progressPercent = percent(progress); const progressPercent = percent(progress);
return html` return html`
<send-archive <send-archive
class="flex flex-col bg-white rounded shadow-light p-4 w-full max-w-sm md:w-128" class="flex flex-col bg-white rounded shadow-light p-4 w-full max-w-sm md:w-128 dark:bg-grey-90"
> >
${archiveInfo(archive)} ${archiveInfo(archive)}
<div class="text-blue-dark text-sm font-medium mt-2"> <div class="link-blue text-sm font-medium mt-2">
${progressPercent} ${progressPercent}
</div> </div>
<progress class="my-3" value="${progress}">${progressPercent}</progress> <progress class="my-3" value="${progress}">${progressPercent}</progress>

View File

@@ -18,7 +18,7 @@ module.exports = function body(main) {
return function(state, emit) { return function(state, emit) {
const b = html` const b = html`
<body <body
class="flex flex-col items-center font-sans md:h-screen md:bg-grey-lightest" class="flex flex-col items-center font-sans md:h-screen md:bg-grey-10 dark:bg-black"
> >
${banner(state, emit)} ${state.cache(Header, 'header').render()} ${banner(state, emit)} ${state.cache(Header, 'header').render()}
${main(state, emit)} ${state.cache(Footer, 'footer').render()} ${main(state, emit)} ${state.cache(Footer, 'footer').render()}

View File

@@ -10,14 +10,16 @@ module.exports = function(name, url) {
<h1 class="text-3xl font-bold my-4"> <h1 class="text-3xl font-bold my-4">
${state.translate('notifyUploadEncryptDone')} ${state.translate('notifyUploadEncryptDone')}
</h1> </h1>
<p class="font-normal leading-normal text-grey-darkest word-break-all"> <p
class="font-normal leading-normal text-grey-80 word-break-all dark:text-grey-40"
>
${state.translate('copyLinkDescription')} <br /> ${state.translate('copyLinkDescription')} <br />
${name} ${name}
</p> </p>
<input <input
type="text" type="text"
id="share-url" id="share-url"
class="w-full my-4 border rounded-lg leading-loose h-12 px-2 py-1" class="w-full my-4 border rounded-lg leading-loose h-12 px-2 py-1 dark:bg-grey-80"
value="${url}" value="${url}"
readonly="true" readonly="true"
/> />
@@ -29,7 +31,7 @@ module.exports = function(name, url) {
${state.translate('copyLinkButton')} ${state.translate('copyLinkButton')}
</button> </button>
<button <button
class="text-blue-dark hover:text-blue-darker focus:text-blue-darker my-4 font-medium cursor-pointer focus:outline" class="link-blue my-4 font-medium cursor-pointer focus:outline"
onclick="${close}" onclick="${close}"
title="${state.translate('okButton')}" title="${state.translate('okButton')}"
> >

View File

@@ -41,7 +41,9 @@ function preview(state, emit) {
<h1 class="text-3xl font-bold mb-4"> <h1 class="text-3xl font-bold mb-4">
${state.translate('downloadTitle')} ${state.translate('downloadTitle')}
</h1> </h1>
<p class="w-full text-grey-darkest text-center leading-normal"> <p
class="w-full text-grey-80 text-center leading-normal dark:text-grey-40"
>
${state.translate('downloadDescription')} ${state.translate('downloadDescription')}
</p> </p>
${archiveTile.preview(state, emit)} ${archiveTile.preview(state, emit)}

View File

@@ -5,13 +5,13 @@ module.exports = function(state) {
return html` return html`
<div <div
id="download-complete" id="download-complete"
class="flex flex-col items-center justify-center h-full w-full bg-white p-2" class="flex flex-col items-center justify-center h-full w-full bg-white p-2 dark:bg-grey-90"
> >
<h1 class="text-center text-3xl font-bold my-2"> <h1 class="text-center text-3xl font-bold my-2">
${state.translate('downloadFinish')} ${state.translate('downloadFinish')}
</h1> </h1>
<img src="${assets.get('completed.svg')}" class="my-12 h-48" /> <img src="${assets.get('completed.svg')}" class="my-12 h-48" />
<p class="text-grey-darkest leading-normal"> <p class="text-grey-80 leading-normal dark:text-grey-40">
${state.translate('trySendDescription')} ${state.translate('trySendDescription')}
</p> </p>
<p class="my-5"> <p class="my-5">

View File

@@ -6,12 +6,14 @@ module.exports = function(state, emit) {
const div = html` const div = html`
<div <div
class="h-full w-full flex flex-col items-center justify-center bg-white py-8 max-w-md mx-auto" class="h-full w-full flex flex-col items-center justify-center bg-white py-8 max-w-md mx-auto dark:bg-grey-90"
> >
<h1 class="text-3xl font-bold mb-4"> <h1 class="text-3xl font-bold mb-4">
${state.translate('downloadTitle')} ${state.translate('downloadTitle')}
</h1> </h1>
<p class="w-full mb-4 text-center text-grey-darkest leading-normal"> <p
class="w-full mb-4 text-center text-grey-80 dark:text-grey-40 leading-normal"
>
${state.translate('downloadDescription')} ${state.translate('downloadDescription')}
</p> </p>
<form <form
@@ -22,8 +24,8 @@ module.exports = function(state, emit) {
<input <input
id="password-input" id="password-input"
class="w-full border-l border-t border-b rounded-l-lg rounded-r-none ${invalid class="w-full border-l border-t border-b rounded-l-lg rounded-r-none ${invalid
? 'border-red' ? 'border-red dark:border-red-40'
: 'border-grey'} leading-loose px-2 py-1" : 'border-grey'} leading-loose px-2 py-1 dark:bg-grey-80"
maxlength="32" maxlength="32"
autocomplete="off" autocomplete="off"
placeholder="${state.translate('unlockInputPlaceholder')}" placeholder="${state.translate('unlockInputPlaceholder')}"
@@ -34,7 +36,7 @@ module.exports = function(state, emit) {
type="submit" type="submit"
id="password-btn" id="password-btn"
class="btn rounded-r-lg rounded-l-none ${invalid class="btn rounded-r-lg rounded-l-none ${invalid
? 'bg-red hover:bg-red focus:bg-red' ? 'bg-red hover:bg-red focus:bg-red dark:bg-red-40'
: ''}" : ''}"
value="${state.translate('unlockButtonLabel')}" value="${state.translate('unlockButtonLabel')}"
title="${state.translate('unlockButtonLabel')}" title="${state.translate('unlockButtonLabel')}"
@@ -42,7 +44,7 @@ module.exports = function(state, emit) {
</form> </form>
<label <label
id="password-error" id="password-error"
class="${invalid ? '' : 'invisible'} text-red my-4" class="${invalid ? '' : 'invisible'} text-red dark:text-red-40 my-4"
for="password-input" for="password-input"
> >
${state.translate('passwordTryAgain')} ${state.translate('passwordTryAgain')}
@@ -72,7 +74,9 @@ module.exports = function(state, emit) {
const password = el.value; const password = el.value;
if (password.length > 0) { if (password.length > 0) {
document.getElementById('password-btn').disabled = true; document.getElementById('password-btn').disabled = true;
state.fileInfo.url = window.location.href; // Strip any url parameters between fileId and secretKey
const fileInfoUrl = window.location.href.replace(/\?.+#/, '#');
state.fileInfo.url = fileInfoUrl;
state.fileInfo.password = password; state.fileInfo.password = password;
emit('getMetadata'); emit('getMetadata');
} }

View File

@@ -13,7 +13,7 @@ module.exports = function(state, emit) {
${state.translate('errorPageHeader')} ${state.translate('errorPageHeader')}
</h1> </h1>
<img class="my-12 h-48" src="${assets.get('error.svg')}" /> <img class="my-12 h-48" src="${assets.get('error.svg')}" />
<p class="max-w-md text-center text-grey-darkest leading-normal"> <p class="max-w-md text-center text-grey-80 leading-normal">
${state.translate('trySendDescription')} ${state.translate('trySendDescription')}
</p> </p>
<p class="my-5"> <p class="my-5">

View File

@@ -19,12 +19,9 @@ class Footer extends Component {
const feedbackUrl = `https://qsurvey.mozilla.com/s3/Firefox-Send-Product-Feedback?ver=${version}&browser=${browser}`; const feedbackUrl = `https://qsurvey.mozilla.com/s3/Firefox-Send-Product-Feedback?ver=${version}&browser=${browser}`;
return html` return html`
<footer <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-dark md:items-center justify-between" 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"
> >
<a <a class="mozilla-logo m-2" href="https://www.mozilla.org/">
class="mozilla-logo pb-10 md:pb-0 m-2"
href="https://www.mozilla.org/"
>
Mozilla Mozilla
</a> </a>
<ul <ul

View File

@@ -16,15 +16,27 @@ class Header extends Component {
this.account.render(); this.account.render();
return false; return false;
} }
createElement() { createElement() {
const title = const title =
platform() === 'android' platform() === 'android'
? html` ? html`
<a class=""><img src="${assets.get('logo.svg')}"/></a> <a class="flex flex-row items-center">
<img src="${assets.get('icon.svg')}" />
<svg class="w-48">
<use xlink:href="${assets.get('wordmark.svg')}#logo" />
</svg>
</a>
` `
: html` : html`
<a class="" href="/"><img src="${assets.get('logo.svg')}"/></a> <a class="flex flex-row items-center" href="/">
<img
alt="${this.state.translate('title')}"
src="${assets.get('icon.svg')}"
/>
<svg class="w-48 md:w-64">
<use xlink:href="${assets.get('wordmark.svg')}#logo" />
</svg>
</a>
`; `;
return html` return html`
<header <header

View File

@@ -4,7 +4,7 @@ const assets = require('../../common/assets');
module.exports = function intro(state) { module.exports = function intro(state) {
return html` return html`
<send-intro <send-intro
class="flex flex-col items-center justify-center bg-white px-6 md:py-0 py-6 mb-0 h-full w-full" class="flex flex-col items-center justify-center bg-white px-6 md:py-0 py-6 mb-0 h-full w-full dark:bg-grey-90"
> >
<div class="mt-12 flex flex-col h-full"> <div class="mt-12 flex flex-col h-full">
<h1 class="text-3xl font-bold md:pb-2"> <h1 class="text-3xl font-bold md:pb-2">

View File

@@ -6,7 +6,7 @@ module.exports = function(state, emit) {
<main class="main"> <main class="main">
${state.modal && modal(state, emit)} ${state.modal && modal(state, emit)}
<div <div
class="flex flex-col items-center bg-white m-4 px-6 py-8 border border-grey-light md:border-none md:px-12 md:py-16 shadow w-full md:h-full" class="flex flex-col items-center bg-white m-4 px-6 py-8 border border-grey-30 md:border-none md:px-12 md:py-16 shadow w-full md:h-full dark:bg-grey-90"
> >
<h1 class="text-center text-3xl font-bold"> <h1 class="text-center text-3xl font-bold">
${state.translate('legalTitle')} ${state.translate('legalTitle')}
@@ -19,7 +19,7 @@ module.exports = function(state, emit) {
href="https://www.mozilla.org/privacy/" href="https://www.mozilla.org/privacy/"
target="__blank" target="__blank"
rel="noopener noreferrer" rel="noopener noreferrer"
class="text-blue-dark hover:underline" class="link-blue hover:underline"
>Mozilla Privacy Policy</a >Mozilla Privacy Policy</a
> >
<span <span
@@ -31,7 +31,7 @@ module.exports = function(state, emit) {
href="https://github.com/mozilla/send/blob/master/docs/metrics.md" href="https://github.com/mozilla/send/blob/master/docs/metrics.md"
target="__blank" target="__blank"
rel="noopener noreferrer" rel="noopener noreferrer"
class="text-blue-dark hover:underline" class="link-blue hover:underline"
>here</a >here</a
>. >.
</p> </p>

View File

@@ -3,13 +3,12 @@ const html = require('choo/html');
module.exports = function(state, emit) { module.exports = function(state, emit) {
return html` return html`
<send-modal <send-modal
class="absolute inset-0 flex items-center justify-center overflow-hidden z-40 bg-white md:rounded-xl md:my-8" class="absolute inset-0 flex items-center justify-center overflow-hidden z-40 bg-white md:rounded-xl md:my-8 dark:bg-grey-90"
onclick="${close}"
> >
<div <div
class="h-full w-full max-h-screen absolute top-0 flex items-center justify-center" class="h-full w-full max-h-screen absolute top-0 flex items-center justify-center"
> >
<div class="w-full" onclick="${e => e.stopPropagation()}"> <div class="w-full">
${state.modal(state, emit, close)} ${state.modal(state, emit, close)}
</div> </div>
</div> </div>

View File

@@ -12,7 +12,7 @@ module.exports = function(state, emit) {
'downloadTitle' 'downloadTitle'
)}</h1> )}</h1>
<p <p
class="w-full p-2 border border-yellow-light rounded md:w-4/5 text-orange-dark bg-yellow-lighter text-center leading-normal" class="w-full p-2 border border-yellow-50 rounded md:w-4/5 text-orange-60 bg-yellow-40 text-center leading-normal"
> >
⚠️ ${state.translate('noStreamsWarning')} ⚠️ ⚠️ ${state.translate('noStreamsWarning')} ⚠️
</p> </p>

View File

@@ -13,7 +13,7 @@ module.exports = function(state, emit) {
${state.translate('expiredTitle')} ${state.translate('expiredTitle')}
</h1> </h1>
<img src="${assets.get('notFound.svg')}" class="my-12" /> <img src="${assets.get('notFound.svg')}" class="my-12" />
<p class="max-w-md text-center text-grey-darkest leading-normal"> <p class="max-w-md text-center text-grey-80 leading-normal">
${state.translate('trySendDescription')} ${state.translate('trySendDescription')}
</p> </p>
<p class="my-5"> <p class="my-5">

View File

@@ -15,7 +15,7 @@ class Promo extends Component {
createElement() { createElement() {
return html` return html`
<send-promo <send-promo
class="w-full flex-row items-center content-center justify-center bg-white text-grey-darkest px-4 py-3 flex border-b border-grey-banner leading-normal" class="w-full flex-row items-center content-center justify-center bg-white text-grey-80 px-4 py-3 flex border-b border-grey-banner leading-normal dark:bg-grey-90 dark:text-grey-20 dark:border-grey-80"
> >
<div class="flex items-center mx-auto"> <div class="flex items-center mx-auto">
<img <img
@@ -26,7 +26,7 @@ class Promo extends Component {
<span class="ml-2 sm:ml-4 text-xs sm:text-base"> <span class="ml-2 sm:ml-4 text-xs sm:text-base">
${this.state.translate('trailheadPromo')}${' '} ${this.state.translate('trailheadPromo')}${' '}
<a <a
class="underline text-blue-dark" class="underline link-blue"
href="http://www.mozilla.org/firefox/accounts/?utm_source=send.firefox.com&utm_medium=banner&utm_campaign=trailhead&utm_content=protect-your-privacy" href="http://www.mozilla.org/firefox/accounts/?utm_source=send.firefox.com&utm_medium=banner&utm_campaign=trailhead&utm_content=protect-your-privacy"
>${this.state.translate('learnMore')}</a >${this.state.translate('learnMore')}</a
> >

View File

@@ -6,7 +6,7 @@ module.exports = function(selected, options, translate, changed, htmlId) {
return html` return html`
<select <select
id="${htmlId}" id="${htmlId}"
class="appearance-none cursor-pointer border rounded bg-grey-lightest hover:border-blue-dark focus:border-blue-dark pl-1 pr-8 py-1 my-1 h-8" class="appearance-none cursor-pointer border rounded bg-grey-10 hover:border-blue-50 focus:border-blue-50 pl-1 pr-8 py-1 my-1 h-8 dark:bg-grey-80"
onchange="${choose}" onchange="${choose}"
> >
${options.map( ${options.map(

View File

@@ -9,14 +9,16 @@ module.exports = function(name, url) {
<h1 class="text-3xl font-bold my-4"> <h1 class="text-3xl font-bold my-4">
${state.translate('notifyUploadEncryptDone')} ${state.translate('notifyUploadEncryptDone')}
</h1> </h1>
<p class="font-normal leading-normal text-grey-darkest word-break-all"> <p
class="font-normal leading-normal text-grey-80 word-break-all dark:text-grey-40"
>
${state.translate('shareLinkDescription')}<br /> ${state.translate('shareLinkDescription')}<br />
${name} ${name}
</p> </p>
<input <input
type="text" type="text"
id="share-url" id="share-url"
class="w-full my-4 border rounded-lg leading-loose h-12 px-2 py-1" class="w-full my-4 border rounded-lg leading-loose h-12 px-2 py-1 dark:bg-grey-80"
value="${url}" value="${url}"
readonly="true" readonly="true"
/> />
@@ -28,7 +30,7 @@ module.exports = function(name, url) {
${state.translate('shareLinkButton')} ${state.translate('shareLinkButton')}
</button> </button>
<button <button
class="text-blue-dark hover:text-blue-darker focus:text-blue-darker my-4 font-medium cursor-pointer focus:outline" class="link-blue my-4 font-medium cursor-pointer focus:outline"
onclick="${close}" onclick="${close}"
title="${state.translate('okButton')}" title="${state.translate('okButton')}"
> >

View File

@@ -20,7 +20,7 @@ module.exports = function(trigger) {
${state.translate('accountBenefitTitle')} ${state.translate('accountBenefitTitle')}
</h1> </h1>
<ul <ul
class="leading-normal text-grey-darkest my-2 mt-4 pl-4 md:self-center" class="leading-normal list-disc text-grey-80 my-2 mt-4 pl-4 md:self-center dark:text-grey-40"
> >
<li> <li>
${state.translate('accountBenefitLargeFiles', { ${state.translate('accountBenefitLargeFiles', {
@@ -42,7 +42,7 @@ module.exports = function(trigger) {
<input <input
id="email-input" id="email-input"
type="email" type="email"
class="${hidden} border rounded-lg w-full px-2 py-1 h-12 mb-3 text-lg text-grey-darker leading-loose" class="${hidden} border rounded-lg w-full px-2 py-1 h-12 mb-3 text-lg text-grey-70 leading-loose dark:bg-grey-80 dark:text-white"
placeholder=${state.translate('emailPlaceholder')} placeholder=${state.translate('emailPlaceholder')}
/> />
<input <input
@@ -54,7 +54,7 @@ module.exports = function(trigger) {
/> />
</form> </form>
<button <button
class="my-3 text-blue-dark hover:text-blue-darker focus:text-blue-darker font-medium" class="my-3 link-blue font-medium"
title="${state.translate('deletePopupCancel')}" title="${state.translate('deletePopupCancel')}"
onclick=${cancel} onclick=${cancel}
> >

View File

@@ -16,7 +16,7 @@ module.exports = function() {
<h1 class="text-3xl font-bold my-4"> <h1 class="text-3xl font-bold my-4">
Tell us what you think. Tell us what you think.
</h1> </h1>
<p class="font-normal leading-normal text-grey-darkest px-4"> <p class="font-normal leading-normal text-grey-80 px-4">
Love Firefox Send? Take a quick survey to let us know how we can make Love Firefox Send? Take a quick survey to let us know how we can make
it better. it better.
</p> </p>
@@ -30,7 +30,7 @@ module.exports = function() {
Give feedback Give feedback
</a> </a>
<button <button
class="text-blue-dark hover:text-blue-darker focus:text-blue-darker font-medium cursor-pointer focus:outline" class="link-blue font-medium cursor-pointer focus:outline"
onclick="${close}" onclick="${close}"
title="Skip" title="Skip"
> >

View File

@@ -27,7 +27,7 @@ module.exports = function(state, emit) {
<main class="main"> <main class="main">
${state.modal && modal(state, emit)} ${state.modal && modal(state, emit)}
<section <section
class="flex flex-col items-center justify-center text-center bg-white m-6 px-6 py-8 border border-grey-light md:border-none md:px-12 md:py-16 shadow w-full md:h-full" class="flex flex-col items-center justify-center text-center bg-white m-6 px-6 py-8 border border-grey-30 md:border-none md:px-12 md:py-16 shadow w-full md:h-full dark:bg-grey-90"
> >
<h1 class="text-3xl font-bold">${strings.header}</h1> <h1 class="text-3xl font-bold">${strings.header}</h1>
<p class="mt-4 mb-8 max-w-md leading-normal">${strings.description}</p> <p class="mt-4 mb-8 max-w-md leading-normal">${strings.description}</p>

View File

@@ -1,9 +1,9 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs> <symbol id="plus" viewBox="0 0 24 24">
<polygon id="addfiles-a" points="11.143 6 11.143 11.143 6 11.143 6 12.857 11.143 12.857 11.143 18 12.857 18 12.857 12.857 18 12.857 18 11.143 12.857 11.143 12.857 6"/>
</defs>
<g fill="none" fill-rule="evenodd"> <g fill="none" fill-rule="evenodd">
<path fill="#0060df" fill-rule="nonzero" d="M12,22.6666667 C17.8910373,22.6666667 22.6666667,17.8910373 22.6666667,12 C22.6666667,6.10896267 17.8910373,1.33333333 12,1.33333333 C6.10896267,1.33333333 1.33333333,6.10896267 1.33333333,12 C1.33333333,17.8910373 6.10896267,22.6666667 12,22.6666667 Z M12,24 C5.372583,24 0,18.627417 0,12 C0,5.372583 5.372583,0 12,0 C18.627417,0 24,5.372583 24,12 C24,18.627417 18.627417,24 12,24 Z"/> <path fill="currentColor" fill-rule="nonzero" d="M12,22.6666667 C17.8910373,22.6666667 22.6666667,17.8910373 22.6666667,12 C22.6666667,6.10896267 17.8910373,1.33333333 12,1.33333333 C6.10896267,1.33333333 1.33333333,6.10896267 1.33333333,12 C1.33333333,17.8910373 6.10896267,22.6666667 12,22.6666667 Z M12,24 C5.372583,24 0,18.627417 0,12 C0,5.372583 5.372583,0 12,0 C18.627417,0 24,5.372583 24,12 C24,18.627417 18.627417,24 12,24 Z"/>
<use fill="#0060df" xlink:href="#addfiles-a"/> <polygon fill="currentColor" points="11.143 6 11.143 11.143 6 11.143 6 12.857 11.143 12.857 11.143 18 12.857 18 12.857 12.857 18 12.857 18 11.143 12.857 11.143 12.857 6"/>
</g> </g>
</symbol>
<use xlink:href="#plus"/>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 856 B

After

Width:  |  Height:  |  Size: 831 B

View File

@@ -1,8 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<svg width="26px" height="32px" viewBox="0 0 26 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: sketchtool 53 (72520) - https://sketchapp.com --> <symbol id="icon" viewBox="0 0 26 32">
<title>6AF7DAB4-6456-44F2-AABE-F001D910B641</title>
<desc>Created with sketchtool.</desc>
<defs> <defs>
<path d="M21.848475,31.6653183 L2.89005487,31.6653183 C1.32717435,31.6653183 0.104050469,30.3742431 0.104050469,28.8793139 L0.104050469,2.7860044 C0.104050469,1.22312388 1.39512568,0 2.89005487,0 L14.7135857,0 C15.4610503,0 16.2085149,0.271805307 16.6841742,0.815415921 L23.8190635,7.95030523 C24.3626741,8.49391584 24.6344794,9.17342911 24.6344794,9.9208937 L24.6344794,28.8793139 C24.6344794,30.3742431 23.4113555,31.6653183 21.848475,31.6653183 Z" id="path-1"></path> <path d="M21.848475,31.6653183 L2.89005487,31.6653183 C1.32717435,31.6653183 0.104050469,30.3742431 0.104050469,28.8793139 L0.104050469,2.7860044 C0.104050469,1.22312388 1.39512568,0 2.89005487,0 L14.7135857,0 C15.4610503,0 16.2085149,0.271805307 16.6841742,0.815415921 L23.8190635,7.95030523 C24.3626741,8.49391584 24.6344794,9.17342911 24.6344794,9.9208937 L24.6344794,28.8793139 C24.6344794,30.3742431 23.4113555,31.6653183 21.848475,31.6653183 Z" id="path-1"></path>
</defs> </defs>
@@ -14,14 +12,15 @@
<mask id="mask-2" fill="white"> <mask id="mask-2" fill="white">
<use xlink:href="#path-1"></use> <use xlink:href="#path-1"></use>
</mask> </mask>
<use id="Mask" fill="#45A1FF" opacity="0.6" xlink:href="#path-1"></use> <use id="Mask" fill="#45a1ff" xlink:href="#path-1"></use>
<path d="M24.3031318,10.6474633 L16.7826187,10.6474633 C15.2742552,10.6474633 14.051485,9.42469306 14.051485,7.91632957 L14.051485,0.395816478" id="Path" stroke="#FFFFFF" stroke-width="2" stroke-linecap="round" mask="url(#mask-2)"></path> <path d="M24.3031318,10.6474633 L16.7826187,10.6474633 C15.2742552,10.6474633 14.051485,9.42469306 14.051485,7.91632957 L14.051485,0.395816478" id="Path" stroke="currentColor" stroke-width="2" stroke-linecap="round" mask="url(#mask-2)"></path>
<path d="M7.2830232,8.93885547 L8.91906464,8.93885547" id="Path" stroke="#0060DF" stroke-width="2" stroke-linecap="round" mask="url(#mask-2)"></path> <path d="M7.2830232,8.93885547 L8.91906464,8.93885547" id="Path" stroke="currentColor" stroke-width="2" stroke-linecap="round" mask="url(#mask-2)"></path>
<path d="M7.2830232,15.7798836 L17.5412669,15.7798836" id="Path" stroke="#0060DF" stroke-width="2" stroke-linecap="round" mask="url(#mask-2)"></path> <path d="M7.2830232,15.7798836 L17.5412669,15.7798836" id="Path" stroke="currentColor" stroke-width="2" stroke-linecap="round" mask="url(#mask-2)"></path>
<path d="M7.2830232,22.6209117 L17.5412669,22.6209117" id="Path" stroke="#0060DF" stroke-width="2" stroke-linecap="round" mask="url(#mask-2)"></path> <path d="M7.2830232,22.6209117 L17.5412669,22.6209117" id="Path" stroke="currentColor" stroke-width="2" stroke-linecap="round" mask="url(#mask-2)"></path>
</g> </g>
</g> </g>
</g> </g>
</g> </g>
</g> </g>
</symbol>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 16 16"><path fill="#4A4A4A" d="M9.414 8l5.293-5.293a1 1 0 0 0-1.414-1.414L8 6.586 2.707 1.293a1 1 0 0 0-1.414 1.414L6.586 8l-5.293 5.293a1 1 0 1 0 1.414 1.414L8 9.414l5.293 5.293a1 1 0 0 0 1.414-1.414z"/></svg> <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 16 16"><path fill="#737373" d="M9.414 8l5.293-5.293a1 1 0 0 0-1.414-1.414L8 6.586 2.707 1.293a1 1 0 0 0-1.414 1.414L6.586 8l-5.293 5.293a1 1 0 1 0 1.414 1.414L8 9.414l5.293 5.293a1 1 0 0 0 1.414-1.414z"/></svg>

Before

Width:  |  Height:  |  Size: 287 B

After

Width:  |  Height:  |  Size: 287 B

View File

@@ -1 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path fill="#0060df" d="M14.707 8.293l-3-3A1 1 0 0 0 11 5h-1V4a1 1 0 0 0-.293-.707l-3-3A1 1 0 0 0 6 0H3a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h3v3a2 2 0 0 0 2 2h5a2 2 0 0 0 2-2V9a1 1 0 0 0-.293-.707zM12.586 9H11V7.414zm-5-5H6V2.414zM6 7v2H3V2h2v2.5a.5.5 0 0 0 .5.5H8a2 2 0 0 0-2 2zm2 7V7h2v2.5a.5.5 0 0 0 .5.5H13v4z"/></svg> <svg xmlns="http://www.w3.org/2000/svg">
<symbol id="icon" viewBox="0 0 16 16">
<path fill="currentColor" d="M14.707 8.293l-3-3A1 1 0 0 0 11 5h-1V4a1 1 0 0 0-.293-.707l-3-3A1 1 0 0 0 6 0H3a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h3v3a2 2 0 0 0 2 2h5a2 2 0 0 0 2-2V9a1 1 0 0 0-.293-.707zM12.586 9H11V7.414zm-5-5H6V2.414zM6 7v2H3V2h2v2.5a.5.5 0 0 0 .5.5H8a2 2 0 0 0-2 2zm2 7V7h2v2.5a.5.5 0 0 0 .5.5H13v4z"/>
</symbol>
</svg>

Before

Width:  |  Height:  |  Size: 398 B

After

Width:  |  Height:  |  Size: 411 B

View File

@@ -1,15 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<svg width="12px" height="16px" viewBox="0 0 12 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <svg width="12px" height="16px" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: sketchtool 53 (72520) - https://sketchapp.com --> <symbol id="icon" viewBox="0 0 12 16">
<title>728D143F-562C-4AE5-80DA-9DBBD9D647D8</title> <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<desc>Created with sketchtool.</desc> <g transform="translate(-770.000000, -481.000000)" fill="currentColor">
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> <g transform="translate(744.000000, 350.000000)">
<g id="Send_Sending" transform="translate(-770.000000, -481.000000)" fill="#0060DF"> <g transform="translate(26.000000, 131.000000)">
<g id="List-Item-3" transform="translate(744.000000, 350.000000)"> <path d="M5.293,12.707 C5.6835,13.097382 6.316501,13.097383 6.707001,12.707 L11.707,7.707 C12.08597,7.31462 12.08054,6.69092 11.69481,6.305189 C11.30908,5.91946 10.68538,5.91403 10.293,6.293 L7,9.586 L7,1 C7,0.44772 6.552285,0 6,0 C5.447715,0 5,0.44772 5,1 L5,9.586 L1.707,6.293 C1.314621,5.91403 0.690915,5.91945 0.305181,6.305182 C-0.080553,6.690915 -0.085973,7.314622 0.293,7.707001 L5.293,12.707 Z M11,14 L1,14 C0.447715,14 0,14.447715 0,15 C0,15.5522852 0.447715,16 1,16 L11,16 C11.55228,16 12,15.5522852 12,15 C12,14.447715 11.55229,14 11,14 Z"></path>
<g id="Download-Icon" transform="translate(26.000000, 131.000000)">
<path d="M5.293,12.707 C5.6835,13.097382 6.316501,13.097383 6.707001,12.707 L11.707,7.707 C12.08597,7.31462 12.08054,6.69092 11.69481,6.305189 C11.30908,5.91946 10.68538,5.91403 10.293,6.293 L7,9.586 L7,1 C7,0.44772 6.552285,0 6,0 C5.447715,0 5,0.44772 5,1 L5,9.586 L1.707,6.293 C1.314621,5.91403 0.690915,5.91945 0.305181,6.305182 C-0.080553,6.690915 -0.085973,7.314622 0.293,7.707001 L5.293,12.707 Z M11,14 L1,14 C0.447715,14 0,14.447715 0,15 C0,15.5522852 0.447715,16 1,16 L11,16 C11.55228,16 12,15.5522852 12,15 C12,14.447715 11.55229,14 11,14 Z" id="Fill-1"></path>
</g> </g>
</g> </g>
</g> </g>
</g> </g>
</symbol>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

41
assets/icon.svg Normal file
View File

@@ -0,0 +1,41 @@
<svg viewBox="0 0 65 64" height="64" width="65" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<linearGradient id="linear-gradient" x1="46.37" y1="59.71" x2="15.42" y2="6.11" gradientTransform="matrix(1, 0, 0, -1, 0, 64)" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#ff980e"/>
<stop offset="0.21" stop-color="#ff7139"/>
<stop offset="0.36" stop-color="#ff5854"/>
<stop offset="0.46" stop-color="#ff4f5e"/>
<stop offset="0.69" stop-color="#ff3750"/>
<stop offset="0.86" stop-color="#f92261"/>
<stop offset="1" stop-color="#f5156c"/>
</linearGradient>
<linearGradient id="linear-gradient-2" x1="46.37" y1="59.71" x2="15.42" y2="6.11" gradientTransform="matrix(1, 0, 0, -1, 0, 64)" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#fff44f" stop-opacity="0.8"/>
<stop offset="0.09" stop-color="#fff44f" stop-opacity="0.7"/>
<stop offset="0.75" stop-color="#fff44f" stop-opacity="0"/>
</linearGradient>
<linearGradient id="linear-gradient-3" x1="40.19" y1="26.08" x2="54.32" y2="50.55" gradientTransform="matrix(1, 0, 0, -1, 0, 64)" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#3a8ee6"/>
<stop offset="0.24" stop-color="#5c79f0"/>
<stop offset="0.63" stop-color="#9059ff"/>
<stop offset="1" stop-color="#c139e6"/>
</linearGradient>
<linearGradient id="linear-gradient-4" x1="54.32" y1="50.58" x2="48.39" y2="40.31" gradientTransform="matrix(1, 0, 0, -1, 0, 64)" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#6e008b" stop-opacity="0.5"/>
<stop offset="0.5" stop-color="#c846cb" stop-opacity="0"/>
</linearGradient>
<linearGradient id="linear-gradient-5" x1="56.96" y1="22.5" x2="41.98" y2="37.46" gradientTransform="matrix(1, 0, 0, -1, 0, 64)" gradientUnits="userSpaceOnUse">
<stop offset="0.14" stop-color="#6a2bea" stop-opacity="0"/>
<stop offset="0.34" stop-color="#642de4" stop-opacity="0.03"/>
<stop offset="0.55" stop-color="#5131d3" stop-opacity="0.12"/>
<stop offset="0.76" stop-color="#3139b7" stop-opacity="0.27"/>
<stop offset="0.98" stop-color="#054490" stop-opacity="0.48"/>
<stop offset="1" stop-color="#00458b" stop-opacity="0.5"/>
</linearGradient>
</defs>
<path d="M32.56,0C14.61,0,0,14.33,0,31.94a3.42,3.42,0,0,0,3.42,3.42H29.14V52.3l-8-8a3.42,3.42,0,1,0-4.84,4.84L30.14,63a2.73,2.73,0,0,0,.25.23l.23.17h.05l.24.14.27.13.28.1.29.07L32,64h1.27l.29-.07.29-.1.27-.13.24-.14.24-.17L35,63,48.8,49.18A3.43,3.43,0,0,0,44,44.34l-8,8v-17H61.7a3.42,3.42,0,0,0,3.42-3.42h0C65.12,14.33,50.51,0,32.56,0ZM7.09,28.51A25.54,25.54,0,0,1,32.56,6.85,25.55,25.55,0,0,1,58,28.51Z" fill="url(#linear-gradient)"/>
<path d="M32.56,0C14.61,0,0,14.33,0,31.94a3.42,3.42,0,0,0,3.42,3.42H29.14V52.3l-8-8a3.42,3.42,0,1,0-4.84,4.84L30.14,63a2.73,2.73,0,0,0,.25.23l.23.17h.05l.24.14.27.13.28.1.29.07L32,64h1.27l.29-.07.29-.1.27-.13.24-.14.24-.17L35,63,48.8,49.18A3.43,3.43,0,0,0,44,44.34l-8,8v-17H61.7a3.42,3.42,0,0,0,3.42-3.42h0C65.12,14.33,50.51,0,32.56,0ZM7.09,28.51A25.54,25.54,0,0,1,32.56,6.85,25.55,25.55,0,0,1,58,28.51Z" fill="url(#linear-gradient-2)"/>
<path d="M36,7.08A25.45,25.45,0,0,1,58,28.51H42.85A6.85,6.85,0,0,0,36,35.36H61.7a3.43,3.43,0,0,0,3.42-3.43c0-12.2-8.63-18.13-16-21.59A35.75,35.75,0,0,0,36,7.08Z" fill="url(#linear-gradient-3)"/>
<path d="M57.89,27.76c2.31,1.86,4.63,3.71,6.9,5.61a3.27,3.27,0,0,0,.33-1.44c0-12.2-8.63-18.13-16-21.59A35.75,35.75,0,0,0,36,7.08,25.47,25.47,0,0,1,57.89,27.76Z" fill="url(#linear-gradient-4)"/>
<path d="M57.5,28.51H42.85A6.85,6.85,0,0,0,36,35.36H61.7a3.36,3.36,0,0,0,2.64-1.28C62.09,32.19,59.79,30.36,57.5,28.51Z" opacity=".9" fill="url(#linear-gradient-5)"/>
</svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 8.1 KiB

View File

@@ -1,8 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<svg width="8px" height="6px" viewBox="0 0 8 6" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <svg width="8px" height="6px" viewBox="0 0 8 6" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: sketchtool 53 (72520) - https://sketchapp.com -->
<title>37845F0A-2932-4C2D-98E1-89BE1B168092</title>
<desc>Created with sketchtool.</desc>
<defs> <defs>
<path d="M6,8.48771202 C5.73480519,8.48765538 5.48049273,8.3822614 5.293,8.19471202 L2.293,5.19471202 C1.91402779,4.80233313 1.91944763,4.17862724 2.30518142,3.79289345 C2.69091522,3.40715965 3.31462111,3.40173981 3.707,3.78071202 L6,6.07371202 L8.293,3.78071202 C8.68537889,3.40173981 9.30908478,3.40715965 9.69481858,3.79289345 C10.0805524,4.17862724 10.0859722,4.80233313 9.707,5.19471202 L6.707,8.19471202 C6.51950727,8.3822614 6.26519481,8.48765538 6,8.48771202 Z" id="path-1"></path> <path d="M6,8.48771202 C5.73480519,8.48765538 5.48049273,8.3822614 5.293,8.19471202 L2.293,5.19471202 C1.91402779,4.80233313 1.91944763,4.17862724 2.30518142,3.79289345 C2.69091522,3.40715965 3.31462111,3.40173981 3.707,3.78071202 L6,6.07371202 L8.293,3.78071202 C8.68537889,3.40173981 9.30908478,3.40715965 9.69481858,3.79289345 C10.0805524,4.17862724 10.0859722,4.80233313 9.707,5.19471202 L6.707,8.19471202 C6.51950727,8.3822614 6.26519481,8.48765538 6,8.48771202 Z" id="path-1"></path>
</defs> </defs>
@@ -14,7 +11,7 @@
<mask id="mask-2" fill="white"> <mask id="mask-2" fill="white">
<use xlink:href="#path-1"></use> <use xlink:href="#path-1"></use>
</mask> </mask>
<use id="Shape" fill="#0C0C0D" fill-rule="nonzero" opacity="0.599283854" xlink:href="#path-1"></use> <use id="Shape" fill="#b1b1b3" fill-rule="nonzero" opacity="0.599283854" xlink:href="#path-1"></use>
</g> </g>
</g> </g>
</g> </g>

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -1,4 +1,5 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public <!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this - License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M18 9a3 3 0 1 0-2.977-2.63l-6.94 3.47a3 3 0 1 0 0 4.319l6.94 3.47a3 3 0 1 0 .895-1.789l-6.94-3.47a3.03 3.03 0 0 0 0-.74l6.94-3.47C16.456 8.68 17.19 9 18 9z" fill="#0060df" fill-opacity=".8"></path></svg> <svg xmlns="http://www.w3.org/2000/svg">
<symbol id="icon" viewBox="0 0 24 24"><path fill-rule="evenodd" clip-rule="evenodd" d="M18 9a3 3 0 1 0-2.977-2.63l-6.94 3.47a3 3 0 1 0 0 4.319l6.94 3.47a3 3 0 1 0 .895-1.789l-6.94-3.47a3.03 3.03 0 0 0 0-.74l6.94-3.47C16.456 8.68 17.19 9 18 9z" fill="currentColor"></path></symbol></svg>

Before

Width:  |  Height:  |  Size: 559 B

After

Width:  |  Height:  |  Size: 539 B

6
assets/wordmark.svg Normal file
View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<symbol id="logo" viewBox="66 0 340 64">
<path d="M84,48h5.83V35.87H103.3V30.45H89.83V23.51H103.3V18H84Zm23.57,0h5.79V25.81h-5.79Zm2.88-32.12a3.46,3.46,0,0,0-2.59,1,3.62,3.62,0,0,0-1,2.65,3.57,3.57,0,0,0,1,2.59,3.52,3.52,0,0,0,2.61,1,3.46,3.46,0,0,0,3.65-3.26c0-.12,0-.23,0-.35a3.71,3.71,0,0,0-1-2.65,3.5,3.5,0,0,0-2.67-1Zm19.14,9.53a7.22,7.22,0,0,0-3.72.93,5.82,5.82,0,0,0-2.4,2.89V25.81h-5.59V48h5.63V36.29a5.27,5.27,0,0,1,1.31-4,4.94,4.94,0,0,1,3.49-1.21,6.33,6.33,0,0,1,1.73.23,4,4,0,0,1,1.23.55l2-5.59a7.51,7.51,0,0,0-1.66-.61,8.11,8.11,0,0,0-2-.26Zm23.94,3.19a11.15,11.15,0,0,0-3.61-2.37,12.08,12.08,0,0,0-4.6-.86,11.62,11.62,0,0,0-8.3,3.37,11.17,11.17,0,0,0-2.44,3.67,11.59,11.59,0,0,0-.89,4.54,12.24,12.24,0,0,0,.83,4.52,10.52,10.52,0,0,0,2.36,3.66,10.93,10.93,0,0,0,3.71,2.44,12.75,12.75,0,0,0,4.85.88,12.15,12.15,0,0,0,6.12-1.39,13.25,13.25,0,0,0,4.11-3.74L151,40.6a6.23,6.23,0,0,1-2.18,2.15,6.36,6.36,0,0,1-3.33.8,6.7,6.7,0,0,1-4.13-1.25,6,6,0,0,1-2.23-3.43h17.62V36.74a11.71,11.71,0,0,0-.87-4.56,10.5,10.5,0,0,0-2.35-3.59Zm-14.21,5.85a6.38,6.38,0,0,1,2.26-3.12,6.11,6.11,0,0,1,3.74-1.15,6.26,6.26,0,0,1,3.73,1.08,5.56,5.56,0,0,1,2.1,3.19ZM167,16.08a6.05,6.05,0,0,0-2.91,1.54,6.15,6.15,0,0,0-1.56,2.89,18.1,18.1,0,0,0-.48,4.52v.78H158.4v5.1h3.65V48h5.63V30.91H173v-5.1h-5.3V24.75a13.34,13.34,0,0,1,.12-2,2,2,0,0,1,.6-1.19,2.45,2.45,0,0,1,1.33-.57,15.25,15.25,0,0,1,2.34-.15H173V15.63h-1.48A19.06,19.06,0,0,0,167,16.08Zm27.4,12.65a12,12,0,0,0-16.72,0,10.87,10.87,0,0,0-2.46,3.67,11.61,11.61,0,0,0-.89,4.5,11.46,11.46,0,0,0,7.07,10.64,11.73,11.73,0,0,0,4.64.9,12,12,0,0,0,4.66-.9,11.26,11.26,0,0,0,3.72-2.49,11.83,11.83,0,0,0,2.46-3.67,11.31,11.31,0,0,0,.9-4.48A11.43,11.43,0,0,0,194.4,28.73ZM191.7,39.3a5.88,5.88,0,0,1-1.29,2,6.53,6.53,0,0,1-1.93,1.31,6,6,0,0,1-4.76,0,6.34,6.34,0,0,1-1.93-1.31,6.06,6.06,0,0,1-1.3-2,6.48,6.48,0,0,1,0-4.86,5.76,5.76,0,0,1,1.3-2,6.08,6.08,0,0,1,1.93-1.32,6,6,0,0,1,4.76,0,6.37,6.37,0,0,1,1.93,1.32,5.73,5.73,0,0,1,1.29,2A6.39,6.39,0,0,1,191.7,39.3Zm29.47-13.49h-6.65l-4.68,6.57-4.64-6.57h-6.74l7.84,10.8L198,48h6.82l5-6.94L214.89,48h6.86l-8.46-11.34Zm34,7.46a12.88,12.88,0,0,0-3.37-1.44c-1.25-.34-2.46-.63-3.63-.88l-3.08-.7a10.64,10.64,0,0,1-2.51-.86A4.54,4.54,0,0,1,240.87,28a3.61,3.61,0,0,1-.62-2.19,4.8,4.8,0,0,1,1.58-3.7c1.06-1,2.73-1.44,5-1.44a9.84,9.84,0,0,1,5.07,1.17,10.47,10.47,0,0,1,3.39,3.23l2.79-2.18A15.22,15.22,0,0,0,253.45,19a13.8,13.8,0,0,0-6.59-1.44,12.13,12.13,0,0,0-4.14.66A10.33,10.33,0,0,0,239.53,20a7.53,7.53,0,0,0-2.05,2.63,7.41,7.41,0,0,0-.72,3.24,6.7,6.7,0,0,0,.84,3.53,7.06,7.06,0,0,0,2.2,2.22A11.11,11.11,0,0,0,242.86,33c1.13.32,2.29.6,3.47.84l3.26.74a12.63,12.63,0,0,1,2.8,1,5.86,5.86,0,0,1,2,1.56,3.88,3.88,0,0,1,.74,2.42,5.2,5.2,0,0,1-1.81,4.09A7.83,7.83,0,0,1,248,45.2a11,11,0,0,1-9.89-5.38l-3,2.34a15.86,15.86,0,0,0,5.23,4.54,16.06,16.06,0,0,0,7.7,1.7,12.58,12.58,0,0,0,4.38-.72,10.14,10.14,0,0,0,3.3-2,8.79,8.79,0,0,0,2.1-2.85,8.09,8.09,0,0,0,.74-3.39,6.94,6.94,0,0,0-1-3.8,7.71,7.71,0,0,0-2.42-2.37Zm27.51-4.72a10.53,10.53,0,0,0-3.58-2.34,11.89,11.89,0,0,0-4.49-.84,11.6,11.6,0,0,0-4.62.9,11.35,11.35,0,0,0-3.66,2.46A11.84,11.84,0,0,0,263,37a12.21,12.21,0,0,0,.82,4.51,10.53,10.53,0,0,0,2.36,3.64,11.24,11.24,0,0,0,3.7,2.42,12.41,12.41,0,0,0,4.82.88A11.68,11.68,0,0,0,280.82,47,12.84,12.84,0,0,0,285,42.82l-2.88-1.69a7.85,7.85,0,0,1-7.43,4.27,9,9,0,0,1-3.22-.53,8.21,8.21,0,0,1-2.55-1.5,8,8,0,0,1-1.78-2.28,7.79,7.79,0,0,1-.87-2.91h19.59V36.66a11.75,11.75,0,0,0-.86-4.54,10.92,10.92,0,0,0-2.35-3.57ZM266.4,35.22a8.88,8.88,0,0,1,1-2.73,8.55,8.55,0,0,1,1.79-2.18,8,8,0,0,1,2.44-1.43,8.31,8.31,0,0,1,3-.52,7.45,7.45,0,0,1,7.84,6.86ZM308.82,28a8.11,8.11,0,0,0-3-2,10.89,10.89,0,0,0-3.92-.67,9.06,9.06,0,0,0-4.58,1.14,8.76,8.76,0,0,0-3.14,3V25.82h-3.29V48h3.37V35.67a7.92,7.92,0,0,1,.53-2.93,7,7,0,0,1,1.48-2.3,6.46,6.46,0,0,1,2.22-1.5,7,7,0,0,1,2.75-.54,6.33,6.33,0,0,1,5,1.93A7.46,7.46,0,0,1,308,35.51V48h3.41V35.34a12.46,12.46,0,0,0-.66-4.19A8.68,8.68,0,0,0,308.82,28Zm27-12.42v14.1a8.14,8.14,0,0,0-1.58-1.83,10.08,10.08,0,0,0-2-1.36,10.39,10.39,0,0,0-2.3-.84,10.22,10.22,0,0,0-2.4-.28,11.63,11.63,0,0,0-4.4.84,11.09,11.09,0,0,0-3.59,2.38,11.3,11.3,0,0,0-2.42,3.65,12.81,12.81,0,0,0,0,9.32,11.56,11.56,0,0,0,2.4,3.66,10.58,10.58,0,0,0,3.59,2.38,11.77,11.77,0,0,0,4.42.84,9.69,9.69,0,0,0,2.4-.31,11,11,0,0,0,2.3-.86,9.72,9.72,0,0,0,2-1.37,8.75,8.75,0,0,0,1.58-1.85v4h3.33V15.59Zm-.37,24.58a8.3,8.3,0,0,1-10.85,4.47h0a7.68,7.68,0,0,1-2.6-1.76,7.88,7.88,0,0,1-1.73-2.67,8.93,8.93,0,0,1-.62-3.35,8.67,8.67,0,0,1,.62-3.3A8,8,0,0,1,322,30.89a8.17,8.17,0,0,1,2.6-1.79,8.27,8.27,0,0,1,6.51,0,8.64,8.64,0,0,1,2.63,1.81,7.85,7.85,0,0,1,1.72,2.67,8.67,8.67,0,0,1,.62,3.26,8.86,8.86,0,0,1-.65,3.33Z" fill="currentColor"/>
</symbol>
<use xlink:href="#logo"/>
</svg>

After

Width:  |  Height:  |  Size: 4.7 KiB

View File

@@ -1,8 +1,8 @@
# Custom Loaders # Custom Loaders
## Generate Asset Map ## Android Index Plugin
This loader enumerates all the files in `assets/` so that `common/assets.js` can provide mappings from the source filename to the hashed filename used on the site. Generates the `index.html` page for the native android client
## Version Plugin ## Version Plugin

View File

@@ -1,4 +1,4 @@
const genmap = require('../build/generate_asset_map'); const genmap = require('./generate_asset_map');
const isServer = typeof genmap === 'function'; const isServer = typeof genmap === 'function';
let prefix = ''; let prefix = '';
let manifest = {}; let manifest = {};

View File

@@ -1,3 +1,7 @@
# Common Code # Common Code
This directory contains code loaded by both the frontend `app` and backend `server`. The code here can be challenging to understand at first because the contexts for the two (three counting the dev server) environments that include them are quite different, but the purpose of these modules are quite simple, to provide mappings from the source assets (`copy-16.png`) to the concrete production assets (`copy-16.db66e0bf.svg`). This directory contains code loaded by both the frontend `app` and backend `server`. The code here can be challenging to understand at first because the contexts for the two (three counting the dev server) environments that include them are quite different, but the purpose of these modules are quite simple, to provide mappings from the source assets (`copy-16.png`) to the concrete production assets (`copy-16.db66e0bf.svg`).
## Generate Asset Map
This loader enumerates all the files in `assets/` so that `common/assets.js` can provide mappings from the source filename to the hashed filename used on the site.

View File

@@ -1,13 +1,6 @@
## Setup ## Setup
Before building the Docker image, you must build the production assets: Run `docker build -t send:latest .` to create an image or `docker-compose up` to run a full testable stack. *We don't recommend using docker-compose for production.*
```sh
npm run build
```
Then you can run either `docker build` or `docker-compose up`.
## Environment variables: ## Environment variables:

2091
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
{ {
"name": "firefox-send", "name": "firefox-send",
"description": "File Sharing Experiment", "description": "File Sharing Experiment",
"version": "3.0.17", "version": "3.0.20",
"author": "Mozilla (https://mozilla.org)", "author": "Mozilla (https://mozilla.org)",
"repository": "mozilla/send", "repository": "mozilla/send",
"homepage": "https://github.com/mozilla/send/", "homepage": "https://github.com/mozilla/send/",
@@ -58,33 +58,33 @@
"cache": true "cache": true
}, },
"engines": { "engines": {
"node": ">=10.0.0" "node": ">=10.0.0 <11.0.0"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.5.5", "@babel/core": "^7.6.4",
"@babel/plugin-proposal-class-properties": "^7.5.5", "@babel/plugin-proposal-class-properties": "^7.5.5",
"@babel/plugin-syntax-dynamic-import": "^7.2.0", "@babel/plugin-syntax-dynamic-import": "^7.2.0",
"@babel/preset-env": "^7.5.5", "@babel/preset-env": "^7.6.3",
"@dannycoates/webcrypto-liner": "^0.1.37", "@dannycoates/webcrypto-liner": "^0.1.37",
"@fullhuman/postcss-purgecss": "^1.2.0", "@fullhuman/postcss-purgecss": "^1.3.0",
"@mattiasbuelens/web-streams-polyfill": "0.2.1", "@mattiasbuelens/web-streams-polyfill": "0.2.1",
"@sentry/browser": "^5.6.3", "@sentry/browser": "^5.7.1",
"asmcrypto.js": "^0.22.0", "asmcrypto.js": "^0.22.0",
"babel-loader": "^8.0.6", "babel-loader": "^8.0.6",
"babel-plugin-istanbul": "^5.2.0", "babel-plugin-istanbul": "^5.2.0",
"base64-js": "^1.3.1", "base64-js": "^1.3.1",
"content-disposition": "^0.5.3", "content-disposition": "^0.5.3",
"copy-webpack-plugin": "^5.0.4", "copy-webpack-plugin": "^5.0.4",
"core-js": "^3.2.1", "core-js": "^3.3.3",
"crc": "^3.8.0", "crc": "^3.8.0",
"cross-env": "^5.2.1", "cross-env": "^6.0.3",
"css-loader": "^3.2.0", "css-loader": "^3.2.0",
"css-mqpacker": "^7.0.0", "css-mqpacker": "^7.0.0",
"cssnano": "^4.1.10", "cssnano": "^4.1.10",
"eslint": "^6.3.0", "eslint": "^6.5.1",
"eslint-config-prettier": "^6.2.0", "eslint-config-prettier": "^6.4.0",
"eslint-plugin-mocha": "^6.1.0", "eslint-plugin-mocha": "^6.2.0",
"eslint-plugin-node": "^9.2.0", "eslint-plugin-node": "^10.0.0",
"eslint-plugin-security": "^1.4.0", "eslint-plugin-security": "^1.4.0",
"expose-loader": "^0.7.5", "expose-loader": "^0.7.5",
"extract-loader": "^3.1.0", "extract-loader": "^3.1.0",
@@ -94,10 +94,10 @@
"git-rev-sync": "^1.12.0", "git-rev-sync": "^1.12.0",
"html-loader": "^0.5.5", "html-loader": "^0.5.5",
"http_ece": "^1.1.0", "http_ece": "^1.1.0",
"husky": "^3.0.5", "husky": "^3.0.9",
"intl-pluralrules": "^1.0.3", "intl-pluralrules": "^1.1.1",
"lint-staged": "^9.2.5", "lint-staged": "^9.4.2",
"mocha": "^6.2.0", "mocha": "^6.2.2",
"morgan": "^1.9.1", "morgan": "^1.9.1",
"nanobus": "^4.4.0", "nanobus": "^4.4.0",
"nanohtml": "^1.8.1", "nanohtml": "^1.8.1",
@@ -108,15 +108,15 @@
"postcss-preset-env": "^6.7.0", "postcss-preset-env": "^6.7.0",
"prettier": "^1.18.2", "prettier": "^1.18.2",
"proxyquire": "^2.1.3", "proxyquire": "^2.1.3",
"puppeteer": "^1.19.0", "puppeteer": "^1.20.0",
"raw-loader": "^3.1.0", "raw-loader": "^3.1.0",
"redis-mock": "^0.46.0", "redis-mock": "^0.46.0",
"rimraf": "^3.0.0", "rimraf": "^3.0.0",
"script-loader": "^0.7.2", "script-loader": "^0.7.2",
"sinon": "^7.4.2", "sinon": "^7.5.0",
"string-hash": "^1.1.3", "string-hash": "^1.1.3",
"stylelint": "^10.1.0", "stylelint": "^11.1.1",
"stylelint-config-standard": "^18.3.0", "stylelint-config-standard": "^19.0.0",
"stylelint-no-unsupported-browser-features": "^3.0.2", "stylelint-no-unsupported-browser-features": "^3.0.2",
"svgo": "^1.3.0", "svgo": "^1.3.0",
"svgo-loader": "^2.2.1", "svgo-loader": "^2.2.1",
@@ -131,27 +131,27 @@
"wdio-spec-reporter": "^0.1.5", "wdio-spec-reporter": "^0.1.5",
"webdriverio": "^4.14.4", "webdriverio": "^4.14.4",
"webpack": "4.38.0", "webpack": "4.38.0",
"webpack-cli": "^3.3.7", "webpack-cli": "^3.3.9",
"webpack-dev-middleware": "^3.7.1", "webpack-dev-middleware": "^3.7.2",
"webpack-dev-server": "^3.8.0", "webpack-dev-server": "^3.8.2",
"webpack-manifest-plugin": "^2.0.4", "webpack-manifest-plugin": "^2.2.0",
"webpack-unassert-loader": "^1.2.0" "webpack-unassert-loader": "^1.2.0"
}, },
"dependencies": { "dependencies": {
"@dannycoates/express-ws": "^5.0.3", "@dannycoates/express-ws": "^5.0.3",
"@fluent/bundle": "^0.13.0", "@fluent/bundle": "^0.13.0",
"@fluent/langneg": "^0.3.0", "@fluent/langneg": "^0.3.0",
"@google-cloud/storage": "^3.2.1", "@google-cloud/storage": "^4.0.0",
"@sentry/node": "^5.6.2", "@sentry/node": "^5.7.1",
"aws-sdk": "^2.523.0", "aws-sdk": "^2.553.0",
"body-parser": "^1.19.0", "body-parser": "^1.19.0",
"choo": "^7.0.0", "choo": "^7.0.0",
"cldr-core": "^35.1.0", "cldr-core": "^35.1.0",
"configstore": "github:dannycoates/configstore#master", "configstore": "github:dannycoates/configstore#master",
"convict": "^5.1.0", "convict": "^5.2.0",
"express": "^4.17.1", "express": "^4.17.1",
"fxa-geodb": "^1.0.4", "fxa-geodb": "^1.0.4",
"helmet": "^3.21.0", "helmet": "^3.21.1",
"mkdirp": "^0.5.1", "mkdirp": "^0.5.1",
"mozlog": "^2.2.0", "mozlog": "^2.2.0",
"node-fetch": "^2.6.0", "node-fetch": "^2.6.0",
@@ -213,6 +213,7 @@
"sr", "sr",
"su", "su",
"sv-SE", "sv-SE",
"te",
"th", "th",
"tr", "tr",
"uk", "uk",

View File

@@ -182,4 +182,5 @@ shareLinkDescription = شارِك الرابط الذي يصل إلى الملف
shareLinkButton = شارِك الرابط shareLinkButton = شارِك الرابط
# $name is the name of the file # $name is the name of the file
shareMessage = نزِّل ”{ $name }“ عبر { -send-brand }: خدمة لمشاركة الملفات بلا عناء وبخصوصية تامة shareMessage = نزِّل ”{ $name }“ عبر { -send-brand }: خدمة لمشاركة الملفات بلا عناء وبخصوصية تامة
trailheadPromo = يمكنك حماية خصوصيتك، طبعا. انضم إلى فَيَرفُكس.
learnMore = اطّلع على المزيد. learnMore = اطّلع على المزيد.

View File

@@ -151,3 +151,5 @@ shareLinkDescription = Compartiu l'enllaç al vostre fitxer:
shareLinkButton = Comparteix l'enllaç shareLinkButton = Comparteix l'enllaç
# $name is the name of the file # $name is the name of the file
shareMessage = Baixeu «{ $name }» amb el { -send-brand }: compartició de fitxers senzilla i segura shareMessage = Baixeu «{ $name }» amb el { -send-brand }: compartició de fitxers senzilla i segura
trailheadPromo = Hi ha una manera de protegir la vostra privadesa. Uniu-vos al Firefox.
learnMore = Més informació.

View File

@@ -151,3 +151,5 @@ shareLinkDescription = Nakomonij ri ximonel rik'in ri awokisab'al:
shareLinkButton = Tikomonïx ximonel shareLinkButton = Tikomonïx ximonel
# $name is the name of the file # $name is the name of the file
shareMessage = Tiqasäx "{ $name }" rik'in { -send-brand }: man k'ayew ta chuqa' ütz kikomonik ri yakb'äl shareMessage = Tiqasäx "{ $name }" rik'in { -send-brand }: man k'ayew ta chuqa' ütz kikomonik ri yakb'äl
trailheadPromo = K'o jun rub'anikil richin nachajij ri awichinanem. Tatunu' awi' rik'in ri Firefox.
learnMore = Tetamäx ch'aqa' chik.

View File

@@ -151,3 +151,5 @@ shareLinkDescription = Jaga linki failile:
shareLinkButton = Jaga linki shareLinkButton = Jaga linki
# $name is the name of the file # $name is the name of the file
shareMessage = Laadi “{ $name }” alla teenusega { -send-brand }, mis pakub lihtsat ja turvalist failijagamist shareMessage = Laadi “{ $name }” alla teenusega { -send-brand }, mis pakub lihtsat ja turvalist failijagamist
trailheadPromo = Oma privaatsust on võimalik kaitsta. Liitu Firefoxiga.
learnMore = Rohkem teavet.

View File

@@ -53,6 +53,7 @@ passwordSetError = امکان ثبت این گذواژه نیست
-send-short-brand = ارسال -send-short-brand = ارسال
-firefox = فایرفاکس -firefox = فایرفاکس
-mozilla = موزیلا -mozilla = موزیلا
introTitle = اشتراک‌گذاری ساده و خصوصیِ پرونده‌ها
# byte abbreviation # byte abbreviation
bytes = B bytes = B
# kibibyte abbreviation # kibibyte abbreviation

View File

@@ -1,7 +1,7 @@
# Firefox Send is a brand name and should not be localized. # Firefox Send is a brand name and should not be localized.
title = Firefox Send title = Firefox Send
siteFeedback = משוב siteFeedback = משוב
importingFile = מתבצע ייבוא... importingFile = מתבצע ייבוא
encryptingFile = מתבצעת הצפנה... encryptingFile = מתבצעת הצפנה...
decryptingFile = מתבצע פענוח... decryptingFile = מתבצע פענוח...
downloadCount = downloadCount =

View File

@@ -54,7 +54,7 @@ passwordSetError = Awal-agi uffir ur izmir ara ad ittwabaded
-firefox = Firefox -firefox = Firefox
-mozilla = Mozilla -mozilla = Mozilla
introTitle = Afessas, beṭṭu n ifuyla s wudem uslig introTitle = Afessas, beṭṭu n ifuyla s wudem uslig
introDescription = { -send-brand } ad k(yeǧǧ ad tebḍuḍ ifuyla iwgelhanensi ṭṭerf ɣer ṭṭerf akked useɣwen ara yemmten s wudem awurman. Daɣen, ad tizmireḍ ad tḥ€rzeḍ ayen i tbeṭṭuḍ s wudem uslig daɣen ad temneḍ imi agbur-ik ur yettɣimi ara srid i lebda. introDescription = { -send-brand } ad k(kem)-yeǧǧ ad tebḍuḍ ifuyla iwgelhanensi ṭṭerf ɣer ṭṭerf akked useɣwen ara yemmten s wudem awurman. Daɣen, ad tizmireḍ ad tḥ€rzeḍ ayen i tbeṭṭuḍ s wudem uslig daɣen ad temneḍ imi agbur-ik ur yettɣimi ara srid i lebda.
notifyUploadEncryptDone = Afaylu-ik yewgelhen daɣen ihegga i tuzna notifyUploadEncryptDone = Afaylu-ik yewgelhen daɣen ihegga i tuzna
# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes' # downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'
archiveExpiryInfo = Ad yemmet deffir { $downloadCount } neɣ { $timespan } archiveExpiryInfo = Ad yemmet deffir { $downloadCount } neɣ { $timespan }

View File

@@ -5,7 +5,7 @@ importingFile = 가져오는 중…
encryptingFile = 암호화 중… encryptingFile = 암호화 중…
decryptingFile = 복호화 중… decryptingFile = 복호화 중…
downloadCount = 다운로드 { $num }회 downloadCount = 다운로드 { $num }회
timespanHours = 1 시간 timespanHours = { $num }시간
copiedUrl = 복사 완료! copiedUrl = 복사 완료!
unlockInputPlaceholder = 비밀번호 unlockInputPlaceholder = 비밀번호
unlockButtonLabel = 잠금 해제 unlockButtonLabel = 잠금 해제

View File

@@ -36,11 +36,11 @@ footerLinkCookies = Cookies
passwordTryAgain = Senha incorreta. Tente novamente. passwordTryAgain = Senha incorreta. Tente novamente.
javascriptRequired = O Firefox Send requer JavaScript javascriptRequired = O Firefox Send requer JavaScript
whyJavascript = Por que o Firefox Send precisa do JavaScript? whyJavascript = Por que o Firefox Send precisa do JavaScript?
enableJavascript = Habilite o JavaScript e tente novamente. enableJavascript = Ative o JavaScript e tente novamente.
# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example "13h 47m" # A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example "13h 47m"
expiresHoursMinutes = { $hours }h { $minutes }m expiresHoursMinutes = { $hours }h { $minutes }min
# A short representation of a countdown timer containing the number of minutes remaining as digits, example "56m" # A short representation of a countdown timer containing the number of minutes remaining as digits, example "56m"
expiresMinutes = { $minutes }m expiresMinutes = { $minutes }min
# A short status message shown when the user enters a long password # A short status message shown when the user enters a long password
maxPasswordLength = Tamanho máximo da senha: { $length } maxPasswordLength = Tamanho máximo da senha: { $length }
# A short status message shown when there was an error setting the password # A short status message shown when there was an error setting the password
@@ -95,7 +95,7 @@ copyLinkDescription = Copie o link para compartilhar seu arquivo:
copyLinkButton = Copiar link copyLinkButton = Copiar link
downloadTitle = Baixar arquivos downloadTitle = Baixar arquivos
downloadDescription = Este arquivo foi compartilhado via { -send-brand } com criptografia de ponta a ponta e um link que expira automaticamente. downloadDescription = Este arquivo foi compartilhado via { -send-brand } com criptografia de ponta a ponta e um link que expira automaticamente.
trySendDescription = Experimente o { -send-brand } para compartilhamento de arquivos simples e seguro. trySendDescription = Experimente o { -send-brand } para compartilhar arquivos com simplicidade e segurança.
# count will always be > 10 # count will always be > 10
tooManyFiles = tooManyFiles =
{ $count -> { $count ->
@@ -127,17 +127,17 @@ emailPlaceholder = Informe seu e-mail
# $size is the size of the file, displayed using the fileSize message as format (e.g. "2.5MB") # $size is the size of the file, displayed using the fileSize message as format (e.g. "2.5MB")
signInSizeBump = Entre na sua conta para enviar até { $size } signInSizeBump = Entre na sua conta para enviar até { $size }
signInOnlyButton = Entrar signInOnlyButton = Entrar
accountBenefitTitle = Crie uma Conta { -firefox } ou entre na sua conta accountBenefitTitle = Crie uma Conta { -firefox } ou entre se já tiver
# $size is the size of the file, displayed using the fileSize message as format (e.g. "2.5MB") # $size is the size of the file, displayed using the fileSize message as format (e.g. "2.5MB")
accountBenefitLargeFiles = Compartilhe arquivos até { $size } accountBenefitLargeFiles = Compartilhe arquivos até { $size }.
accountBenefitDownloadCount = Compartilhe arquivos com mais pessoas accountBenefitDownloadCount = Compartilhe arquivos com mais pessoas.
accountBenefitTimeLimit = accountBenefitTimeLimit =
{ $count -> { $count ->
[one] Mantenha links ativos por até 1 dia [one] Mantenha links ativos por até 1 dia.
*[other] Mantenha links ativos por até { $count } dias *[other] Mantenha links ativos por até { $count } dias.
} }
accountBenefitSync = Gerencie arquivos compartilhados a partir de qualquer dispositivo accountBenefitSync = Gerencie arquivos compartilhados a partir de qualquer dispositivo.
accountBenefitMoz = Conheça outros serviços da { -mozilla } accountBenefitMoz = Conheça outros serviços da { -mozilla }.
signOut = Sair signOut = Sair
okButton = OK okButton = OK
downloadingTitle = Baixando downloadingTitle = Baixando

View File

@@ -141,7 +141,7 @@ accountBenefitMoz = Läs om andra { -mozilla }-tjänster
signOut = Logga ut signOut = Logga ut
okButton = OK okButton = OK
downloadingTitle = Laddar ner downloadingTitle = Laddar ner
noStreamsWarning = Den här webbläsaren kanske inte kan dekryptera en fil så stor. noStreamsWarning = Den här webbläsaren kanske inte kan dekryptera en så stor fil.
noStreamsOptionCopy = Kopiera länken för att öppna i en annan webbläsare noStreamsOptionCopy = Kopiera länken för att öppna i en annan webbläsare
noStreamsOptionFirefox = Prova vår favoritwebbläsare noStreamsOptionFirefox = Prova vår favoritwebbläsare
noStreamsOptionDownload = Fortsätt med den här webbläsaren noStreamsOptionDownload = Fortsätt med den här webbläsaren

View File

@@ -141,9 +141,9 @@ accountBenefitLargeFiles = Обмінюйтесь файлами розміро
accountBenefitDownloadCount = Обмінюйтесь файлами з більшою кількістю людей accountBenefitDownloadCount = Обмінюйтесь файлами з більшою кількістю людей
accountBenefitTimeLimit = accountBenefitTimeLimit =
{ $count -> { $count ->
[one] Зберігати посилання активними протягом 1 дня [one] Термін дії посилання 1 день
[few] Зберігати посилання активними протягом { $count } днів [few] Термін дії посилання { $count } дні
*[other] Зберігати посилання активними протягом { $count } днів *[many] Термін дії посилання { $count } днів
} }
accountBenefitSync = Керуйте спільними файлами з буль-якого пристрою accountBenefitSync = Керуйте спільними файлами з буль-якого пристрою
accountBenefitMoz = Дізнайтеся про інші сервіси { -mozilla } accountBenefitMoz = Дізнайтеся про інші сервіси { -mozilla }

View File

@@ -53,7 +53,7 @@ passwordSetError = 未能设置此密码
-mozilla = Mozilla -mozilla = Mozilla
introTitle = 简单、私密的文件分享服务 introTitle = 简单、私密的文件分享服务
introDescription = 使用 { -send-brand } 端到端加密分享文件,链接到期即焚。分享更私密,文件到期真正无痕迹。 introDescription = 使用 { -send-brand } 端到端加密分享文件,链接到期即焚。分享更私密,文件到期真正无痕迹。
notifyUploadEncryptDone = 您的文件已加密可以发送 notifyUploadEncryptDone = 您的文件已加密,现在可以发送
# downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes' # downloadCount is from the downloadCount string and timespan is a timespanMinutes string. ex. 'Expires after 2 downloads or 25 minutes'
archiveExpiryInfo = { $downloadCount }或 { $timespan }后过期 archiveExpiryInfo = { $downloadCount }或 { $timespan }后过期
timespanMinutes = timespanMinutes =
@@ -109,7 +109,7 @@ expiredTitle = 此链接已过期。
notSupportedDescription = { -send-brand } 无法在此浏览器上正常工作。{ -send-short-brand } 与最新版本 { -firefox } 配合使用体验最佳,也适用于目前的大多数浏览器。 notSupportedDescription = { -send-brand } 无法在此浏览器上正常工作。{ -send-short-brand } 与最新版本 { -firefox } 配合使用体验最佳,也适用于目前的大多数浏览器。
downloadFirefox = 下载 { -firefox } downloadFirefox = 下载 { -firefox }
legalTitle = { -send-short-brand } 隐私声明 legalTitle = { -send-short-brand } 隐私声明
legalDateStamp = 版本 1.0日期 2019年3月12日 legalDateStamp = 版本 1.0 2019年3月12日
# A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example "2d 11h 56m" # A short representation of a countdown timer containing the number of days, hours, and minutes remaining as digits, example "2d 11h 56m"
expiresDaysHoursMinutes = { $days } 天 { $hours } 小时 { $minutes } 分钟 expiresDaysHoursMinutes = { $days } 天 { $hours } 小时 { $minutes } 分钟
addFilesButton = 选择要上传的文件 addFilesButton = 选择要上传的文件
@@ -127,7 +127,7 @@ signInOnlyButton = 登录
accountBenefitTitle = 创建一个 { -firefox } 账户或登录 accountBenefitTitle = 创建一个 { -firefox } 账户或登录
# $size is the size of the file, displayed using the fileSize message as format (e.g. "2.5MB") # $size is the size of the file, displayed using the fileSize message as format (e.g. "2.5MB")
accountBenefitLargeFiles = 分享最大 { $size } 文件 accountBenefitLargeFiles = 分享最大 { $size } 文件
accountBenefitDownloadCount = 与更多人分享文件 accountBenefitDownloadCount = 可以与更多人分享
accountBenefitTimeLimit = accountBenefitTimeLimit =
{ $count -> { $count ->
[one] 链接有效期延至 1 天 [one] 链接有效期延至 1 天
@@ -140,7 +140,7 @@ okButton = 确定
downloadingTitle = 正在下载 downloadingTitle = 正在下载
noStreamsWarning = 此浏览器可能无法解密这么大的文件。 noStreamsWarning = 此浏览器可能无法解密这么大的文件。
noStreamsOptionCopy = 复制链接以在其他浏览器中打开 noStreamsOptionCopy = 复制链接以在其他浏览器中打开
noStreamsOptionFirefox = 试试大家最爱的浏览器 noStreamsOptionFirefox = 试试大家最爱的浏览器
noStreamsOptionDownload = 使用此浏览器继续 noStreamsOptionDownload = 使用此浏览器继续
downloadFirefoxPromo = { -send-short-brand } 由焕然一新的 { -firefox } 为您奉上。 downloadFirefoxPromo = { -send-short-brand } 由焕然一新的 { -firefox } 为您奉上。
# the next line after the colon contains a file name # the next line after the colon contains a file name

View File

@@ -1,89 +1,103 @@
const colors = { const colors = {
transparent: 'transparent', transparent: 'transparent',
black: '#22292f', black: '#000000',
'grey-darkest': '#4a4a4f', 'grey-90': '#0c0c0d',
'grey-darker': '#606f7b', 'grey-80': '#2a2a2e',
'grey-dark': '#8795a1', 'grey-70': '#38383d',
grey: '#B1B1B3', 'grey-60': '#4a4a4f',
'grey-light': '#dae1e7', 'grey-50': '#737373',
grey: '#b1b1b3',
'grey-40': '#b1b1b3',
'grey-30': '#d7d7db',
'grey-banner': '#f0f0f4', 'grey-banner': '#f0f0f4',
'grey-transparent': 'hsla(250, 13%, 9%, .2)', 'grey-transparent': 'hsla(250, 13%, 9%, .2)',
'grey-lighter': '#f1f5f8', 'grey-20': '#ededf0',
'grey-lightest': '#F9F9FA', 'grey-10': '#f9f9fa',
white: '#ffffff', white: '#ffffff',
'red-darkest': '#3b0d0c', 'red-90': '#3e0200',
'red-darker': '#621b18', 'red-80': '#5a0002',
'red-dark': '#cc1f1a', 'red-70': '#a4000f',
red: '#e3342f', 'red-60': '#d70022',
'red-light': '#ef5753', red: '#d70022',
'red-lighter': '#f9acaa', 'red-50': '#ff0039',
'red-lightest': '#fcebea', // unspec
'red-40': '#ff3363',
'red-30': '#ff99aa',
'orange-darkest': '#462a16', 'orange-90': '#3e1300',
'orange-darker': '#613b1f', 'orange-80': '#712b00',
'orange-dark': '#de751f', 'orange-70': '#a44900',
orange: '#f6993f', 'orange-60': '#d76e00',
'orange-light': '#faad63', 'orange-50': '#ff9400',
'orange-lighter': '#fcd9b6', // unspec
'orange-lightest': '#fff5eb', 'orange-40': '#ffb24c',
'orange-30': '#ffd399',
'yellow-darkest': '#453411', 'yellow-90': '#3e2800',
'yellow-darker': '#684f1d', 'yellow-80': '#715100',
'yellow-dark': '#f2d024', 'yellow-70': '#a47f00',
yellow: '#ffed4a', 'yellow-60': '#d7b600',
'yellow-light': '#fff382', yellow: '#d7b600',
'yellow-lighter': '#fff9c2', 'yellow-50': '#ffe900',
'yellow-lightest': '#fcfbeb', 'yellow-40': '#ffed4c',
'yellow-30': '#fff599',
'green-darkest': '#003706', // 'green-darkest': '#003706',
'green-darker': '#006504', // 'green-darker': '#006504',
'green-dark': '#058b00', // 'green-dark': '#058b00',
green: '#12bc00', // green: '#12bc00',
'green-light': '#51d88a', // 'green-light': '#51d88a',
'green-lighter': '#a2f5bf', // 'green-lighter': '#a2f5bf',
'green-lightest': '#e3fcec', // 'green-lightest': '#e3fcec',
'teal-darkest': '#0d3331', // 'teal-darkest': '#0d3331',
'teal-darker': '#20504f', // 'teal-darker': '#20504f',
'teal-dark': '#38a89d', // 'teal-dark': '#38a89d',
teal: '#4dc0b5', // teal: '#4dc0b5',
'teal-light': '#64d5ca', // 'teal-light': '#64d5ca',
'teal-lighter': '#a0f0ed', // 'teal-lighter': '#a0f0ed',
'teal-lightest': '#e8fffe', // 'teal-lightest': '#e8fffe',
'blue-darkest': '#002275', 'blue-90': '#000f40',
'blue-darker': '#003eaa', 'blue-80': '#002275',
'blue-dark': '#0060df', 'blue-70': '#003eaa',
'blue-60': '#0060df',
'blue-50': '#0a84ff',
blue: '#0a84ff', blue: '#0a84ff',
'blue-light': '#6cb2eb', 'blue-40': '#45a1ff',
'blue-lighter': '#bcdefa', 'blue-30': '#99ccff',
'blue-lightest': '#eff8ff', 'blue-20': '#cce6ff',
'indigo-darkest': '#191e38', 'ink-90': '#0f1126',
'indigo-darker': '#2f365f', 'ink-80': '#202340',
'indigo-dark': '#5661b3', 'ink-70': '#363959',
indigo: '#6574cd',
'indigo-light': '#7886d7',
'indigo-lighter': '#b2b7ff',
'indigo-lightest': '#e6e8ff',
'purple-darkest': '#21183c', // 'indigo-darkest': '#191e38',
'purple-darker': '#382b5f', // 'indigo-darker': '#2f365f',
'purple-dark': '#794acf', // 'indigo-dark': '#5661b3',
purple: '#9561e2', // indigo: '#6574cd',
'purple-light': '#a779e9', // 'indigo-light': '#7886d7',
'purple-lighter': '#d6bbfc', // 'indigo-lighter': '#b2b7ff',
'purple-lightest': '#f3ebff', // 'indigo-lightest': '#e6e8ff',
'pink-darkest': '#451225', 'purple-90': '#25003e',
'pink-darker': '#6f213f', 'purple-80': '#440071',
'pink-dark': '#eb5286', 'purple-70': '#6200a4',
pink: '#f66d9b', 'purple-60': '#8000d7',
'pink-light': '#fa7ea8', 'purple-50': '#9400ff',
'pink-lighter': '#ffbbca', 'purple-40': '#ad3bff',
'pink-lightest': '#ffebef', 'purple-30': '#c069ff',
'purple-20': '#d7a3ff',
// 'pink-darkest': '#451225',
// 'pink-darker': '#6f213f',
// 'pink-dark': '#eb5286',
// pink: '#f66d9b',
// 'pink-light': '#fa7ea8',
// 'pink-lighter': '#ffbbca',
// 'pink-lightest': '#ffebef',
cloud: 'rgba(255, 255, 255, 0.8)', cloud: 'rgba(255, 255, 255, 0.8)',
violet: 'hsl(258, 57%, 35%)' violet: 'hsl(258, 57%, 35%)'
}; };
@@ -95,7 +109,8 @@ module.exports = {
sm: '576px', sm: '576px',
md: '768px', md: '768px',
lg: '992px', lg: '992px',
xl: '1200px' xl: '1200px',
dark: { raw: '(prefers-color-scheme: dark)' }
}, },
fontFamily: { fontFamily: {
sans: [ sans: [
@@ -181,10 +196,7 @@ module.exports = {
'4': '4px', '4': '4px',
'8': '8px' '8': '8px'
}, },
borderColor: global.Object.assign( borderColor: global.Object.assign({ default: colors['grey-30'] }, colors),
{ default: colors['grey-light'] },
colors
),
borderRadius: { borderRadius: {
none: '0', none: '0',
sm: '.125rem', sm: '.125rem',

View File

@@ -82,4 +82,29 @@ describe('Firefox Send', function() {
// check if upload and download file sizes are equal // check if upload and download file sizes are equal
assert.equal(uploadSize, downloadSize); assert.equal(uploadSize, downloadSize);
}); });
it(`should upload and download file with added tracking parameter`, function() {
const trackingUrl =
'?fbclid=IaMFak3Tr4ck1ng1d_SDlP0shBk8SM2EN3cCLFKpHVl-k-Pvv0sf9Zy0tnTu9srqVY';
const password = 'strongpassword';
browser.chooseFile(
homePage.uploadInput,
`${testFilesPath}/${testFiles[0]}`
);
browser.waitForExist(homePage.addPassword);
browser.click(homePage.addPassword);
browser.waitForExist(homePage.passwordInput);
browser.setValue(homePage.passwordInput, password);
browser.click(homePage.uploadButton);
browser.waitForExist(homePage.shareUrl);
const shareUrl = browser.getValue(homePage.shareUrl);
const downloadPage = new DownloadPage(
shareUrl.replace('#', `${trackingUrl}#`)
);
downloadPage.open();
downloadPage.downloadUsingPassword(password);
browser.waitForExist(downloadPage.downloadComplete);
assert.ok(fs.existsSync(path.join(downloadDir, testFiles[0])));
});
}); });

View File

@@ -4,23 +4,22 @@ const Page = require('./page');
class DownloadPage extends Page { class DownloadPage extends Page {
constructor(path) { constructor(path) {
super(path); super(path);
this.fileId = /download\/(\w+)\/#/.exec(path)[1]; this.fileId = /download\/(\w+)\/\??.*#/.exec(path)[1];
this.downloadButton = '#download-btn'; this.downloadButton = '#download-btn';
this.downloadComplete = '#download-complete'; this.downloadComplete = '#download-complete';
this.passwordInput = '#password-input';
this.passwordButton = '#password-btn';
} }
/** downloadUsingPassword(password) {
* @function waitForPageToLoad browser.waitForExist(this.passwordInput);
* @returns {Object} An object representing the page. browser.setValue(this.passwordInput, password);
* @throws ElementNotFound browser.click(this.passwordButton);
*/ return browser.click(this.downloadButton);
waitForPageToLoad() {
super.waitForPageToLoad();
browser.waitForExist(this.downloadButton);
return this;
} }
download() { download() {
browser.waitForExist(this.downloadButton);
return browser.click(this.downloadButton); return browser.click(this.downloadButton);
} }
} }

View File

@@ -10,6 +10,9 @@ class HomePage extends Page {
this.progress = 'progress'; this.progress = 'progress';
this.shareUrl = '#share-url'; this.shareUrl = '#share-url';
this.downloadCountSelect = '#expire-after-dl-count-select'; this.downloadCountSelect = '#expire-after-dl-count-select';
this.addPassword = '#add-password';
this.passwordInput = '#password-input';
this.passwordButton = '#password-btn';
} }
waitForPageToLoad() { waitForPageToLoad() {

View File

@@ -67,7 +67,7 @@ const serviceWorker = {
}, },
{ {
// loads all assets from assets/ for use by common/assets.js // loads all assets from assets/ for use by common/assets.js
test: require.resolve('./build/generate_asset_map.js'), test: require.resolve('./common/generate_asset_map.js'),
use: ['babel-loader', 'val-loader'] use: ['babel-loader', 'val-loader']
} }
] ]
@@ -142,6 +142,7 @@ const web = {
loader: 'svgo-loader', loader: 'svgo-loader',
options: { options: {
plugins: [ plugins: [
{ cleanupIDs: false },
{ removeViewBox: false }, // true causes stretched images { removeViewBox: false }, // true causes stretched images
{ convertStyleToAttrs: true }, // for CSP, no unsafe-eval { convertStyleToAttrs: true }, // for CSP, no unsafe-eval
{ removeTitle: true } // for smallness { removeTitle: true } // for smallness
@@ -176,7 +177,7 @@ const web = {
}, },
{ {
// loads all assets from assets/ for use by common/assets.js // loads all assets from assets/ for use by common/assets.js
test: require.resolve('./build/generate_asset_map.js'), test: require.resolve('./common/generate_asset_map.js'),
use: ['babel-loader', 'val-loader'] use: ['babel-loader', 'val-loader']
} }
] ]