aboutsummaryrefslogtreecommitdiff
path: root/src/components/style_switcher/style_switcher.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/style_switcher/style_switcher.js')
-rw-r--r--src/components/style_switcher/style_switcher.js580
1 files changed, 0 insertions, 580 deletions
diff --git a/src/components/style_switcher/style_switcher.js b/src/components/style_switcher/style_switcher.js
deleted file mode 100644
index ebde4475..00000000
--- a/src/components/style_switcher/style_switcher.js
+++ /dev/null
@@ -1,580 +0,0 @@
-import { rgb2hex, hex2rgb, getContrastRatio, alphaBlend } from '../../services/color_convert/color_convert.js'
-import { set, delete as del } from 'vue'
-import { generateColors, generateShadows, generateRadii, generateFonts, composePreset, getThemes } from '../../services/style_setter/style_setter.js'
-import ColorInput from '../color_input/color_input.vue'
-import RangeInput from '../range_input/range_input.vue'
-import OpacityInput from '../opacity_input/opacity_input.vue'
-import ShadowControl from '../shadow_control/shadow_control.vue'
-import FontControl from '../font_control/font_control.vue'
-import ContrastRatio from '../contrast_ratio/contrast_ratio.vue'
-import TabSwitcher from '../tab_switcher/tab_switcher.js'
-import Preview from './preview.vue'
-import ExportImport from '../export_import/export_import.vue'
-import Checkbox from '../checkbox/checkbox.vue'
-
-// List of color values used in v1
-const v1OnlyNames = [
- 'bg',
- 'fg',
- 'text',
- 'link',
- 'cRed',
- 'cGreen',
- 'cBlue',
- 'cOrange'
-].map(_ => _ + 'ColorLocal')
-
-export default {
- data () {
- return {
- availableStyles: [],
- selected: this.$store.getters.mergedConfig.theme,
-
- previewShadows: {},
- previewColors: {},
- previewRadii: {},
- previewFonts: {},
-
- shadowsInvalid: true,
- colorsInvalid: true,
- radiiInvalid: true,
-
- keepColor: false,
- keepShadows: false,
- keepOpacity: false,
- keepRoundness: false,
- keepFonts: false,
-
- textColorLocal: '',
- linkColorLocal: '',
-
- bgColorLocal: '',
- bgOpacityLocal: undefined,
-
- fgColorLocal: '',
- fgTextColorLocal: undefined,
- fgLinkColorLocal: undefined,
-
- btnColorLocal: undefined,
- btnTextColorLocal: undefined,
- btnOpacityLocal: undefined,
-
- inputColorLocal: undefined,
- inputTextColorLocal: undefined,
- inputOpacityLocal: undefined,
-
- panelColorLocal: undefined,
- panelTextColorLocal: undefined,
- panelLinkColorLocal: undefined,
- panelFaintColorLocal: undefined,
- panelOpacityLocal: undefined,
-
- topBarColorLocal: undefined,
- topBarTextColorLocal: undefined,
- topBarLinkColorLocal: undefined,
-
- alertErrorColorLocal: undefined,
- alertWarningColorLocal: undefined,
-
- badgeOpacityLocal: undefined,
- badgeNotificationColorLocal: undefined,
-
- borderColorLocal: undefined,
- borderOpacityLocal: undefined,
-
- faintColorLocal: undefined,
- faintOpacityLocal: undefined,
- faintLinkColorLocal: undefined,
-
- cRedColorLocal: '',
- cBlueColorLocal: '',
- cGreenColorLocal: '',
- cOrangeColorLocal: '',
-
- shadowSelected: undefined,
- shadowsLocal: {},
- fontsLocal: {},
-
- btnRadiusLocal: '',
- inputRadiusLocal: '',
- checkboxRadiusLocal: '',
- panelRadiusLocal: '',
- avatarRadiusLocal: '',
- avatarAltRadiusLocal: '',
- attachmentRadiusLocal: '',
- tooltipRadiusLocal: ''
- }
- },
- created () {
- const self = this
-
- getThemes().then((themesComplete) => {
- self.availableStyles = themesComplete
- })
- },
- mounted () {
- this.normalizeLocalState(this.$store.getters.mergedConfig.customTheme)
- if (typeof this.shadowSelected === 'undefined') {
- this.shadowSelected = this.shadowsAvailable[0]
- }
- },
- computed: {
- selectedVersion () {
- return Array.isArray(this.selected) ? 1 : 2
- },
- currentColors () {
- return {
- bg: this.bgColorLocal,
- text: this.textColorLocal,
- link: this.linkColorLocal,
-
- fg: this.fgColorLocal,
- fgText: this.fgTextColorLocal,
- fgLink: this.fgLinkColorLocal,
-
- panel: this.panelColorLocal,
- panelText: this.panelTextColorLocal,
- panelLink: this.panelLinkColorLocal,
- panelFaint: this.panelFaintColorLocal,
-
- input: this.inputColorLocal,
- inputText: this.inputTextColorLocal,
-
- topBar: this.topBarColorLocal,
- topBarText: this.topBarTextColorLocal,
- topBarLink: this.topBarLinkColorLocal,
-
- btn: this.btnColorLocal,
- btnText: this.btnTextColorLocal,
-
- alertError: this.alertErrorColorLocal,
- alertWarning: this.alertWarningColorLocal,
- badgeNotification: this.badgeNotificationColorLocal,
-
- faint: this.faintColorLocal,
- faintLink: this.faintLinkColorLocal,
- border: this.borderColorLocal,
-
- cRed: this.cRedColorLocal,
- cBlue: this.cBlueColorLocal,
- cGreen: this.cGreenColorLocal,
- cOrange: this.cOrangeColorLocal
- }
- },
- currentOpacity () {
- return {
- bg: this.bgOpacityLocal,
- btn: this.btnOpacityLocal,
- input: this.inputOpacityLocal,
- panel: this.panelOpacityLocal,
- topBar: this.topBarOpacityLocal,
- border: this.borderOpacityLocal,
- faint: this.faintOpacityLocal
- }
- },
- currentRadii () {
- return {
- btn: this.btnRadiusLocal,
- input: this.inputRadiusLocal,
- checkbox: this.checkboxRadiusLocal,
- panel: this.panelRadiusLocal,
- avatar: this.avatarRadiusLocal,
- avatarAlt: this.avatarAltRadiusLocal,
- tooltip: this.tooltipRadiusLocal,
- attachment: this.attachmentRadiusLocal
- }
- },
- preview () {
- return composePreset(this.previewColors, this.previewRadii, this.previewShadows, this.previewFonts)
- },
- previewTheme () {
- if (!this.preview.theme.colors) return { colors: {}, opacity: {}, radii: {}, shadows: {}, fonts: {} }
- return this.preview.theme
- },
- // This needs optimization maybe
- previewContrast () {
- if (!this.previewTheme.colors.bg) return {}
- const colors = this.previewTheme.colors
- const opacity = this.previewTheme.opacity
- if (!colors.bg) return {}
- const hints = (ratio) => ({
- text: ratio.toPrecision(3) + ':1',
- // AA level, AAA level
- aa: ratio >= 4.5,
- aaa: ratio >= 7,
- // same but for 18pt+ texts
- laa: ratio >= 3,
- laaa: ratio >= 4.5
- })
-
- // fgsfds :DDDD
- const fgs = {
- text: hex2rgb(colors.text),
- panelText: hex2rgb(colors.panelText),
- panelLink: hex2rgb(colors.panelLink),
- btnText: hex2rgb(colors.btnText),
- topBarText: hex2rgb(colors.topBarText),
- inputText: hex2rgb(colors.inputText),
-
- link: hex2rgb(colors.link),
- topBarLink: hex2rgb(colors.topBarLink),
-
- red: hex2rgb(colors.cRed),
- green: hex2rgb(colors.cGreen),
- blue: hex2rgb(colors.cBlue),
- orange: hex2rgb(colors.cOrange)
- }
-
- const bgs = {
- bg: hex2rgb(colors.bg),
- btn: hex2rgb(colors.btn),
- panel: hex2rgb(colors.panel),
- topBar: hex2rgb(colors.topBar),
- input: hex2rgb(colors.input),
- alertError: hex2rgb(colors.alertError),
- alertWarning: hex2rgb(colors.alertWarning),
- badgeNotification: hex2rgb(colors.badgeNotification)
- }
-
- /* This is a bit confusing because "bottom layer" used is text color
- * This is done to get worst case scenario when background below transparent
- * layer matches text color, making it harder to read the lower alpha is.
- */
- const ratios = {
- bgText: getContrastRatio(alphaBlend(bgs.bg, opacity.bg, fgs.text), fgs.text),
- bgLink: getContrastRatio(alphaBlend(bgs.bg, opacity.bg, fgs.link), fgs.link),
- bgRed: getContrastRatio(alphaBlend(bgs.bg, opacity.bg, fgs.red), fgs.red),
- bgGreen: getContrastRatio(alphaBlend(bgs.bg, opacity.bg, fgs.green), fgs.green),
- bgBlue: getContrastRatio(alphaBlend(bgs.bg, opacity.bg, fgs.blue), fgs.blue),
- bgOrange: getContrastRatio(alphaBlend(bgs.bg, opacity.bg, fgs.orange), fgs.orange),
-
- tintText: getContrastRatio(alphaBlend(bgs.bg, 0.5, fgs.panelText), fgs.text),
-
- panelText: getContrastRatio(alphaBlend(bgs.panel, opacity.panel, fgs.panelText), fgs.panelText),
- panelLink: getContrastRatio(alphaBlend(bgs.panel, opacity.panel, fgs.panelLink), fgs.panelLink),
-
- btnText: getContrastRatio(alphaBlend(bgs.btn, opacity.btn, fgs.btnText), fgs.btnText),
-
- inputText: getContrastRatio(alphaBlend(bgs.input, opacity.input, fgs.inputText), fgs.inputText),
-
- topBarText: getContrastRatio(alphaBlend(bgs.topBar, opacity.topBar, fgs.topBarText), fgs.topBarText),
- topBarLink: getContrastRatio(alphaBlend(bgs.topBar, opacity.topBar, fgs.topBarLink), fgs.topBarLink)
- }
-
- return Object.entries(ratios).reduce((acc, [k, v]) => { acc[k] = hints(v); return acc }, {})
- },
- previewRules () {
- if (!this.preview.rules) return ''
- return [
- ...Object.values(this.preview.rules),
- 'color: var(--text)',
- 'font-family: var(--interfaceFont, sans-serif)'
- ].join(';')
- },
- shadowsAvailable () {
- return Object.keys(this.previewTheme.shadows).sort()
- },
- currentShadowOverriden: {
- get () {
- return !!this.currentShadow
- },
- set (val) {
- if (val) {
- set(this.shadowsLocal, this.shadowSelected, this.currentShadowFallback.map(_ => Object.assign({}, _)))
- } else {
- del(this.shadowsLocal, this.shadowSelected)
- }
- }
- },
- currentShadowFallback () {
- return this.previewTheme.shadows[this.shadowSelected]
- },
- currentShadow: {
- get () {
- return this.shadowsLocal[this.shadowSelected]
- },
- set (v) {
- set(this.shadowsLocal, this.shadowSelected, v)
- }
- },
- themeValid () {
- return !this.shadowsInvalid && !this.colorsInvalid && !this.radiiInvalid
- },
- exportedTheme () {
- const saveEverything = (
- !this.keepFonts &&
- !this.keepShadows &&
- !this.keepOpacity &&
- !this.keepRoundness &&
- !this.keepColor
- )
-
- const theme = {}
-
- if (this.keepFonts || saveEverything) {
- theme.fonts = this.fontsLocal
- }
- if (this.keepShadows || saveEverything) {
- theme.shadows = this.shadowsLocal
- }
- if (this.keepOpacity || saveEverything) {
- theme.opacity = this.currentOpacity
- }
- if (this.keepColor || saveEverything) {
- theme.colors = this.currentColors
- }
- if (this.keepRoundness || saveEverything) {
- theme.radii = this.currentRadii
- }
-
- return {
- // To separate from other random JSON files and possible future theme formats
- _pleroma_theme_version: 2, theme
- }
- }
- },
- components: {
- ColorInput,
- OpacityInput,
- RangeInput,
- ContrastRatio,
- ShadowControl,
- FontControl,
- TabSwitcher,
- Preview,
- ExportImport,
- Checkbox
- },
- methods: {
- setCustomTheme () {
- this.$store.dispatch('setOption', {
- name: 'customTheme',
- value: {
- shadows: this.shadowsLocal,
- fonts: this.fontsLocal,
- opacity: this.currentOpacity,
- colors: this.currentColors,
- radii: this.currentRadii
- }
- })
- },
- onImport (parsed) {
- if (parsed._pleroma_theme_version === 1) {
- this.normalizeLocalState(parsed, 1)
- } else if (parsed._pleroma_theme_version === 2) {
- this.normalizeLocalState(parsed.theme, 2)
- }
- },
- importValidator (parsed) {
- const version = parsed._pleroma_theme_version
- return version >= 1 || version <= 2
- },
- clearAll () {
- const state = this.$store.getters.mergedConfig.customTheme
- const version = state.colors ? 2 : 'l1'
- this.normalizeLocalState(this.$store.getters.mergedConfig.customTheme, version)
- },
-
- // Clears all the extra stuff when loading V1 theme
- clearV1 () {
- Object.keys(this.$data)
- .filter(_ => _.endsWith('ColorLocal') || _.endsWith('OpacityLocal'))
- .filter(_ => !v1OnlyNames.includes(_))
- .forEach(key => {
- set(this.$data, key, undefined)
- })
- },
-
- clearRoundness () {
- Object.keys(this.$data)
- .filter(_ => _.endsWith('RadiusLocal'))
- .forEach(key => {
- set(this.$data, key, undefined)
- })
- },
-
- clearOpacity () {
- Object.keys(this.$data)
- .filter(_ => _.endsWith('OpacityLocal'))
- .forEach(key => {
- set(this.$data, key, undefined)
- })
- },
-
- clearShadows () {
- this.shadowsLocal = {}
- },
-
- clearFonts () {
- this.fontsLocal = {}
- },
-
- /**
- * This applies stored theme data onto form. Supports three versions of data:
- * v2 (version = 2) - newer version of themes.
- * v1 (version = 1) - older version of themes (import from file)
- * v1l (version = l1) - older version of theme (load from local storage)
- * v1 and v1l differ because of way themes were stored/exported.
- * @param {Object} input - input data
- * @param {Number} version - version of data. 0 means try to guess based on data. "l1" means v1, locastorage type
- */
- normalizeLocalState (input, version = 0) {
- const colors = input.colors || input
- const radii = input.radii || input
- const opacity = input.opacity
- const shadows = input.shadows || {}
- const fonts = input.fonts || {}
-
- if (version === 0) {
- if (input.version) version = input.version
- // Old v1 naming: fg is text, btn is foreground
- if (typeof colors.text === 'undefined' && typeof colors.fg !== 'undefined') {
- version = 1
- }
- // New v2 naming: text is text, fg is foreground
- if (typeof colors.text !== 'undefined' && typeof colors.fg !== 'undefined') {
- version = 2
- }
- }
-
- // Stuff that differs between V1 and V2
- if (version === 1) {
- this.fgColorLocal = rgb2hex(colors.btn)
- this.textColorLocal = rgb2hex(colors.fg)
- }
-
- if (!this.keepColor) {
- this.clearV1()
- const keys = new Set(version !== 1 ? Object.keys(colors) : [])
- if (version === 1 || version === 'l1') {
- keys
- .add('bg')
- .add('link')
- .add('cRed')
- .add('cBlue')
- .add('cGreen')
- .add('cOrange')
- }
-
- keys.forEach(key => {
- this[key + 'ColorLocal'] = rgb2hex(colors[key])
- })
- }
-
- if (!this.keepRoundness) {
- this.clearRoundness()
- Object.entries(radii).forEach(([k, v]) => {
- // 'Radius' is kept mostly for v1->v2 localstorage transition
- const key = k.endsWith('Radius') ? k.split('Radius')[0] : k
- this[key + 'RadiusLocal'] = v
- })
- }
-
- if (!this.keepShadows) {
- this.clearShadows()
- this.shadowsLocal = shadows
- this.shadowSelected = this.shadowsAvailable[0]
- }
-
- if (!this.keepFonts) {
- this.clearFonts()
- this.fontsLocal = fonts
- }
-
- if (opacity && !this.keepOpacity) {
- this.clearOpacity()
- Object.entries(opacity).forEach(([k, v]) => {
- if (typeof v === 'undefined' || v === null || Number.isNaN(v)) return
- this[k + 'OpacityLocal'] = v
- })
- }
- }
- },
- watch: {
- currentRadii () {
- try {
- this.previewRadii = generateRadii({ radii: this.currentRadii })
- this.radiiInvalid = false
- } catch (e) {
- this.radiiInvalid = true
- console.warn(e)
- }
- },
- shadowsLocal: {
- handler () {
- try {
- this.previewShadows = generateShadows({ shadows: this.shadowsLocal })
- this.shadowsInvalid = false
- } catch (e) {
- this.shadowsInvalid = true
- console.warn(e)
- }
- },
- deep: true
- },
- fontsLocal: {
- handler () {
- try {
- this.previewFonts = generateFonts({ fonts: this.fontsLocal })
- this.fontsInvalid = false
- } catch (e) {
- this.fontsInvalid = true
- console.warn(e)
- }
- },
- deep: true
- },
- currentColors () {
- try {
- this.previewColors = generateColors({
- opacity: this.currentOpacity,
- colors: this.currentColors
- })
- this.colorsInvalid = false
- } catch (e) {
- this.colorsInvalid = true
- console.warn(e)
- }
- },
- currentOpacity () {
- try {
- this.previewColors = generateColors({
- opacity: this.currentOpacity,
- colors: this.currentColors
- })
- } catch (e) {
- console.warn(e)
- }
- },
- selected () {
- if (this.selectedVersion === 1) {
- if (!this.keepRoundness) {
- this.clearRoundness()
- }
-
- if (!this.keepShadows) {
- this.clearShadows()
- }
-
- if (!this.keepOpacity) {
- this.clearOpacity()
- }
-
- if (!this.keepColor) {
- this.clearV1()
-
- this.bgColorLocal = this.selected[1]
- this.fgColorLocal = this.selected[2]
- this.textColorLocal = this.selected[3]
- this.linkColorLocal = this.selected[4]
- this.cRedColorLocal = this.selected[5]
- this.cGreenColorLocal = this.selected[6]
- this.cBlueColorLocal = this.selected[7]
- this.cOrangeColorLocal = this.selected[8]
- }
- } else if (this.selectedVersion >= 2) {
- this.normalizeLocalState(this.selected.theme, 2)
- }
- }
- }
-}