Replaced v3compat
with source
to reduce code complexity. Made more slots
customizable. `theme` now contains a snapshot of theme generated for better compatiblity and future-proofing
This commit is contained in:
parent
332d31dc02
commit
4bb1c98e0f
5 changed files with 488 additions and 80 deletions
|
@ -1,7 +1,15 @@
|
||||||
import { rgb2hex, hex2rgb, getContrastRatio, getContrastRatioLayers, alphaBlend } from '../../services/color_convert/color_convert.js'
|
import { rgb2hex, hex2rgb, getContrastRatio, getContrastRatioLayers, alphaBlend } from '../../services/color_convert/color_convert.js'
|
||||||
import { set, delete as del } from 'vue'
|
import { set, delete as del } from 'vue'
|
||||||
import { merge } from 'lodash'
|
import { merge } from 'lodash'
|
||||||
import { generateCompat, generateColors, generateShadows, generateRadii, generateFonts, composePreset, getThemes } from '../../services/style_setter/style_setter.js'
|
import {
|
||||||
|
generateColors,
|
||||||
|
generateShadows,
|
||||||
|
generateRadii,
|
||||||
|
generateFonts,
|
||||||
|
composePreset,
|
||||||
|
getThemes,
|
||||||
|
CURRENT_VERSION
|
||||||
|
} from '../../services/style_setter/style_setter.js'
|
||||||
import ColorInput from '../color_input/color_input.vue'
|
import ColorInput from '../color_input/color_input.vue'
|
||||||
import RangeInput from '../range_input/range_input.vue'
|
import RangeInput from '../range_input/range_input.vue'
|
||||||
import OpacityInput from '../opacity_input/opacity_input.vue'
|
import OpacityInput from '../opacity_input/opacity_input.vue'
|
||||||
|
@ -135,15 +143,6 @@ export default {
|
||||||
selectedVersion () {
|
selectedVersion () {
|
||||||
return Array.isArray(this.selected) ? 1 : 2
|
return Array.isArray(this.selected) ? 1 : 2
|
||||||
},
|
},
|
||||||
currentCompat () {
|
|
||||||
return generateCompat({
|
|
||||||
shadows: this.shadowsLocal,
|
|
||||||
fonts: this.fontsLocal,
|
|
||||||
opacity: this.currentOpacity,
|
|
||||||
colors: this.currentColors,
|
|
||||||
radii: this.currentRadii
|
|
||||||
})
|
|
||||||
},
|
|
||||||
currentColors () {
|
currentColors () {
|
||||||
return {
|
return {
|
||||||
bg: this.bgColorLocal,
|
bg: this.bgColorLocal,
|
||||||
|
@ -339,27 +338,32 @@ export default {
|
||||||
!this.keepColor
|
!this.keepColor
|
||||||
)
|
)
|
||||||
|
|
||||||
const theme = {}
|
const source = {
|
||||||
|
themeEngineVersion: CURRENT_VERSION
|
||||||
|
}
|
||||||
|
|
||||||
if (this.keepFonts || saveEverything) {
|
if (this.keepFonts || saveEverything) {
|
||||||
theme.fonts = this.fontsLocal
|
source.fonts = this.fontsLocal
|
||||||
}
|
}
|
||||||
if (this.keepShadows || saveEverything) {
|
if (this.keepShadows || saveEverything) {
|
||||||
theme.shadows = this.shadowsLocal
|
source.shadows = this.shadowsLocal
|
||||||
}
|
}
|
||||||
if (this.keepOpacity || saveEverything) {
|
if (this.keepOpacity || saveEverything) {
|
||||||
theme.opacity = this.currentOpacity
|
source.opacity = this.currentOpacity
|
||||||
}
|
}
|
||||||
if (this.keepColor || saveEverything) {
|
if (this.keepColor || saveEverything) {
|
||||||
theme.colors = this.currentColors
|
source.colors = this.currentColors
|
||||||
}
|
}
|
||||||
if (this.keepRoundness || saveEverything) {
|
if (this.keepRoundness || saveEverything) {
|
||||||
theme.radii = this.currentRadii
|
source.radii = this.currentRadii
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const theme = this.previewTheme
|
||||||
|
|
||||||
|
console.log(source)
|
||||||
return {
|
return {
|
||||||
// To separate from other random JSON files and possible future theme formats
|
// To separate from other random JSON files and possible future source formats
|
||||||
_pleroma_theme_version: 2, theme: merge(theme, this.currentCompat)
|
_pleroma_theme_version: 2, theme, source
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -392,7 +396,7 @@ export default {
|
||||||
if (parsed._pleroma_theme_version === 1) {
|
if (parsed._pleroma_theme_version === 1) {
|
||||||
this.normalizeLocalState(parsed, 1)
|
this.normalizeLocalState(parsed, 1)
|
||||||
} else if (parsed._pleroma_theme_version >= 2) {
|
} else if (parsed._pleroma_theme_version >= 2) {
|
||||||
this.normalizeLocalState(parsed.theme, 2)
|
this.normalizeLocalState(parsed.theme, 2, parsed.source)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
importValidator (parsed) {
|
importValidator (parsed) {
|
||||||
|
@ -402,7 +406,7 @@ export default {
|
||||||
clearAll () {
|
clearAll () {
|
||||||
const state = this.$store.getters.mergedConfig.customTheme
|
const state = this.$store.getters.mergedConfig.customTheme
|
||||||
const version = state.colors ? 2 : 'l1'
|
const version = state.colors ? 2 : 'l1'
|
||||||
this.normalizeLocalState(this.$store.getters.mergedConfig.customTheme, version)
|
this.normalizeLocalState(this.$store.getters.mergedConfig.customTheme, version, this.$store.getters.mergedConfig.customThemeSource)
|
||||||
},
|
},
|
||||||
|
|
||||||
// Clears all the extra stuff when loading V1 theme
|
// Clears all the extra stuff when loading V1 theme
|
||||||
|
@ -441,24 +445,30 @@ export default {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This applies stored theme data onto form. Supports three versions of data:
|
* This applies stored theme data onto form. Supports three versions of data:
|
||||||
* v3 (version = 3) - same as 2 but with some incompatible changes
|
* v3 (version >= 3) - newest version of themes which supports snapshots for better compatiblity
|
||||||
* v2 (version = 2) - newer version of themes.
|
* v2 (version = 2) - newer version of themes.
|
||||||
* v1 (version = 1) - older version of themes (import from file)
|
* v1 (version = 1) - older version of themes (import from file)
|
||||||
* v1l (version = l1) - older version of theme (load from local storage)
|
* v1l (version = l1) - older version of theme (load from local storage)
|
||||||
* v1 and v1l differ because of way themes were stored/exported.
|
* v1 and v1l differ because of way themes were stored/exported.
|
||||||
* @param {Object} input - input data
|
* @param {Object} theme - theme data (snapshot)
|
||||||
* @param {Number} version - version of data. 0 means try to guess based on data. "l1" means v1, locastorage type
|
* @param {Number} version - version of data. 0 means try to guess based on data. "l1" means v1, locastorage type
|
||||||
|
* @param {Object} source - theme source - this will be used if compatible
|
||||||
|
* @param {Boolean} source - by default source won't be used if version doesn't match since it might render differently
|
||||||
|
* this allows importing source anyway
|
||||||
*/
|
*/
|
||||||
normalizeLocalState (originalInput, version = 0) {
|
normalizeLocalState (theme, version = 0, source, forceSource = false) {
|
||||||
let input
|
let input
|
||||||
if (typeof originalInput.v3compat !== 'undefined') {
|
if (typeof source !== 'undefined') {
|
||||||
version = 3
|
if (forceSource || source.themeEngineVersion === CURRENT_VERSION) {
|
||||||
input = merge(originalInput, originalInput.v3compat)
|
input = source
|
||||||
|
version = source.themeEngineVersion
|
||||||
|
} else {
|
||||||
|
input = theme
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
input = originalInput
|
input = theme
|
||||||
}
|
}
|
||||||
|
|
||||||
const compat = input.v3compat
|
|
||||||
const radii = input.radii || input
|
const radii = input.radii || input
|
||||||
const opacity = input.opacity
|
const opacity = input.opacity
|
||||||
const shadows = input.shadows || {}
|
const shadows = input.shadows || {}
|
||||||
|
@ -615,7 +625,7 @@ export default {
|
||||||
this.cOrangeColorLocal = this.selected[8]
|
this.cOrangeColorLocal = this.selected[8]
|
||||||
}
|
}
|
||||||
} else if (this.selectedVersion >= 2) {
|
} else if (this.selectedVersion >= 2) {
|
||||||
this.normalizeLocalState(this.selected.theme, 2)
|
this.normalizeLocalState(this.selected.theme, 2, this.selected.source)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,7 +106,7 @@
|
||||||
<OpacityInput
|
<OpacityInput
|
||||||
v-model="bgOpacityLocal"
|
v-model="bgOpacityLocal"
|
||||||
name="bgOpacity"
|
name="bgOpacity"
|
||||||
:fallback="previewTheme.opacity.bg || 1"
|
:fallback="previewTheme.opacity.bg"
|
||||||
/>
|
/>
|
||||||
<ColorInput
|
<ColorInput
|
||||||
v-model="textColorLocal"
|
v-model="textColorLocal"
|
||||||
|
@ -238,7 +238,7 @@
|
||||||
<OpacityInput
|
<OpacityInput
|
||||||
v-model="panelOpacityLocal"
|
v-model="panelOpacityLocal"
|
||||||
name="panelOpacity"
|
name="panelOpacity"
|
||||||
:fallback="previewTheme.opacity.panel || 1"
|
:fallback="previewTheme.opacity.panel"
|
||||||
/>
|
/>
|
||||||
<ColorInput
|
<ColorInput
|
||||||
v-model="panelTextColorLocal"
|
v-model="panelTextColorLocal"
|
||||||
|
@ -295,7 +295,7 @@
|
||||||
<OpacityInput
|
<OpacityInput
|
||||||
v-model="inputOpacityLocal"
|
v-model="inputOpacityLocal"
|
||||||
name="inputOpacity"
|
name="inputOpacity"
|
||||||
:fallback="previewTheme.opacity.input || 1"
|
:fallback="previewTheme.opacity.input"
|
||||||
/>
|
/>
|
||||||
<ColorInput
|
<ColorInput
|
||||||
v-model="inputTextColorLocal"
|
v-model="inputTextColorLocal"
|
||||||
|
@ -316,7 +316,7 @@
|
||||||
<OpacityInput
|
<OpacityInput
|
||||||
v-model="btnOpacityLocal"
|
v-model="btnOpacityLocal"
|
||||||
name="btnOpacity"
|
name="btnOpacity"
|
||||||
:fallback="previewTheme.opacity.btn || 1"
|
:fallback="previewTheme.opacity.btn"
|
||||||
/>
|
/>
|
||||||
<ColorInput
|
<ColorInput
|
||||||
v-model="btnTextColorLocal"
|
v-model="btnTextColorLocal"
|
||||||
|
@ -337,7 +337,7 @@
|
||||||
<OpacityInput
|
<OpacityInput
|
||||||
v-model="borderOpacityLocal"
|
v-model="borderOpacityLocal"
|
||||||
name="borderOpacity"
|
name="borderOpacity"
|
||||||
:fallback="previewTheme.opacity.border || 1"
|
:fallback="previewTheme.opacity.border"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="color-item">
|
<div class="color-item">
|
||||||
|
@ -363,7 +363,7 @@
|
||||||
<OpacityInput
|
<OpacityInput
|
||||||
v-model="faintOpacityLocal"
|
v-model="faintOpacityLocal"
|
||||||
name="faintOpacity"
|
name="faintOpacity"
|
||||||
:fallback="previewTheme.opacity.faint || 0.5"
|
:fallback="previewTheme.opacity.faint"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="color-item">
|
<div class="color-item">
|
||||||
|
@ -377,7 +377,7 @@
|
||||||
<OpacityInput
|
<OpacityInput
|
||||||
v-model="underlayOpacityLocal"
|
v-model="underlayOpacityLocal"
|
||||||
name="underlayOpacity"
|
name="underlayOpacity"
|
||||||
:fallback="previewTheme.opacity.underlay || 0.15"
|
:fallback="previewTheme.opacity.underlay"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -2,6 +2,8 @@ import { times } from 'lodash'
|
||||||
import { brightness, invertLightness, convert, contrastRatio } from 'chromatism'
|
import { brightness, invertLightness, convert, contrastRatio } from 'chromatism'
|
||||||
import { rgb2hex, hex2rgb, mixrgb, getContrastRatio, alphaBlend, alphaBlendLayers } from '../color_convert/color_convert.js'
|
import { rgb2hex, hex2rgb, mixrgb, getContrastRatio, alphaBlend, alphaBlendLayers } from '../color_convert/color_convert.js'
|
||||||
|
|
||||||
|
export const CURRENT_VERSION = 3
|
||||||
|
|
||||||
// While this is not used anymore right now, I left it in if we want to do custom
|
// While this is not used anymore right now, I left it in if we want to do custom
|
||||||
// styles that aren't just colors, so user can pick from a few different distinct
|
// styles that aren't just colors, so user can pick from a few different distinct
|
||||||
// styles as well as set their own colors in the future.
|
// styles as well as set their own colors in the future.
|
||||||
|
@ -150,29 +152,13 @@ const getCssColor = (input, a) => {
|
||||||
return rgb2rgba({ ...rgb, a })
|
return rgb2rgba({ ...rgb, a })
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generates a "patch" for theme to make it compatible with v2
|
|
||||||
export const generateCompat = (input) => {
|
|
||||||
const { colors } = input
|
|
||||||
const v3compat = {
|
|
||||||
colors: {}
|
|
||||||
}
|
|
||||||
const v2colorsPatch = {}
|
|
||||||
|
|
||||||
// # Link became optional in v3
|
|
||||||
if (typeof colors.link === 'undefined') {
|
|
||||||
v2colorsPatch.link = colors.accent
|
|
||||||
v3compat.colors.link = null
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
v3compat,
|
|
||||||
colors: v2colorsPatch
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const generateColors = (themeData) => {
|
const generateColors = (themeData) => {
|
||||||
const colors = {}
|
const colors = {}
|
||||||
const rawOpacity = Object.assign({
|
const rawOpacity = Object.assign({
|
||||||
|
panel: 1,
|
||||||
|
btn: 1,
|
||||||
|
border: 1,
|
||||||
|
bg: 1,
|
||||||
alert: 0.5,
|
alert: 0.5,
|
||||||
input: 0.5,
|
input: 0.5,
|
||||||
faint: 0.5,
|
faint: 0.5,
|
||||||
|
@ -207,6 +193,7 @@ const generateColors = (themeData) => {
|
||||||
} else {
|
} else {
|
||||||
let value = v
|
let value = v
|
||||||
if (v === 'transparent') {
|
if (v === 'transparent') {
|
||||||
|
// TODO: hack to keep rest of the code from complaining
|
||||||
value = '#FF00FF'
|
value = '#FF00FF'
|
||||||
}
|
}
|
||||||
acc[k] = hex2rgb(value)
|
acc[k] = hex2rgb(value)
|
||||||
|
@ -221,7 +208,7 @@ const generateColors = (themeData) => {
|
||||||
const isLightOnDark = convert(colors.bg).hsl.l < convert(colors.text).hsl.l
|
const isLightOnDark = convert(colors.bg).hsl.l < convert(colors.text).hsl.l
|
||||||
const mod = isLightOnDark ? 1 : -1
|
const mod = isLightOnDark ? 1 : -1
|
||||||
|
|
||||||
colors.lightText = brightness(20 * mod, colors.text).rgb
|
colors.lightText = col.lightText || brightness(20 * mod, colors.text).rgb
|
||||||
|
|
||||||
colors.accent = col.accent || col.link
|
colors.accent = col.accent || col.link
|
||||||
colors.link = col.link || col.accent
|
colors.link = col.link || col.accent
|
||||||
|
@ -231,7 +218,8 @@ const generateColors = (themeData) => {
|
||||||
colors.lightBg = col.lightBg || brightness(5 * mod, colors.bg).rgb
|
colors.lightBg = col.lightBg || brightness(5 * mod, colors.bg).rgb
|
||||||
|
|
||||||
const underlay = [colors.underlay, opacity.underlay]
|
const underlay = [colors.underlay, opacity.underlay]
|
||||||
const fg = [col.fg, opacity.fg]
|
// Technically, foreground can't be transparent (descendants can) but let's keep it just in case
|
||||||
|
const fg = [col.fg, opacity.fg || 1]
|
||||||
const bg = [col.bg, opacity.bg]
|
const bg = [col.bg, opacity.bg]
|
||||||
|
|
||||||
colors.fg = col.fg
|
colors.fg = col.fg
|
||||||
|
@ -271,16 +259,16 @@ const generateColors = (themeData) => {
|
||||||
|
|
||||||
colors.alertError = col.alertError || Object.assign({}, colors.cRed)
|
colors.alertError = col.alertError || Object.assign({}, colors.cRed)
|
||||||
const alertError = [colors.alertError, opacity.alert]
|
const alertError = [colors.alertError, opacity.alert]
|
||||||
colors.alertErrorText = getTextColor(alphaBlendLayers(colors.text, [underlay, bg, alertError]), colors.text)
|
colors.alertErrorText = col.alertErrorText || getTextColor(alphaBlendLayers(colors.text, [underlay, bg, alertError]), colors.text)
|
||||||
colors.alertErrorPanelText = getTextColor(alphaBlendLayers(colors.panelText, [underlay, bg, panel, panel, alertError]), colors.panelText)
|
colors.alertErrorPanelText = col.alertErrorPanelText || getTextColor(alphaBlendLayers(colors.panelText, [underlay, bg, panel, panel, alertError]), colors.panelText)
|
||||||
|
|
||||||
colors.alertWarning = col.alertWarning || Object.assign({}, colors.cOrange)
|
colors.alertWarning = col.alertWarning || Object.assign({}, colors.cOrange)
|
||||||
const alertWarning = [colors.alertWarning, opacity.alert]
|
const alertWarning = [colors.alertWarning, opacity.alert]
|
||||||
colors.alertWarningText = getTextColor(alphaBlendLayers(colors.text, [underlay, bg, alertWarning]), colors.text)
|
colors.alertWarningText = col.alertWarningText || getTextColor(alphaBlendLayers(colors.text, [underlay, bg, alertWarning]), colors.text)
|
||||||
colors.alertWarningPanelText = getTextColor(alphaBlendLayers(colors.panelText, [underlay, bg, panel, panel, alertWarning]), colors.panelText)
|
colors.alertWarningPanelText = col.alertWarningPanelText || getTextColor(alphaBlendLayers(colors.panelText, [underlay, bg, panel, panel, alertWarning]), colors.panelText)
|
||||||
|
|
||||||
colors.badgeNotification = col.badgeNotification || Object.assign({}, colors.cRed)
|
colors.badgeNotification = col.badgeNotification || Object.assign({}, colors.cRed)
|
||||||
colors.badgeNotificationText = contrastRatio(colors.badgeNotification).rgb
|
colors.badgeNotificationText = colors.badgeNotificationText || contrastRatio(colors.badgeNotification).rgb
|
||||||
|
|
||||||
Object.entries(opacity).forEach(([ k, v ]) => {
|
Object.entries(opacity).forEach(([ k, v ]) => {
|
||||||
console.log(k)
|
console.log(k)
|
||||||
|
|
|
@ -2,6 +2,218 @@
|
||||||
"_pleroma_theme_version": 2,
|
"_pleroma_theme_version": 2,
|
||||||
"name": "Breezy Dark (beta)",
|
"name": "Breezy Dark (beta)",
|
||||||
"theme": {
|
"theme": {
|
||||||
|
"shadows": {
|
||||||
|
"panel": [
|
||||||
|
{
|
||||||
|
"x": "1",
|
||||||
|
"y": "2",
|
||||||
|
"blur": "6",
|
||||||
|
"spread": 0,
|
||||||
|
"color": "#000000",
|
||||||
|
"alpha": 0.6
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"topBar": [
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"blur": 4,
|
||||||
|
"spread": 0,
|
||||||
|
"color": "#000000",
|
||||||
|
"alpha": 0.6
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"popup": [
|
||||||
|
{
|
||||||
|
"x": 2,
|
||||||
|
"y": 2,
|
||||||
|
"blur": 3,
|
||||||
|
"spread": 0,
|
||||||
|
"color": "#000000",
|
||||||
|
"alpha": 0.5
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"avatar": [
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 1,
|
||||||
|
"blur": 8,
|
||||||
|
"spread": 0,
|
||||||
|
"color": "#000000",
|
||||||
|
"alpha": 0.7
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"avatarStatus": [],
|
||||||
|
"panelHeader": [
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": "40",
|
||||||
|
"blur": "40",
|
||||||
|
"spread": "-40",
|
||||||
|
"inset": true,
|
||||||
|
"color": "#ffffff",
|
||||||
|
"alpha": "0.1"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"button": [
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": "0",
|
||||||
|
"blur": "0",
|
||||||
|
"spread": "1",
|
||||||
|
"color": "#ffffff",
|
||||||
|
"alpha": "0.15",
|
||||||
|
"inset": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": "1",
|
||||||
|
"y": "1",
|
||||||
|
"blur": "1",
|
||||||
|
"spread": 0,
|
||||||
|
"color": "#000000",
|
||||||
|
"alpha": "0.3",
|
||||||
|
"inset": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"buttonHover": [
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": "0",
|
||||||
|
"blur": 0,
|
||||||
|
"spread": "1",
|
||||||
|
"color": "--accent",
|
||||||
|
"alpha": "0.3",
|
||||||
|
"inset": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": "1",
|
||||||
|
"y": "1",
|
||||||
|
"blur": "1",
|
||||||
|
"spread": 0,
|
||||||
|
"color": "#000000",
|
||||||
|
"alpha": "0.3",
|
||||||
|
"inset": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"buttonPressed": [
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"blur": "0",
|
||||||
|
"spread": "50",
|
||||||
|
"color": "--faint",
|
||||||
|
"alpha": 1,
|
||||||
|
"inset": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": "0",
|
||||||
|
"blur": 0,
|
||||||
|
"spread": "1",
|
||||||
|
"color": "#ffffff",
|
||||||
|
"alpha": 0.2,
|
||||||
|
"inset": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": "1",
|
||||||
|
"y": "1",
|
||||||
|
"blur": 0,
|
||||||
|
"spread": 0,
|
||||||
|
"color": "#000000",
|
||||||
|
"alpha": "0.3",
|
||||||
|
"inset": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"input": [
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": "0",
|
||||||
|
"blur": 0,
|
||||||
|
"spread": "1",
|
||||||
|
"color": "#FFFFFF",
|
||||||
|
"alpha": "0.2",
|
||||||
|
"inset": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"colors": {
|
||||||
|
"bg": "#31363b",
|
||||||
|
"underlay": "#000000",
|
||||||
|
"text": "#eff0f1",
|
||||||
|
"lightText": "#ffffff",
|
||||||
|
"accent": "#3daee9",
|
||||||
|
"link": "#3daee9",
|
||||||
|
"faint": "#eff0f1",
|
||||||
|
"lightBg": "#3d4349",
|
||||||
|
"fg": "#31363b",
|
||||||
|
"fgText": "#eff0f1",
|
||||||
|
"fgLink": "#3daee9",
|
||||||
|
"border": "#4c545b",
|
||||||
|
"btn": "#31363b",
|
||||||
|
"btnText": "#eff0f1",
|
||||||
|
"input": "#232629",
|
||||||
|
"inputText": "#ffffff",
|
||||||
|
"panel": "#ff00ff",
|
||||||
|
"panelText": "#eff0f1",
|
||||||
|
"panelLink": "#3daee9",
|
||||||
|
"panelFaint": "#eff0f1",
|
||||||
|
"topBar": "#31363b",
|
||||||
|
"topBarText": "#eff0f1",
|
||||||
|
"topBarLink": "#eff0f1",
|
||||||
|
"faintLink": "#3daee9",
|
||||||
|
"linkBg": "#366681",
|
||||||
|
"icon": "#909396",
|
||||||
|
"cBlue": "#3daee9",
|
||||||
|
"cRed": "#da4453",
|
||||||
|
"cGreen": "#27ae60",
|
||||||
|
"cOrange": "#f67400",
|
||||||
|
"alertError": "#da4453",
|
||||||
|
"alertErrorText": "#eff0f1",
|
||||||
|
"alertErrorPanelText": "#eff0f1",
|
||||||
|
"alertWarning": "#f67400",
|
||||||
|
"alertWarningText": "#eff0f1",
|
||||||
|
"alertWarningPanelText": "#eff0f1",
|
||||||
|
"badgeNotification": "#da4453",
|
||||||
|
"badgeNotificationText": "#ffffff"
|
||||||
|
},
|
||||||
|
"opacity": {
|
||||||
|
"panel": 0,
|
||||||
|
"btn": 1,
|
||||||
|
"border": 1,
|
||||||
|
"bg": 1,
|
||||||
|
"alert": 0.5,
|
||||||
|
"input": 0.5,
|
||||||
|
"faint": 0.5,
|
||||||
|
"underlay": 0.15
|
||||||
|
},
|
||||||
|
"radii": {
|
||||||
|
"btn": "2",
|
||||||
|
"input": "2",
|
||||||
|
"checkbox": "1",
|
||||||
|
"panel": "2",
|
||||||
|
"avatar": "2",
|
||||||
|
"avatarAlt": "2",
|
||||||
|
"tooltip": "2",
|
||||||
|
"attachment": "2"
|
||||||
|
},
|
||||||
|
"fonts": {
|
||||||
|
"interface": {
|
||||||
|
"family": "sans-serif"
|
||||||
|
},
|
||||||
|
"input": {
|
||||||
|
"family": "inherit"
|
||||||
|
},
|
||||||
|
"post": {
|
||||||
|
"family": "inherit"
|
||||||
|
},
|
||||||
|
"postCode": {
|
||||||
|
"family": "monospace"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"source": {
|
||||||
|
"themeEngineVersion": 3,
|
||||||
|
"fonts": {},
|
||||||
"shadows": {
|
"shadows": {
|
||||||
"panel": [
|
"panel": [
|
||||||
{
|
{
|
||||||
|
@ -105,21 +317,13 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"fonts": {},
|
"opacity": {},
|
||||||
"opacity": {
|
|
||||||
"input": "1"
|
|
||||||
},
|
|
||||||
"v3compat": {
|
|
||||||
"colors": {
|
|
||||||
"panel": "transparent"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"colors": {
|
"colors": {
|
||||||
"bg": "#31363b",
|
"bg": "#31363b",
|
||||||
"text": "#eff0f1",
|
"text": "#eff0f1",
|
||||||
"link": "#3daee9",
|
"link": "#3daee9",
|
||||||
"fg": "#31363b",
|
"fg": "#31363b",
|
||||||
"panel": "#31363b",
|
"panel": "transparent",
|
||||||
"input": "#232629",
|
"input": "#232629",
|
||||||
"topBarLink": "#eff0f1",
|
"topBarLink": "#eff0f1",
|
||||||
"btn": "#31363b",
|
"btn": "#31363b",
|
||||||
|
|
|
@ -2,6 +2,218 @@
|
||||||
"_pleroma_theme_version": 2,
|
"_pleroma_theme_version": 2,
|
||||||
"name": "Breezy Light (beta)",
|
"name": "Breezy Light (beta)",
|
||||||
"theme": {
|
"theme": {
|
||||||
|
"shadows": {
|
||||||
|
"panel": [
|
||||||
|
{
|
||||||
|
"x": "1",
|
||||||
|
"y": "2",
|
||||||
|
"blur": "6",
|
||||||
|
"spread": 0,
|
||||||
|
"color": "#000000",
|
||||||
|
"alpha": 0.6
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"topBar": [
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"blur": 4,
|
||||||
|
"spread": 0,
|
||||||
|
"color": "#000000",
|
||||||
|
"alpha": 0.6
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"popup": [
|
||||||
|
{
|
||||||
|
"x": 2,
|
||||||
|
"y": 2,
|
||||||
|
"blur": 3,
|
||||||
|
"spread": 0,
|
||||||
|
"color": "#000000",
|
||||||
|
"alpha": 0.5
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"avatar": [
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 1,
|
||||||
|
"blur": 8,
|
||||||
|
"spread": 0,
|
||||||
|
"color": "#000000",
|
||||||
|
"alpha": 0.7
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"avatarStatus": [],
|
||||||
|
"panelHeader": [
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": "40",
|
||||||
|
"blur": "40",
|
||||||
|
"spread": "-40",
|
||||||
|
"inset": true,
|
||||||
|
"color": "#ffffff",
|
||||||
|
"alpha": "0.1"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"button": [
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": "0",
|
||||||
|
"blur": "0",
|
||||||
|
"spread": "1",
|
||||||
|
"color": "#000000",
|
||||||
|
"alpha": "0.3",
|
||||||
|
"inset": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": "1",
|
||||||
|
"y": "1",
|
||||||
|
"blur": "1",
|
||||||
|
"spread": 0,
|
||||||
|
"color": "#000000",
|
||||||
|
"alpha": "0.3",
|
||||||
|
"inset": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"buttonHover": [
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": "0",
|
||||||
|
"blur": 0,
|
||||||
|
"spread": "1",
|
||||||
|
"color": "--accent",
|
||||||
|
"alpha": "0.3",
|
||||||
|
"inset": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": "1",
|
||||||
|
"y": "1",
|
||||||
|
"blur": "1",
|
||||||
|
"spread": 0,
|
||||||
|
"color": "#000000",
|
||||||
|
"alpha": "0.3",
|
||||||
|
"inset": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"buttonPressed": [
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"blur": "0",
|
||||||
|
"spread": "50",
|
||||||
|
"color": "--faint",
|
||||||
|
"alpha": 1,
|
||||||
|
"inset": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": "0",
|
||||||
|
"blur": 0,
|
||||||
|
"spread": "1",
|
||||||
|
"color": "#ffffff",
|
||||||
|
"alpha": 0.2,
|
||||||
|
"inset": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": "1",
|
||||||
|
"y": "1",
|
||||||
|
"blur": 0,
|
||||||
|
"spread": 0,
|
||||||
|
"color": "#000000",
|
||||||
|
"alpha": "0.3",
|
||||||
|
"inset": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"input": [
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": "0",
|
||||||
|
"blur": 0,
|
||||||
|
"spread": "1",
|
||||||
|
"color": "#000000",
|
||||||
|
"alpha": "0.2",
|
||||||
|
"inset": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"colors": {
|
||||||
|
"bg": "#eff0f1",
|
||||||
|
"underlay": "#000000",
|
||||||
|
"text": "#232627",
|
||||||
|
"lightText": "#000000",
|
||||||
|
"accent": "#2980b9",
|
||||||
|
"link": "#2980b9",
|
||||||
|
"faint": "#232627",
|
||||||
|
"lightBg": "#e2e4e6",
|
||||||
|
"fg": "#bcc2c7",
|
||||||
|
"fgText": "#232627",
|
||||||
|
"fgLink": "#2980b9",
|
||||||
|
"border": "#b7bdc3",
|
||||||
|
"btn": "#eff0f1",
|
||||||
|
"btnText": "#232627",
|
||||||
|
"input": "#fcfcfc",
|
||||||
|
"inputText": "#000000",
|
||||||
|
"panel": "#475057",
|
||||||
|
"panelText": "#fcfcfc",
|
||||||
|
"panelLink": "#ffffff",
|
||||||
|
"panelFaint": "#d8dbdc",
|
||||||
|
"topBar": "#475057",
|
||||||
|
"topBarText": "#d8dbdc",
|
||||||
|
"topBarLink": "#eff0f1",
|
||||||
|
"faintLink": "#2980b9",
|
||||||
|
"linkBg": "#a0c4db",
|
||||||
|
"icon": "#898b8c",
|
||||||
|
"cBlue": "#2980b9",
|
||||||
|
"cRed": "#da4453",
|
||||||
|
"cGreen": "#27ae60",
|
||||||
|
"cOrange": "#f67400",
|
||||||
|
"alertError": "#da4453",
|
||||||
|
"alertErrorText": "#232627",
|
||||||
|
"alertErrorPanelText": "#fcfcfc",
|
||||||
|
"alertWarning": "#f67400",
|
||||||
|
"alertWarningText": "#232627",
|
||||||
|
"alertWarningPanelText": "#fcfcfc",
|
||||||
|
"badgeNotification": "#da4453",
|
||||||
|
"badgeNotificationText": "#ffffff"
|
||||||
|
},
|
||||||
|
"opacity": {
|
||||||
|
"panel": 1,
|
||||||
|
"btn": 1,
|
||||||
|
"border": 1,
|
||||||
|
"bg": 1,
|
||||||
|
"alert": 0.5,
|
||||||
|
"input": "1",
|
||||||
|
"faint": 0.5,
|
||||||
|
"underlay": 0.15
|
||||||
|
},
|
||||||
|
"radii": {
|
||||||
|
"btn": "2",
|
||||||
|
"input": "2",
|
||||||
|
"checkbox": "1",
|
||||||
|
"panel": "2",
|
||||||
|
"avatar": "2",
|
||||||
|
"avatarAlt": "2",
|
||||||
|
"tooltip": "2",
|
||||||
|
"attachment": "2"
|
||||||
|
},
|
||||||
|
"fonts": {
|
||||||
|
"interface": {
|
||||||
|
"family": "sans-serif"
|
||||||
|
},
|
||||||
|
"input": {
|
||||||
|
"family": "inherit"
|
||||||
|
},
|
||||||
|
"post": {
|
||||||
|
"family": "inherit"
|
||||||
|
},
|
||||||
|
"postCode": {
|
||||||
|
"family": "monospace"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"source": {
|
||||||
|
"themeEngineVersion": 3,
|
||||||
|
"fonts": {},
|
||||||
"shadows": {
|
"shadows": {
|
||||||
"panel": [
|
"panel": [
|
||||||
{
|
{
|
||||||
|
@ -105,20 +317,14 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"fonts": {},
|
|
||||||
"opacity": {
|
"opacity": {
|
||||||
"input": "1"
|
"input": "1"
|
||||||
},
|
},
|
||||||
"v3compat": {
|
|
||||||
"colors": {
|
|
||||||
"panel": "transparent"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"colors": {
|
"colors": {
|
||||||
"bg": "#eff0f1",
|
"bg": "#eff0f1",
|
||||||
"text": "#232627",
|
"text": "#232627",
|
||||||
"link": "#2980b9",
|
|
||||||
"fg": "#bcc2c7",
|
"fg": "#bcc2c7",
|
||||||
|
"accent": "#2980b9",
|
||||||
"panel": "#475057",
|
"panel": "#475057",
|
||||||
"panelText": "#fcfcfc",
|
"panelText": "#fcfcfc",
|
||||||
"input": "#fcfcfc",
|
"input": "#fcfcfc",
|
||||||
|
|
Loading…
Reference in a new issue