new theme selector, RC

appearance-tab
Henry Jameson 2 months ago
parent 9bbdad1a6f
commit d2683a6728

@ -95,7 +95,7 @@ const AppearanceTab = {
if (!isIntersecting) return if (!isIntersecting) return
const theme = this.availableStyles.find(x => x.key === target.dataset.themeKey) const theme = this.availableStyles.find(x => x.key === target.dataset.themeKey)
this.$nextTick(() => { this.$nextTick(() => {
theme.ready = true if (theme) theme.ready = true
}) })
observer.unobserve(target) observer.unobserve(target)
}) })
@ -144,13 +144,20 @@ const AppearanceTab = {
this.$store.dispatch('setOption', { name: 'interfaceLanguage', value: val }) this.$store.dispatch('setOption', { name: 'interfaceLanguage', value: val })
} }
}, },
isCustomThemeUsed () {
const { theme } = this.mergedConfig
return theme === 'custom' || theme === null
},
...SharedComputedObject() ...SharedComputedObject()
}, },
methods: { methods: {
isThemeActive (key, name) { isThemeActive (key) {
console.log(this.$store.getters.mergedConfig) const { theme } = this.mergedConfig
const { customTheme, themeName, customThemeSource } = this.$store.getters.mergedConfig console.log(key, theme)
console.log(customTheme, customThemeSource, themeName) return key === theme
},
setTheme (name) {
this.$store.dispatch('setTheme', { themeName: name, saveData: true, recompile: true })
}, },
previewTheme (key, input) { previewTheme (key, input) {
const style = normalizeThemeData(input) const style = normalizeThemeData(input)

@ -3,14 +3,24 @@
<div class="setting-item"> <div class="setting-item">
<h2>{{ $t('settings.theme') }}</h2> <h2>{{ $t('settings.theme') }}</h2>
<ul <ul
class="input theme-list" class="theme-list"
ref="themeList" ref="themeList"
> >
<button
v-if="isCustomThemeUsed"
disabled
class="button-default theme-preview"
>
<preview />
<h4 class="theme-name">{{ $t('settings.style.custom_theme_used') }}</h4>
</button>
<button <button
v-for="style in availableStyles" v-for="style in availableStyles"
:data-theme-key="style.key" :data-theme-key="style.key"
:key="style.key" :key="style.key"
class="button-default theme-preview" class="button-default theme-preview"
:class="{ toggled: isThemeActive(style.key) }"
@click="setTheme(style.key)"
> >
<!-- eslint-disable vue/no-v-text-v-html-on-component --> <!-- eslint-disable vue/no-v-text-v-html-on-component -->
<component <component
@ -260,14 +270,17 @@
list-style: none; list-style: none;
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
margin: 0 -0.5em; margin: -0.5em 0;
height: 15em; height: 25em;
overflow-x: hidden; overflow-x: hidden;
overflow-y: auto; overflow-y: auto;
scrollbar-gutter: stable; scrollbar-gutter: stable;
border-radius: var(--roundness);
border: 1px solid var(--border);
padding: 0;
.theme-preview { .theme-preview {
width: 21rem; width: 19rem;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
@ -278,9 +291,11 @@
} }
.preview-container { .preview-container {
pointer-events: none;
zoom: 0.5; zoom: 0.5;
border: none; border: none;
border-radius: var(--roundness); border-radius: var(--roundness);
text-align: left;
} }
} }
} }

