mirror of
https://git.pleroma.social/sjw/pleroma-fe.git
synced 2024-12-22 19:30:37 +01:00
MASSIVELY streamlined theme setting process, now EVERYTHING happens in a vuex action "setTheme" instead of several different applyTheme()s scattered around
This commit is contained in:
parent
8a41313bb4
commit
c6ccab778f
@ -13,8 +13,7 @@ import VBodyScrollLock from 'src/directives/body_scroll_lock'
|
||||
import { windowWidth, windowHeight } from '../services/window_utils/window_utils'
|
||||
import { getOrCreateApp, getClientToken } from '../services/new_api/oauth.js'
|
||||
import backendInteractorService from '../services/backend_interactor_service/backend_interactor_service.js'
|
||||
import { CURRENT_VERSION } from '../services/theme_data/theme_data.service.js'
|
||||
import { applyTheme, applyConfig, tryLoadCache } from '../services/style_setter/style_setter.js'
|
||||
import { applyConfig } from '../services/style_setter/style_setter.js'
|
||||
import FaviconService from '../services/favicon_service/favicon_service.js'
|
||||
import { initServiceWorker, updateFocus } from '../services/sw/sw.js'
|
||||
|
||||
@ -160,8 +159,6 @@ const setSettings = async ({ apiConfig, staticConfig, store }) => {
|
||||
copyInstanceOption('showFeaturesPanel')
|
||||
copyInstanceOption('hideSitename')
|
||||
copyInstanceOption('sidebarRight')
|
||||
|
||||
return store.dispatch('setTheme', config.theme)
|
||||
}
|
||||
|
||||
const getTOS = async ({ store }) => {
|
||||
@ -352,29 +349,7 @@ const afterStoreSetup = async ({ store, i18n }) => {
|
||||
store.dispatch('setInstanceOption', { name: 'server', value: server })
|
||||
|
||||
await setConfig({ store })
|
||||
|
||||
const { customTheme, customThemeSource, forceThemeRecompilation, themeDebug } = store.state.config
|
||||
const { theme } = store.state.instance
|
||||
const customThemePresent = customThemeSource || customTheme
|
||||
|
||||
console.log('DEBUG INITIAL', themeDebug, forceThemeRecompilation)
|
||||
|
||||
if (!forceThemeRecompilation && !themeDebug && tryLoadCache()) {
|
||||
store.commit('setThemeApplied')
|
||||
} else {
|
||||
if (customThemePresent) {
|
||||
if (customThemeSource && customThemeSource.themeEngineVersion === CURRENT_VERSION) {
|
||||
applyTheme(customThemeSource, () => {}, themeDebug)
|
||||
} else {
|
||||
applyTheme(customTheme, () => {}, themeDebug)
|
||||
}
|
||||
store.commit('setThemeApplied')
|
||||
} else if (theme) {
|
||||
// do nothing, it will load asynchronously
|
||||
} else {
|
||||
console.error('Failed to load any theme!')
|
||||
}
|
||||
}
|
||||
await store.dispatch('setTheme')
|
||||
|
||||
applyConfig(store.state.config)
|
||||
|
||||
|
@ -29,6 +29,11 @@ const AppearanceTab = {
|
||||
key: mode,
|
||||
value: i - 1,
|
||||
label: this.$t(`settings.forced_roundness_mode_${mode}`)
|
||||
})),
|
||||
underlayOverrideModes: ['none', 'opaque', 'transparent'].map((mode, i) => ({
|
||||
key: mode,
|
||||
value: mode,
|
||||
label: this.$t(`settings.underlay_override_mode_${mode}`)
|
||||
}))
|
||||
}
|
||||
},
|
||||
|
@ -182,6 +182,15 @@
|
||||
{{ $t('settings.force_interface_roundness') }}
|
||||
</ChoiceSetting>
|
||||
</li>
|
||||
<li>
|
||||
<ChoiceSetting
|
||||
id="underlayOverride"
|
||||
path="theme3hacks.underlay"
|
||||
:options="underlayOverrideModes"
|
||||
>
|
||||
{{ $t('settings.underlay_overrides') }}
|
||||
</ChoiceSetting>
|
||||
</li>
|
||||
<li v-if="instanceWallpaperUsed">
|
||||
<BooleanSetting path="hideInstanceWallpaper">
|
||||
{{ $t('settings.hide_wallpaper') }}
|
||||
|
@ -502,6 +502,7 @@ export default {
|
||||
this.$store.dispatch('setOption', {
|
||||
name: 'customTheme',
|
||||
value: {
|
||||
ignore: true,
|
||||
themeFileVersion: this.selectedVersion,
|
||||
themeEngineVersion: CURRENT_VERSION,
|
||||
...this.previewTheme
|
||||
@ -699,13 +700,13 @@ export default {
|
||||
}
|
||||
},
|
||||
updateTheme3Preview () {
|
||||
console.log(this.previewTheme)
|
||||
const theme2 = convertTheme2To3(this.previewTheme)
|
||||
const theme3 = init({
|
||||
extraRuleset: theme2,
|
||||
inputRuleset: theme2,
|
||||
ultimateBackgroundColor: '#000000',
|
||||
liteMode: true
|
||||
})
|
||||
|
||||
this.themeV3Preview = getCssRules(theme3.eager)
|
||||
.map(x => {
|
||||
if (x.startsWith('html')) {
|
||||
@ -722,7 +723,7 @@ export default {
|
||||
watch: {
|
||||
currentRadii () {
|
||||
try {
|
||||
this.previewTheme.radii = generateRadii({ radii: this.currentRadii }).theme
|
||||
this.previewTheme.radii = generateRadii({ radii: this.currentRadii }).theme.radii
|
||||
this.radiiInvalid = false
|
||||
} catch (e) {
|
||||
this.radiiInvalid = true
|
||||
@ -744,7 +745,7 @@ export default {
|
||||
fontsLocal: {
|
||||
handler () {
|
||||
try {
|
||||
this.previewTheme.fonts = generateFonts({ fonts: this.fontsLocal }).theme
|
||||
this.previewTheme.fonts = generateFonts({ fonts: this.fontsLocal }).theme.fonts
|
||||
this.fontsInvalid = false
|
||||
} catch (e) {
|
||||
this.fontsInvalid = true
|
||||
|
@ -1,10 +1,21 @@
|
||||
import Cookies from 'js-cookie'
|
||||
import { setPreset, applyTheme, applyConfig } from '../services/style_setter/style_setter.js'
|
||||
import { applyConfig } from '../services/style_setter/style_setter.js'
|
||||
import messages from '../i18n/messages'
|
||||
import { set } from 'lodash'
|
||||
import localeService from '../services/locale/locale.service.js'
|
||||
|
||||
const BACKEND_LANGUAGE_COOKIE_NAME = 'userLanguage'
|
||||
const APPEARANCE_SETTINGS_KEYS = new Set([
|
||||
'sidebarColumnWidth',
|
||||
'contentColumnWidth',
|
||||
'notifsColumnWidth',
|
||||
'textSize',
|
||||
'navbarSize',
|
||||
'panelHeaderSize',
|
||||
'forcedRoundness',
|
||||
'emojiSize',
|
||||
'emojiReactionsScale'
|
||||
])
|
||||
|
||||
const browserLocale = (window.navigator.language || 'en').split('-')[0]
|
||||
|
||||
@ -81,6 +92,11 @@ export const defaultState = {
|
||||
chatMention: true,
|
||||
polls: true
|
||||
},
|
||||
palette: null,
|
||||
theme3hacks: {
|
||||
underlay: 'none',
|
||||
badgeColor: null
|
||||
},
|
||||
webPushNotifications: false,
|
||||
webPushAlwaysShowNotifications: false,
|
||||
muteWords: [],
|
||||
@ -185,7 +201,6 @@ const config = {
|
||||
applyConfig(state)
|
||||
},
|
||||
setOption (state, { name, value }) {
|
||||
console.log('SET OPTION', state, name, value)
|
||||
set(state, name, value)
|
||||
},
|
||||
setHighlight (state, { user, color, type }) {
|
||||
@ -261,30 +276,23 @@ const config = {
|
||||
}
|
||||
} else {
|
||||
commit('setOption', { name, value })
|
||||
if (
|
||||
name.startsWith('theme3hacks') ||
|
||||
APPEARANCE_SETTINGS_KEYS.has(name)
|
||||
) {
|
||||
applyConfig(state)
|
||||
}
|
||||
switch (name) {
|
||||
case 'theme':
|
||||
setPreset(value)
|
||||
break
|
||||
case 'sidebarColumnWidth':
|
||||
case 'contentColumnWidth':
|
||||
case 'notifsColumnWidth':
|
||||
case 'textSize':
|
||||
case 'navbarSize':
|
||||
case 'panelHeaderSize':
|
||||
case 'forcedRoundness':
|
||||
case 'emojiSize':
|
||||
case 'emojiReactionsScale':
|
||||
applyConfig(state)
|
||||
dispatch('setTheme', { themeName: value, recompile: true })
|
||||
break
|
||||
case 'customTheme':
|
||||
case 'customThemeSource': {
|
||||
const { themeDebug } = state
|
||||
applyTheme(value, () => {}, themeDebug)
|
||||
if (!value.ignore) dispatch('setTheme', { themeData: value })
|
||||
break
|
||||
}
|
||||
case 'themeDebug': {
|
||||
const { customTheme, customThemeSource } = state
|
||||
applyTheme(customTheme || customThemeSource, () => {}, value)
|
||||
dispatch('setTheme', { recompile: true })
|
||||
break
|
||||
}
|
||||
case 'interfaceLanguage':
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { getPreset, applyTheme } from '../services/style_setter/style_setter.js'
|
||||
import { CURRENT_VERSION } from '../services/theme_data/theme_data.service.js'
|
||||
import { getPreset, applyTheme, tryLoadCache } from '../services/style_setter/style_setter.js'
|
||||
import { CURRENT_VERSION, generatePreset } from 'src/services/theme_data/theme_data.service.js'
|
||||
import { convertTheme2To3 } from 'src/services/theme_data/theme2_to_theme3.js'
|
||||
import apiService from '../services/api/api.service.js'
|
||||
import { instanceDefaultProperties } from './config.js'
|
||||
import { langCodeToCldrName, ensureFinalFallback } from '../i18n/languages.js'
|
||||
@ -286,9 +287,6 @@ const instance = {
|
||||
dispatch('initializeSocket')
|
||||
}
|
||||
break
|
||||
case 'theme':
|
||||
dispatch('setTheme', value)
|
||||
break
|
||||
}
|
||||
},
|
||||
async getStaticEmoji ({ commit }) {
|
||||
@ -378,25 +376,86 @@ const instance = {
|
||||
}
|
||||
},
|
||||
|
||||
setTheme ({ commit, rootState }, themeName) {
|
||||
commit('setInstanceOption', { name: 'theme', value: themeName })
|
||||
getPreset(themeName)
|
||||
.then(themeData => {
|
||||
commit('setInstanceOption', { name: 'themeData', value: themeData })
|
||||
// No need to apply theme if there's user theme already
|
||||
const { customTheme, themeDebug } = rootState.config
|
||||
const { themeApplied } = rootState.interface
|
||||
if (customTheme || themeApplied) return
|
||||
setTheme ({ commit, state, rootState }, { themeName, themeData, recompile } = {}) {
|
||||
// const {
|
||||
// themeApplied
|
||||
// } = rootState.interface
|
||||
const {
|
||||
theme: instanceThemeName
|
||||
} = state
|
||||
|
||||
// New theme presets don't have 'theme' property, they use 'source'
|
||||
const themeSource = themeData.source
|
||||
if (!themeData.theme || (themeSource && themeSource.themeEngineVersion === CURRENT_VERSION)) {
|
||||
applyTheme(themeSource, null, themeDebug)
|
||||
const {
|
||||
customTheme: userThemeSnapshot,
|
||||
customThemeSource: userThemeSource,
|
||||
forceThemeRecompilation,
|
||||
themeDebug
|
||||
} = rootState.config
|
||||
|
||||
const forceRecompile = forceThemeRecompilation || recompile
|
||||
|
||||
// If we're not not forced to recompile try using
|
||||
// cache (tryLoadCache return true if load successful)
|
||||
if (!forceRecompile && !themeDebug && tryLoadCache()) {
|
||||
commit('setThemeApplied')
|
||||
}
|
||||
|
||||
const normalizeThemeData = (themeData) => {
|
||||
console.log('NORMAL', themeData)
|
||||
if (themeData.themeFileVerison === 1) {
|
||||
return generatePreset(themeData).theme
|
||||
}
|
||||
// New theme presets don't have 'theme' property, they use 'source'
|
||||
const themeSource = themeData.source
|
||||
|
||||
let out // shout, shout let it all out
|
||||
if (!themeData.theme || (themeSource && themeSource.themeEngineVersion === CURRENT_VERSION)) {
|
||||
out = themeSource || themeData
|
||||
} else {
|
||||
out = themeData.theme
|
||||
}
|
||||
|
||||
// generatePreset here basically creates/updates "snapshot",
|
||||
// while also fixing the 2.2 -> 2.3 colors/shadows/etc
|
||||
return generatePreset(out).theme
|
||||
}
|
||||
|
||||
let promise = null
|
||||
|
||||
if (themeName) {
|
||||
// commit('setInstanceOption', { name: 'theme', value: themeName })
|
||||
promise = getPreset(themeName)
|
||||
.then(themeData => {
|
||||
// commit('setInstanceOption', { name: 'themeData', value: themeData })
|
||||
return normalizeThemeData(themeData)
|
||||
})
|
||||
} else if (themeData) {
|
||||
promise = Promise.resolve(normalizeThemeData(themeData))
|
||||
} else {
|
||||
if (userThemeSource || userThemeSnapshot) {
|
||||
if (userThemeSource && userThemeSource.themeEngineVersion === CURRENT_VERSION) {
|
||||
promise = Promise.resolve(normalizeThemeData(userThemeSource))
|
||||
} else {
|
||||
applyTheme(themeData.theme, null, themeDebug)
|
||||
promise = Promise.resolve(normalizeThemeData(userThemeSnapshot))
|
||||
}
|
||||
commit('setThemeApplied')
|
||||
} else if (instanceThemeName) {
|
||||
promise = getPreset(themeName).then(themeData => normalizeThemeData(themeData))
|
||||
}
|
||||
}
|
||||
|
||||
promise
|
||||
.then(realThemeData => {
|
||||
console.log('FR FR 1', realThemeData)
|
||||
const ruleset = convertTheme2To3(realThemeData)
|
||||
console.log('FR FR 2', ruleset)
|
||||
|
||||
applyTheme(
|
||||
ruleset,
|
||||
() => commit('setThemeApplied'),
|
||||
themeDebug
|
||||
)
|
||||
})
|
||||
|
||||
return promise
|
||||
},
|
||||
fetchEmoji ({ dispatch, state }) {
|
||||
if (!state.customEmojiFetched) {
|
||||
|
@ -1,7 +1,5 @@
|
||||
import { hex2rgb } from '../color_convert/color_convert.js'
|
||||
import { generatePreset } from '../theme_data/theme_data.service.js'
|
||||
import { init, getEngineChecksum } from '../theme_data/theme_data_3.service.js'
|
||||
import { convertTheme2To3 } from '../theme_data/theme2_to_theme3.js'
|
||||
import { getCssRules } from '../theme_data/css_utils.js'
|
||||
import { defaultState } from '../../modules/config.js'
|
||||
import { chunk } from 'lodash'
|
||||
@ -45,30 +43,20 @@ const adoptStyleSheets = (styles) => {
|
||||
// is nothing to do here.
|
||||
}
|
||||
|
||||
export const generateTheme = async (input, callbacks, debug) => {
|
||||
export const generateTheme = async (inputRuleset, callbacks, debug) => {
|
||||
const {
|
||||
onNewRule = (rule, isLazy) => {},
|
||||
onLazyFinished = () => {},
|
||||
onEagerFinished = () => {}
|
||||
} = callbacks
|
||||
|
||||
let extraRules
|
||||
if (input.themeFileVersion === 1) {
|
||||
extraRules = convertTheme2To3(input)
|
||||
} else {
|
||||
const { theme } = generatePreset(input)
|
||||
extraRules = convertTheme2To3(theme)
|
||||
}
|
||||
|
||||
// Assuming that "worst case scenario background" is panel background since it's the most likely one
|
||||
const themes3 = init({
|
||||
extraRules,
|
||||
ultimateBackgroundColor: extraRules[0].directives['--bg'].split('|')[1].trim(),
|
||||
inputRuleset,
|
||||
ultimateBackgroundColor: inputRuleset[0].directives['--bg'].split('|')[1].trim(),
|
||||
debug
|
||||
})
|
||||
|
||||
console.log('DEBUG 2 IS', debug)
|
||||
|
||||
getCssRules(themes3.eager, debug).forEach(rule => {
|
||||
// Hacks to support multiple selectors on same component
|
||||
if (rule.match(/::-webkit-scrollbar-button/)) {
|
||||
@ -162,8 +150,6 @@ export const applyTheme = async (input, onFinish = (data) => {}, debug) => {
|
||||
const eagerStyles = createStyleSheet(EAGER_STYLE_ID)
|
||||
const lazyStyles = createStyleSheet(LAZY_STYLE_ID)
|
||||
|
||||
console.log('DEBUG IS', debug)
|
||||
|
||||
const { lazyProcessFunc } = await generateTheme(
|
||||
input,
|
||||
{
|
||||
@ -216,7 +202,6 @@ const extractStyleConfig = ({
|
||||
textSize
|
||||
}
|
||||
|
||||
console.log(forcedRoundness)
|
||||
switch (forcedRoundness) {
|
||||
case 'disable':
|
||||
break
|
||||
@ -325,5 +310,3 @@ export const getPreset = (val) => {
|
||||
return { theme: data, source: theme.source }
|
||||
})
|
||||
}
|
||||
|
||||
export const setPreset = (val) => getPreset(val).then(data => applyTheme(data))
|
||||
|
@ -265,6 +265,7 @@ export const convertTheme2To3 = (data) => {
|
||||
const newRules = []
|
||||
Object.keys(data.fonts || {}).forEach(key => {
|
||||
if (!fontsKeys.has(key)) return
|
||||
if (!data.fonts[key]) return
|
||||
const originalFont = data.fonts[key].family
|
||||
const rule = { source: '2to3' }
|
||||
|
||||
|
@ -150,12 +150,13 @@ const ruleToSelector = genericRuleToSelector(components)
|
||||
export const getEngineChecksum = () => engineChecksum
|
||||
|
||||
export const init = ({
|
||||
extraRuleset,
|
||||
inputRuleset,
|
||||
ultimateBackgroundColor,
|
||||
debug = false,
|
||||
liteMode = false,
|
||||
rootComponentName = 'Root'
|
||||
}) => {
|
||||
if (!inputRuleset) throw new Error('Ruleset is null or undefined!')
|
||||
const staticVars = {}
|
||||
const stacked = {}
|
||||
const computed = {}
|
||||
@ -164,7 +165,7 @@ export const init = ({
|
||||
...Object.values(components)
|
||||
.map(c => (c.defaultRules || []).map(r => ({ component: c.name, ...r, source: 'Built-in' })))
|
||||
.reduce((acc, arr) => [...acc, ...arr], []),
|
||||
...extraRuleset
|
||||
...inputRuleset
|
||||
].map(rule => {
|
||||
normalizeCombination(rule)
|
||||
let currentParent = rule.parent
|
||||
|
@ -66,7 +66,7 @@ describe('Theme Data 3', () => {
|
||||
this.timeout(5000)
|
||||
|
||||
it('Test initialization without anything', () => {
|
||||
const out = init([], '#DEADAF')
|
||||
const out = init({ ruleset: [], ultimateBackgroundColor: '#DEADAF' })
|
||||
|
||||
expect(out).to.have.property('eager')
|
||||
expect(out).to.have.property('lazy')
|
||||
@ -85,13 +85,16 @@ describe('Theme Data 3', () => {
|
||||
})
|
||||
|
||||
it('Test initialization with a basic palette', () => {
|
||||
const out = init([{
|
||||
component: 'Root',
|
||||
directives: {
|
||||
'--bg': 'color | #008080',
|
||||
'--fg': 'color | #00C0A0'
|
||||
}
|
||||
}], '#DEADAF')
|
||||
const out = init({
|
||||
ruleset: [{
|
||||
component: 'Root',
|
||||
directives: {
|
||||
'--bg': 'color | #008080',
|
||||
'--fg': 'color | #00C0A0'
|
||||
}
|
||||
}],
|
||||
ultimateBackgroundColor: '#DEADAF'
|
||||
})
|
||||
|
||||
expect(out.staticVars).to.have.property('bg').equal('#008080')
|
||||
expect(out.staticVars).to.have.property('fg').equal('#00C0A0')
|
||||
@ -105,17 +108,20 @@ describe('Theme Data 3', () => {
|
||||
})
|
||||
|
||||
it('Test initialization with opacity', () => {
|
||||
const out = init([{
|
||||
component: 'Root',
|
||||
directives: {
|
||||
'--bg': 'color | #008080'
|
||||
}
|
||||
}, {
|
||||
component: 'Panel',
|
||||
directives: {
|
||||
opacity: 0.5
|
||||
}
|
||||
}], '#DEADAF')
|
||||
const out = init({
|
||||
ruleset: [{
|
||||
component: 'Root',
|
||||
directives: {
|
||||
'--bg': 'color | #008080'
|
||||
}
|
||||
}, {
|
||||
component: 'Panel',
|
||||
directives: {
|
||||
opacity: 0.5
|
||||
}
|
||||
}],
|
||||
ultimateBackgroundColor: '#DEADAF'
|
||||
})
|
||||
|
||||
expect(out.staticVars).to.have.property('bg').equal('#008080')
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user