nx: support header logo change (fix #871)
Signed-off-by: Varun Patil <radialapps@gmail.com>pull/877/head
parent
cae270e931
commit
afaebe6106
|
@ -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)
|
||||||
|
|
|
@ -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 |
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue