UI: Shorten version info in about footer and improve scrollbar styles

This commit is contained in:
Michael Mayer 2022-05-20 19:33:07 +02:00
parent d6461e9de6
commit a37c6d4c83
13 changed files with 217 additions and 39 deletions

View file

@ -74,10 +74,17 @@ export default class Config {
document.body.classList.remove("nojs");
// Set body class for browser optimizations.
if (navigator.appVersion.indexOf("Chrome/") !== -1) {
if (navigator.userAgent.indexOf("Chrome/") !== -1) {
document.body.classList.add("chrome");
} else if (navigator.appVersion.indexOf("Safari/") !== -1) {
} else if (navigator.userAgent.indexOf("Safari/") !== -1) {
document.body.classList.add("safari");
document.body.classList.add("not-chrome");
} else if (navigator.userAgent.indexOf("Firefox/") !== -1) {
document.body.classList.add("firefox");
document.body.classList.add("not-chrome");
} else {
document.body.classList.add("other-browser");
document.body.classList.add("not-chrome");
}
}
@ -301,6 +308,19 @@ export default class Config {
this.$vuetify = instance;
}
setBodyTheme(name) {
if (!document || !document.body) {
return;
}
document.body.classList.forEach((c) => {
if (c.startsWith("theme-")) {
document.body.classList.remove(c);
}
});
document.body.classList.add("theme-" + name);
}
setColorMode(value) {
if (!document || !document.body) {
return;
@ -326,6 +346,8 @@ export default class Config {
this.theme = themes[name] ? themes[name] : themes["default"];
this.setBodyTheme(name);
if (this.theme.dark) {
this.setColorMode("dark");
} else {
@ -401,7 +423,29 @@ export default class Config {
return !this.values.demo && !this.values.test;
}
appIcon() {
getName() {
const name = this.get("name");
if (!name) {
return "PhotoPrism";
} else if (name === "PhotoPrism" && this.values.sponsor) {
return "PhotoPrism+";
}
return name;
}
getEdition() {
const edition = this.get("edition");
if (!edition) {
return "PhotoPrism® Dev";
}
return edition;
}
getIcon() {
switch (this.get("appIcon")) {
case "crisp":
case "mint":
@ -411,4 +455,8 @@ export default class Config {
return `${this.staticUri}/icons/logo.svg`;
}
}
getVersion() {
return this.get("version");
}
}

View file

@ -1,19 +1,18 @@
<template>
<v-card flat tile class="ma-0 pa-0 application p-about-footer">
<v-card-actions class="px-4 py-2">
<v-card flat tile class="application footer">
<v-card-actions class="footer-actions">
<v-layout wrap align-top pt-3>
<v-flex xs12 sm6 class="px-0 pb-2 body-1 text-selectable text-xs-center text-sm-left">
<template v-if="sponsor"><router-link to="/about" class="text-link"><translate>Thank you for supporting PhotoPrism®</translate></router-link></template>
<strong v-else><router-link to="/about" class="text-link"><translate>PhotoPrism® needs your support</translate></router-link></strong>
<br><a href="https://docs.photoprism.app/release-notes/" target="_blank">Build {{ $config.get("version") }}</a>
<v-flex xs12 sm6 class="px-0 pb-2 body-1 text-selectable text-xs-left">
<strong><router-link to="/about" class="text-link">{{ $config.getEdition() }}</router-link></strong>
<a href="https://docs.photoprism.app/release-notes/" class="body-link" target="_blank" :title="version">{{ build }}</a>
</v-flex>
<v-flex xs12 sm6 class="px-0 pb-2 body-1 text-xs-center text-sm-right">
<span class="hidden-sm-and-down">
<a href="https://raw.githubusercontent.com/photoprism/photoprism/develop/NOTICE"
target="_blank" class="text-link">3rd-party software packages</a><br>
target="_blank" class="text-link">3rd-party software packages</a>
<a href="https://photoprism.app/team/" target="_blank">© 2018-2022 PhotoPrism UG</a>
</span>
<a href="https://photoprism.app/team/" target="_blank">© 2018-2022 PhotoPrism UG</a>
</v-flex>
</v-layout>
</v-card-actions>
@ -24,8 +23,13 @@
export default {
name: 'PAboutFooter',
data() {
const ver = this.$config.getVersion().split("-");
const build = ver.slice(0, 2).join("-");
return {
rtl: this.$rtl,
build: build,
version: this.$config.getVersion(),
sponsor: this.$config.isSponsor(),
};
},

View file

@ -4,7 +4,7 @@
<v-toolbar dark fixed flat scroll-off-screen dense color="navigation darken-1" class="nav-small"
@click.stop="showNavigation()">
<v-avatar tile :size="28" :class="{'clickable': auth}">
<img :src="$config.appIcon()" :alt="config.name">
<img :src="appIcon" :alt="config.name">
</v-avatar>
<v-toolbar-title class="nav-title">
{{ page.title }}
@ -18,7 +18,7 @@
<template v-else-if="visible && !auth">
<v-toolbar dark flat scroll-off-screen dense color="navigation darken-1" class="nav-small">
<v-avatar tile :size="28">
<img :src="$config.appIcon()" :alt="config.name">
<img :src="appIcon" :alt="config.name">
</v-avatar>
<v-toolbar-title class="nav-title">
{{ page.title }}
@ -40,11 +40,11 @@
<v-list class="navigation-home">
<v-list-tile class="nav-logo">
<v-list-tile-avatar class="clickable" @click.stop.prevent="goHome">
<img :src="$config.appIcon()" :alt="config.name">
<img :src="appIcon" :alt="appName">
</v-list-tile-avatar>
<v-list-tile-content>
<v-list-tile-title class="title">
{{ config.name }}<span v-if="isSponsor">+</span>
{{ appName }}
</v-list-tile-title>
</v-list-tile-content>
<v-list-tile-action class="hidden-sm-and-down" :title="$gettext('Minimize')">
@ -543,17 +543,15 @@ export default {
}
},
data() {
const name = this.$config.get("name");
const isSponsor = name === "PhotoPrism" && this.$config.isSponsor();
return {
name: this.$config.get("name"),
appName: this.$config.getName(),
appEdition: this.$config.getEdition(),
appIcon: this.$config.getIcon(),
drawer: null,
isMini: localStorage.getItem('last_navigation_mode') !== 'false',
isPublic: this.$config.get("public"),
isTest: this.$config.test,
isReadOnly: this.$config.get("readonly"),
isSponsor: isSponsor,
session: this.$session,
config: this.$config.values,
page: this.$config.page,

View file

@ -27,6 +27,7 @@ Additional information can be found in our Developer Guide:
@import url("../../node_modules/vuetify/dist/vuetify.min.css");
@import url("../../node_modules/maplibre-gl/dist/maplibre-gl.css");
@import url("wallpapers.css");
@import url("scrollbar.css");
@import url("themes.css");
@import url("effects.css");
@import url("splash.css");
@ -42,7 +43,6 @@ Additional information can be found in our Developer Guide:
@import url("pages.css");
@import url("help.css");
@import url("auth.css");
@import url("scrollbar.css");
@media (min-width: 1750px) {
.flex.xlg2 {
@ -68,6 +68,11 @@ Additional information can be found in our Developer Guide:
}
}
html {
height: 100%;
overflow: auto overlay;
}
html,
body {
overscroll-behavior-y: contain;
@ -79,6 +84,29 @@ body {
font-family: Roboto, sans-serif;
min-width: 320px;
min-height: 500px;
/* Text rendering defaults. */
letter-spacing: normal;
text-justify: inter-word;
/* Support for all WebKit browsers. */
-webkit-font-smoothing: antialiased;
/* Support for Safari and Chrome. */
text-rendering: optimizeLegibility;
/* Support for Firefox. */
-moz-osx-font-smoothing: grayscale;
/* Enable font features. */
font-feature-settings: 'kern', 'liga';
}
body.chrome {
overflow: auto overlay;
min-height: 100%;
margin: 0;
padding: 0;
}
footer {
@ -86,6 +114,34 @@ footer {
padding: 1rem 2rem;
}
#photoprism .footer {
margin: 0;
padding: 6px 24px 12px;
}
#photoprism .footer a {
display: block;
}
@media only screen and (max-width: 959px) {
#photoprism .footer a {
display: inline-block;
}
#photoprism .footer a.text-link {
float: left;
}
#photoprism .footer a.body-link {
float:right;
}
}
#photoprism .footer .footer-actions {
padding: 0;
margin: 0;
}
#photoprism .p-about-footer .body-1 {
line-height: 1.8em;
}
@ -311,6 +367,10 @@ ol, ul {
border-radius: 6px;
}
#photoprism div.v-dialog.v-dialog--fullscreen>div.v-card {
border-radius: 0;
}
.v-autocomplete__content.v-menu__content,
.v-autocomplete__content.v-menu__content .v-card {
border-radius: 0 0 4px 4px;

View file

@ -2,18 +2,12 @@
z-index: 10;
}
/* hide scrollbar to save space */
#p-navigation ::-webkit-scrollbar {
width: 0;
background: transparent;
}
nav .v-list__tile__title.title {
line-height: normal!important;
}
#p-navigation .nav-title {
text-align: left;
text-align: center;
-webkit-box-flex: 1!important;
-ms-flex-positive: 1!important;
flex-grow: 1!important;
@ -63,9 +57,11 @@ nav .v-list__tile__title.title {
bottom: 0;
left: 50%;
transform: translateX(-50%);
min-width: 200px;
padding: 0 5px;
background-color: rgba(255, 255, 255, 0.6);
margin: 0;
text-align: center;
border-radius: 5px 5px 0 0;
}

View file

@ -4,9 +4,10 @@
see https://css-tricks.com/custom-scrollbars-in-webkit/#aa-the-different-pieces
*/
[data-color-mode=light][data-light-theme*=dark],
[data-color-mode=dark][data-dark-theme*=dark] {
color-scheme: dark;
/* Hide scrollbar in navigation to save space */
#p-navigation ::-webkit-scrollbar {
width: 0;
background: transparent;
}
:root,
@ -15,6 +16,11 @@ see https://css-tricks.com/custom-scrollbars-in-webkit/#aa-the-different-pieces
color-scheme: light;
}
[data-color-mode=light][data-light-theme*=dark],
[data-color-mode=dark][data-dark-theme*=dark] {
color-scheme: dark!important;
}
body.nojs::-webkit-scrollbar,
body.viewer::-webkit-scrollbar,
body.player::-webkit-scrollbar,
@ -33,5 +39,44 @@ body.hide-scrollbar {
body.dark-theme {
color-scheme: dark !important;
background-color: black;
}
body.firefox.dark-theme {
scrollbar-color: dark !important;
}
}
/* Chrome specific styles */
::-webkit-scrollbar {
height: 11px;
overflow: visible;
width: 11px;
}
::-webkit-scrollbar-button {
height: 0;
width: 0;
}
::-webkit-scrollbar-corner {
background: transparent;
}
::-webkit-scrollbar-track {
border: solid transparent;
border-width: 0 0 0 4px;
}
::-webkit-scrollbar-thumb {
background-color: rgba(0, 0, 0, .3);
border: solid transparent;
border-width: 1px 1px 1px 6px;
min-height: 28px;
padding: 100px 0 0;
}
[data-color-mode=light][data-light-theme*=dark] ::-webkit-scrollbar-thumb,
[data-color-mode=dark][data-dark-theme*=dark] ::-webkit-scrollbar-thumb {
background-color: rgba(200, 200, 200, .4);
}

View file

@ -1,5 +1,9 @@
/* Abyss Theme */
body.dark-theme.theme-abyss {
background: #212121 !important;
}
.theme-abyss .v-content__wrap,
.theme-abyss .p-page,
.theme-abyss .form,
@ -31,11 +35,11 @@
}
#photoprism.theme-abyss .theme--light.v-chip,
#photoprism.theme-abyss .v-card__actions .theme--light.v-text-field--solo>.v-input__control>.v-input__slot {
#photoprism.theme-abyss .v-card__actions .theme--light.v-text-field--solo > .v-input__control > .v-input__slot {
background: #333;
}
#photoprism.theme-abyss .theme--light.v-text-field--solo>.v-input__control>.v-input__slot {
#photoprism.theme-abyss .theme--light.v-text-field--solo > .v-input__control > .v-input__slot {
background: #262626;
}

View file

@ -1,5 +1,9 @@
/* Gemstone Theme */
body.dark-theme.theme-gemstone {
background: #444 !important;
}
#photoprism.container.theme-gemstone {
background-image: linear-gradient(160deg, #808080 0%, #262626 100%);
}

View file

@ -1,5 +1,9 @@
/* Grayscale Theme */
body.dark-theme.theme-grayscale {
background: #525252 !important;
}
#photoprism.container.theme-grayscale {
background-image: linear-gradient(160deg, #f5f5f5 0%, #bebfc5 100%);
}

