new theme selector, RC
This commit is contained in:
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…
Reference in a new issue