From 96804d42f0f6aa6af85295933af6fd267b19e473 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Sun, 7 Oct 2018 19:59:22 +0300
Subject: Some themeing is working!!

---
 src/components/timeline/timeline.vue | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

(limited to 'src/components/timeline/timeline.vue')

diff --git a/src/components/timeline/timeline.vue b/src/components/timeline/timeline.vue
index 2dd4376a..77a9a2af 100644
--- a/src/components/timeline/timeline.vue
+++ b/src/components/timeline/timeline.vue
@@ -61,12 +61,12 @@
     opacity: 0.8;
     background-color: transparent;
     color: $fallback--faint;
-    color: var(--faint, $fallback--faint);
+    color: var(--panelFaint, $fallback--faint);
   }
 
   .loadmore-error {
-    color: $fallback--fg;
-    color: var(--fg, $fallback--fg);
+    color: $fallback--text;
+    color: var(--text, $fallback--text);
   }
 }
 
@@ -79,7 +79,7 @@
   border-color: var(--border, $fallback--border);
   padding: 10px;
   z-index: 1;
-  background-color: $fallback--btn;
-  background-color: var(--btn, $fallback--btn);
+  background-color: $fallback--fg;
+  background-color: var(--fg, $fallback--fg);
 }
 </style>
-- 
cgit v1.2.3-70-g09d2


From e7fe2dc9f9e52771c2ffe8d0ee1c4e8b2e38ab2f Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Wed, 14 Nov 2018 19:39:17 +0300
Subject: collateral fixes, removed alpha control for alerts, added contrast
 text generation for alerts, updated getTextColor to also have fallback to
 black/white if resulting contrast isn't passable (only when inverting
 lightness!), updated UI to use tabs.

---
 src/App.js                                        |   7 +-
 src/App.scss                                      |   9 +-
 src/components/contrast_ratio/contrast_ratio.vue  |   4 +-
 src/components/delete_button/delete_button.vue    |   2 +-
 src/components/notifications/notifications.scss   |  10 +-
 src/components/style_switcher/style_switcher.js   |  40 ++--
 src/components/style_switcher/style_switcher.vue  | 257 +++++++++++-----------
 src/components/timeline/timeline.vue              |   5 -
 src/services/color_convert/color_convert.js       |  23 +-
 src/services/style_setter/style_setter.js         |  28 ++-
 src/services/user_highlighter/user_highlighter.js |   2 +-
 11 files changed, 200 insertions(+), 187 deletions(-)

(limited to 'src/components/timeline/timeline.vue')

diff --git a/src/App.js b/src/App.js
index 05e3eda3..b06e8b5d 100644
--- a/src/App.js
+++ b/src/App.js
@@ -59,7 +59,12 @@ export default {
       })
     },
     logo () { return this.$store.state.instance.logo },
-    style () { return { 'background-image': `url(${this.background})` } },
+    style () {
+      return {
+        '--body-background-image': `url(${this.background})`,
+        'background-image': `url(${this.background})`
+      }
+    },
     sitename () { return this.$store.state.instance.name },
     chat () { return this.$store.state.chat.channel.state === 'joined' },
     suggestionsEnabled () { return this.$store.state.instance.suggestionsEnabled },
diff --git a/src/App.scss b/src/App.scss
index 0a2ff5cc..8fb3c488 100644
--- a/src/App.scss
+++ b/src/App.scss
@@ -473,14 +473,19 @@ nav {
   padding: 0.25em;
   border-radius: $fallback--tooltipRadius;
   border-radius: var(--tooltipRadius, $fallback--tooltipRadius);
-  color: $fallback--faint;
-  color: var(--faint, $fallback--faint);
   min-height: 28px;
   line-height: 28px;
 
   &.error {
     background-color: $fallback--alertError;
     background-color: var(--alertError, $fallback--alertError);
+    color: $fallback--text;
+    color: var(--alertErrorText, $fallback--text);
+
+    .panel-heading & {
+      color: $fallback--text;
+      color: var(--alertErrorPanelText, $fallback--text);
+    }
   }
 }
 
diff --git a/src/components/contrast_ratio/contrast_ratio.vue b/src/components/contrast_ratio/contrast_ratio.vue
index a428e75f..cb65c371 100644
--- a/src/components/contrast_ratio/contrast_ratio.vue
+++ b/src/components/contrast_ratio/contrast_ratio.vue
@@ -1,5 +1,5 @@
 <template>
-<span class="contrast-ratio">
+<span  v-if="contrast" class="contrast-ratio">
   <span :title="`Contrast is ${contrast.text}`" class="rating">
     <span v-if="contrast.aaa">
       <i class="icon-thumbs-up-alt"/>
@@ -11,7 +11,7 @@
       <i class="icon-attention"/>
     </span>
   </span>
-  <span class="rating" v-if="large" :title="`Contrast is ${contrast.text} (18pt+)`">
+  <span class="rating" v-if="contrast && large" :title="`Contrast is ${contrast.text} (18pt+)`">
     <span v-if="contrast.aaa">
       <i class="icon-thumbs-up-alt"/>
     </span>
diff --git a/src/components/delete_button/delete_button.vue b/src/components/delete_button/delete_button.vue
index d13547e2..b458b0dc 100644
--- a/src/components/delete_button/delete_button.vue
+++ b/src/components/delete_button/delete_button.vue
@@ -14,8 +14,8 @@
 .icon-cancel,.delete-status {
   cursor: pointer;
   &:hover {
-    color: var(--cRed, $fallback--cRed);
     color: $fallback--cRed;
+    color: var(--cRed, $fallback--cRed);
   }
 }
 </style>
diff --git a/src/components/notifications/notifications.scss b/src/components/notifications/notifications.scss
index 98fdd3f5..fcc0c3d4 100644
--- a/src/components/notifications/notifications.scss
+++ b/src/components/notifications/notifications.scss
@@ -8,13 +8,13 @@
     display: inline-block;
     background-color: $fallback--cRed;
     background-color: var(--badgeNotification, $fallback--cRed);
-    text-shadow: 0px 0px 3px rgba(0, 0, 0, 0.5);
     border-radius: 99px;
     min-width: 22px;
     max-width: 22px;
     min-height: 22px;
     max-height: 22px;
     color: white;
+    color: var(--badgeNotificationText, white);
     font-size: 15px;
     line-height: 22px;
     text-align: center;
@@ -27,8 +27,8 @@
   }
 
   .unseen {
-    box-shadow: inset 4px 0 0 var(--badgeNotification, $fallback--cRed);
-    padding-left: 0;
+
+    background-image: linear-gradient(135deg, var(--badgeNotification, $fallback--cRed) 4px, transparent 10px)
   }
 }
 
