Update and fix theming images

Signed-off-by: John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>
This commit is contained in:
John Molakvoæ (skjnldsv) 2022-04-01 15:19:15 +02:00 committed by John Molakvoæ
parent 738fcba51a
commit a1aaaaa0c8
No known key found for this signature in database
GPG key ID: 60C25B8C072916CF
15 changed files with 151 additions and 153 deletions

View file

@ -100,7 +100,8 @@
margin-top: 10px;
margin-bottom: 20px;
cursor: pointer;
background-image: var(--image-login);
background-color: var(--color-primary);
background-image: var(--image-background, var(--image-background-plain, url('../../../core/img/background.svg'), linear-gradient(40deg, #0082c9 0%, #30b6ff 100%)));
#theming-preview-logo {
cursor: pointer;
@ -111,7 +112,7 @@
background-position: center;
background-repeat: no-repeat;
background-size: contain;
background-image: var(--image-logo);
background-image: var(--image-logo, url('../../../core/img/logo/logo.svg'));
}
}
@ -127,6 +128,15 @@
background-repeat: no-repeat;
background-size: contain;
}
#theming-preview-logoheader {
// Only using --image-logoheader to show the custom value only
background-image: var(--image-logoheader);
}
#theming-preview-favicon {
background-image: var(--image-favicon);
}
}
/* transition effects for theming value changes */

View file

@ -45,18 +45,6 @@ $invert: luma($color-primary) > 0.6;
}
}
.nc-theming-main-background {
background-color: $color-primary;
}
.nc-theming-main-text {
color: $color-primary-text;
}
.nc-theming-contrast {
color: $color-primary-text;
}
@if ($invert) {
// too bright, use dark text to mix the primary
$color-primary-light: mix($color-primary, $color-main-text, 10%);
@ -157,16 +145,6 @@ $invert: luma($color-primary) > 0.6;
}
}
@if variable_exists('theming-favicon-mime') and $theming-favicon-mime != '' {
#theming .advanced-option-favicon .image-preview {
background-image: $image-favicon;
}
} @else {
#theming .advanced-option-favicon .image-preview {
background-image: none;
}
}
input.primary {
background-color: $color-primary-element;
border: 1px solid $color-primary-text;
@ -305,9 +283,3 @@ input.primary {
border: 1px solid #ebebeb;
}
}
@if ($has-legal-links == 'true') {
footer {
height: 92px;
}
}

View file

@ -58,20 +58,6 @@ class BeforeTemplateRenderedListener implements IEventListener {
return $serverContainer->query(JSDataService::class);
});
// $linkToCSS = $this->urlGenerator->linkToRoute(
// 'theming.Theming.getStylesheet',
// [
// 'v' => $this->config->getAppValue('theming', 'cachebuster', '0'),
// ]
// );
// \OCP\Util::addHeader(
// 'link',
// [
// 'rel' => 'stylesheet',
// 'href' => $linkToCSS,
// ]
// );
$this->themeInjectionService->injectHeaders();
// Making sure to inject just after core

View file

