From 6e1c538e4182263a75fb65b0f3c5d1ad9de94541 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Mon, 20 Jan 2020 01:31:54 +0200
Subject: [PATCH] multiple fixes to make style switcher not die. Made shadows
 work, incuding compatibility

---
 .../style_switcher/style_switcher.js          | 117 ++++++++++--------
 src/services/style_setter/style_setter.js     |  23 +++-
 src/services/theme_data/theme_data.service.js |   9 +-
 static/themes/breezy-dark.json                |   2 +-
 static/themes/breezy-light.json               |   2 +-
 5 files changed, 94 insertions(+), 59 deletions(-)

diff --git a/src/components/style_switcher/style_switcher.js b/src/components/style_switcher/style_switcher.js
index 2984873f..2a1e439b 100644
--- a/src/components/style_switcher/style_switcher.js
+++ b/src/components/style_switcher/style_switcher.js
@@ -11,7 +11,8 @@ import {
   generateRadii,
   generateFonts,
   composePreset,
-  getThemes
+  getThemes,
+  shadows2to3
 } from '../../services/style_setter/style_setter.js'
 import {
   CURRENT_VERSION,
@@ -159,62 +160,66 @@ export default {
     },
     // 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
-      })
-      const colorsConverted = Object.entries(colors).reduce((acc, [key, value]) => ({ ...acc, [key]: colorConvert(value) }), {})
+      try {
+        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
+        })
+        const colorsConverted = Object.entries(colors).reduce((acc, [key, value]) => ({ ...acc, [key]: colorConvert(value) }), {})
 
-      const ratios = Object.entries(SLOT_INHERITANCE).reduce((acc, [key, value]) => {
-        const slotIsBaseText = key === 'text' || key === 'link'
-        const slotIsText = slotIsBaseText || (
-          typeof value === 'object' && value !== null && value.textColor
-        )
-        if (!slotIsText) return acc
-        const { layer, variant } = slotIsBaseText ? { layer: 'bg' } : value
-        const background = variant || layer
-        const opacitySlot = getOpacitySlot(SLOT_INHERITANCE[background])
-        const textColors = [
-          key,
-          ...(background === 'bg' ? ['cRed', 'cGreen', 'cBlue', 'cOrange'] : [])
-        ]
+        const ratios = Object.entries(SLOT_INHERITANCE).reduce((acc, [key, value]) => {
+          const slotIsBaseText = key === 'text' || key === 'link'
+          const slotIsText = slotIsBaseText || (
+            typeof value === 'object' && value !== null && value.textColor
+          )
+          if (!slotIsText) return acc
+          const { layer, variant } = slotIsBaseText ? { layer: 'bg' } : value
+          const background = variant || layer
+          const opacitySlot = getOpacitySlot(SLOT_INHERITANCE[background])
+          const textColors = [
+            key,
+            ...(background === 'bg' ? ['cRed', 'cGreen', 'cBlue', 'cOrange'] : [])
+          ]
 
-        const layers = getLayers(
-          layer,
-          variant || layer,
-          opacitySlot,
-          colorsConverted,
-          opacity
-        )
+          const layers = getLayers(
+            layer,
+            variant || layer,
+            opacitySlot,
+            colorsConverted,
+            opacity
+          )
 
-        return {
-          ...acc,
-          ...textColors.reduce((acc, textColorKey) => {
-            const newKey = slotIsBaseText
-              ? 'bg' + textColorKey[0].toUpperCase() + textColorKey.slice(1)
-              : textColorKey
-            return {
-              ...acc,
-              [newKey]: getContrastRatioLayers(
-                colorsConverted[textColorKey],
-                layers,
-                colorsConverted[textColorKey]
-              )
-            }
-          }, {})
-        }
-      }, {})
+          return {
+            ...acc,
+            ...textColors.reduce((acc, textColorKey) => {
+              const newKey = slotIsBaseText
+                    ? 'bg' + textColorKey[0].toUpperCase() + textColorKey.slice(1)
+                    : textColorKey
+              return {
+                ...acc,
+                [newKey]: getContrastRatioLayers(
+                  colorsConverted[textColorKey],
+                  layers,
+                  colorsConverted[textColorKey]
+                )
+              }
+            }, {})
+          }
+        }, {})
 
