theme selector new
This commit is contained in:
parent
1866dcfdc2
commit
9bbdad1a6f
|
@ -35,6 +35,7 @@ const AppearanceTab = {
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
availableStyles: [],
|
availableStyles: [],
|
||||||
|
intersectionObserver: null,
|
||||||
thirdColumnModeOptions: ['none', 'notifications', 'postform'].map(mode => ({
|
thirdColumnModeOptions: ['none', 'notifications', 'postform'].map(mode => ({
|
||||||
key: mode,
|
key: mode,
|
||||||
value: mode,
|
value: mode,
|
||||||
|
@ -62,9 +63,7 @@ const AppearanceTab = {
|
||||||
FontControl,
|
FontControl,
|
||||||
Preview
|
Preview
|
||||||
},
|
},
|
||||||
created () {
|
mounted () {
|
||||||
const self = this
|
|
||||||
|
|
||||||
getThemes()
|
getThemes()
|
||||||
.then((promises) => {
|
.then((promises) => {
|
||||||
return Promise.all(
|
return Promise.all(
|
||||||
|
@ -74,19 +73,48 @@ const AppearanceTab = {
|
||||||
})
|
})
|
||||||
.then(themes => themes.reduce((acc, [k, v]) => {
|
.then(themes => themes.reduce((acc, [k, v]) => {
|
||||||
if (v) {
|
if (v) {
|
||||||
return {
|
return [
|
||||||
...acc,
|
...acc,
|
||||||
[k]: v
|
{
|
||||||
}
|
name: v.name || v[0],
|
||||||
|
key: k,
|
||||||
|
data: v
|
||||||
|
}
|
||||||
|
]
|
||||||
} else {
|
} else {
|
||||||
return acc
|
return acc
|
||||||
}
|
}
|
||||||
}, {}))
|
}, []))
|
||||||
.then((themesComplete) => {
|
.then((themesComplete) => {
|
||||||
self.availableStyles = themesComplete
|
this.availableStyles = themesComplete
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if (window.IntersectionObserver) {
|
||||||
|
this.intersectionObserver = new IntersectionObserver((entries, observer) => {
|
||||||
|
entries.forEach(({ target, isIntersecting }) => {
|
||||||
|
if (!isIntersecting) return
|
||||||
|
const theme = this.availableStyles.find(x => x.key === target.dataset.themeKey)
|
||||||
|
this.$nextTick(() => {
|
||||||
|
theme.ready = true
|
||||||
|
})
|
||||||
|
observer.unobserve(target)
|
||||||
|
})
|
||||||
|
}, {
|
||||||
|
root: this.$refs.themeList
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
updated () {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.$refs.themeList.querySelectorAll('.theme-preview').forEach(node => {
|
||||||
|
this.intersectionObserver.observe(node)
|
||||||
|
})
|
||||||
|
})
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
noIntersectionObserver () {
|
||||||
|
return !window.IntersectionObserver
|
||||||
|
},
|
||||||
horizontalUnits () {
|
horizontalUnits () {
|
||||||
return defaultHorizontalUnits
|
return defaultHorizontalUnits
|
||||||
},
|
},
|
||||||
|
@ -119,7 +147,12 @@ const AppearanceTab = {
|
||||||
...SharedComputedObject()
|
...SharedComputedObject()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
previewTheme (input) {
|
isThemeActive (key, name) {
|
||||||
|
console.log(this.$store.getters.mergedConfig)
|
||||||
|
const { customTheme, themeName, customThemeSource } = this.$store.getters.mergedConfig
|
||||||
|
console.log(customTheme, customThemeSource, themeName)
|
||||||
|
},
|
||||||
|
previewTheme (key, input) {
|
||||||
const style = normalizeThemeData(input)
|
const style = normalizeThemeData(input)
|
||||||
const x = 2
|
const x = 2
|
||||||
if (x === 1) return
|
if (x === 1) return
|
||||||
|
@ -128,12 +161,13 @@ const AppearanceTab = {
|
||||||
inputRuleset: theme2,
|
inputRuleset: theme2,
|
||||||
ultimateBackgroundColor: '#000000',
|
ultimateBackgroundColor: '#000000',
|
||||||
liteMode: true,
|
liteMode: true,
|
||||||
|
debug: true,
|
||||||
onlyNormalState: true
|
onlyNormalState: true
|
||||||
})
|
})
|
||||||
|
|
||||||
return getScopedVersion(
|
return getScopedVersion(
|
||||||
getCssRules(theme3.eager),
|
getCssRules(theme3.eager),
|
||||||
'#theme-preview-' + (input.name || input[0]).replace(/ /g, '_')
|
'#theme-preview-' + key
|
||||||
).join('\n')
|
).join('\n')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,18 +2,26 @@
|
||||||
<div :label="$t('settings.general')">
|
<div :label="$t('settings.general')">
|
||||||
<div class="setting-item">
|
<div class="setting-item">
|
||||||
<h2>{{ $t('settings.theme') }}</h2>
|
<h2>{{ $t('settings.theme') }}</h2>
|
||||||
<ul class="theme-list">
|
<ul
|
||||||
<li
|
class="input theme-list"
|
||||||
|
ref="themeList"
|
||||||
|
>
|
||||||
|
<button
|
||||||
v-for="style in availableStyles"
|
v-for="style in availableStyles"
|
||||||
:key="style.name || style[0]"
|
:data-theme-key="style.key"
|
||||||
class="theme-preview"
|
:key="style.key"
|
||||||
|
class="button-default theme-preview"
|
||||||
>
|
>
|
||||||
<h6>{{ style[0] || style.name }}</h6>
|
|
||||||
<!-- eslint-disable vue/no-v-text-v-html-on-component -->
|
<!-- eslint-disable vue/no-v-text-v-html-on-component -->
|
||||||
<component :is="'style'" v-html="previewTheme(style)"/>
|
<component
|
||||||
|
:is="'style'"
|
||||||
|
v-if="style.ready || noIntersectionObserver"
|
||||||
|
v-html="previewTheme(style.key, style.data)"
|
||||||
|
/>
|
||||||
<!-- eslint-enable vue/no-v-text-v-html-on-component -->
|
<!-- eslint-enable vue/no-v-text-v-html-on-component -->
|
||||||
<preview :id="'theme-preview-' + (style[0] || style.name).replace(/ /g,'_')"/>
|
<preview :class="{ placeholder: ready }" :id="'theme-preview-' + style.key"/>
|
||||||
</li>
|
<h4 class="theme-name">{{ style.name }}</h4>
|
||||||
|
</button>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="setting-item">
|
<div class="setting-item">
|
||||||
|
@ -252,13 +260,28 @@
|
||||||
list-style: none;
|
list-style: none;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
margin: 0 -0.5em;
|
||||||
|
height: 15em;
|
||||||
|
overflow-x: hidden;
|
||||||
|
overflow-y: auto;
|
||||||
|
scrollbar-gutter: stable;
|
||||||
|
|
||||||
.theme-preview {
|
.theme-preview {
|
||||||
width: 10rem;
|
width: 21rem;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
margin: 0.5em;
|
||||||
|
|
||||||
.preview-container {
|
&.placeholder {
|
||||||
zoom: 0.33;
|
opacity: 0.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-container {
|
||||||
|
zoom: 0.5;
|
||||||
|
border: none;
|
||||||
|
border-radius: var(--roundness);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
Loading…
Reference in a new issue