View file

@ -1,5 +1,9 @@
/* Shadow Theme */
body.dark-theme.theme-shadow {
background: #444 !important;
}
#photoprism.container.theme-shadow {
background-image: linear-gradient(160deg, #808080 0%, #262626 100%);
}

View file

@ -1,5 +1,9 @@
/* Vanta Theme */
body.dark-theme.theme-vanta {
background: #212121 !important;
}
#photoprism.container.theme-vanta {
background-image: linear-gradient(160deg, #333333 0%, #000000 100%);
}

View file

@ -1,5 +1,9 @@
/* Yellowstone Theme */
body.dark-theme.theme-yellowstone {
background: #444 !important;
}
#photoprism.container.theme-yellowstone {
background-image: linear-gradient(160deg, #808080 0%, #262626 100%);
}

View file

@ -6,7 +6,7 @@
<v-card class="elevation-12 auth-login-box blur-7">
<v-card-text class="pa-3">
<div class="logo text-xs-center">
<img :src="$config.appIcon()" :alt="config.name">
<img :src="$config.getIcon()" :alt="config.name">
</div>
<v-spacer></v-spacer>
<v-text-field
@ -107,7 +107,7 @@ export default {
},
loading: false,
showPassword: false,
username: sponsor ? "" : "admin",
username: "",
password: "",
sponsor: sponsor,
config: this.$config.values,
@ -119,7 +119,7 @@ export default {
},
computed: {
loginDisabled() {
return this.loading || !this.password || !this.username;
return this.loading || this.username.trim() === "" || this.password.trim() === "";
}
},
created() {
@ -137,12 +137,15 @@ export default {
return "";
},
login() {
if (!this.username || !this.password) {
const username = this.username.trim();
const password = this.password.trim();
if (username === "" || password === "") {
return;
}
this.loading = true;
this.$session.login(this.username, this.password).then(
this.$session.login(username, password).then(
() => {
this.loading = false;
this.$router.push(this.nextUrl);