@ -24,21 +24,32 @@ declare(strict_types=1);
*/
namespace OCA\Theming\Themes;
use OCA\Theming\ImageManager;
use OCA\Theming\ThemingDefaults;
use OCA\Theming\Util;
use OCA\Theming\ITheme;
use OCP\IConfig;
use OCP\IURLGenerator;
class DefaultTheme implements ITheme {
public Util $util;
public ThemingDefaults $themingDefaults;
public IURLGenerator $urlGenerator;
public ImageManager $imageManager;
public IConfig $config;
public string $primaryColor;
public function __construct(Util $util, ThemingDefaults $themingDefaults, IURLGenerator $urlGenerator) {
public function __construct(Util $util,
ThemingDefaults $themingDefaults,
IURLGenerator $urlGenerator,
ImageManager $imageManager,
IConfig $config) {
$this->util = $util;
$this->themingDefaults = $themingDefaults;
$this->urlGenerator = $urlGenerator;
$this->imageManager = $imageManager;
$this->config = $config;
$this->primaryColor = $this->themingDefaults->getColorPrimary();
}
@ -58,11 +69,7 @@ class DefaultTheme implements ITheme {
$colorBoxShadow = $this->util->darken($colorMainBackground, 70);
$colorBoxShadowRGB = join(',', $this->util->hexToRGB($colorBoxShadow));
// Logo variables
$logoSvgPath = $this->urlGenerator->getAbsoluteURL($this->themingDefaults->getLogo());
$backgroundSvgPath = $this->urlGenerator->getAbsoluteURL($this->themingDefaults->getBackground());
return [
$variables = [
'--color-main-background' => $colorMainBackground,
'--color-main-background-rgb' => $colorMainBackgroundRGB,
'--color-main-background-translucent' => 'rgba(var(--color-main-background-rgb), .97)',
@ -124,11 +131,6 @@ class DefaultTheme implements ITheme {
'--animation-slow' => '300ms',
// Default variables --------------------------------------------
'--image-logo' => "url('$logoSvgPath')",
'--image-login' => "url('$backgroundSvgPath')",
'--image-logoheader' => "url('$logoSvgPath')",
'--image-favicon' => "url('$logoSvgPath')",
'--border-radius' => '3px',
'--border-radius-large' => '10px',
// pill-style button, value is large so big buttons also have correct roundness
@ -156,5 +158,22 @@ class DefaultTheme implements ITheme {
'--primary-invert-if-bright' => $this->util->invertTextColor($this->primaryColor) ? 'invert(100%)' : 'unset',
'--background-invert-if-bright' => 'unset',
];
// Register image variables only if custom-defined
$backgroundDeleted = $this->config->getAppValue('theming', 'backgroundMime', '') === 'backgroundColor';
foreach(['logo', 'logoheader', 'favicon', 'background'] as $image) {
if ($this->imageManager->hasImage($image)) {
// If primary as background has been request, let's not define the background image
if ($image === 'background' && $backgroundDeleted) {
$variables["--image-background-plain"] = true;
continue;
} else if ($image === 'background') {
$variables['--image-background-size'] = 'cover';
}
$variables["--image-$image"] = "url('".$this->imageManager->getImageUrl($image)."')";
}
}
return $variables;
}
}

View file

@ -116,7 +116,7 @@ style('theming', 'settings-admin');
<label for="upload-login-logoheader"><span><?php p($l->t('Header logo')) ?></span></label>
<input id="upload-login-logoheader" class="fileupload" name="image" type="file">
<label for="upload-login-logoheader" class="button icon-upload svg" id="upload-login-logoheader" title="<?php p($l->t("Upload new header logo")) ?>"></label>
<div class="image-preview"></div>
<div id="theming-preview-logoheader" class="image-preview"></div>
<div data-setting="logoheaderMime" data-toggle="tooltip" data-original-title="<?php p($l->t('Reset to default')); ?>" class="theme-undo icon icon-history"></div>
</form>
</div>
@ -127,7 +127,7 @@ style('theming', 'settings-admin');
<label for="upload-login-favicon"><span><?php p($l->t('Favicon')) ?></span></label>
<input id="upload-login-favicon" class="fileupload" name="image" type="file">
<label for="upload-login-favicon" class="button icon-upload svg" id="upload-login-favicon" title="<?php p($l->t("Upload new favicon")) ?>"></label>
<div class="image-preview"></div>
<div id="theming-preview-favicon" class="image-preview"></div>
<div data-setting="faviconMime" data-toggle="tooltip" data-original-title="<?php p($l->t('Reset to default')); ?>" class="theme-undo icon icon-history"></div>
</form>
</div>

View file

@ -15,20 +15,19 @@ a, a *, input, input *, select, .button span, label { cursor:pointer; }
ul { list-style:none; }
body {
background-color: #ffffff;
font-weight: normal;
/* bring the default font size up to 14px */
font-size: .875em;
line-height: 1.6em;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
color: #000;
color: var(--color-primary-text);
text-align: center;
background-color: #0082c9;
background-image: url('../img/background.png?v=2');
background-image: url('../img/background.png?v=2'), linear-gradient(40deg, #0082c9 0%, rgba(28,175,255,1) 100%);
background-color: var(--color-primary);
background-image: var(--image-background);
background-image: var(--image-background), linear-gradient(40deg, var(--color-primary) 0%, var(--color-primary-light) 100%);
background-position: 50% 50%;
background-repeat: repeat;
background-size: 275px, contain;
background-size: var(--image-background-size, 275px, contain);
background-attachment: fixed; /* fix background gradient */
min-height: 100%; /* fix sticky footer */
height: auto;
@ -36,7 +35,7 @@ body {
/* Various fonts settings */
#body-login a {
color: #fff;
color: var(--color-primary-text);
font-weight: 600;
}
#body-login a:not(.button):hover,
@ -46,7 +45,7 @@ body {
}
#showAdvanced {
color: #fff;
color: var(--color-primary-text);
}
em {
@ -80,13 +79,12 @@ body {
}
#header .logo {
background-image: url('../img/logo/logo.svg?v=1');
background-image: var(--image-logo);
background-repeat: no-repeat;
background-size: 175px;
background-size: contain;
background-position: center;
width: 256px;
min-height: 128px;
max-height: 200px;
width: 175px;
height: 130px;
margin: 0 auto;
position: relative;
left: unset;
@ -185,7 +183,7 @@ form #datadirField legend {
}
.alternative-logins .button {
color: #ffffff;
color: var(--color-text-lighter);
padding: 12px 20px;
}
@ -263,9 +261,9 @@ select {
width: auto;
min-width: 25px;
padding: 12px;
background-color: white;
background-color: var(--color-main-background);
font-weight: bold;
color: #555;
color: var(--color-text-lighter);
border: none;
border-radius: 100px; /* --border-radius-pill */
cursor: pointer;
@ -280,7 +278,7 @@ input[type='password'],
input[type='email'] {
width: 249px;
background: #fff;
color: #555;
color: var(--color-text-lighter);
cursor: text;
font-family: inherit;
-webkit-appearance: textfield;
@ -338,9 +336,9 @@ input::-moz-focus-inner {
input.primary,
button.primary,
a.primary {
border: 1px solid #fff;
background-color: #0082c9;
color: #fff;
border: 1px solid var(--color-primary-text);
background-color: var(--color-primary);
color: var(--color-primary-text);
transition: color 100ms ease-in-out;
}
@ -350,8 +348,8 @@ button.primary:not(:disabled):hover,
button.primary:not(:disabled):focus,
a.primary:not(:disabled):hover,
a.primary:not(:disabled):focus {
color: rgba(255, 255, 255, 1);
background-image: linear-gradient(40deg, #0082c9 0%, #30b6ff 100%);
color: var(--color-primary-text);
background-image: linear-gradient(40deg, var(--color-primary) 0%, var(--color-primary-light) 100%);
background-position: initial;
}
@ -479,13 +477,13 @@ form fieldset legend,
form fieldset .warning-info,
form input[type='checkbox']+label {
text-align: center;
color: #fff;
color: var(--color-primary-text);
}
/* overrides another !important statement that sets this to unreadable black */
form .warning input[type='checkbox']:hover+label,
form .warning input[type='checkbox']:focus+label,
form .warning input[type='checkbox']+label {
color: #fff !important;
color: var(--color-primary-text) !important;
}
.body-login-container.two-factor {
@ -559,7 +557,7 @@ form .warning input[type='checkbox']+label {
display: inline-block;
font-weight: normal !important;
padding: 12px;
color: #fff;
color: var(--color-primary-text);
cursor: pointer;
text-shadow: 0 0 2px rgba(0, 0, 0, .4); /* better readability on bright background */
}
@ -569,7 +567,7 @@ form .warning input[type='checkbox']+label {
#forgot-password {
padding: 11px;
float: right;
color: #fff;
color: var(--color-primary-text);
}
/* Alternative Logins */
@ -587,16 +585,16 @@ form .warning input[type='checkbox']+label {
display: inline-block;
text-align: center;
box-sizing: border-box;
border: 2px solid #ffffff;
background-color: #0082c9;
color: #ffffff;
border: 2px solid var(--color-primary-text);
background-color: var(--color-primary);
color: var(--color-primary-text);
border-radius: 100px; /* --border-radius-pill */
}
.alternative-logins a.button:focus,
.alternative-logins li a:focus {
border: 2px solid #000000;
background-image: linear-gradient(40deg, #0082c9 0%, #30b6ff 100%);
border: 2px solid var(--color-primary-hover);
background-image: linear-gradient(40deg, var(--color-primary) 0%, var(--color-primary-light) 100%);
background-position: initial;
}
@ -854,6 +852,7 @@ p.info {
}
.loading, .loading-small, .icon-loading, .icon-loading-dark, .icon-loading-small, .icon-loading-small-dark {
position: relative;
filter: var(--background-invert-if-bright)
}
.loading:after, .loading-small:after, .icon-loading:after, .icon-loading-dark:after, .icon-loading-small:after, .icon-loading-small-dark:after {
z-index: 2;
@ -871,6 +870,9 @@ p.info {
-ms-transform-origin: center;
transform-origin: center;
}
.primary .loading,.primary+.loading,.primary .loading-small,.primary+.loading-small,.primary .icon-loading,.primary+.icon-loading,.primary .icon-loading-dark,.primary+.icon-loading-dark,.primary .icon-loading-small,.primary+.icon-loading-small,.primary .icon-loading-small-dark,.primary+.icon-loading-small-dark {
filter: var(--primary-invert-if-bright)
}
.loading:after, .loading-small:after, .icon-loading:after, .icon-loading-dark:after, .icon-loading-small:after, .icon-loading-small-dark:after {
border: 2px solid rgba(150, 150, 150, 0.5);
border-top-color: #646464;
@ -920,7 +922,7 @@ img.icon-loading-small-dark, object.icon-loading-small-dark, video.icon-loading-
/* FOOTER */
footer {
height: 70px;
min-height: 70px;
margin-top: auto;
}

View file

@ -172,7 +172,7 @@
}
.logo {
display: inline-flex;
background-image: var(--image-logo);
background-image: var(--image-logoheader, var(--image-logo, url('../img/logo/logo.svg')));
background-repeat: no-repeat;
background-size: contain;
background-position: center;

View file

@ -64,6 +64,14 @@
transform-origin: center;
border: 2px solid var(--color-loading-light);
border-top-color: var(--color-loading-dark);
// revert if background is too bright
filter: var(--background-invert-if-bright);
.primary &,
.primary + & {
// revert if primary is too bright
filter: var(--primary-invert-if-bright);
}
}
}

View file

@ -20,25 +20,33 @@
-->
<template>
<div id="submit-wrapper" @click="$emit('click')">
<input id="submit-form"
type="submit"
class="login primary"
<div class="submit-wrapper" @click="$emit('click')">
<input type="submit"
class="submit-wrapper__input primary"
title=""
:value="!loading ? t('core', 'Log in') : t('core', 'Logging in …')">
<div class="submit-icon"
:class="{
'icon-confirm-white': !loading,
'icon-loading-small': loading && invertedColors,
'icon-loading-small-dark': loading && !invertedColors,
}" />
:value="!loading ? value : valueLoading">
<div v-if="loading" class="submit-wrapper__icon icon-loading-small-dark" />
<ArrowRight v-else class="submit-wrapper__icon" />
</div>
</template>
<script>
import ArrowRight from 'vue-material-design-icons/ArrowRight.vue'
export default {
name: 'LoginButton',
components: {
ArrowRight,
},
props: {
value: {
type: String,
default: t('core', 'Log in'),
},
valueLoading: {
type: String,
default: t('core', 'Logging in …'),
},
loading: {
type: Boolean,
required: true,
@ -51,6 +59,36 @@ export default {
}
</script>
<style scoped>
<style scoped lang="scss">
.submit-wrapper {
display: flex;
align-items: center;
justify-content: center;
padding: 10px 5px;
position: relative;
margin: 0 auto;
&__input {
width: 260px;
height: 50px;
}
&__icon {
display: flex;
position: absolute;
right: 24px;
transition: right 100ms ease-in-out;
/* The submit icon is positioned on the submit button.
From the user point of view the icon is part of the
button, so the clicks on the icon have to be
applied to the button instead. */
pointer-events: none;
}
&__input:hover + &__icon:not(.icon-loading-small-dark),
&__input:focus + &__icon:not(.icon-loading-small-dark),
&__input:active + &__icon:not(.icon-loading-small-dark) {
right: 20px;
}
}
</style>

View file

@ -89,7 +89,7 @@
</a>
</p>
<LoginButton :loading="loading" :inverted-colors="invertedColors" />
<LoginButton :loading="loading" />
<p v-if="invalidPassword"
class="warning wrongPasswordMsg">
@ -158,10 +158,6 @@ export default {
type: Number,
default: 0,
},
invertedColors: {
type: Boolean,
default: false,
},
autoCompleteAllowed: {
type: Boolean,
default: true,

View file

@ -25,7 +25,6 @@
<LoginButton v-if="validCredentials"
:loading="loading"
:inverted-colors="invertedColors"
@click="authenticate" />
</fieldset>
</form>
@ -74,10 +73,6 @@ export default {
type: [String, Boolean],
default: false,
},
invertedColors: {
type: Boolean,
default: false,
},
autoCompleteAllowed: {
type: Boolean,
default: true,

View file

@ -37,17 +37,7 @@
<label for="user" class="infield">{{ t('core', 'Username or email') }}</label>
</p>
<div id="reset-password-wrapper">
<input id="reset-password-submit"
type="submit"
class="login primary"
title=""
:value="t('core', 'Reset password')">
<div class="submit-icon"
:class="{
'icon-confirm-white': !loading,
'icon-loading-small': loading && invertedColors,
'icon-loading-small-dark': loading && !invertedColors,
}" />
<LoginButton :value="t('core', 'Reset password')" />
</div>
<p v-if="message === 'send-success'"
class="update">
@ -77,11 +67,14 @@
<script>
import axios from '@nextcloud/axios'
import { generateUrl } from '@nextcloud/router'
import LoginButton from './LoginButton.vue'
export default {
name: 'ResetPassword',
components: {
LoginButton,
},
props: {
username: {
type: String,
@ -91,10 +84,6 @@ export default {
type: String,
required: true,
},
invertedColors: {
type: Boolean,
default: false,
},
},
data() {
return {

View file

@ -49,18 +49,9 @@
</label>
</div>
<div id="submit-wrapper">
<input id="submit"
type="submit"
class="login primary"
title=""
:value="!loading ? t('core', 'Reset password') : t('core', 'Resetting password')">
<div class="submit-icon"
:class="{
'icon-loading-small': loading && invertedColors,
'icon-loading-small-dark': loading && !invertedColors
}" />
</div>
<LoginButton :loading="loading"
:value="t('core', 'Reset password')"
:value-loading="t('core', 'Resetting password')" />
<p v-if="error && message" :class="{warning: error}">
{{ message }}
@ -71,9 +62,13 @@
<script>
import Axios from '@nextcloud/axios'
import LoginButton from './LoginButton.vue'
export default {
name: 'UpdatePassword',
components: {
LoginButton,
},
props: {
username: {
type: String,
@ -83,10 +78,6 @@ export default {
type: String,
required: true,
},
invertedColors: {
type: Boolean,
default: false,
},
},
data() {
return {

View file

@ -30,7 +30,6 @@
:messages="messages"
:errors="errors"
:throttle-delay="throttleDelay"
:inverted-colors="invertedColors"
:auto-complete-allowed="autoCompleteAllowed"
@submit="loading = true" />
<a v-if="canResetPassword && resetPasswordLink !== ''"
@ -68,7 +67,6 @@
class="login-additional">
<PasswordLessLoginForm :username.sync="user"
:redirect-url="redirectUrl"
:inverted-colors="invertedColors"
:auto-complete-allowed="autoCompleteAllowed"
:is-https="isHttps"
:is-localhost="isLocalhost"
@ -85,14 +83,12 @@
<ResetPassword v-if="resetPassword"
:username.sync="user"
:reset-password-link="resetPasswordLink"
:inverted-colors="invertedColors"
@abort="resetPassword = false" />
</div>
</div>
<div v-else-if="resetPasswordTarget !== ''">
<UpdatePassword :username.sync="user"
:reset-password-target="resetPasswordTarget"
:inverted-colors="invertedColors"
@done="passwordResetFinished" />
</div>
</transition>
@ -150,7 +146,6 @@ export default {
messages: loadState('core', 'loginMessages', []),
redirectUrl: loadState('core', 'loginRedirectUrl', false),
throttleDelay: loadState('core', 'loginThrottleDelay', 0),
invertedColors: OCA.Theming && OCA.Theming.inverted,
canResetPassword: loadState('core', 'loginCanResetPassword', false),
resetPasswordLink: loadState('core', 'loginResetPasswordLink', ''),
autoCompleteAllowed: loadState('core', 'loginAutocomplete', true),
@ -165,6 +160,7 @@ export default {
hideLoginForm: loadState('core', 'hideLoginForm', false),
}
},
methods: {
passwordResetFinished() {
this.resetPasswordTarget = ''

View file

@ -36,10 +36,6 @@
<h1 class="hidden-visually">
<?php p($theme->getName()); ?>
</h1>
<?php if (\OC::$server->getConfig()->getSystemValue('installed', false)
&& \OC::$server->getConfig()->getAppValue('theming', 'logoMime', false)): ?>
<img src="<?php p($theme->getLogo()); ?>"/>
<?php endif; ?>
</div>
</div>
</header>