@@ -42,8 +42,8 @@
   .broken-favorite {
     border-radius: $fallback--tooltipRadius;
     border-radius: var(--tooltipRadius, $fallback--tooltipRadius);
-    color: $fallback--faint;
-    color: var(--faint, $fallback--faint);
+    color: $fallback--text;
+    color: var(--alertErrorText, $fallback--text);
     background-color: $fallback--alertError;
     background-color: var(--alertError, $fallback--alertError);
     padding: 2px .5em
diff --git a/src/components/style_switcher/style_switcher.js b/src/components/style_switcher/style_switcher.js
index 8953dc49..9e236488 100644
--- a/src/components/style_switcher/style_switcher.js
+++ b/src/components/style_switcher/style_switcher.js
@@ -1,8 +1,9 @@
-import { rgb2hex, hex2rgb, getContrastRatio, worstCase } from '../../services/color_convert/color_convert.js'
+import { rgb2hex, hex2rgb, getContrastRatio, alphaBlend } from '../../services/color_convert/color_convert.js'
 import ColorInput from '../color_input/color_input.vue'
 import ContrastRatio from '../contrast_ratio/contrast_ratio.vue'
 import OpacityInput from '../opacity_input/opacity_input.vue'
 import StyleSetter from '../../services/style_setter/style_setter.js'
+import TabSwitcher from '../tab_switcher/tab_switcher.jsx'
 
 export default {
   data () {
@@ -38,7 +39,6 @@ export default {
       topBarTextColorLocal: undefined,
       topBarLinkColorLocal: undefined,
 
-      alertOpacityLocal: undefined,
       alertErrorColorLocal: undefined,
 
       badgeOpacityLocal: undefined,
@@ -123,8 +123,6 @@ export default {
           btn: this.btnOpacityLocal,
           input: this.inputOpacityLocal,
           panel: this.panelOpacityLocal,
-          alert: this.alertOpacityLocal,
-          badge: this.badgeOpacityLocal,
           topBar: this.topBarOpacityLocal,
           border: this.borderOpacityLocal,
           faint: this.faintOpacityLocal
@@ -160,6 +158,7 @@ export default {
       if (!this.previewTheme.colors) 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
@@ -197,26 +196,28 @@ export default {
         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(worstCase(bgs.bg, opacity.bg, fgs.text), fgs.text),
-        bgLink: getContrastRatio(worstCase(bgs.bg, opacity.bg, fgs.link), fgs.link),
-        bgRed: getContrastRatio(worstCase(bgs.bg, opacity.bg, fgs.red), fgs.red),
-        bgGreen: getContrastRatio(worstCase(bgs.bg, opacity.bg, fgs.green), fgs.green),
-        bgBlue: getContrastRatio(worstCase(bgs.bg, opacity.bg, fgs.blue), fgs.blue),
-        bgOrange: getContrastRatio(worstCase(bgs.bg, opacity.bg, fgs.orange), fgs.orange),
+        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(worstCase(bgs.bg, 0.5, fgs.panelText), fgs.text),
+        tintText: getContrastRatio(alphaBlend(bgs.bg, 0.5, fgs.panelText), fgs.text),
 
-        panelText: getContrastRatio(worstCase(bgs.panel, opacity.panel, fgs.panelText), fgs.panelText),
+        panelText: getContrastRatio(alphaBlend(bgs.panel, opacity.panel, fgs.panelText), fgs.panelText),
 
-        btnText: getContrastRatio(worstCase(bgs.btn, opacity.btn, fgs.btnText), fgs.btnText),
+        btnText: getContrastRatio(alphaBlend(bgs.btn, opacity.btn, fgs.btnText), fgs.btnText),
 
-        inputText: getContrastRatio(worstCase(bgs.input, opacity.input, fgs.inputText), fgs.inputText),
+        inputText: getContrastRatio(alphaBlend(bgs.input, opacity.input, fgs.inputText), fgs.inputText),
 
-        badgeNotification: getContrastRatio(worstCase(bgs.badgeNotification, opacity.badge, fgs.text), fgs.text),
-
-        topBarText: getContrastRatio(worstCase(bgs.topBar, opacity.topBar, fgs.topBarText), fgs.topBarText),
-        topBarLink: getContrastRatio(worstCase(bgs.topBar, opacity.topBar, fgs.topBarLink), fgs.topBarLink)
+        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 }, {})
@@ -229,7 +230,8 @@ export default {
   components: {
     ColorInput,
     OpacityInput,
-    ContrastRatio
+    ContrastRatio,
+    TabSwitcher
   },
   methods: {
     exportCurrentTheme () {
diff --git a/src/components/style_switcher/style_switcher.vue b/src/components/style_switcher/style_switcher.vue
index f4b4e88f..5bc38318 100644
--- a/src/components/style_switcher/style_switcher.vue
+++ b/src/components/style_switcher/style_switcher.vue
@@ -24,8 +24,8 @@
     </div>
   </div>
 
-  <div class="preview-container" :style="previewRules">
-    <div class="panel dummy">
+  <div class="preview-container">
+    <div class="panel dummy" :style="previewRules">
       <div class="panel-heading">Preview</div>
       <div class="panel-body theme-preview-content">
         <div class="avatar">
@@ -45,132 +45,132 @@
     </div>
   </div>
 
-  <div class="color-container">
     <p>{{$t('settings.theme_help')}}</p>
-    <h3>Basic colors!!</h3>
-    <div>
-      <div class="color-item">
-        <ColorInput name="bgColor" v-model="bgColorLocal" :label="$t('settings.background')"/>
-        <OpacityInput name="bgOpacity" v-model="bgOpacityLocal" :fallback="previewTheme.opacity.bg || 1"/>
-        <ColorInput name="textColor" v-model="textColorLocal" :label="$t('settings.text')"/>
-        <ContrastRatio :contrast="previewContrast.bgText"/>
-        <ColorInput name="linkColor" v-model="linkColorLocal" :label="$t('settings.links')"/>
-        <ContrastRatio :contrast="previewContrast.bgLink"/>
-      </div>
-      <div class="color-item">
-        <ColorInput name="fgColor" v-model="fgColorLocal" :label="$t('settings.foreground')"/>
-        <ColorInput name="fgTextColor" v-model="fgTextColorLocal" :label="$t('settings.text')" :fallback="previewTheme.colors.fgText"/>
-        <ColorInput name="fgLinkColor" v-model="fgLinkColorLocal" :label="$t('settings.links')" :fallback="previewTheme.colors.fgLink"/>
-      </div>
-      <div class="color-item">
-        <ColorInput name="cRedColor" v-model="cRedColorLocal" :label="$t('settings.cRed')"/>
-        <ContrastRatio :contrast="previewContrast.bgRed"/>
-        <ColorInput name="cBlueColor" v-model="cBlueColorLocal" :label="$t('settings.cBlue')"/>
-        <ContrastRatio :contrast="previewContrast.bgBlue"/>
-      </div>
-      <div class="color-item">
-        <ColorInput name="cGreenColor" v-model="cGreenColorLocal" :label="$t('settings.cGreen')"/>
-        <ContrastRatio :contrast="previewContrast.bgGreen"/>
-        <ColorInput name="cOrangeColor" v-model="cOrangeColorLocal" :label="$t('settings.cOrange')"/>
-        <ContrastRatio :contrast="previewContrast.bgOrange"/>
+    <tab-switcher>
+      <div label="Basic" class="color-container">
+        <div class="color-item">
+          <h4>Main colors</h4>
+          <ColorInput name="bgColor" v-model="bgColorLocal" :label="$t('settings.background')"/>
+          <OpacityInput name="bgOpacity" v-model="bgOpacityLocal" :fallback="previewTheme.opacity.bg || 1"/>
+          <ColorInput name="textColor" v-model="textColorLocal" :label="$t('settings.text')"/>
+          <ContrastRatio :contrast="previewContrast.bgText"/>
+          <ColorInput name="linkColor" v-model="linkColorLocal" :label="$t('settings.links')"/>
+          <ContrastRatio :contrast="previewContrast.bgLink"/>
+        </div>
+        <div class="color-item">
+          <h4>Panel header, top bar, buttons, text fields</h4>
+          <ColorInput name="fgColor" v-model="fgColorLocal" :label="$t('settings.foreground')"/>
+          <ColorInput name="fgTextColor" v-model="fgTextColorLocal" :label="$t('settings.text')" :fallback="previewTheme.colors.fgText"/>
+          <ColorInput name="fgLinkColor" v-model="fgLinkColorLocal" :label="$t('settings.links')" :fallback="previewTheme.colors.fgLink"/>
+          <p>See "Advanced" tab for more detailed control</p>
+        </div>
+        <div class="color-item">
+          <h4>Icons, alerts, etc.</h4>
+          <ColorInput name="cRedColor" v-model="cRedColorLocal" :label="$t('settings.cRed')"/>
+          <ContrastRatio :contrast="previewContrast.bgRed"/>
+          <ColorInput name="cBlueColor" v-model="cBlueColorLocal" :label="$t('settings.cBlue')"/>
+          <ContrastRatio :contrast="previewContrast.bgBlue"/>
+        </div>
+        <div class="color-item">
+          <h4>.</h4>
+          <ColorInput name="cGreenColor" v-model="cGreenColorLocal" :label="$t('settings.cGreen')"/>
+          <ContrastRatio :contrast="previewContrast.bgGreen"/>
+          <ColorInput name="cOrangeColor" v-model="cOrangeColorLocal" :label="$t('settings.cOrange')"/>
+          <ContrastRatio :contrast="previewContrast.bgOrange"/>
+        </div>
       </div>
-    </div>
 
-    <h3>More customs!</h3>
-    <div>
-      <div class="color-item">
-        <h4>Alerts</h4>
-        <ColorInput name="alertError" v-model="alertErrorColorLocal" :label="$t('settings.error')" :fallback="previewTheme.colors.alertError"/>
-        <OpacityInput name="alertOpacity" v-model="alertOpacityLocal" :fallback="previewTheme.opacity.alert || 1"/>
-      </div>
-      <div class="color-item">
-        <h4>Alerts</h4>
-        <ColorInput name="badgeNotification" v-model="badgeNotificationColorLocal" :label="$t('settings.notification')" :fallback="previewTheme.colors.badgeNotification"/>
-        <ContrastRatio :contrast="previewContrast.badgeNotification"/>
-        <OpacityInput name="badgeOpacity" v-model="badgeOpacityLocal" :fallback="previewTheme.opacity.badge || 1"/>
-      </div>
-      <div class="color-item">
-        <h4>Panel header</h4>
-        <ColorInput name="panelColor" v-model="panelColorLocal" :fallback="fgColorLocal" :label="$t('settings.background')"/>
-        <OpacityInput name="panelOpacity" v-model="panelOpacityLocal" :fallback="previewTheme.opacity.panel || 1"/>
-        <ColorInput name="panelTextColor" v-model="panelTextColorLocal" :fallback="previewTheme.colors.panelText" :label="$t('settings.links')"/>
-        <ContrastRatio :contrast="previewContrast.panelText" large="1"/>
-      </div>
-      <div class="color-item">
-        <h4>Top bar</h4>
-        <ColorInput name="topBarColor" v-model="topBarColorLocal" :fallback="fgColorLocal" :label="$t('settings.background')"/>
-        <ColorInput name="topBarTextColor" v-model="topBarTextColorLocal" :fallback="previewTheme.colors.topBarText" :label="$t('settings.text')"/>
-        <ContrastRatio :contrast="previewContrast.topBarText"/>
-        <ColorInput name="topBarLinkColor" v-model="topBarLinkColorLocal" :fallback="previewTheme.colors.topBarLink" :label="$t('settings.links')"/>
-        <ContrastRatio :contrast="previewContrast.topBarLink"/>
-      </div>
-      <div class="color-item">
-        <h4>Text fields</h4>
-        <ColorInput name="inputColor" v-model="inputColorLocal" :fallback="fgColorLocal" :label="$t('settings.background')"/>
-        <OpacityInput name="inputOpacity" v-model="inputOpacityLocal" :fallback="previewTheme.opacity.input || 1"/>
-        <ColorInput name="inputTextColor" v-model="inputTextColorLocal" :fallback="previewTheme.colors.inputText" :label="$t('settings.text')"/>
-        <ContrastRatio :contrast="previewContrast.inputText"/>
-      </div>
-      <div class="color-item">
-        <h4>Buttons</h4>
-        <ColorInput name="btnColor" v-model="btnColorLocal" :fallback="fgColorLocal" :label="$t('settings.background')"/>
-        <OpacityInput name="btnOpacity" v-model="btnOpacityLocal" :fallback="previewTheme.opacity.btn || 1"/>
-        <ColorInput name="btnTextColor" v-model="btnTextColorLocal" :fallback="previewTheme.colors.btnText" :label="$t('settings.text')"/>
-        <ContrastRatio :contrast="previewContrast.btnText"/>
-      </div>
-      <div class="color-item">
-        <h4>Borders</h4>
-        <ColorInput name="borderColor" v-model="borderColorLocal" :fallback="previewTheme.colors.border" label="Color"/>
-        <OpacityInput name="borderOpacity" v-model="borderOpacityLocal" :fallback="previewTheme.opacity.border || 1"/>
+      <div label="Advanced" class="color-container">
+        <div class="color-item">
+          <h4>Alerts</h4>
+          <ColorInput name="alertError" v-model="alertErrorColorLocal" :label="$t('settings.error')" :fallback="previewTheme.colors.alertError"/>
+          <ContrastRatio :contrast="previewContrast.alertError"/>
+        </div>
+        <div class="color-item">
+          <h4>Badges</h4>
+          <ColorInput name="badgeNotification" v-model="badgeNotificationColorLocal" :label="$t('settings.notification')" :fallback="previewTheme.colors.badgeNotification"/>
+        </div>
+        <div class="color-item">
+          <h4>Panel header</h4>
+          <ColorInput name="panelColor" v-model="panelColorLocal" :fallback="fgColorLocal" :label="$t('settings.background')"/>
+          <OpacityInput name="panelOpacity" v-model="panelOpacityLocal" :fallback="previewTheme.opacity.panel || 1"/>
+          <ColorInput name="panelTextColor" v-model="panelTextColorLocal" :fallback="previewTheme.colors.panelText" :label="$t('settings.links')"/>
+          <ContrastRatio :contrast="previewContrast.panelText" large="1"/>
+        </div>
+        <div class="color-item">
+          <h4>Top bar</h4>
+          <ColorInput name="topBarColor" v-model="topBarColorLocal" :fallback="fgColorLocal" :label="$t('settings.background')"/>
+          <ColorInput name="topBarTextColor" v-model="topBarTextColorLocal" :fallback="previewTheme.colors.topBarText" :label="$t('settings.text')"/>
+          <ContrastRatio :contrast="previewContrast.topBarText"/>
+          <ColorInput name="topBarLinkColor" v-model="topBarLinkColorLocal" :fallback="previewTheme.colors.topBarLink" :label="$t('settings.links')"/>
+          <ContrastRatio :contrast="previewContrast.topBarLink"/>
+        </div>
+        <div class="color-item">
+          <h4>Text fields</h4>
+          <ColorInput name="inputColor" v-model="inputColorLocal" :fallback="fgColorLocal" :label="$t('settings.background')"/>
+          <OpacityInput name="inputOpacity" v-model="inputOpacityLocal" :fallback="previewTheme.opacity.input || 1"/>
+          <ColorInput name="inputTextColor" v-model="inputTextColorLocal" :fallback="previewTheme.colors.inputText" :label="$t('settings.text')"/>
+          <ContrastRatio :contrast="previewContrast.inputText"/>
+        </div>
+        <div class="color-item">
+          <h4>Buttons</h4>
+          <ColorInput name="btnColor" v-model="btnColorLocal" :fallback="fgColorLocal" :label="$t('settings.background')"/>
+          <OpacityInput name="btnOpacity" v-model="btnOpacityLocal" :fallback="previewTheme.opacity.btn || 1"/>
+          <ColorInput name="btnTextColor" v-model="btnTextColorLocal" :fallback="previewTheme.colors.btnText" :label="$t('settings.text')"/>
+          <ContrastRatio :contrast="previewContrast.btnText"/>
+        </div>
+        <div class="color-item">
+          <h4>Borders</h4>
+          <ColorInput name="borderColor" v-model="borderColorLocal" :fallback="previewTheme.colors.border" label="Color"/>
+          <OpacityInput name="borderOpacity" v-model="borderOpacityLocal" :fallback="previewTheme.opacity.border || 1"/>
+        </div>
+        <div class="color-item">
+          <h4>Faint text</h4>
+          <ColorInput name="faintColor" v-model="faintColorLocal" :fallback="previewTheme.colors.faint || 1" :label="$t('settings.text')"/>
+          <ColorInput name="faintLinkColor" v-model="faintLinkColorLocal" :fallback="previewTheme.colors.faintLink" :label="$t('settings.links')"/>
+          <ColorInput name="panelFaintColor" v-model="panelFaintColorLocal" :fallback="previewTheme.colors.panelFaint" :label="$t('settings.panel')"/>
+          <OpacityInput name="faintOpacity" v-model="faintOpacityLocal" :fallback="previewTheme.opacity.faint || 0.5"/>
+        </div>
       </div>
-      <div class="color-item">
-        <h4>Faint text</h4>
-        <ColorInput name="faintColor" v-model="faintColorLocal" :fallback="previewTheme.colors.faint || 1" :label="$t('settings.text')"/>
-        <ColorInput name="faintLinkColor" v-model="faintLinkColorLocal" :fallback="previewTheme.colors.faintLink" :label="$t('settings.links')"/>
-        <ColorInput name="panelFaintColor" v-model="panelFaintColorLocal" :fallback="previewTheme.colors.panelFaint" :label="$t('settings.panel')"/>
-        <OpacityInput name="faintOpacity" v-model="faintOpacityLocal" :fallback="previewTheme.opacity.faint || 0.5"/>
+      <div label="Roundness" class="radius-container">
+        <p>{{$t('settings.radii_help')}}</p>
+        <div class="radius-item">
+          <label for="btnradius" class="theme-radius-lb">{{$t('settings.btnRadius')}}</label>
+          <input id="btnradius" class="theme-radius-rn" type="range" v-model="btnRadiusLocal" max="16">
+          <input id="btnradius-t" class="theme-radius-in" type="text" v-model="btnRadiusLocal">
+        </div>
+        <div class="radius-item">
+          <label for="inputradius" class="theme-radius-lb">{{$t('settings.inputRadius')}}</label>
+          <input id="inputradius" class="theme-radius-rn" type="range" v-model="inputRadiusLocal" max="16">
+          <input id="inputradius-t" class="theme-radius-in" type="text" v-model="inputRadiusLocal">
+        </div>
+        <div class="radius-item">
+          <label for="panelradius" class="theme-radius-lb">{{$t('settings.panelRadius')}}</label>
+          <input id="panelradius" class="theme-radius-rn" type="range" v-model="panelRadiusLocal" max="50">
+          <input id="panelradius-t" class="theme-radius-in" type="text" v-model="panelRadiusLocal">
+        </div>
+        <div class="radius-item">
+          <label for="avatarradius" class="theme-radius-lb">{{$t('settings.avatarRadius')}}</label>
+          <input id="avatarradius" class="theme-radius-rn" type="range" v-model="avatarRadiusLocal" max="28">
+          <input id="avatarradius-t" class="theme-radius-in" type="green" v-model="avatarRadiusLocal">
+        </div>
+        <div class="radius-item">
+          <label for="avataraltradius" class="theme-radius-lb">{{$t('settings.avatarAltRadius')}}</label>
+          <input id="avataraltradius" class="theme-radius-rn" type="range" v-model="avatarAltRadiusLocal" max="28">
+          <input id="avataraltradius-t" class="theme-radius-in" type="text" v-model="avatarAltRadiusLocal">
+        </div>
+        <div class="radius-item">
+          <label for="attachmentradius" class="theme-radius-lb">{{$t('settings.attachmentRadius')}}</label>
+          <input id="attachmentrradius" class="theme-radius-rn" type="range" v-model="attachmentRadiusLocal" max="50">
+          <input id="attachmentradius-t" class="theme-radius-in" type="text" v-model="attachmentRadiusLocal">
+        </div>
+        <div class="radius-item">
+          <label for="tooltipradius" class="theme-radius-lb">{{$t('settings.tooltipRadius')}}</label>
+          <input id="tooltipradius" class="theme-radius-rn" type="range" v-model="tooltipRadiusLocal" max="20">
+          <input id="tooltipradius-t" class="theme-radius-in" type="text" v-model="tooltipRadiusLocal">
+        </div>
       </div>
-    </div>
-  </div>
-
-  <div class="radius-container">
-    <p>{{$t('settings.radii_help')}}</p>
-    <div class="radius-item">
-      <label for="btnradius" class="theme-radius-lb">{{$t('settings.btnRadius')}}</label>
-      <input id="btnradius" class="theme-radius-rn" type="range" v-model="btnRadiusLocal" max="16">
-      <input id="btnradius-t" class="theme-radius-in" type="text" v-model="btnRadiusLocal">
-    </div>
-    <div class="radius-item">
-      <label for="inputradius" class="theme-radius-lb">{{$t('settings.inputRadius')}}</label>
-      <input id="inputradius" class="theme-radius-rn" type="range" v-model="inputRadiusLocal" max="16">
-      <input id="inputradius-t" class="theme-radius-in" type="text" v-model="inputRadiusLocal">
-    </div>
-    <div class="radius-item">
-      <label for="panelradius" class="theme-radius-lb">{{$t('settings.panelRadius')}}</label>
-      <input id="panelradius" class="theme-radius-rn" type="range" v-model="panelRadiusLocal" max="50">
-      <input id="panelradius-t" class="theme-radius-in" type="text" v-model="panelRadiusLocal">
-    </div>
-    <div class="radius-item">
-      <label for="avatarradius" class="theme-radius-lb">{{$t('settings.avatarRadius')}}</label>
-      <input id="avatarradius" class="theme-radius-rn" type="range" v-model="avatarRadiusLocal" max="28">
-      <input id="avatarradius-t" class="theme-radius-in" type="green" v-model="avatarRadiusLocal">
-    </div>
-    <div class="radius-item">
-      <label for="avataraltradius" class="theme-radius-lb">{{$t('settings.avatarAltRadius')}}</label>
-      <input id="avataraltradius" class="theme-radius-rn" type="range" v-model="avatarAltRadiusLocal" max="28">
-      <input id="avataraltradius-t" class="theme-radius-in" type="text" v-model="avatarAltRadiusLocal">
-    </div>
-    <div class="radius-item">
-      <label for="attachmentradius" class="theme-radius-lb">{{$t('settings.attachmentRadius')}}</label>
-      <input id="attachmentrradius" class="theme-radius-rn" type="range" v-model="attachmentRadiusLocal" max="50">
-      <input id="attachmentradius-t" class="theme-radius-in" type="text" v-model="attachmentRadiusLocal">
-    </div>
-    <div class="radius-item">
-      <label for="tooltipradius" class="theme-radius-lb">{{$t('settings.tooltipRadius')}}</label>
-      <input id="tooltipradius" class="theme-radius-rn" type="range" v-model="tooltipRadiusLocal" max="20">
-      <input id="tooltipradius-t" class="theme-radius-in" type="text" v-model="tooltipRadiusLocal">
-    </div>
-  </div>
+    </tab-switcher>
 
   <div class="apply-container">
     <button class="btn submit" @click="setCustomTheme">{{$t('general.apply')}}</button>
@@ -193,14 +193,12 @@
 
 .apply-container,
 .radius-container,
-.color-container > div,
+.color-container,
 .presets-container {
   display: flex;
 
   p {
-    flex: 2 0 100%;
-    margin-top: 2em;
-    margin-bottom: .5em;
+    margin-left: 1em
   }
 }
 
@@ -208,7 +206,7 @@
   flex-direction: column;
 }
 
-.color-container > div{
+.color-container{
   flex-wrap: wrap;
   justify-content: space-between;
 }
@@ -231,6 +229,9 @@
   border-color: var(--border, $fallback--border);
   margin: 1em -1em 0;
   padding: 1em;
+  background: var(--body-background-image);
+  background-size: cover;
+  background-position: 50% 50%;
 
   .btn {
     margin-top: 1em;
diff --git a/src/components/timeline/timeline.vue b/src/components/timeline/timeline.vue
index 77a9a2af..c2d5b9e6 100644
--- a/src/components/timeline/timeline.vue
+++ b/src/components/timeline/timeline.vue
@@ -63,11 +63,6 @@
     color: $fallback--faint;
     color: var(--panelFaint, $fallback--faint);
   }
-
-  .loadmore-error {
-    color: $fallback--text;
-    color: var(--text, $fallback--text);
-  }
 }
 
 .new-status-notification {
diff --git a/src/services/color_convert/color_convert.js b/src/services/color_convert/color_convert.js
index 7a5254b9..6f046a1d 100644
--- a/src/services/color_convert/color_convert.js
+++ b/src/services/color_convert/color_convert.js
@@ -80,30 +80,23 @@ const getContrastRatio = (a, b) => {
 }
 
 /**
- * This generates what "worst case" color would look like for transparent
- * segments. I.e. transparent black with yellow text over yellow background.
+ * This performs alpha blending between solid background and semi-transparent foreground
  *
- * @param {Object} srgb - transparent color
- * @param {Number} alpha - color's opacity/alpha channel
- * @param {Object} textSrgb - text color (considered as worst case scenario for transparent background)
+ * @param {Object} fg - top layer color
+ * @param {Number} fga - top layer's alpha
+ * @param {Object} bg - bottom layer color
  * @returns {Object} sRGB of resulting color
  */
-const transparentWorstCase = (srgb, alpha, textSrgb) => {
+const alphaBlend = (fg, fga, bg) => {
+  if (fga === 1 || typeof fga === 'undefined') return fg
   return 'rgb'.split('').reduce((acc, c) => {
     // Simplified https://en.wikipedia.org/wiki/Alpha_compositing#Alpha_blending
     // for opaque bg and transparent fg
-    acc[c] = (srgb[c] * alpha + textSrgb[c] * (1 - alpha))
+    acc[c] = (fg[c] * fga + bg[c] * (1 - fga))
     return acc
   }, {})
 }
 
-const worstCase = (bg, bga, text) => {
-  console.log(bg)
-  console.log(text)
-  if (bga === 1 || typeof bga === 'undefined') return bg
-  return transparentWorstCase(bg, bga, text)
-}
-
 const hex2rgb = (hex) => {
   const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex)
   return result ? {
@@ -134,5 +127,5 @@ export {
   mixrgb,
   rgbstr2hex,
   getContrastRatio,
-  worstCase
+  alphaBlend
 }
diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js
index 666e74c1..9388e6f9 100644
--- a/src/services/style_setter/style_setter.js
+++ b/src/services/style_setter/style_setter.js
@@ -1,6 +1,6 @@
 import { times } from 'lodash'
-import { brightness, invertLightness, convert } from 'chromatism'
-import { rgb2hex, hex2rgb, mixrgb } from '../color_convert/color_convert.js'
+import { brightness, invertLightness, convert, contrastRatio } from 'chromatism'
+import { rgb2hex, hex2rgb, mixrgb, getContrastRatio, alphaBlend } from '../color_convert/color_convert.js'
 
 // 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
@@ -58,13 +58,17 @@ const rgb2rgba = function (rgba) {
   return `rgba(${rgba.r}, ${rgba.g}, ${rgba.b}, ${rgba.a})`
 }
 
-const getTextColor = function (bg, text) {
+const getTextColor = function (bg, text, preserve) {
   const bgIsLight = convert(bg).hsl.l > 50
   const textIsLight = convert(text).hsl.l > 50
 
   if ((bgIsLight && textIsLight) || (!bgIsLight && !textIsLight)) {
     const base = typeof text.a !== 'undefined' ? { a: text.a } : {}
-    return Object.assign(base, invertLightness(text).rgb)
+    const result = Object.assign(base, invertLightness(text).rgb)
+    if (!preserve && getContrastRatio(bg, result) < 4.5) {
+      return contrastRatio(bg, text).rgb
+    }
+    return result
   }
   return text
 }
@@ -104,7 +108,12 @@ const generatePreset = (input) => {
     alert: 0.5,
     input: 0.5,
     faint: 0.5
-  }, input.opacity)
+  }, Object.entries(input.opacity || {}).reduce((acc, [k, v]) => {
+    if (typeof v !== 'undefined') {
+      acc[k] = v
+    }
+    return acc
+  }, {}))
 
   const col = Object.entries(input.colors || input).reduce((acc, [k, v]) => {
     if (typeof v === 'object') {
@@ -128,9 +137,9 @@ const generatePreset = (input) => {
 
   colors.fg = col.fg
   colors.fgText = col.fgText || getTextColor(colors.fg, colors.text)
-  colors.fgLink = col.fgLink || getTextColor(colors.fg, colors.link)
+  colors.fgLink = col.fgLink || getTextColor(colors.fg, colors.link, true)
 
-  colors.border = col.border || brightness(20 * mod, colors.fg).rgb
+  colors.border = col.border || brightness(2 * mod, colors.fg).rgb
 
   colors.btn = col.btn || Object.assign({}, col.fg)
   colors.btnText = col.btnText || getTextColor(colors.btn, colors.fgText)
@@ -156,8 +165,11 @@ const generatePreset = (input) => {
   colors.cOrange = col.cOrange
 
   colors.alertError = col.alertError || Object.assign({}, col.cRed)
+  colors.alertErrorText = getTextColor(alphaBlend(colors.alertError, opacity.alert, colors.bg), colors.text)
+  colors.alertErrorPanelText = getTextColor(alphaBlend(colors.alertError, opacity.alert, colors.panel), colors.panelText)
+
   colors.badgeNotification = col.badgeNotification || Object.assign({}, col.cRed)
-  colors.badgeNotificationText = col.badgeNotification || Object.assign({}, col.cRed)
+  colors.badgeNotificationText = contrastRatio(colors.badgeNotification).rgb
 
   Object.entries(opacity).forEach(([ k, v ]) => {
     if (typeof v === 'undefined') return
diff --git a/src/services/user_highlighter/user_highlighter.js b/src/services/user_highlighter/user_highlighter.js
index ebb25eca..f6ddfb9c 100644
--- a/src/services/user_highlighter/user_highlighter.js
+++ b/src/services/user_highlighter/user_highlighter.js
@@ -11,7 +11,7 @@ const highlightStyle = (prefs) => {
   if (type === 'striped') {
     return {
       backgroundImage: [
-        'repeating-linear-gradient(-45deg,',
+        'repeating-linear-gradient(135deg,',
         `${tintColor} ,`,
         `${tintColor} 20px,`,
         `${tintColor2} 20px,`,
-- 
cgit v1.2.3-70-g09d2


From dc3df7bc4e91abf4a911e4c5ecc0c627d00dcfb1 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Wed, 21 Nov 2018 18:22:05 +0300
Subject: fixes

---
 src/components/notifications/notifications.scss       | 1 +
 src/components/post_status_form/post_status_form.vue  | 4 ++--
 src/components/timeline/timeline.vue                  | 2 +-
 src/components/user_card_content/user_card_content.js | 6 ++++--
 src/services/style_setter/style_setter.js             | 3 +++
 5 files changed, 11 insertions(+), 5 deletions(-)

(limited to 'src/components/timeline/timeline.vue')

diff --git a/src/components/notifications/notifications.scss b/src/components/notifications/notifications.scss
index 26455ffb..3f22b690 100644
--- a/src/components/notifications/notifications.scss
+++ b/src/components/notifications/notifications.scss
@@ -35,6 +35,7 @@
       right: 0;
       left: 0;
       bottom: 0;
+      pointer-events: none;
     }
 
     &.unseen {
diff --git a/src/components/post_status_form/post_status_form.vue b/src/components/post_status_form/post_status_form.vue
index 4514e79f..751b048a 100644
--- a/src/components/post_status_form/post_status_form.vue
+++ b/src/components/post_status_form/post_status_form.vue
@@ -154,7 +154,7 @@
       margin-left: $fallback--attachmentRadius;
       margin-left: var(--attachmentRadius, $fallback--attachmentRadius);
       background-color: $fallback--fg;
-      background-color: var(--fg, $fallback--fg);
+      background-color: var(--btn, $fallback--fg);
       border-bottom-left-radius: 0;
       border-bottom-right-radius: 0;
     }
@@ -292,7 +292,7 @@
 
     &.highlighted {
       background-color: $fallback--fg;
-      background-color: var(--fg, $fallback--fg);
+      background-color: var(--lightBg, $fallback--fg);
     }
   }
 }
diff --git a/src/components/timeline/timeline.vue b/src/components/timeline/timeline.vue
index c2d5b9e6..39f1b5bc 100644
--- a/src/components/timeline/timeline.vue
+++ b/src/components/timeline/timeline.vue
@@ -75,6 +75,6 @@
   padding: 10px;
   z-index: 1;
   background-color: $fallback--fg;
-  background-color: var(--fg, $fallback--fg);
+  background-color: var(--panel, $fallback--fg);
 }
 </style>
diff --git a/src/components/user_card_content/user_card_content.js b/src/components/user_card_content/user_card_content.js
index e8073021..6f9ed9fe 100644
--- a/src/components/user_card_content/user_card_content.js
+++ b/src/components/user_card_content/user_card_content.js
@@ -1,11 +1,13 @@
 import StillImage from '../still-image/still-image.vue'
+import { hex2rgb } from '../../services/color_convert/color_convert.js'
 
 export default {
   props: [ 'user', 'switcher', 'selected', 'hideBio' ],
   computed: {
     headingStyle () {
-      const rgb = this.$store.state.config.customTheme.colors.bg
-      if (rgb) {
+      const color = this.$store.state.config.customTheme.colors.bg
+      if (color) {
+        const rgb = (typeof color === 'string') ? hex2rgb(color) : color
         const tintColor = `rgba(${Math.floor(rgb.r)}, ${Math.floor(rgb.g)}, ${Math.floor(rgb.b)}, .5)`
         return {
           backgroundColor: `rgb(${Math.floor(rgb.r * 0.53)}, ${Math.floor(rgb.g * 0.56)}, ${Math.floor(rgb.b * 0.59)})`,
diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js
index 1b7ec7f2..57bd2841 100644
--- a/src/services/style_setter/style_setter.js
+++ b/src/services/style_setter/style_setter.js
@@ -202,6 +202,9 @@ const generateColors = (input) => {
       colors[k + 'Link'].a = v
       colors['panelFaint'].a = v
     }
+    if (k === 'bg') {
+      colors['lightBg'].a = v
+    }
     if (colors[k]) {
       colors[k].a = v
     } else {
-- 
cgit v1.2.3-70-g09d2


From 9a9dc47fc573af28429a641bf5408ead1c0d33ec Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Mon, 26 Nov 2018 03:19:04 +0300
Subject: better preview, collateral fixes

---
 src/App.scss                                      | 27 ++++++++++
 src/components/notifications/notifications.scss   | 17 -------
 src/components/notifications/notifications.vue    |  2 +-
 src/components/status/status.vue                  |  1 +
 src/components/style_switcher/style_switcher.scss | 25 +++++++++-
 src/components/style_switcher/style_switcher.vue  | 61 +++++++++++++++++++++--
 src/components/timeline/timeline.vue              |  5 +-
 src/i18n/en.json                                  | 13 +++++
 8 files changed, 123 insertions(+), 28 deletions(-)

(limited to 'src/components/timeline/timeline.vue')

diff --git a/src/App.scss b/src/App.scss
index 50645ec8..8c9df0ba 100644
--- a/src/App.scss
+++ b/src/App.scss
@@ -381,6 +381,12 @@ main-router {
     font-size: 1.3em;
   }
 
+  .faint {
+    background-color: transparent;
+    color: $fallback--faint;
+    color: var(--panelFaint, $fallback--faint);
+  }
+
   .alert {
     white-space: nowrap;
     text-overflow: ellipsis;
@@ -509,6 +515,27 @@ nav {
     flex-grow: 0;
   }
 }
+.badge {
+  display: inline-block;
+  border-radius: 99px;
+  min-width: 22px;
+  max-width: 22px;
+  min-height: 22px;
+  max-height: 22px;
+  font-size: 15px;
+  line-height: 22px;
+  text-align: center;
+  vertical-align: middle;
+  white-space: nowrap;
+  padding: 0;
+
+  &.badge-notification {
+    background-color: $fallback--cRed;
+    background-color: var(--badgeNotification, $fallback--cRed);
+    color: white;
+    color: var(--badgeNotificationText, white);
+  }
+}
 
 .alert {
   margin: 0.35em;
diff --git a/src/components/notifications/notifications.scss b/src/components/notifications/notifications.scss
index 3f22b690..87c89f6a 100644
--- a/src/components/notifications/notifications.scss
+++ b/src/components/notifications/notifications.scss
@@ -4,23 +4,6 @@
   // a bit of a hack to allow scrolling below notifications
   padding-bottom: 15em;
 
-  .unseen-count {
-    display: inline-block;
-    background-color: $fallback--cRed;
-    background-color: var(--badgeNotification, $fallback--cRed);
-    border-radius: 99px;
-    min-width: 22px;
-    max-width: 22px;
-    min-height: 22px;
-    max-height: 22px;
-    color: white;
-    color: var(--badgeNotificationText, white);
-    font-size: 15px;
-    line-height: 22px;
-    text-align: center;
-    vertical-align: middle
-  }
-
   .loadmore-error {
     color: $fallback--text;
     color: var(--text, $fallback--text);
diff --git a/src/components/notifications/notifications.vue b/src/components/notifications/notifications.vue
index eb6c4dd0..64f18720 100644
--- a/src/components/notifications/notifications.vue
+++ b/src/components/notifications/notifications.vue
@@ -4,7 +4,7 @@
       <div class="panel-heading">
         <div class="title">
           {{$t('notifications.notifications')}}
-          <span class="unseen-count" v-if="unseenCount">{{unseenCount}}</span>
+          <span class="badge badge-notification unseen-count" v-if="unseenCount">{{unseenCount}}</span>
         </div>
         <div @click.prevent class="loadmore-error alert error" v-if="error">
           {{$t('timeline.error_fetching')}}
diff --git a/src/components/status/status.vue b/src/components/status/status.vue
index 8682d996..0edc7b71 100644
--- a/src/components/status/status.vue
+++ b/src/components/status/status.vue
@@ -471,6 +471,7 @@
 .avatar {
   width: 48px;
   height: 48px;
+  box-shadow: var(--avatarStatusShadow);
   border-radius: $fallback--avatarRadius;
   border-radius: var(--avatarRadius, $fallback--avatarRadius);
   overflow: hidden;
diff --git a/src/components/style_switcher/style_switcher.scss b/src/components/style_switcher/style_switcher.scss
index 9c4f4ecd..2c33224b 100644
--- a/src/components/style_switcher/style_switcher.scss
+++ b/src/components/style_switcher/style_switcher.scss
@@ -163,11 +163,32 @@
     background-size: cover;
     background-position: 50% 50%;
 
+    .separator {
+      margin: 1em;
+      border-bottom: 1px solid;
+      border-color: $fallback--border;
+      border-color: var(--border, $fallback--border);
+    }
+
+    .panel-heading {
+      .badge, .alert, .btn, .faint {
+        margin-left: 1em;
+      }
+      .flex-spacer {
+        flex: 1;
+      }
+    }
+    .checkbox {
+      display: inline-flex;
+      align-items: baseline;
+      margin-right: 1em;
+    }
+
     .btn {
       margin-left: 0;
-      margin-top: 1em;
+      padding: 0 1em;
+      min-width: 3em;
       min-height: 30px;
-      width: 10em;
     }
   }
 
diff --git a/src/components/style_switcher/style_switcher.vue b/src/components/style_switcher/style_switcher.vue
index a444c6a7..2a7756ed 100644
--- a/src/components/style_switcher/style_switcher.vue
+++ b/src/components/style_switcher/style_switcher.vue
@@ -46,27 +46,80 @@
           v-model="keepRoundness">
         <label for="keep-roundness">{{$t('settings.style.switcher.keep_roundness')}}</label>
       </span>
+      <span>
+        <input
+          id="keep-fonts"
+          type="checkbox"
+          v-model="keepFonts">
+        <label for="keep-fonts">{{$t('settings.style.switcher.keep_fonts')}}</label>
+      </span>
       <p>{{$t('settings.style.switcher.save_load_hint')}}</p>
     </div>
   </div>
 
   <div class="preview-container">
     <div class="panel dummy" :style="previewRules">
-      <div class="panel-heading">Preview</div>
+      <div class="panel-heading">
+        {{$t('settings.style.preview.header')}}
+        <span class="badge badge-notification">
+          99
+        </span>
+        <span class="alert error">
+          {{$t('settings.style.preview.error')}}
+        </span>
+        <button class="btn">
+          {{$t('settings.style.preview.button')}}
+        </button>
+        <span class="flex-spacer"/>
+        <span class="faint">
+          {{$t('settings.style.preview.header_faint')}}
+        </span>
+      </div>
       <div class="panel-body theme-preview-content">
         <div class="avatar">
           ( ͡° ͜ʖ ͡°)
         </div>
         <h4>Content</h4>
+
         <br>
-        A bunch of more content and
-        <a style="color: var(--link)">a nice lil' link</a>
+
+        <i18n path="settings.style.preview.text">
+          <a style="color: var(--link)">
+            {{$t('settings.style.preview.link')}}
+          </a>
+        </i18n>
+
         <i style="color: var(--cBlue)" class="icon-reply"/>
         <i style="color: var(--cGreen)" class="icon-retweet"/>
         <i style="color: var(--cRed)" class="icon-cancel"/>
         <i style="color: var(--cOrange)" class="icon-star"/>
+
         <br>
-        <button class="btn">Button</button>
+        <br>
+
+        <input :value="$t('settings.style.preview.error')" type="text">
+        <span class="alert error">
+          {{$t('settings.style.preview.error')}}
+        </span>
+
+        <br>
+        <br>
+
+        <span class="checkbox">
+          <input checked="very yes" type="checkbox" id="preview_checkbox">
+          <label for="preview_checkbox">{{$t('settings.style.preview.checkbox')}}</label>
+        </span>
+        <button class="btn">
+          {{$t('settings.style.preview.button')}}
+        </button>
+
+        <div class="separator"></div>
+
+        <i18n path="settings.style.preview.fine_print" tag="span" class="faint">
+          <a style="color: var(--faintLink)">
+            {{$t('settings.style.preview.faint_link')}}
+          </a>
+        </i18n>
       </div>
     </div>
   </div>
diff --git a/src/components/timeline/timeline.vue b/src/components/timeline/timeline.vue
index 39f1b5bc..b69a09fd 100644
--- a/src/components/timeline/timeline.vue
+++ b/src/components/timeline/timeline.vue
@@ -58,10 +58,7 @@
 
 .timeline {
   .loadmore-text {
-    opacity: 0.8;
-    background-color: transparent;
-    color: $fallback--faint;
-    color: var(--panelFaint, $fallback--faint);
+    opacity: 1;
   }
 }
 
diff --git a/src/i18n/en.json b/src/i18n/en.json
index c70c488c..0530b66d 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -170,6 +170,7 @@
         "keep_shadows": "Keep shadows",
         "keep_opacity": "Keep opacity",
         "keep_roundness": "Keep roundness",
+        "keep_fonts": "Keep fonts",
         "save_load_hint": "\"Keep\" options preserve currently set options when selecting or loading themes, it also stores said options when exporting a theme.",
         "reset": "Reset",
         "clear_all": "Clear all",
@@ -250,6 +251,18 @@
         "size": "Size (in px)",
         "weight": "Weight (boldness)",
         "custom": "Custom"
+      },
+      "preview": {
+        "header": "Preview of header",
+        "error": "Example error",
+        "button": "Button",
+        "text": "A bunch of more content and {0}",
+        "input": "Just landed in L.A.",
+        "faint_link": "helpful manual",
+        "fine_print": "Read our {0} to learn nothing useful!",
+        "header_faint": "This is fine",
+        "checkbox": "I have skimmed over terms and conditions",
+        "link": "a nice lil' link"
       }
     }
   },
-- 
cgit v1.2.3-70-g09d2


From b45fc6c6523b1332c6422a5dc6eff95c11a32690 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Tue, 27 Nov 2018 04:54:59 +0300
Subject: updated preview window

---
 src/components/style_switcher/style_switcher.scss | 120 +++++++++++++++-------
 src/components/style_switcher/style_switcher.vue  |  98 ++++++++++--------
 src/components/timeline/timeline.vue              |   2 +-
 src/i18n/en.json                                  |   3 +-
 4 files changed, 143 insertions(+), 80 deletions(-)

(limited to 'src/components/timeline/timeline.vue')

diff --git a/src/components/style_switcher/style_switcher.scss b/src/components/style_switcher/style_switcher.scss
index 2c33224b..baf2b73a 100644
--- a/src/components/style_switcher/style_switcher.scss
+++ b/src/components/style_switcher/style_switcher.scss
@@ -163,32 +163,95 @@
     background-size: cover;
     background-position: 50% 50%;
 
-    .separator {
-      margin: 1em;
-      border-bottom: 1px solid;
-      border-color: $fallback--border;
-      border-color: var(--border, $fallback--border);
-    }
+    .dummy {
+      .post {
+        font-family: var(--postFont);
+        display: flex;
+
+        .content {
+          flex: 1;
+
+          h4 {
+            margin-bottom: .25em;
+          }
+
+          .icons {
+            margin-top: .5em;
+            display: flex;
+
+            i {
+              margin-right: 1em;
+            }
+          }
+        }
+      }
 
-    .panel-heading {
-      .badge, .alert, .btn, .faint {
-        margin-left: 1em;
+      .after-post {
+        margin-top: 1em;
+        display: flex;
+        align-items: center;
       }
-      .flex-spacer {
-        flex: 1;
+
+      .avatar, .avatar-alt{
+        background: linear-gradient(135deg, #b8e1fc 0%,#a9d2f3 10%,#90bae4 25%,#90bcea 37%,#90bff0 50%,#6ba8e5 51%,#a2daf5 83%,#bdf3fd 100%);
+        color: black;
+        font-family: sans-serif;
+        text-align: center;
+        margin-right: 1em;
       }
-    }
-    .checkbox {
-      display: inline-flex;
-      align-items: baseline;
-      margin-right: 1em;
-    }
 
-    .btn {
-      margin-left: 0;
-      padding: 0 1em;
-      min-width: 3em;
-      min-height: 30px;
+      .avatar-alt {
+        flex: 0 auto;
+        margin-left: 28px;
+        font-size: 12px;
+        width: 20px;
+        height: 20px;
+        line-height: 20px;
+        border-radius: $fallback--avatarAltRadius;
+        border-radius: var(--avatarAltRadius, $fallback--avatarAltRadius);
+      }
+
+      .avatar {
+        flex: 0 auto;
+        width: 48px;
+        height: 48px;
+        font-size: 14px;
+        line-height: 48px;
+      }
+
+      .actions {
+        display: flex;
+        align-items: baseline;
+
+        .checkbox {
+          display: inline-flex;
+          align-items: baseline;
+          margin-right: 1em;
+          flex: 1;
+        }
+      }
+
+      .separator {
+        margin: 1em;
+        border-bottom: 1px solid;
+        border-color: $fallback--border;
+        border-color: var(--border, $fallback--border);
+      }
+
+      .panel-heading {
+        .badge, .alert, .btn, .faint {
+          margin-left: 1em;
+        }
+        .flex-spacer {
+          flex: 1;
+        }
+      }
+      .btn {
+        margin-left: 0;
+        padding: 0 1em;
+        min-width: 3em;
+        min-height: 30px;
+      }
     }
   }
 
@@ -259,17 +322,4 @@
     margin-left: .25em;
     margin-right: .25em;
   }
-
-  .dummy {
-    .avatar {
-      background: linear-gradient(135deg, #b8e1fc 0%,#a9d2f3 10%,#90bae4 25%,#90bcea 37%,#90bff0 50%,#6ba8e5 51%,#a2daf5 83%,#bdf3fd 100%);
-      color: black;
-      text-align: center;
-      height: 48px;
-      line-height: 48px;
-      width: 48px;
-      float: left;
-      margin-right: 1em;
-    }
-  }
 }
diff --git a/src/components/style_switcher/style_switcher.vue b/src/components/style_switcher/style_switcher.vue
index 655e0589..fa173b98 100644
--- a/src/components/style_switcher/style_switcher.vue
+++ b/src/components/style_switcher/style_switcher.vue
@@ -60,9 +60,14 @@
   <div class="preview-container">
     <div class="panel dummy" :style="previewRules">
       <div class="panel-heading">
-        {{$t('settings.style.preview.header')}}
-        <span class="badge badge-notification">
-          99
+        <div class="title">
+          {{$t('settings.style.preview.header')}}
+          <span class="badge badge-notification">
+            99
+          </span>
+        </div>
+        <span class="faint">
+          {{$t('settings.style.preview.header_faint')}}
         </span>
         <span class="alert error">
           {{$t('settings.style.preview.error')}}
@@ -70,56 +75,63 @@
         <button class="btn">
           {{$t('settings.style.preview.button')}}
         </button>
-        <span class="flex-spacer"/>
-        <span class="faint">
-          {{$t('settings.style.preview.header_faint')}}
-        </span>
       </div>
       <div class="panel-body theme-preview-content">
-        <div class="avatar">
-          ( ͡° ͜ʖ ͡°)
-        </div>
-        <h4>Content</h4>
-
-        <br>
+        <div class="post">
+          <div class="avatar">
+            ( ͡° ͜ʖ ͡°)
+          </div>
+          <div class="content">
+            <h4>
+              Content
+            </h4>
 
-        <i18n path="settings.style.preview.text">
-          <a style="color: var(--link)">
-            {{$t('settings.style.preview.link')}}
-          </a>
-        </i18n>
+            <i18n path="settings.style.preview.text">
+              <code style="font-family: var(--postCodeFont)">
+                {{$t('settings.style.preview.mono')}}
+              </code>
+              <a style="color: var(--link)">
+                {{$t('settings.style.preview.link')}}
+              </a>
+            </i18n>
 
-        <i style="color: var(--cBlue)" class="icon-reply"/>
-        <i style="color: var(--cGreen)" class="icon-retweet"/>
-        <i style="color: var(--cRed)" class="icon-cancel"/>
-        <i style="color: var(--cOrange)" class="icon-star"/>
+            <div class="icons">
+              <i style="color: var(--cBlue)" class="icon-reply"/>
+              <i style="color: var(--cGreen)" class="icon-retweet"/>
+              <i style="color: var(--cOrange)" class="icon-star"/>
+              <i style="color: var(--cRed)" class="icon-cancel"/>
+            </div>
+          </div>
+        </div>
 
-        <br>
-        <br>
+        <div class="after-post">
+          <div class="avatar-alt">
+            :^)
+          </div>
+          <div class="content">
+            <i18n path="settings.style.preview.fine_print" tag="span" class="faint">
+              <a style="color: var(--faintLink)">
+                {{$t('settings.style.preview.faint_link')}}
+              </a>
+            </i18n>
+          </div>
+        </div>
+        <div class="separator"></div>
 
-        <input :value="$t('settings.style.preview.input')" type="text">
         <span class="alert error">
           {{$t('settings.style.preview.error')}}
         </span>
+        <input :value="$t('settings.style.preview.input')" type="text">
 
-        <br>
-        <br>
-
-        <span class="checkbox">
-          <input checked="very yes" type="checkbox" id="preview_checkbox">
-          <label for="preview_checkbox">{{$t('settings.style.preview.checkbox')}}</label>
-        </span>
-        <button class="btn">
-          {{$t('settings.style.preview.button')}}
-        </button>
-
-        <div class="separator"></div>
-
-        <i18n path="settings.style.preview.fine_print" tag="span" class="faint">
-          <a style="color: var(--faintLink)">
-            {{$t('settings.style.preview.faint_link')}}
-          </a>
-        </i18n>
+        <div class="actions">
+          <span class="checkbox">
+            <input checked="very yes" type="checkbox" id="preview_checkbox">
+            <label for="preview_checkbox">{{$t('settings.style.preview.checkbox')}}</label>
+          </span>
+          <button class="btn">
+            {{$t('settings.style.preview.button')}}
+          </button>
+        </div>
       </div>
     </div>
   </div>
diff --git a/src/components/timeline/timeline.vue b/src/components/timeline/timeline.vue
index b69a09fd..bc7f74c2 100644
--- a/src/components/timeline/timeline.vue
+++ b/src/components/timeline/timeline.vue
@@ -10,7 +10,7 @@
       <button @click.prevent="showNewStatuses" class="loadmore-button" v-if="timeline.newStatusCount > 0 && !timelineError">
         {{$t('timeline.show_new')}}{{newStatusCountStr}}
       </button>
-      <div @click.prevent class="loadmore-text" v-if="!timeline.newStatusCount > 0 && !timelineError">
+      <div @click.prevent class="loadmore-text faint" v-if="!timeline.newStatusCount > 0 && !timelineError">
         {{$t('timeline.up_to_date')}}
       </div>
     </div>
diff --git a/src/i18n/en.json b/src/i18n/en.json
index 74e7a556..8847b11e 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -268,7 +268,8 @@
         "header": "Preview of header",
         "error": "Example error",
         "button": "Button",
-        "text": "A bunch of more content and {0}",
+        "text": "A bunch of more {0} and {1}",
+        "mono": "content",
         "input": "Just landed in L.A.",
         "faint_link": "helpful manual",
         "fine_print": "Read our {0} to learn nothing useful!",
-- 
cgit v1.2.3-70-g09d2

