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 117 additions and 121 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>

Binary file not shown.

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>