nx: support header logo change (fix #871)

Signed-off-by: Varun Patil <radialapps@gmail.com>
pull/877/head
Varun Patil 2023-10-16 14:22:35 -07:00
parent cae270e931
commit afaebe6106
3 changed files with 72 additions and 6 deletions

View File

@ -125,6 +125,25 @@ If you are migrating from Google Takeout, you may run the following command to m
occ memories:migrate-google-takeout occ memories:migrate-google-takeout
``` ```
## Customization
### Header Logo
Nextcloud supports customizing the logo for your instance. To properly theme the logo to match the user's theme, the logo you use in `Admninistration => Theming` must follow the following criteria:
- It must be an SVG file.
- The `viewBox` attribute on the `<svg>` element must be set appropriately.
- All paths that correspond to white areas must have the `fill` attribute set to `currentColor`. These areas will then automatically be colored according to the user's theme.
- Since Nextcloud doesn't support `currentColor`, you must set the default value for the color (e.g. `white`) as an inline style on the `<svg>` element (`<svg style="color:white">`).
A sample SVG that follows these criteria is shown below (from [here](https://github.com/pulsejet/memories/blob/master/src/assets/nextcloud.svg)):
```xml
--8<-- "src/assets/nextcloud.svg"
```
Note that you may skip these steps and also use a PNG file, but the logo will not be colored according to the user's theme. This can be especially troublesome since Nextcloud mostly shows the logo on a dark background while Memories uses both light and dark backgrounds.
## Other notes ## Other notes
- For optimal performance, enable HTTP/2 on your reverse proxy (nginx/apache) - For optimal performance, enable HTTP/2 on your reverse proxy (nginx/apache)

View File

@ -1 +1,3 @@
<svg width="256" height="128" version="1.1" viewBox="0 0 256 128" xmlns="http://www.w3.org/2000/svg"><path d="m128 7c-25.871 0-47.817 17.485-54.713 41.209-5.9795-12.461-18.642-21.209-33.287-21.209-20.304 0-37 16.696-37 37s16.696 37 37 37c14.645 0 27.308-8.7481 33.287-21.209 6.8957 23.724 28.842 41.209 54.713 41.209s47.817-17.485 54.713-41.209c5.9795 12.461 18.642 21.209 33.287 21.209 20.304 0 37-16.696 37-37s-16.696-37-37-37c-14.645 0-27.308 8.7481-33.287 21.209-6.8957-23.724-28.842-41.209-54.713-41.209zm0 22c19.46 0 35 15.54 35 35s-15.54 35-35 35-35-15.54-35-35 15.54-35 35-35zm-88 20c8.4146 0 15 6.5854 15 15s-6.5854 15-15 15-15-6.5854-15-15 6.5854-15 15-15zm176 0c8.4146 0 15 6.5854 15 15s-6.5854 15-15 15-15-6.5854-15-15 6.5854-15 15-15z" fill="currentColor" style="-inkscape-stroke:none"/></svg> <svg viewBox="0 0 256 128" style="color:white" width="256" height="128" version="1.1" xmlns="http://www.w3.org/2000/svg">
<path fill="currentColor" d="m128 7c-25.871 0-47.817 17.485-54.713 41.209-5.9795-12.461-18.642-21.209-33.287-21.209-20.304 0-37 16.696-37 37s16.696 37 37 37c14.645 0 27.308-8.7481 33.287-21.209 6.8957 23.724 28.842 41.209 54.713 41.209s47.817-17.485 54.713-41.209c5.9795 12.461 18.642 21.209 33.287 21.209 20.304 0 37-16.696 37-37s-16.696-37-37-37c-14.645 0-27.308 8.7481-33.287 21.209-6.8957-23.724-28.842-41.209-54.713-41.209zm0 22c19.46 0 35 15.54 35 35s-15.54 35-35 35-35-15.54-35-35 15.54-35 35-35zm-88 20c8.4146 0 15 6.5854 15 15s-6.5854 15-15 15-15-6.5854-15-15 6.5854-15 15-15zm176 0c8.4146 0 15 6.5854 15 15s-6.5854 15-15 15-15-6.5854-15-15 6.5854-15 15-15z" />
</svg>

Before

Width:  |  Height:  |  Size: 807 B

After

Width:  |  Height:  |  Size: 800 B

View File

@ -8,7 +8,7 @@
> >
<div class="logo"> <div class="logo">
<a :href="homeUrl"> <a :href="homeUrl">
<XImg :src="nextcloudsvg" :svg-tag="true" /> <XImg v-if="logo" :src="logo" :svg-tag="true" />
</a> </a>
</div> </div>
</div> </div>
@ -17,6 +17,7 @@
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import { generateUrl } from '@nextcloud/router'; import { generateUrl } from '@nextcloud/router';
import axios from '@nextcloud/axios';
import nextcloudsvg from '../assets/nextcloud.svg'; import nextcloudsvg from '../assets/nextcloud.svg';
import * as utils from '../services/utils'; import * as utils from '../services/utils';
@ -26,7 +27,7 @@ export default defineComponent({
data: () => ({ data: () => ({
isScrollDown: false, isScrollDown: false,
nextcloudsvg, logo: null as string | null,
}), }),
computed: { computed: {
@ -37,6 +38,7 @@ export default defineComponent({
mounted() { mounted() {
utils.bus.on('memories.recycler.scroll', this.onScroll); utils.bus.on('memories.recycler.scroll', this.onScroll);
this.getLogo();
}, },
beforeDestroy() { beforeDestroy() {
@ -47,6 +49,40 @@ export default defineComponent({
onScroll({ current, previous }: utils.BusEvent['memories.recycler.scroll']) { onScroll({ current, previous }: utils.BusEvent['memories.recycler.scroll']) {
this.isScrollDown = (this.isScrollDown && previous - current < 40) || current - previous > 40; // momentum scroll this.isScrollDown = (this.isScrollDown && previous - current < 40) || current - previous > 40; // momentum scroll
}, },
async getLogo() {
// try to get the logo
try {
const style = getComputedStyle(document.body);
const override = style.getPropertyValue('--image-logoheader') || style.getPropertyValue('--image-logo');
if (override) {
// Extract URL from CSS url
const url = override.match(/url\(["']?([^"']*)["']?\)/i)?.[1];
if (!url) throw new Error('No URL found');
// Fetch image
const blob = (await axios.get(url, { responseType: 'blob' })).data;
console.log('Loaded logo', blob);
// Convert to data URI and pass to logo
const reader = new FileReader();
reader.readAsDataURL(blob);
this.logo = await new Promise<string>((resolve, reject) => {
reader.onloadend = () => resolve(reader.result as string);
reader.onerror = reject;
reader.onabort = reject;
});
return;
}
} catch (e) {
// Go to fallback
console.warn('Could not load logo', e);
}
// Fallback to default
this.logo = nextcloudsvg;
},
}, },
}); });
</script> </script>
@ -80,13 +116,22 @@ export default defineComponent({
.logo { .logo {
width: 62px; width: 62px;
height: 90%;
position: absolute; position: absolute;
top: 60%; top: 10%;
left: 50%; left: 50%;
transform: translate(-50%, -50%); transform: translateX(-50%);
> a { > a {
color: var(--color-primary); :deep svg {
color: var(--color-primary) !important;
}
> * {
width: 100%;
height: 100%;
object-fit: contain;
}
} }
} }
} }