commit: 9bbdad1a6f4c3d52569f4c58c04dace95d9a6bb3
parent 1866dcfdc206d7aa0d09ccefe05333db67f4a4d4
Author: Henry Jameson <me@hjkos.com>
Date: Wed, 17 Jul 2024 19:58:04 +0300
theme selector new
Diffstat:
2 files changed, 80 insertions(+), 23 deletions(-)
diff --git a/src/components/settings_modal/tabs/appearance_tab.js b/src/components/settings_modal/tabs/appearance_tab.js
@@ -35,6 +35,7 @@ const AppearanceTab = {
data () {
return {
availableStyles: [],
+ intersectionObserver: null,
thirdColumnModeOptions: ['none', 'notifications', 'postform'].map(mode => ({
key: mode,
value: mode,
@@ -62,9 +63,7 @@ const AppearanceTab = {
FontControl,
Preview
},
- created () {
- const self = this
-
+ mounted () {
getThemes()
.then((promises) => {
return Promise.all(
@@ -74,19 +73,48 @@ const AppearanceTab = {
})
.then(themes => themes.reduce((acc, [k, v]) => {
if (v) {
- return {
+ return [
...acc,
- [k]: v
- }
+ {
+ name: v.name || v[0],
+ key: k,
+ data: v
+ }
+ ]
} else {
return acc
}
- }, {}))
+ }, []))
.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: {
+ noIntersectionObserver () {
+ return !window.IntersectionObserver
+ },
horizontalUnits () {
return defaultHorizontalUnits
},
@@ -119,7 +147,12 @@ const AppearanceTab = {
...SharedComputedObject()
},
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 x = 2
if (x === 1) return
@@ -128,12 +161,13 @@ const AppearanceTab = {
inputRuleset: theme2,
ultimateBackgroundColor: '#000000',
liteMode: true,
+ debug: true,
onlyNormalState: true
})
return getScopedVersion(
getCssRules(theme3.eager),
- '#theme-preview-' + (input.name || input[0]).replace(/ /g, '_')
+ '#theme-preview-' + key
).join('\n')
}
}
diff --git a/src/components/settings_modal/tabs/appearance_tab.vue b/src/components/settings_modal/tabs/appearance_tab.vue
@@ -2,18 +2,26 @@
<div :label="$t('settings.general')">
<div class="setting-item">
<h2>{{ $t('settings.theme') }}</h2>
- <ul class="theme-list">
- <li
+ <ul
+ class="input theme-list"
+ ref="themeList"
+ >
+ <button
v-for="style in availableStyles"
- :key="style.name || style[0]"
- class="theme-preview"
+ :data-theme-key="style.key"
+ :key="style.key"
+ class="button-default theme-preview"
>
- <h6>{{ style[0] || style.name }}</h6>
<!-- 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 -->
- <preview :id="'theme-preview-' + (style[0] || style.name).replace(/ /g,'_')"/>
- </li>
+ <preview :class="{ placeholder: ready }" :id="'theme-preview-' + style.key"/>
+ <h4 class="theme-name">{{ style.name }}</h4>
+ </button>
</ul>
</div>
<div class="setting-item">
@@ -252,13 +260,28 @@
list-style: none;
display: flex;
flex-wrap: wrap;
-}
+ margin: 0 -0.5em;
+ height: 15em;
+ overflow-x: hidden;
+ overflow-y: auto;
+ scrollbar-gutter: stable;
+
+ .theme-preview {
+ width: 21rem;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ margin: 0.5em;
-.theme-preview {
- width: 10rem;
+ &.placeholder {
+ opacity: 0.2;
+ }
- .preview-container {
- zoom: 0.33;
+ .preview-container {
+ zoom: 0.5;
+ border: none;
+ border-radius: var(--roundness);
+ }
}
}
</style>