Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F85629703
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
17 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/src/services/theme_data/theme2_to_theme3.js b/src/services/theme_data/theme2_to_theme3.js
index 96955edfdb..8c3ac6ad2a 100644
--- a/src/services/theme_data/theme2_to_theme3.js
+++ b/src/services/theme_data/theme2_to_theme3.js
@@ -1,574 +1,584 @@
import { convert } from 'chromatism'
import allKeys from './theme2_keys'
// keys that are meant to be used globally, i.e. what's the rest of the theme is based upon.
export const basePaletteKeys = new Set([
'bg',
'fg',
'text',
'link',
'accent',
'cBlue',
'cRed',
'cGreen',
'cOrange',
'wallpaper',
])
export const fontsKeys = new Set(['interface', 'input', 'post', 'postCode'])
export const opacityKeys = new Set([
'alert',
'alertPopup',
'bg',
'border',
'btn',
'faint',
'input',
'panel',
'popover',
'profileTint',
'underlay',
])
export const shadowsKeys = new Set([
'panel',
'topBar',
'popup',
'avatar',
'avatarStatus',
'panelHeader',
'button',
'buttonHover',
'buttonPressed',
'input',
])
export const radiiKeys = new Set([
'btn',
'input',
'checkbox',
'panel',
'avatar',
'avatarAlt',
'tooltip',
'attachment',
'chatMessage',
])
// Keys that are not available in editor and never meant to be edited
export const hiddenKeys = new Set(['profileBg', 'profileTint'])
export const extendedBasePrefixes = [
'border',
'icon',
'highlight',
'lightText',
'popover',
'panel',
'topBar',
'tab',
'btn',
'input',
'selectedMenu',
'alert',
'alertPopup',
'badge',
'post',
'selectedPost', // wrong nomenclature
'poll',
'chatBg',
'chatMessage',
]
export const nonComponentPrefixes = new Set([
'border',
'icon',
'highlight',
'lightText',
'chatBg',
])
export const extendedBaseKeys = Object.fromEntries(
extendedBasePrefixes.map((prefix) => [
prefix,
allKeys.filter((k) => {
if (prefix === 'alert') {
return k.startsWith(prefix) && !k.startsWith('alertPopup')
}
return k.startsWith(prefix)
}),
]),
)
// Keysets that are only really used intermideately, i.e. to generate other colors
export const temporary = new Set(['', 'highlight'])
export const temporaryColors = {}
export const convertTheme2To3 = (data) => {
data.colors.accent = data.colors.accent || data.colors.link
data.colors.link = data.colors.link || data.colors.accent
const generateRoot = () => {
const directives = {}
basePaletteKeys.forEach((key) => {
directives['--' + key] = 'color | ' + convert(data.colors[key]).hex
})
return {
component: 'Root',
directives,
}
}
const convertOpacity = () => {
const newRules = []
Object.keys(data.opacity || {}).forEach((key) => {
if (!opacityKeys.has(key) || data.opacity[key] === undefined) return null
const originalOpacity = data.opacity[key]
const rule = { source: '2to3' }
switch (key) {
case 'alert':
rule.component = 'Alert'
break
case 'alertPopup':
rule.component = 'Alert'
rule.parent = { component: 'Popover' }
break
case 'bg':
rule.component = 'Panel'
break
case 'border':
rule.component = 'Border'
break
case 'btn':
rule.component = 'Button'
break
case 'faint':
rule.component = 'Text'
rule.state = ['faint']
break
case 'input':
rule.component = 'Input'
break
case 'panel':
rule.component = 'PanelHeader'
break
case 'popover':
rule.component = 'Popover'
break
case 'profileTint':
return null
case 'underlay':
rule.component = 'Underlay'
break
}
switch (key) {
case 'alert':
case 'alertPopup':
case 'bg':
case 'btn':
case 'input':
case 'panel':
case 'popover':
case 'underlay':
rule.directives = { opacity: originalOpacity }
break
case 'faint':
case 'border':
rule.directives = { textOpacity: originalOpacity }
break
}
newRules.push(rule)
if (rule.component === 'Button') {
- newRules.push({ ...rule, component: 'ScrollbarElement' })
- newRules.push({ ...rule, component: 'Tab' })
- newRules.push({
- ...rule,
- component: 'Tab',
- state: ['active'],
- directives: { opacity: 0 },
- })
+ newRules.push(
+ { ...rule, component: 'ScrollbarElement' },
+ { ...rule, component: 'Tab' },
+ {
+ ...rule,
+ component: 'Tab',
+ state: ['active'],
+ directives: { opacity: 0 },
+ },
+ )
}
if (rule.component === 'Panel') {
newRules.push({ ...rule, component: 'Post' })
}
})
return newRules
}
const convertRadii = () => {
const newRules = []
Object.keys(data.radii || {}).forEach((key) => {
if (!radiiKeys.has(key) || data.radii[key] === undefined) return null
const originalRadius = data.radii[key]
const rule = { source: '2to3' }
switch (key) {
case 'btn':
rule.component = 'Button'
break
case 'tab':
rule.component = 'Tab'
break
case 'input':
rule.component = 'Input'
break
case 'checkbox':
rule.component = 'Input'
rule.variant = 'checkbox'
break
case 'panel':
rule.component = 'Panel'
break
case 'avatar':
rule.component = 'Avatar'
break
case 'avatarAlt':
rule.component = 'Avatar'
rule.variant = 'compact'
break
case 'tooltip':
rule.component = 'Popover'
break
case 'ChatMessage':
rule.component = 'Button'
break
}
rule.directives = {
roundness: originalRadius,
}
newRules.push(rule)
if (rule.component === 'Button') {
- newRules.push({ ...rule, component: 'ScrollbarElement' })
- newRules.push({ ...rule, component: 'Tab' })
+ newRules.push(
+ { ...rule, component: 'ScrollbarElement' },
+ { ...rule, component: 'Tab' },
+ )
}
})
return newRules
}
const convertFonts = () => {
const newRules = []
Object.keys(data.fonts || {}).forEach((key) => {
if (!fontsKeys.has(key)) return
if (!data.fonts[key]) return
const originalFont = data.fonts[key]
const rule = { source: '2to3' }
switch (key) {
case 'interface':
case 'postCode':
rule.component = 'Root'
break
case 'input':
rule.component = 'Input'
break
case 'post':
rule.component = 'RichContent'
break
}
switch (key) {
case 'interface':
case 'input':
case 'post':
rule.directives = { '--font': 'generic | ' + originalFont }
break
case 'postCode':
rule.directives = { '--monoFont': 'generic | ' + originalFont }
newRules.push({ ...rule, component: 'RichContent' })
break
}
newRules.push(rule)
})
return newRules
}
const convertShadows = () => {
const newRules = []
Object.keys(data.shadows || {}).forEach((key) => {
if (!shadowsKeys.has(key)) return
const originalShadow = data.shadows[key]
const rule = { source: '2to3' }
switch (key) {
case 'panel':
rule.component = 'Panel'
break
case 'topBar':
rule.component = 'TopBar'
break
case 'popup':
rule.component = 'Popover'
break
case 'avatar':
rule.component = 'Avatar'
break
case 'avatarStatus':
rule.component = 'Avatar'
rule.parent = { component: 'Post' }
break
case 'panelHeader':
rule.component = 'PanelHeader'
break
case 'button':
rule.component = 'Button'
break
case 'buttonHover':
rule.component = 'Button'
rule.state = ['hover']
break
case 'buttonPressed':
rule.component = 'Button'
rule.state = ['pressed']
break
case 'input':
rule.component = 'Input'
break
}
rule.directives = {
shadow: originalShadow,
}
newRules.push(rule)
if (key === 'topBar') {
newRules.push({
...rule,
component: 'PanelHeader',
parent: { component: 'MobileDrawer' },
})
}
if (key === 'avatarStatus') {
newRules.push({ ...rule, parent: { component: 'Notification' } })
}
if (key === 'buttonPressed') {
- newRules.push({ ...rule, state: ['toggled'] })
- newRules.push({ ...rule, state: ['toggled', 'focus'] })
- newRules.push({ ...rule, state: ['pressed', 'focus'] })
- newRules.push({ ...rule, state: ['toggled', 'focus', 'hover'] })
- newRules.push({ ...rule, state: ['pressed', 'focus', 'hover'] })
+ newRules.push(
+ { ...rule, state: ['toggled'] },
+ { ...rule, state: ['toggled', 'focus'] },
+ { ...rule, state: ['pressed', 'focus'] },
+ { ...rule, state: ['toggled', 'focus', 'hover'] },
+ { ...rule, state: ['pressed', 'focus', 'hover'] },
+ )
}
if (rule.component === 'Button') {
- newRules.push({ ...rule, component: 'ScrollbarElement' })
- newRules.push({ ...rule, component: 'Tab' })
+ newRules.push(
+ { ...rule, component: 'ScrollbarElement' },
+ { ...rule, component: 'Tab' },
+ )
}
})
return newRules
}
const extendedRules = Object.entries(extendedBaseKeys).map(
([prefix, keys]) => {
if (nonComponentPrefixes.has(prefix)) return null
const rule = { source: '2to3' }
if (prefix === 'alertPopup') {
rule.component = 'Alert'
rule.parent = { component: 'Popover' }
} else if (prefix === 'selectedPost') {
rule.component = 'Post'
rule.state = ['selected']
} else if (prefix === 'selectedMenu') {
rule.component = 'MenuItem'
rule.state = ['hover']
} else if (prefix === 'chatMessageIncoming') {
rule.component = 'ChatMessage'
} else if (prefix === 'chatMessageOutgoing') {
rule.component = 'ChatMessage'
rule.variant = 'outgoing'
} else if (prefix === 'panel') {
rule.component = 'PanelHeader'
} else if (prefix === 'topBar') {
rule.component = 'TopBar'
} else if (prefix === 'chatMessage') {
rule.component = 'ChatMessage'
} else if (prefix === 'poll') {
rule.component = 'PollGraph'
} else if (prefix === 'btn') {
rule.component = 'Button'
} else {
rule.component = prefix[0].toUpperCase() + prefix.slice(1).toLowerCase()
}
return keys.map((key) => {
if (!data.colors[key]) return null
const leftoverKey = key.replace(prefix, '')
const parts = (leftoverKey || 'Bg').match(/[A-Z][a-z]*/g)
const last = parts.slice(-1)[0]
let newRule = { source: '2to3', directives: {} }
let variantArray = []
switch (last) {
case 'Text':
case 'Faint': // typo
case 'Link':
case 'Icon':
case 'Greentext':
case 'Cyantext':
case 'Border':
newRule.parent = rule
newRule.directives.textColor = data.colors[key]
variantArray = parts.slice(0, -1)
break
default:
newRule = { ...rule, directives: {} }
newRule.directives.background = data.colors[key]
variantArray = parts
break
}
if (last === 'Text' || last === 'Link') {
const secondLast = parts.slice(-2)[0]
if (secondLast === 'Light') {
return null // unsupported
} else if (secondLast === 'Faint') {
newRule.state = ['faint']
variantArray = parts.slice(0, -2)
}
}
switch (last) {
case 'Text':
case 'Link':
case 'Icon':
case 'Border':
newRule.component = last
break
case 'Greentext':
case 'Cyantext':
newRule.component = 'FunText'
newRule.variant = last.toLowerCase()
break
case 'Faint':
newRule.component = 'Text'
newRule.state = ['faint']
break
}
variantArray = variantArray.filter((x) => x !== 'Bg')
if (last === 'Link' && prefix === 'selectedPost') {
// selectedPost has typo - duplicate 'Post'
variantArray = variantArray.filter((x) => x !== 'Post')
}
if (prefix === 'popover' && variantArray[0] === 'Post') {
newRule.component = 'Post'
newRule.parent = { source: '2to3hack', component: 'Popover' }
variantArray = variantArray.filter((x) => x !== 'Post')
}
if (prefix === 'selectedMenu' && variantArray[0] === 'Popover') {
newRule.parent = { source: '2to3hack', component: 'Popover' }
variantArray = variantArray.filter((x) => x !== 'Popover')
}
switch (prefix) {
case 'btn':
case 'input':
case 'alert': {
const hasPanel = variantArray.find((x) => x === 'Panel')
if (hasPanel) {
newRule.parent = {
source: '2to3hack',
component: 'PanelHeader',
parent: newRule.parent,
}
variantArray = variantArray.filter((x) => x !== 'Panel')
}
const hasTop = variantArray.find((x) => x === 'Top') // TopBar
if (hasTop) {
newRule.parent = {
source: '2to3hack',
component: 'TopBar',
parent: newRule.parent,
}
variantArray = variantArray.filter(
(x) => x !== 'Top' && x !== 'Bar',
)
}
break
}
}
if (variantArray.length > 0) {
if (prefix === 'btn') {
newRule.state = variantArray.map((x) => x.toLowerCase())
} else {
newRule.variant = variantArray[0].toLowerCase()
}
}
if (newRule.component === 'Panel') {
return [newRule, { ...newRule, component: 'MobileDrawer' }]
} else if (newRule.component === 'Button') {
const rules = [
newRule,
{ ...newRule, component: 'Tab' },
{ ...newRule, component: 'ScrollbarElement' },
]
if (newRule.state?.includes('toggled')) {
- rules.push({ ...newRule, state: [...newRule.state, 'focused'] })
- rules.push({ ...newRule, state: [...newRule.state, 'hover'] })
- rules.push({
- ...newRule,
- state: [...newRule.state, 'hover', 'focused'],
- })
+ rules.push(
+ { ...newRule, state: [...newRule.state, 'focused'] },
+ { ...newRule, state: [...newRule.state, 'hover'] },
+ {
+ ...newRule,
+ state: [...newRule.state, 'hover', 'focused'],
+ },
+ )
}
if (newRule.state?.includes('hover')) {
rules.push({ ...newRule, state: [...newRule.state, 'focused'] })
}
return rules
} else if (newRule.component === 'Badge') {
if (newRule.variant === 'notification') {
return [
newRule,
{
component: 'Root',
directives: {
'--badgeNotification':
'color | ' + newRule.directives.background,
},
},
]
} else if (newRule.variant === 'neutral') {
return [{ ...newRule, variant: 'normal' }]
} else {
return [newRule]
}
} else if (newRule.component === 'TopBar') {
return [
newRule,
{
...newRule,
parent: { component: 'MobileDrawer' },
component: 'PanelHeader',
},
]
} else {
return [newRule]
}
})
},
)
const flatExtRules = extendedRules
.filter(Boolean)
.flat()
.filter(Boolean)
.flat()
return [
generateRoot(),
...convertShadows(),
...convertRadii(),
...convertOpacity(),
...convertFonts(),
...flatExtRules,
]
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sun, Aug 9, 3:58 AM (1 d, 22 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1724182
Default Alt Text
(17 KB)
Attached To
Mode
rPUFE pleroma-fe-upstream
Attached
Detach File
Event Timeline
Log In to Comment