optimizations, WIP theme selector

This commit is contained in:
Henry Jameson 2024-07-17 17:19:57 +03:00
commit 40c9163d21
12 changed files with 361 additions and 158 deletions

View file

@ -6,6 +6,18 @@ import UnitSetting, { defaultHorizontalUnits } from '../helpers/unit_setting.vue
import FontControl from 'src/components/font_control/font_control.vue'
import { normalizeThemeData } from 'src/modules/interface'
import {
getThemes
} from 'src/services/style_setter/style_setter.js'
import { convertTheme2To3 } from 'src/services/theme_data/theme2_to_theme3.js'
import { init } from 'src/services/theme_data/theme_data_3.service.js'
import {
getCssRules,
getScopedVersion
} from 'src/services/theme_data/css_utils.js'
import SharedComputedObject from '../helpers/shared_computed_object.js'
import ProfileSettingIndicator from '../helpers/profile_setting_indicator.vue'
import { library } from '@fortawesome/fontawesome-svg-core'
@ -13,6 +25,8 @@ import {
faGlobe
} from '@fortawesome/free-solid-svg-icons'
import Preview from './theme_tab/preview.vue'
library.add(
faGlobe
)
@ -20,6 +34,7 @@ library.add(
const AppearanceTab = {
data () {
return {
availableStyles: [],
thirdColumnModeOptions: ['none', 'notifications', 'postform'].map(mode => ({
key: mode,
value: mode,
@ -44,7 +59,32 @@ const AppearanceTab = {
FloatSetting,
UnitSetting,
ProfileSettingIndicator,
FontControl
FontControl,
Preview
},
created () {
const self = this
getThemes()
.then((promises) => {
return Promise.all(
Object.entries(promises)
.map(([k, v]) => v.then(res => [k, res]))
)
})
.then(themes => themes.reduce((acc, [k, v]) => {
if (v) {
return {
...acc,
[k]: v
}
} else {
return acc
}
}, {}))
.then((themesComplete) => {
self.availableStyles = themesComplete
})
},
computed: {
horizontalUnits () {
@ -77,6 +117,25 @@ const AppearanceTab = {
}
},
...SharedComputedObject()
},
methods: {
previewTheme (input) {
const style = normalizeThemeData(input)
const x = 2
if (x === 1) return
const theme2 = convertTheme2To3(style)
const theme3 = init({
inputRuleset: theme2,
ultimateBackgroundColor: '#000000',
liteMode: true,
onlyNormalState: true
})
return getScopedVersion(
getCssRules(theme3.eager),
'#theme-preview-' + (input.name || input[0]).replace(/ /g, '_')
).join('\n')
}
}
}

View file

@ -1,5 +1,21 @@
<template>
<div :label="$t('settings.general')">
<div class="setting-item">
<h2>{{ $t('settings.theme') }}</h2>
<ul class="theme-list">
<li
v-for="style in availableStyles"
:key="style.name || style[0]"
class="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)"/>
<!-- eslint-enable vue/no-v-text-v-html-on-component -->
<preview :id="'theme-preview-' + (style[0] || style.name).replace(/ /g,'_')"/>
</li>
</ul>
</div>
<div class="setting-item">
<h2>{{ $t('settings.scale_and_layout') }}</h2>
<ul class="setting-list">
@ -231,4 +247,18 @@
margin-bottom: 0.5em;
margin-top: 0.5em;
}
.theme-list {
list-style: none;
display: flex;
flex-wrap: wrap;
}
.theme-preview {
width: 10rem;
.preview-container {
zoom: 0.33;
}
}
</style>

View file

@ -139,6 +139,108 @@ export default {}
<style lang="scss">
.preview-container {
position: relative;
border-top: 1px dashed;
border-bottom: 1px dashed;
border-color: var(--border);
margin: 1em 0;
padding: 1em;
background-color: var(--wallpaper);
background-image: var(--body-background-image);
background-size: cover;
background-position: 50% 50%;
.theme-preview-content {
padding: 20px;
}
.dummy {
.post {
font-family: var(--postFont);
display: flex;
.content {
flex: 1;
h4 {
margin-bottom: 0.25em;
}
.icons {
margin-top: 0.5em;
display: flex;
i {
margin-right: 1em;
}
}
}
}
.after-post {
margin-top: 1em;
display: flex;
align-items: center;
}
.avatar,
.avatar-alt {
background:
linear-gradient(
135deg,
#b8e1fc 0%,
#a9d2f3 10%,
#90bae4 25%,
#90bcea 37%,
#90bff0 50%,
#6ba8e5 51%,
#a2daf5 83%,
#bdf3fd 100%
);
color: black;
font-family: sans-serif;
text-align: center;
margin-right: 1em;
}
.avatar-alt {
flex: 0 auto;
margin-left: 28px;
font-size: 12px;
min-width: 20px;
min-height: 20px;
line-height: 20px;
}
.avatar {
flex: 0 auto;
width: 48px;
height: 48px;
font-size: 14px;
line-height: 48px;
}
.actions {
display: flex;
align-items: baseline;
.checkbox {
display: inline-flex;
align-items: baseline;
margin-right: 1em;
flex: 1;
}
}
.separator {
margin: 1em;
border-bottom: 1px solid;
border-color: var(--border);
}
.btn {
min-width: 3em;
}
}
}
.underlay-preview {
@ -148,4 +250,4 @@ export default {}
left: 10px;
right: 10px;
}
</style>
</style>

View file

@ -30,7 +30,10 @@ import {
import { convertTheme2To3 } from 'src/services/theme_data/theme2_to_theme3.js'
import { init } from 'src/services/theme_data/theme_data_3.service.js'
import { getCssRules } from 'src/services/theme_data/css_utils.js'
import {
getCssRules,
getScopedVersion
} from 'src/services/theme_data/css_utils.js'
import ColorInput from 'src/components/color_input/color_input.vue'
import RangeInput from 'src/components/range_input/range_input.vue'
@ -703,17 +706,10 @@ export default {
liteMode: true
})
this.themeV3Preview = getCssRules(theme3.eager)
.map(x => {
if (x.startsWith('html')) {
return x.replace('html', '#theme-preview')
} else if (x.startsWith('#content')) {
return x.replace('#content', '#theme-preview')
} else {
return '#theme-preview > ' + x
}
})
.join('\n')
this.themeV3Preview = getScopedVersion(
getCssRules(theme3.eager),
'#theme-preview'
).join('\n')
}
},
watch: {

View file

@ -161,107 +161,6 @@
}
}
.preview-container {
border-top: 1px dashed;
border-bottom: 1px dashed;
border-color: var(--border);
margin: 1em 0;
padding: 1em;
background-color: var(--wallpaper);
background-image: var(--body-background-image);
background-size: cover;
background-position: 50% 50%;
.dummy {
.post {
font-family: var(--postFont);
display: flex;
.content {
flex: 1;
h4 {
margin-bottom: 0.25em;
}
.icons {
margin-top: 0.5em;
display: flex;
i {
margin-right: 1em;
}
}
}
}
.after-post {
margin-top: 1em;
display: flex;
align-items: center;
}
.avatar,
.avatar-alt {
background:
linear-gradient(
135deg,
#b8e1fc 0%,
#a9d2f3 10%,
#90bae4 25%,
#90bcea 37%,
#90bff0 50%,
#6ba8e5 51%,
#a2daf5 83%,
#bdf3fd 100%
);
color: black;
font-family: sans-serif;
text-align: center;
margin-right: 1em;
}
.avatar-alt {
flex: 0 auto;
margin-left: 28px;
font-size: 12px;
min-width: 20px;
min-height: 20px;
line-height: 20px;
}
.avatar {
flex: 0 auto;
width: 48px;
height: 48px;
font-size: 14px;
line-height: 48px;
}
.actions {
display: flex;
align-items: baseline;
.checkbox {
display: inline-flex;
align-items: baseline;
margin-right: 1em;
flex: 1;
}
}
.separator {
margin: 1em;
border-bottom: 1px solid;
border-color: var(--border);
}
.btn {
min-width: 3em;
}
}
}
.radius-item {
flex-basis: auto;
}
@ -314,10 +213,6 @@
max-width: 50em;
}
.theme-preview-content {
padding: 20px;
}
.theme-warning {
display: flex;
align-items: baseline;