-      return Object.entries(ratios).reduce((acc, [k, v]) => { acc[k] = hints(v); return acc }, {})
+        return Object.entries(ratios).reduce((acc, [k, v]) => { acc[k] = hints(v); return acc }, {})
+      } catch (e) {
+        console.warn('Failure computing contrasts', e)
+      }
     },
     previewRules () {
       if (!this.preview.rules) return ''
@@ -466,7 +471,11 @@ export default {
 
       if (!this.keepShadows) {
         this.clearShadows()
-        this.shadowsLocal = shadows
+        if (version === 2) {
+          this.shadowsLocal = shadows2to3(shadows)
+        } else {
+          this.shadowsLocal = shadows
+        }
         this.shadowSelected = this.shadowsAvailable[0]
       }
 
diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js
index 74af190c..ee264c49 100644
--- a/src/services/style_setter/style_setter.js
+++ b/src/services/style_setter/style_setter.js
@@ -291,8 +291,8 @@ export const generateShadows = (input, colors, mod) => {
   const shadows = Object.entries({
     ...DEFAULT_SHADOWS,
     ...(input.shadows || {})
-  }).reduce((shadowsAcc, [slotName, shadowdefs]) => {
-    const newShadow = shadowdefs.reduce((shadowAcc, def) => [
+  }).reduce((shadowsAcc, [slotName, shadowDefs]) => {
+    const newShadow = shadowDefs.reduce((shadowAcc, def) => [
       ...shadowAcc,
       {
         ...def,
@@ -380,6 +380,25 @@ export const getThemes = () => {
     })
 }
 
+/**
+ * This handles compatibility issues when importing v2 theme's shadows to current format
+ *
+ * Back in v2 shadows allowed you to use dynamic colors however those used pure CSS3 variables
+ */
+export const shadows2to3 = (shadows) => {
+  return Object.entries(shadows).reduce((shadowsAcc, [slotName, shadowDefs]) => {
+    const isDynamic = ({ color }) => console.log(color) || color.startsWith('--')
+    const newShadow = shadowDefs.reduce((shadowAcc, def) => [
+      ...shadowAcc,
+      {
+        ...def,
+        alpha: isDynamic(def) ? 1 : def.alpha
+      }
+    ], [])
+    return { ...shadowsAcc, [slotName]: newShadow }
+  }, {})
+}
+
 export const setPreset = (val, commit) => {
   return getThemes()
     .then((themes) => themes[val] ? themes[val] : themes['pleroma-dark'])
diff --git a/src/services/theme_data/theme_data.service.js b/src/services/theme_data/theme_data.service.js
index e4456b29..36837b44 100644
--- a/src/services/theme_data/theme_data.service.js
+++ b/src/services/theme_data/theme_data.service.js
@@ -663,7 +663,14 @@ export const SLOT_ORDERED = topoSort(
   Object.entries(SLOT_INHERITANCE)
     .sort(([aK, aV], [bK, bV]) => ((aV && aV.priority) || 0) - ((bV && bV.priority) || 0))
     .reduce((acc, [k, v]) => ({ ...acc, [k]: v }), {})
-)
+).sort((a, b) => {
+  const depsA = getDependencies(a, SLOT_INHERITANCE).length
+  const depsB = getDependencies(b, SLOT_INHERITANCE).length
+
+  if (depsA === depsB || (depsB !== 0 && depsA !== 0)) return 0
+  if (depsA === 0 && depsB !== 0) return -1
+  if (depsB === 0 && depsA !== 0) return 1
+})
 
 /**
  * Dictionary where keys are color slots and values are opacity associated
diff --git a/static/themes/breezy-dark.json b/static/themes/breezy-dark.json
index 97e81f3d..3aafda52 100644
--- a/static/themes/breezy-dark.json
+++ b/static/themes/breezy-dark.json
@@ -53,7 +53,7 @@
           "blur": 0,
           "spread": "1",
           "color": "--accent",
-          "alpha": "0.3",
+          "alpha": "1",
           "inset": true
         },
         {
diff --git a/static/themes/breezy-light.json b/static/themes/breezy-light.json
index fd307b80..df6e1a66 100644
--- a/static/themes/breezy-light.json
+++ b/static/themes/breezy-light.json
@@ -53,7 +53,7 @@
           "blur": 0,
           "spread": "1",
           "color": "--accent",
-          "alpha": "0.3",
+          "alpha": "1",
           "inset": true
         },
         {