Add ability to change the branding
This commit is contained in:
parent
81741dcc76
commit
560747106b
28 changed files with 275 additions and 201 deletions
|
@ -7,7 +7,7 @@ const experiments = {
|
|||
return true;
|
||||
},
|
||||
variant: function() {
|
||||
return ['white-blue', 'blue', 'white-violet', 'violet'][
|
||||
return ['white-primary', 'primary', 'white-violet', 'violet'][
|
||||
Math.floor(Math.random() * 4)
|
||||
];
|
||||
},
|
||||
|
|
68
app/main.css
68
app/main.css
|
@ -39,7 +39,7 @@ body {
|
|||
}
|
||||
|
||||
.btn {
|
||||
@apply bg-blue-60;
|
||||
@apply bg-primary;
|
||||
@apply text-white;
|
||||
@apply cursor-pointer;
|
||||
@apply py-4;
|
||||
|
@ -48,11 +48,11 @@ body {
|
|||
}
|
||||
|
||||
.btn:hover {
|
||||
@apply bg-blue-70;
|
||||
@apply bg-primary_accent;
|
||||
}
|
||||
|
||||
.btn:focus {
|
||||
@apply bg-blue-70;
|
||||
@apply bg-primary_accent;
|
||||
}
|
||||
|
||||
.checkbox {
|
||||
|
@ -82,16 +82,16 @@ body {
|
|||
}
|
||||
|
||||
.checkbox > label:hover::before {
|
||||
@apply border-blue-50;
|
||||
@apply border-primary;
|
||||
}
|
||||
|
||||
.checkbox > input:focus + label::before {
|
||||
@apply border-blue-50;
|
||||
@apply border-primary;
|
||||
}
|
||||
|
||||
.checkbox > input:checked + label::before {
|
||||
@apply bg-blue-50;
|
||||
@apply border-blue-50;
|
||||
@apply bg-primary;
|
||||
@apply border-primary;
|
||||
|
||||
background-image: url('../assets/lock.svg');
|
||||
background-position: center;
|
||||
|
@ -104,8 +104,8 @@ body {
|
|||
}
|
||||
|
||||
.checkbox > input:disabled + label::before {
|
||||
@apply bg-blue-50;
|
||||
@apply border-blue-50;
|
||||
@apply bg-primary;
|
||||
@apply border-primary;
|
||||
|
||||
background-image: url('../assets/lock.svg');
|
||||
background-position: center;
|
||||
|
@ -153,16 +153,16 @@ footer li a:hover {
|
|||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.link-blue {
|
||||
@apply text-blue-60;
|
||||
.link-primary {
|
||||
@apply text-primary;
|
||||
}
|
||||
|
||||
.link-blue:hover {
|
||||
@apply text-blue-70;
|
||||
.link-primary:hover {
|
||||
@apply text-primary_accent;
|
||||
}
|
||||
|
||||
.link-blue:focus {
|
||||
@apply text-blue-70;
|
||||
.link-primary:focus {
|
||||
@apply text-primary_accent;
|
||||
}
|
||||
|
||||
.main-header img {
|
||||
|
@ -212,7 +212,7 @@ progress::-webkit-progress-value {
|
|||
rgba(255, 255, 255, 0.4) 80%,
|
||||
transparent 80%
|
||||
),
|
||||
-webkit-linear-gradient(left, #0a84ff, #0a84ff);
|
||||
-webkit-linear-gradient(left, var(--color-primary), var(--color-primary));
|
||||
/* stylelint-enable */
|
||||
border-radius: 2px;
|
||||
background-size: 21px 20px, 100% 100%, 100% 100%;
|
||||
|
@ -232,7 +232,7 @@ progress::-moz-progress-bar {
|
|||
rgba(255, 255, 255, 0.4) 80%,
|
||||
transparent 80%
|
||||
),
|
||||
-moz-linear-gradient(left, #0a84ff, #0a84ff);
|
||||
-moz-linear-gradient(left, var(--color-primary), var(--color-primary));
|
||||
/* stylelint-enable */
|
||||
border-radius: 2px;
|
||||
background-size: 21px 20px, 100% 100%, 100% 100%;
|
||||
|
@ -283,28 +283,28 @@ select {
|
|||
}
|
||||
|
||||
.btn {
|
||||
@apply bg-blue-40;
|
||||
@apply bg-primary;
|
||||
@apply text-white;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
@apply bg-blue-50;
|
||||
@apply bg-primary_accent;
|
||||
}
|
||||
|
||||
.btn:focus {
|
||||
@apply bg-blue-50;
|
||||
@apply bg-primary_accent;
|
||||
}
|
||||
|
||||
.link-blue {
|
||||
@apply text-blue-40;
|
||||
.link-primary {
|
||||
@apply text-primary;
|
||||
}
|
||||
|
||||
.link-blue:hover {
|
||||
@apply text-blue-50;
|
||||
.link-primary:hover {
|
||||
@apply text-primary_accent;
|
||||
}
|
||||
|
||||
.link-blue:focus {
|
||||
@apply text-blue-50;
|
||||
.link-primary:focus {
|
||||
@apply text-primary_accent;
|
||||
}
|
||||
|
||||
.main > section {
|
||||
|
@ -363,20 +363,20 @@ select {
|
|||
|
||||
/* begin signin button color experiment */
|
||||
|
||||
.white-blue {
|
||||
@apply border-blue-60;
|
||||
.white-primary {
|
||||
@apply border-primary;
|
||||
@apply border-2;
|
||||
@apply text-blue-60;
|
||||
@apply text-primary;
|
||||
}
|
||||
|
||||
.white-blue:hover,
|
||||
.white-blue:focus {
|
||||
@apply bg-blue-60;
|
||||
.white-primary:hover,
|
||||
.white-primary:focus {
|
||||
@apply bg-primary;
|
||||
@apply text-white;
|
||||
}
|
||||
|
||||
.blue {
|
||||
@apply bg-blue-60;
|
||||
.primary {
|
||||
@apply bg-primary;
|
||||
@apply text-white;
|
||||
}
|
||||
|
||||
|
|
|
@ -69,7 +69,7 @@ class Account extends Component {
|
|||
return html`
|
||||
<send-account>
|
||||
<button
|
||||
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"
|
||||
class="px-4 py-2 md:px-8 md:py-4 focus:outline signin border-2 link-primary border-primary hover:border-primary dark:border-primary dark:hover:border-primary"
|
||||
onclick="${e => this.login(e)}"
|
||||
title="${translate('signInOnlyButton')}"
|
||||
>
|
||||
|
@ -83,7 +83,7 @@ class Account extends Component {
|
|||
<input
|
||||
type="image"
|
||||
alt="${user.email}"
|
||||
class="w-8 h-8 rounded-full border text-blue-50 md:text-white focus:outline"
|
||||
class="w-8 h-8 rounded-full border text-primary md:text-white focus:outline"
|
||||
src="${user.avatar}"
|
||||
onclick="${e => this.avatarClick(e)}"
|
||||
/>
|
||||
|
@ -95,7 +95,7 @@ class Account extends Component {
|
|||
<li class="p-2 text-grey-60 dark:text-grey-50">${user.email}</li>
|
||||
<li>
|
||||
<button
|
||||
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"
|
||||
class="block w-full text-left px-4 py-2 text-grey-80 dark:text-grey-30 hover:bg-primary hover:text-white cursor-pointer focus:outline"
|
||||
onclick="${e => this.logout(e)}"
|
||||
title="${translate('signOut')}"
|
||||
>
|
||||
|
|
|
@ -53,7 +53,7 @@ function password(state) {
|
|||
id="password-input"
|
||||
class="${state.archive.password
|
||||
? ''
|
||||
: 'invisible'} border rounded focus:border-blue-60 leading-normal my-1 py-1 px-2 h-8 dark:bg-grey-80"
|
||||
: 'invisible'} border rounded focus:border-primary leading-normal my-1 py-1 px-2 h-8 dark:bg-grey-80"
|
||||
autocomplete="off"
|
||||
maxlength="${MAX_LENGTH}"
|
||||
type="password"
|
||||
|
@ -150,7 +150,7 @@ function password(state) {
|
|||
function fileInfo(file, action) {
|
||||
return html`
|
||||
<send-file class="flex flex-row items-center p-3 w-full">
|
||||
<svg class="h-8 w-8 text-white dark:text-grey-90">
|
||||
<svg class="h-8 w-8 text-primary">
|
||||
<use xlink:href="${assets.get('blue_file.svg')}#icon"/>
|
||||
</svg>
|
||||
<p class="ml-4 w-full">
|
||||
|
@ -166,7 +166,7 @@ function fileInfo(file, action) {
|
|||
function archiveInfo(archive, action) {
|
||||
return html`
|
||||
<p class="w-full flex items-center">
|
||||
<svg class="h-8 w-6 mr-3 flex-shrink-0 text-white dark:text-grey-90">
|
||||
<svg class="h-8 w-6 mr-3 flex-shrink-0 text-primary">
|
||||
<use xlink:href="${assets.get('blue_file.svg')}#icon"/>
|
||||
</svg>
|
||||
<p class="flex-grow">
|
||||
|
@ -188,7 +188,7 @@ function archiveDetails(translate, archive) {
|
|||
ontoggle="${toggled}"
|
||||
>
|
||||
<summary
|
||||
class="flex items-center link-blue text-sm cursor-pointer outline-none"
|
||||
class="flex items-center link-primary text-sm cursor-pointer outline-none"
|
||||
>
|
||||
<svg
|
||||
class="fill-current w-4 h-4 mr-1"
|
||||
|
@ -218,7 +218,7 @@ module.exports = function(state, emit, archive) {
|
|||
state.capabilities.share || platform() === 'android'
|
||||
? html`
|
||||
<button
|
||||
class="link-blue self-end flex items-start"
|
||||
class="link-primary self-end flex items-start"
|
||||
onclick=${share}
|
||||
title="Share link"
|
||||
>
|
||||
|
@ -230,7 +230,7 @@ module.exports = function(state, emit, archive) {
|
|||
`
|
||||
: html`
|
||||
<button
|
||||
class="link-blue focus:outline self-end flex items-center"
|
||||
class="link-primary focus:outline self-end flex items-center"
|
||||
onclick=${copy}
|
||||
title="${state.translate('copyLinkButton')}"
|
||||
>
|
||||
|
@ -244,7 +244,7 @@ module.exports = function(state, emit, archive) {
|
|||
platform() === 'web'
|
||||
? html`
|
||||
<a
|
||||
class="flex items-baseline link-blue"
|
||||
class="flex items-baseline link-primary"
|
||||
href="${archive.url}"
|
||||
title="${state.translate('downloadButtonLabel')}"
|
||||
tabindex="0"
|
||||
|
@ -358,7 +358,7 @@ module.exports.wip = function(state, emit) {
|
|||
class="flex items-center cursor-pointer"
|
||||
title="${state.translate('addFilesButton')}"
|
||||
>
|
||||
<svg class="w-6 h-6 mr-2 link-blue">
|
||||
<svg class="w-6 h-6 mr-2 link-primary">
|
||||
<use xlink:href="${assets.get('addfiles.svg')}#plus" />
|
||||
</svg>
|
||||
${state.translate('addFilesButton')}
|
||||
|
@ -448,12 +448,12 @@ module.exports.uploading = function(state, emit) {
|
|||
expiresAt: Date.now() + 500 + state.archive.timeLimit * 1000
|
||||
})}
|
||||
</div>
|
||||
<div class="link-blue text-sm font-medium mt-2">
|
||||
<div class="link-primary text-sm font-medium mt-2">
|
||||
${progressPercent}
|
||||
</div>
|
||||
<progress class="my-3" value="${progress}">${progressPercent}</progress>
|
||||
<button
|
||||
class="link-blue self-end font-medium"
|
||||
class="link-primary self-end font-medium"
|
||||
onclick=${cancel}
|
||||
title="${state.translate('deletePopupCancel')}"
|
||||
>
|
||||
|
@ -475,7 +475,7 @@ module.exports.empty = function(state, emit) {
|
|||
? ''
|
||||
: html`
|
||||
<button
|
||||
class="center font-medium text-sm link-blue mt-4 mb-2"
|
||||
class="center font-medium text-sm link-primary mt-4 mb-2"
|
||||
onclick="${event => {
|
||||
event.stopPropagation();
|
||||
emit('signup-cta', 'drop');
|
||||
|
@ -495,7 +495,7 @@ module.exports.empty = function(state, emit) {
|
|||
}
|
||||
}}"
|
||||
>
|
||||
<svg class="w-10 h-10 link-blue">
|
||||
<svg class="w-10 h-10 link-primary">
|
||||
<use xlink:href="/${assets.get('addfiles.svg')}#plus" />
|
||||
</svg>
|
||||
<div class="pt-6 pb-2 text-center text-lg font-bold tracking-wide">
|
||||
|
@ -531,11 +531,11 @@ module.exports.empty = function(state, emit) {
|
|||
`;
|
||||
|
||||
function focus(event) {
|
||||
event.target.nextElementSibling.classList.add('bg-blue-70', 'outline');
|
||||
event.target.nextElementSibling.classList.add('bg-primary', 'outline');
|
||||
}
|
||||
|
||||
function blur(event) {
|
||||
event.target.nextElementSibling.classList.remove('bg-blue-70', 'outline');
|
||||
event.target.nextElementSibling.classList.remove('bg-primary', 'outline');
|
||||
}
|
||||
|
||||
function add(event) {
|
||||
|
@ -593,7 +593,7 @@ module.exports.downloading = function(state) {
|
|||
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)}
|
||||
<div class="link-blue text-sm font-medium mt-2">
|
||||
<div class="link-primary text-sm font-medium mt-2">
|
||||
${progressPercent}
|
||||
</div>
|
||||
<progress class="my-3" value="${progress}">${progressPercent}</progress>
|
||||
|
|
|
@ -42,7 +42,7 @@ module.exports = function(name, url) {
|
|||
${state.translate('copyLinkButton')}
|
||||
</button>
|
||||
<button
|
||||
class="link-blue my-4 font-medium cursor-pointer focus:outline"
|
||||
class="link-primary my-4 font-medium cursor-pointer focus:outline"
|
||||
onclick="${close}"
|
||||
title="${state.translate('okButton')}"
|
||||
>
|
||||
|
|
|
@ -11,7 +11,9 @@ module.exports = function(state) {
|
|||
<h1 class="text-center text-3xl font-bold my-2">
|
||||
${state.translate('downloadFinish')}
|
||||
</h1>
|
||||
<img src="${assets.get('completed.svg')}" class="my-8 h-48" />
|
||||
<svg class="my-8 h-48 text-primary">
|
||||
<use xlink:href="${assets.get('completed.svg')}#Page-1" />
|
||||
</svg>
|
||||
<p
|
||||
class="text-grey-80 leading-normal dark:text-grey-40 ${state.user
|
||||
.loggedIn
|
||||
|
|
|
@ -13,7 +13,9 @@ module.exports = function(state, emit) {
|
|||
<h1 class="text-center text-3xl font-bold my-2">
|
||||
${state.translate('errorPageHeader')}
|
||||
</h1>
|
||||
<img class="my-12 h-48" src="${assets.get('error.svg')}" />
|
||||
<svg class="text-primary my-12 h-48">
|
||||
<use xlink:href="${assets.get('error.svg')}#svg114" />
|
||||
</svg>
|
||||
<p
|
||||
class="max-w-md text-center text-grey-80 leading-normal dark:text-grey-40 ${state
|
||||
.user.loggedIn
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
/*global WEB_UI*/
|
||||
|
||||
const { platform } = require('../utils');
|
||||
const assets = require('../../common/assets');
|
||||
|
||||
const size = 32;
|
||||
const loaderWidth = 5;
|
||||
const loaderColor = '#0090ed';
|
||||
const loaderColor = WEB_UI.COLORS.PRIMARY;
|
||||
|
||||
function drawCircle(canvas, context, color, lineWidth, outerWidth, percent) {
|
||||
canvas.width = canvas.height = outerWidth;
|
||||
|
@ -32,7 +34,10 @@ module.exports.updateFavicon = function(progressRatio) {
|
|||
const progress = progressRatio * 100;
|
||||
if (progress === 0 || progress === 100) {
|
||||
link.type = 'image/png';
|
||||
link.href = assets.get('favicon-32x32.png');
|
||||
link.href =
|
||||
WEB_UI.CUSTOM_ASSETS.favicon_32px !== ''
|
||||
? WEB_UI.CUSTOM_ASSETS.favicon_32px
|
||||
: assets.get('favicon-32x32.png');
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,13 +18,26 @@ class Header extends Component {
|
|||
}
|
||||
|
||||
createElement() {
|
||||
let assetMap = {};
|
||||
if (this.state.ui !== undefined) assetMap = this.state.ui.assets;
|
||||
else
|
||||
assetMap = {
|
||||
icon:
|
||||
this.state.WEB_UI.CUSTOM_ASSETS.icon !== ''
|
||||
? this.state.WEB_UI.CUSTOM_ASSETS.icon
|
||||
: assets.get('icon.svg'),
|
||||
wordmark:
|
||||
this.state.WEB_UI.CUSTOM_ASSETS.wordmark !== ''
|
||||
? this.state.WEB_UI.CUSTOM_ASSETS.wordmark
|
||||
: assets.get('wordmark.svg') + '#logo'
|
||||
};
|
||||
const title =
|
||||
platform() === 'android'
|
||||
? html`
|
||||
<a class="flex flex-row items-center">
|
||||
<img src="${assets.get('icon.svg')}" />
|
||||
<img src="${assetMap.icon}" />
|
||||
<svg class="w-48">
|
||||
<use xlink:href="${assets.get('wordmark.svg')}#logo" />
|
||||
<use xlink:href="${assetMap.wordmark}" />
|
||||
</svg>
|
||||
</a>
|
||||
`
|
||||
|
@ -32,10 +45,10 @@ class Header extends Component {
|
|||
<a class="flex flex-row items-center" href="/">
|
||||
<img
|
||||
alt="${this.state.translate('title')}"
|
||||
src="${assets.get('icon.svg')}"
|
||||
src="${assetMap.icon}"
|
||||
/>
|
||||
<svg viewBox="66 0 340 64" class="w-48 md:w-64">
|
||||
<use xlink:href="${assets.get('wordmark.svg')}#logo" />
|
||||
<use xlink:href="${assetMap.wordmark}" />
|
||||
</svg>
|
||||
</a>
|
||||
`;
|
||||
|
|
|
@ -19,7 +19,7 @@ module.exports = function(state, emit) {
|
|||
<form class="md:w-128" onsubmit=${submit}>
|
||||
<fieldset class="border rounded p-4 my-4" onchange=${optionChanged}>
|
||||
<div class="flex items-center mb-2">
|
||||
<svg class="h-8 w-6 mr-3 flex-shrink-0 text-white dark:text-grey-90">
|
||||
<svg class="h-8 w-6 mr-3 flex-shrink-0 text-primary">
|
||||
<use xlink:href="${assets.get('blue_file.svg')}#icon"/>
|
||||
</svg>
|
||||
<p class="flex-grow">
|
||||
|
|
|
@ -13,7 +13,9 @@ module.exports = function(state, emit) {
|
|||
<h1 class="text-center text-3xl font-bold my-2">
|
||||
${state.translate('expiredTitle')}
|
||||
</h1>
|
||||
<img src="${assets.get('notFound.svg')}" class="my-12" />
|
||||
<svg class="text-primary my-12">
|
||||
<use xlink:href="${assets.get('notFound.svg')}#svg124" />
|
||||
</svg>
|
||||
<p
|
||||
class="max-w-md text-center text-grey-80 leading-normal dark:text-grey-40 ${state
|
||||
.user.loggedIn
|
||||
|
|
|
@ -3,15 +3,22 @@ const html = require('choo/html');
|
|||
module.exports = function(selected, options, translate, changed, htmlId) {
|
||||
function choose(event) {
|
||||
if (event.target.value != selected) {
|
||||
console.log('Selected new value from dropdown', htmlId, ':', selected, '->', event.target.value)
|
||||
console.log(
|
||||
'Selected new value from dropdown',
|
||||
htmlId,
|
||||
':',
|
||||
selected,
|
||||
'->',
|
||||
event.target.value
|
||||
);
|
||||
changed(event.target.value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return html`
|
||||
<select
|
||||
id="${htmlId}"
|
||||
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"
|
||||
class="appearance-none cursor-pointer border rounded bg-grey-10 hover:border-primary focus:border-primary pl-1 pr-8 py-1 my-1 h-8 dark:bg-grey-80"
|
||||
data-selected="${selected}"
|
||||
onchange="${choose}"
|
||||
>
|
||||
|
|
|
@ -30,7 +30,7 @@ module.exports = function(name, url) {
|
|||
${state.translate('shareLinkButton')}
|
||||
</button>
|
||||
<button
|
||||
class="link-blue my-4 font-medium cursor-pointer focus:outline"
|
||||
class="link-primary my-4 font-medium cursor-pointer focus:outline"
|
||||
onclick="${close}"
|
||||
title="${state.translate('okButton')}"
|
||||
>
|
||||
|
|
|
@ -50,7 +50,7 @@ module.exports = function() {
|
|||
? ''
|
||||
: html`
|
||||
<button
|
||||
class="my-3 link-blue font-medium"
|
||||
class="my-3 link-primary font-medium"
|
||||
title="${state.translate('deletePopupCancel')}"
|
||||
onclick=${cancel}
|
||||
>
|
||||
|
|
|
@ -30,7 +30,7 @@ module.exports = function() {
|
|||
Give feedback
|
||||
</a>
|
||||
<button
|
||||
class="link-blue font-medium cursor-pointer focus:outline"
|
||||
class="link-primary font-medium cursor-pointer focus:outline"
|
||||
onclick="${close}"
|
||||
title="Skip"
|
||||
>
|
||||
|
|
|
@ -10,7 +10,7 @@ module.exports = function(state, emit) {
|
|||
strings = unsupportedStrings(state);
|
||||
why = html`
|
||||
<a
|
||||
class="text-blue"
|
||||
class="text-primary"
|
||||
href="https://github.com/timvisee/send/blob/master/docs/faq.md#why-is-my-browser-not-supported"
|
||||
>
|
||||
${state.translate('notSupportedLink')}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue