logo

pleroma-fe

My custom branche(s) on git.pleroma.social/pleroma/pleroma-fe git clone https://hacktivis.me/git/pleroma-fe.git
commit: 96e3a1593ab6b45b2b6794e353623d0e87a7d8ff
parent 34e4dd0a79cdc03976c4137969beb4259ecdf500
Author: Henry Jameson <me@hjkos.com>
Date:   Thu, 15 Feb 2024 20:20:27 +0200

more optimizations, execution is now split into eager (for main UI) and
lazy (for modals, popovers etc) parts

Diffstat:

Asrc/components/alert.style.js42++++++++++++++++++++++++++++++++++++++++++
Asrc/components/badge.style.js25+++++++++++++++++++++++++
Msrc/components/button.style.js22++--------------------
Msrc/components/button_unstyled.style.js3++-
Msrc/components/menu_item.style.js3++-
Msrc/components/modals.style.js1+
Msrc/components/panel.style.js3++-
Msrc/components/panel_header.style.js4+++-
Msrc/components/popover.style.js2+-
Msrc/components/top_bar.style.js3++-
Msrc/components/underlay.style.js3++-
Msrc/services/style_setter/style_setter.js10++++++++--
Msrc/services/theme_data/theme_data_3.service.js86+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------
13 files changed, 156 insertions(+), 51 deletions(-)

diff --git a/src/components/alert.style.js b/src/components/alert.style.js @@ -0,0 +1,42 @@ +export default { + name: 'Alert', + selector: '.alert', + validInnerComponents: [ + 'Text', + 'Icon', + 'Link', + 'Border' + ], + variants: { + normal: '.neutral', + error: '.error', + warning: '.warning', + success: '.success' + }, + defaultRules: [ + { + directives: { + background: '--text', + opacity: 0.8 + } + }, + { + variant: 'error', + directives: { + background: '--cRed' + } + }, + { + variant: 'warning', + directives: { + background: '--cOrange' + } + }, + { + variant: 'success', + directives: { + background: '--cGreen' + } + } + ] +} diff --git a/src/components/badge.style.js b/src/components/badge.style.js @@ -0,0 +1,25 @@ +export default { + name: 'Badge', + selector: '.badge', + validInnerComponents: [ + 'Text', + 'Icon' + ], + variants: { + normal: '.neutral', + notification: '.notification' + }, + defaultRules: [ + { + directives: { + background: '--cGreen' + } + }, + { + variant: 'notification', + directives: { + background: '--cRed' + } + } + ] +} diff --git a/src/components/button.style.js b/src/components/button.style.js @@ -38,11 +38,11 @@ export default { // All states inherit from "normal" state, there is no other inheirtance, i.e. hover+disabled only inherits from "normal", not from hover nor disabled. // However, cascading still works, so resulting state will be result of merging of all relevant states/variants // normal: '' // normal state is implicitly added, it is always included - disabled: ':disabled', toggled: '.toggled', pressed: ':active', hover: ':hover', - focused: ':focus-within' + focused: ':focus-within', + disabled: ':disabled' }, // Variants are mutually exclusive, each component implicitly has "normal" variant, and all other variants inherit from it. variants: { @@ -108,13 +108,6 @@ export default { } }, { - state: ['disabled', 'hover'], - directives: { - background: '$blend(--background, 0.25, --parent)', - shadow: [...buttonInsetFakeBorders] - } - }, - { component: 'Text', parent: { component: 'Button', @@ -124,17 +117,6 @@ export default { textOpacity: 0.25, textOpacityMode: 'blend' } - }, - { - component: 'Text', - parent: { - component: 'Button', - state: ['disabled', 'hover'] - }, - directives: { - textOpacity: 0.25, - textOpacityMode: 'blend' - } } ] } diff --git a/src/components/button_unstyled.style.js b/src/components/button_unstyled.style.js @@ -10,7 +10,8 @@ export default { }, validInnerComponents: [ 'Text', - 'Icon' + 'Icon', + 'Badge' ], defaultRules: [ { diff --git a/src/components/menu_item.style.js b/src/components/menu_item.style.js @@ -5,7 +5,8 @@ export default { 'Text', 'Icon', 'Input', - 'Border' + 'Border', + 'ButtonUnstyled' ], states: { hover: ':hover', diff --git a/src/components/modals.style.js b/src/components/modals.style.js @@ -1,6 +1,7 @@ export default { name: 'Modals', selector: '.modal-view', + lazy: true, validInnerComponents: [ 'Panel' ], diff --git a/src/components/panel.style.js b/src/components/panel.style.js @@ -11,7 +11,8 @@ export default { 'PanelHeader', 'MenuItem', 'Post', - 'Notification' + 'Notification', + 'Alert' ], defaultRules: [ { diff --git a/src/components/panel_header.style.js b/src/components/panel_header.style.js @@ -6,7 +6,9 @@ export default { 'Link', 'Icon', 'Button', - 'ButtonUnstyled' + 'ButtonUnstyled', + 'Badge', + 'Alert' ], defaultRules: [ { diff --git a/src/components/popover.style.js b/src/components/popover.style.js @@ -1,8 +1,8 @@ export default { name: 'Popover', selector: '.popover', + lazy: true, variants: { - tooltip: '.tooltip', modal: '.modal' }, validInnerComponents: [ diff --git a/src/components/top_bar.style.js b/src/components/top_bar.style.js @@ -7,7 +7,8 @@ export default { 'Icon', 'Button', 'ButtonUnstyled', - 'Input' + 'Input', + 'Badge' ], defaultRules: [ { diff --git a/src/components/underlay.style.js b/src/components/underlay.style.js @@ -6,7 +6,8 @@ export default { // we are searching for underlay specifically or for whatever is laid on top of it. outOfTreeSelector: '.underlay', validInnerComponents: [ - 'Panel' + 'Panel', + 'Alert' ], defaultRules: [ { diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js @@ -28,11 +28,17 @@ export const applyTheme = (input) => { // styleSheet.insertRule(`:root { ${rules.colors} }`, 'index-max') // styleSheet.insertRule(`:root { ${rules.shadows} }`, 'index-max') styleSheet.insertRule(`:root { ${rules.fonts} }`, 'index-max') - themes3.css.forEach(rule => { - console.log(rule) + themes3.css(themes3.eager).forEach(rule => { styleSheet.insertRule(rule, 'index-max') }) body.classList.remove('hidden') + themes3.lazy.then(lazyRules => { + themes3.css(lazyRules).forEach(rule => { + styleSheet.insertRule(rule, 'index-max') + }) + const t3 = performance.now() + console.log('Themes 3 finalization took ' + (t3 - t2) + 'ms') + }) } const configColumns = ({ sidebarColumnWidth, contentColumnWidth, notifsColumnWidth, emojiReactionsScale }) => diff --git a/src/services/theme_data/theme_data_3.service.js b/src/services/theme_data/theme_data_3.service.js @@ -27,6 +27,8 @@ import Post from 'src/components/post.style.js' import Notification from 'src/components/notification.style.js' import RichContent from 'src/components/rich_content.style.js' import Avatar from 'src/components/avatar.style.js' +import Badge from 'src/components/badge.style.js' +import Alert from 'src/components/alert.style.js' const DEBUG = false @@ -50,7 +52,9 @@ const components = { Post, Notification, RichContent, - Avatar + Avatar, + Alert, + Badge } // "Unrolls" a tree structure of item: { parent: { ...item2, parent: { ...item3, parent: {...} } }} @@ -59,9 +63,8 @@ const unroll = (item) => { const out = [] let currentParent = item while (currentParent) { - const { parent: newParent, ...rest } = currentParent - out.push(rest) - currentParent = newParent + out.push(currentParent) + currentParent = currentParent.parent } return out } @@ -173,7 +176,8 @@ export const init = (extraRuleset, palette) => { const stacked = {} const computed = {} - const rules = [] + const eagerRules = [] + const lazyRules = [] const normalizeCombination = rule => { rule.variant = rule.variant ?? 'normal' @@ -211,10 +215,6 @@ export const init = (extraRuleset, palette) => { const virtualComponents = new Set(Object.values(components).filter(c => c.virtual).map(c => c.name)) - const addRule = (rule) => { - rules.push(rule) - } - const findColor = (color, dynamicVars) => { if (typeof color !== 'string' || (!color.startsWith('--') && !color.startsWith('$'))) return color let targetColor = null @@ -346,7 +346,14 @@ export const init = (extraRuleset, palette) => { .join(' ') } - const processInnerComponent = (component, parent) => { + let counter = 0 + const promises = [] + const processInnerComponent = (component, rules, parent) => { + const addRule = (rule) => { + rules.push(rule) + } + + const parentSelector = ruleToSelector(parent, true) // const parentList = parent ? unroll(parent).reverse().map(c => c.component) : [] // if (!component.virtual) { // const path = [...parentList, component.name].join(' > ') @@ -367,18 +374,36 @@ export const init = (extraRuleset, palette) => { // Optimization: we only really need combinations without "normal" because all states implicitly have it const permutationStateKeys = Object.keys(states).filter(s => s !== 'normal') - const stateCombinations = [['normal'], ...getAllPossibleCombinations(permutationStateKeys).map(combination => ['normal', ...combination])] + const stateCombinations = [ + ['normal'], + ...getAllPossibleCombinations(permutationStateKeys) + .map(combination => ['normal', ...combination]) + .filter(combo => { + // Optimization: filter out some hard-coded combinations that don't make sense + if (combo.indexOf('disabled') >= 0) { + return !( + combo.indexOf('hover') >= 0 || + combo.indexOf('focused') >= 0 || + combo.indexOf('pressed') >= 0 + ) + } + return true + }) + ] const stateVariantCombination = Object.keys(variants).map(variant => { return stateCombinations.map(state => ({ variant, state })) }).reduce((acc, x) => [...acc, ...x], []) stateVariantCombination.forEach(combination => { + counter++ // const tt0 = performance.now() - const soloSelector = ruleToSelector({ component: component.name, ...combination }, true) - const selector = ruleToSelector({ component: component.name, ...combination, parent }, true) - const lowerLevelSelector = selector.split(/ /g).slice(0, -1).join(' ') + combination.component = component.name + const soloSelector = ruleToSelector(combination, true) + const selector = [parentSelector, soloSelector].filter(x => x).join(' ') + + const lowerLevelSelector = parentSelector const lowerLevelBackground = computed[lowerLevelSelector]?.background const lowerLevelVirtualDirectives = computed[lowerLevelSelector]?.virtualDirectives const lowerLevelVirtualDirectivesRaw = computed[lowerLevelSelector]?.virtualDirectivesRaw @@ -489,10 +514,7 @@ export const init = (extraRuleset, palette) => { // TODO: DEFAULT TEXT COLOR const lowerLevelComputedBackground = computed[lowerLevelSelector]?.background || convert('#FFFFFF').rgb - if ( - computedDirectives.shadow != null || - computedDirectives.roundness != null - ) { + if (computedDirectives.shadow != null || computedDirectives.roundness != null) { addRuleNeeded = true } @@ -549,7 +571,22 @@ export const init = (extraRuleset, palette) => { } } - innerComponents.forEach(innerComponent => processInnerComponent(innerComponent, { parent, component: name, ...combination })) + innerComponents.forEach(innerComponent => { + if (innerComponent.lazy) { + promises.push(new Promise((resolve, reject) => { + setTimeout(() => { + try { + processInnerComponent(innerComponent, lazyRules, { parent, component: name, ...combination }) + resolve() + } catch (e) { + reject(e) + } + }, 0) + })) + } else { + processInnerComponent(innerComponent, rules, { parent, component: name, ...combination }) + } + }) // const tt1 = performance.now() // if (!component.virtual) { // console.log('State-variant ' + combination.variant + ' : ' + combination.state.join('+') + ' procession time: ' + (tt1 - tt0) + 'ms') @@ -563,11 +600,16 @@ export const init = (extraRuleset, palette) => { // } } - processInnerComponent(components.Root) + processInnerComponent(components.Root, eagerRules) + console.log('TOTAL COMBOS: ' + counter) + const lazyExec = Promise.all(promises).then(() => { + console.log('TOTAL COMBOS: ' + counter) + }).then(() => lazyRules) return { - raw: rules, - css: rules.map(rule => { + lazy: lazyExec, + eager: eagerRules, + css: rules => rules.map(rule => { let selector = rule.selector if (!selector) { selector = 'body'