@ -606,7 +606,7 @@ export default {
normalizeLocalState (theme, version = 0, source, forceSource = false) { normalizeLocalState (theme, version = 0, source, forceSource = false) {
let input let input
if (typeof source !== 'undefined') { if (typeof source !== 'undefined') {
if (forceSource || source.themeEngineVersion === CURRENT_VERSION) { if (forceSource || source?.themeEngineVersion === CURRENT_VERSION) {
input = source input = source
version = source.themeEngineVersion version = source.themeEngineVersion
} else { } else {

@ -740,6 +740,7 @@
"enable_web_push_always_show_tip": "Some browsers (Chromium, Chrome) require that push messages always result in a notification, otherwise generic 'Website was updated in background' is shown, enable this to prevent this notification from showing, as Chrome seem to hide push notifications if tab is in focus. Can result in showing duplicate notifications on other browsers.", "enable_web_push_always_show_tip": "Some browsers (Chromium, Chrome) require that push messages always result in a notification, otherwise generic 'Website was updated in background' is shown, enable this to prevent this notification from showing, as Chrome seem to hide push notifications if tab is in focus. Can result in showing duplicate notifications on other browsers.",
"more_settings": "More settings", "more_settings": "More settings",
"style": { "style": {
"custom_theme_used": "(Custom theme)",
"themes2_outdated": "Editor for Themes V2 is no longer supported and presented here for sake of legacy.", "themes2_outdated": "Editor for Themes V2 is no longer supported and presented here for sake of legacy.",
"update_preview": "Update preview", "update_preview": "Update preview",
"themes3": { "themes3": {

@ -35,11 +35,26 @@ export const multiChoiceProperties = [
export const defaultState = { export const defaultState = {
expertLevel: 0, // used to track which settings to show and hide expertLevel: 0, // used to track which settings to show and hide
colors: {},
theme: undefined, // Theme stuff
customTheme: undefined, theme: undefined, // Very old theme store, stores preset name, still in use
customThemeSource: undefined,
forceThemeRecompilation: false, // V1
colors: {}, // VERY old theme store, just colors of V1, probably not even used anymore
// V2
customTheme: undefined, // "snapshot", previously was used as actual theme store for V2 so it's still used in case of PleromaFE downgrade event.
customThemeSource: undefined, // "source", stores original theme data
// V3
themeDebug: false, // debug mode that uses computed backgrounds instead of real ones to debug contrast functions
forceThemeRecompilation: false, // flag that forces recompilation on boot even if cache exists
palette: null, // not used yet, will be used for V3
theme3hacks: { // Hacks, user overrides that are independent of theme used
underlay: 'none',
badgeColor: null
},
hideISP: false, hideISP: false,
hideInstanceWallpaper: false, hideInstanceWallpaper: false,
hideShoutbox: false, hideShoutbox: false,
@ -92,11 +107,6 @@ export const defaultState = {
chatMention: true, chatMention: true,
polls: true polls: true
}, },
palette: null,
theme3hacks: {
underlay: 'none',
badgeColor: null
},
webPushNotifications: false, webPushNotifications: false,
webPushAlwaysShowNotifications: false, webPushAlwaysShowNotifications: false,
muteWords: [], muteWords: [],
@ -164,7 +174,6 @@ export const defaultState = {
maxDepthInThread: undefined, // instance default maxDepthInThread: undefined, // instance default
autocompleteSelect: undefined, // instance default autocompleteSelect: undefined, // instance default
closingDrawerMarksAsSeen: undefined, // instance default closingDrawerMarksAsSeen: undefined, // instance default
themeDebug: false,
unseenAtTop: undefined, // instance default unseenAtTop: undefined, // instance default
ignoreInactionableSeen: undefined // instance default ignoreInactionableSeen: undefined // instance default
} }
@ -256,6 +265,7 @@ const config = {
}) })
}, },
setThemeV2 ({ commit, dispatch }, { customTheme, customThemeSource }) { setThemeV2 ({ commit, dispatch }, { customTheme, customThemeSource }) {
commit('setOption', { name: 'theme', value: 'custom' })
commit('setOption', { name: 'customTheme', value: customTheme }) commit('setOption', { name: 'customTheme', value: customTheme })
commit('setOption', { name: 'customThemeSource', value: customThemeSource }) commit('setOption', { name: 'customThemeSource', value: customThemeSource })
dispatch('setTheme', { themeData: customThemeSource, recompile: true }) dispatch('setTheme', { themeData: customThemeSource, recompile: true })
@ -290,7 +300,8 @@ const config = {
} }
switch (name) { switch (name) {
case 'theme': case 'theme':
dispatch('setTheme', { themeName: value, recompile: true }) if (value === 'custom') break
dispatch('setTheme', { themeName: value, recompile: true, saveData: true })
break break
case 'themeDebug': { case 'themeDebug': {
dispatch('setTheme', { recompile: true }) dispatch('setTheme', { recompile: true })

@ -212,12 +212,13 @@ const interfaceMod = {
setLastTimeline ({ commit }, value) { setLastTimeline ({ commit }, value) {
commit('setLastTimeline', value) commit('setLastTimeline', value)
}, },
setTheme ({ commit, rootState }, { themeName, themeData, recompile } = {}) { setTheme ({ commit, rootState }, { themeName, themeData, recompile, saveData } = {}) {
const { const {
theme: instanceThemeName theme: instanceThemeName
} = rootState.instance } = rootState.instance
const { const {
theme: userThemeName,
customTheme: userThemeSnapshot, customTheme: userThemeSnapshot,
customThemeSource: userThemeSource, customThemeSource: userThemeSource,
forceThemeRecompilation, forceThemeRecompilation,
@ -225,6 +226,8 @@ const interfaceMod = {
theme3hacks theme3hacks
} = rootState.config } = rootState.config
const actualThemeName = userThemeName || instanceThemeName
const forceRecompile = forceThemeRecompilation || recompile const forceRecompile = forceThemeRecompilation || recompile
// If we're not not forced to recompile try using // If we're not not forced to recompile try using
@ -236,28 +239,31 @@ const interfaceMod = {
let promise = null let promise = null
if (themeName) { if (themeData) {
promise = getPreset(themeName)
.then(themeData => {
return normalizeThemeData(themeData)
})
} else if (themeData) {
promise = Promise.resolve(normalizeThemeData(themeData)) promise = Promise.resolve(normalizeThemeData(themeData))
} else { } else if (themeName) {
if (userThemeSource || userThemeSnapshot) { promise = getPreset(themeName).then(themeData => normalizeThemeData(themeData))
if (userThemeSource && userThemeSource.themeEngineVersion === CURRENT_VERSION) { } else if (userThemeSource || userThemeSnapshot) {
promise = Promise.resolve(normalizeThemeData(userThemeSource)) if (userThemeSource && userThemeSource.themeEngineVersion === CURRENT_VERSION) {
} else { promise = Promise.resolve(normalizeThemeData(userThemeSource))
promise = Promise.resolve(normalizeThemeData(userThemeSnapshot)) } else {
} promise = Promise.resolve(normalizeThemeData(userThemeSnapshot))
} else if (instanceThemeName) {
promise = getPreset(themeName).then(themeData => normalizeThemeData(themeData))
} }
} else if (actualThemeName && actualThemeName !== 'custom') {
promise = getPreset(actualThemeName).then(themeData => normalizeThemeData(themeData))
} else {
throw new Error('Cannot load any theme!')
} }
promise promise
.then(realThemeData => { .then(realThemeData => {
const theme2ruleset = convertTheme2To3(realThemeData) const theme2ruleset = convertTheme2To3(realThemeData)
if (saveData) {
commit('setOption', { name: 'theme', value: themeName || actualThemeName })
commit('setOption', { name: 'customTheme', value: realThemeData })
commit('setOption', { name: 'customThemeSource', value: realThemeData })
}
const hacks = [] const hacks = []
Object.entries(theme3hacks).forEach(([key, value]) => { Object.entries(theme3hacks).forEach(([key, value]) => {

Loading…
Cancel
Save