aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHenry Jameson <me@hjkos.com>2018-11-25 21:48:16 +0300
committerHenry Jameson <me@hjkos.com>2018-11-25 21:48:16 +0300
commit1a65895bfd441ea57163ee3e185785c82a81b736 (patch)
tree6acf07e334d43b08740bf68d3bfbc7e257d99693 /src
parente8536f3d95144945dcbd6bd96542f8401de3f1ed (diff)
initial font support
Diffstat (limited to 'src')
-rw-r--r--src/App.scss3
-rw-r--r--src/components/font_control/font_control.vue93
-rw-r--r--src/components/shadow_control/shadow_control.vue5
-rw-r--r--src/components/style_switcher/style_switcher.js63
-rw-r--r--src/components/style_switcher/style_switcher.scss3
-rw-r--r--src/components/style_switcher/style_switcher.vue55
-rw-r--r--src/i18n/en.json13
-rw-r--r--src/services/style_setter/style_setter.js48
8 files changed, 251 insertions, 32 deletions
diff --git a/src/App.scss b/src/App.scss
index ceb0bb87..45491fd2 100644
--- a/src/App.scss
+++ b/src/App.scss
@@ -34,6 +34,7 @@ h4 {
body {
font-family: sans-serif;
+ font-family: var(--interfaceFont, sans-serif);
font-size: 14px;
margin: 0;
color: $fallback--text;
@@ -62,6 +63,7 @@ button {
box-shadow: var(--buttonShadow);
font-size: 14px;
font-family: sans-serif;
+ font-family: var(--interfaceFont, sans-serif);
i[class*=icon-] {
color: $fallback--text;
@@ -111,6 +113,7 @@ input, textarea, .select {
color: $fallback--lightText;
color: var(--inputText, $fallback--lightText);
font-family: sans-serif;
+ font-family: var(--inputFont, sans-serif);
font-size: 14px;
padding: 8px 7px;
box-sizing: border-box;
diff --git a/src/components/font_control/font_control.vue b/src/components/font_control/font_control.vue
new file mode 100644
index 00000000..424f6259
--- /dev/null
+++ b/src/components/font_control/font_control.vue
@@ -0,0 +1,93 @@
+<template>
+<div class="font-control style-control">
+ <label :for="preset === 'custom' ? name : name + '-font-switcher'" class="label">
+ {{label}}
+ </label>
+ <input
+ v-if="typeof fallback !== 'undefined'"
+ class="opt exlcude-disabled"
+ type="checkbox"
+ :id="name + '-o'"
+ :checked="present"
+ @input="$emit('input', typeof value === 'undefined' ? fallback : undefined)">
+ <label v-if="typeof fallback !== 'undefined'" class="opt-l" :for="name + '-o'"></label>
+ <label :for="name + '-font-switcher'" class="select" :disabled="!present">
+ <select
+ :disabled="!present"
+ v-model="preset"
+ class="font-switcher"
+ id="name + '-font-switcher'">
+ <option v-for="option in options" :value="option">
+ {{ option }}
+ </option>
+ </select>
+ <i class="icon-down-open"/>
+ </label>
+ <input
+ v-if="preset === 'custom'"
+ class="custom-font"
+ type="text"
+ id="name"
+ v-model="family">
+</div>
+</template>
+
+<script>
+import { set } from 'vue'
+
+export default {
+ props: [
+ 'name', 'label', 'value', 'fallback', 'options'
+ ],
+ data () {
+ return {
+ lValue: this.value
+ }
+ },
+ beforeUpdate () {
+ this.lValue = this.value
+ },
+ computed: {
+ present () {
+ return typeof this.lValue !== 'undefined'
+ },
+ dValue () {
+ return this.lValue || this.fallback || {}
+ },
+ family: {
+ get () {
+ return this.dValue.family
+ },
+ set (v) {
+ set(this.lValue, 'family', v)
+ this.$emit('input', this.lValue)
+ }
+ },
+ preset: {
+ get () {
+ console.log(this.family)
+ if (this.family === 'serif' ||
+ this.family === 'sans-serif' ||
+ this.family === 'monospace' ||
+ this.family === 'inherit') {
+ return this.family
+ } else {
+ return 'custom'
+ }
+ },
+ set (v) {
+ this.family = v === 'custom' ? '' : v
+ }
+ }
+ }
+}
+</script>
+
+<style lang="scss">
+@import '../../_variables.scss';
+.font-control {
+ input.custom-font {
+ min-width: 10em;
+ }
+}
+</style>
diff --git a/src/components/shadow_control/shadow_control.vue b/src/components/shadow_control/shadow_control.vue
index 85346e17..744925d4 100644
--- a/src/components/shadow_control/shadow_control.vue
+++ b/src/components/shadow_control/shadow_control.vue
@@ -124,9 +124,9 @@
<OpacityInput
v-model="selected.alpha"
:disabled="!present"/>
- <div>
+ <p>
{{$t('settings.style.shadows.hint')}}
- </div>
+ </p>
</div>
</div>
</template>
@@ -139,6 +139,7 @@
display: flex;
flex-wrap: wrap;
justify-content: center;
+ margin-bottom: 1em;
.shadow-preview-container,
.shadow-tweak {
diff --git a/src/components/style_switcher/style_switcher.js b/src/components/style_switcher/style_switcher.js
index 57faa61b..bbd28bdc 100644
--- a/src/components/style_switcher/style_switcher.js
+++ b/src/components/style_switcher/style_switcher.js
@@ -1,10 +1,11 @@
import { rgb2hex, hex2rgb, getContrastRatio, alphaBlend } from '../../services/color_convert/color_convert.js'
import { set, delete as del } from 'vue'
-import { generateColors, generateShadows, generateRadii, composePreset } from '../../services/style_setter/style_setter.js'
+import { generateColors, generateShadows, generateRadii, generateFonts, composePreset } 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.jsx'
@@ -30,6 +31,7 @@ export default {
previewShadows: {},
previewColors: {},
previewRadii: {},
+ previewFonts: {},
shadowsInvalid: true,
colorsInvalid: true,
@@ -38,6 +40,7 @@ export default {
keepShadows: false,
keepOpacity: false,
keepRoundness: false,
+ keepFonts: false,
textColorLocal: '',
linkColorLocal: '',
@@ -85,6 +88,7 @@ export default {
shadowSelected: undefined,
shadowsLocal: {},
+ fontsLocal: {},
btnRadiusLocal: '',
inputRadiusLocal: '',
@@ -176,10 +180,11 @@ export default {
}
},
preview () {
- return composePreset(this.previewColors, this.previewRadii, this.previewShadows)
+ return composePreset(this.previewColors, this.previewRadii, this.previewShadows, this.previewFonts)
},
previewTheme () {
- if (!this.preview.theme.colors) return { colors: {}, opacity: {}, radii: {}, shadows: {} }
+ if (!this.preview.theme.colors) return { colors: {}, opacity: {}, radii: {}, shadows: {}, fonts: {} }
+ console.log(this.preview.theme)
return this.preview.theme
},
// This needs optimization maybe
@@ -253,7 +258,11 @@ export default {
},
previewRules () {
if (!this.preview.rules) return ''
- return [...Object.values(this.preview.rules), 'color: var(--text)'].join(';')
+ return [
+ ...Object.values(this.preview.rules),
+ 'color: var(--text)',
+ 'font-family: var(--interfaceFont, sans-serif)'
+ ].join(';')
},
shadowsAvailable () {
return Object.keys(this.previewTheme.shadows).sort()
@@ -291,6 +300,7 @@ export default {
RangeInput,
ContrastRatio,
ShadowControl,
+ FontControl,
TabSwitcher
},
methods: {
@@ -300,6 +310,7 @@ export default {
_pleroma_theme_version: 2,
theme: {
shadows: this.shadowsLocal,
+ fonts: this.fontsLocal,
opacity: this.currentOpacity,
colors: this.currentColors,
radii: this.currentRadii
@@ -357,6 +368,7 @@ export default {
name: 'customTheme',
value: {
shadows: this.shadowsLocal,
+ fonts: this.fontsLocal,
opacity: this.currentOpacity,
colors: this.currentColors,
radii: this.currentRadii
@@ -398,6 +410,10 @@ export default {
this.shadowsLocal = {}
},
+ clearFonts () {
+ this.fontsLocal = {}
+ },
+
/**
* This applies stored theme data onto form.
* @param {Object} input - input data
@@ -408,6 +424,7 @@ export default {
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
@@ -458,6 +475,11 @@ export default {
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]) => {
@@ -477,14 +499,31 @@ export default {
console.warn(e)
}
},
- shadowsLocal () {
- try {
- this.previewShadows = generateShadows({ shadows: this.shadowsLocal })
- this.shadowsInvalid = false
- } catch (e) {
- this.shadowsInvalid = 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 })
+ console.log('BENIS')
+ console.log(this.previewFonts)
+ this.fontsInvalid = false
+ } catch (e) {
+ this.fontsInvalid = true
+ console.warn(e)
+ }
+ },
+ deep: true
},
currentColors () {
try {
diff --git a/src/components/style_switcher/style_switcher.scss b/src/components/style_switcher/style_switcher.scss
index ad203856..9c4f4ecd 100644
--- a/src/components/style_switcher/style_switcher.scss
+++ b/src/components/style_switcher/style_switcher.scss
@@ -67,6 +67,7 @@
flex-wrap: wrap;
}
+ .fonts-container,
.reset-container,
.apply-container,
.radius-container,
@@ -75,6 +76,7 @@
display: flex;
}
+ .fonts-container,
.radius-container {
flex-direction: column;
}
@@ -87,6 +89,7 @@
justify-content: space-between;
}
+ .fonts-container,
.color-container,
.shadow-container,
.radius-container,
diff --git a/src/components/style_switcher/style_switcher.vue b/src/components/style_switcher/style_switcher.vue
index 5e9af19e..f64bda3f 100644
--- a/src/components/style_switcher/style_switcher.vue
+++ b/src/components/style_switcher/style_switcher.vue
@@ -75,7 +75,7 @@
<tab-switcher key="style-tweak">
<div :label="$t('settings.style.common_colors._tab_label')" class="color-container">
<div class="tab-header">
- <p>{{$t('settings.theme_help')}}</p>
+ <p>{{$t('settings.theme_help')}}</p>
<button class="btn" @click="clearOpacity">{{$t('settings.style.switcher.clear_opacity')}}</button>
<button class="btn" @click="clearV1">{{$t('settings.style.switcher.clear_all')}}</button>
</div>
@@ -169,20 +169,18 @@
</div>
</div>
<div :label="$t('settings.style.radii._tab_label')" class="radius-container">
- <div>
- <div class="tab-header">
- <p>{{$t('settings.radii_help')}}</p>
- <button class="btn" @click="clearRoundness">{{$t('settings.style.switcher.clear_all')}}</button>
- </div>
- <RangeInput name="btnRadius" :label="$t('settings.btnRadius')" v-model="btnRadiusLocal" :fallback="previewTheme.radii.btn" max="16" hardMin="0"/>
- <RangeInput name="inputRadius" :label="$t('settings.inputRadius')" v-model="inputRadiusLocal" :fallback="previewTheme.radii.input" max="9" hardMin="0"/>
- <RangeInput name="checkboxRadius" :label="$t('settings.checkboxRadius')" v-model="checkboxRadiusLocal" :fallback="previewTheme.radii.checkbox" max="16" hardMin="0"/>
- <RangeInput name="panelRadius" :label="$t('settings.panelRadius')" v-model="panelRadiusLocal" :fallback="previewTheme.radii.panel" max="50" hardMin="0"/>
- <RangeInput name="avatarRadius" :label="$t('settings.avatarRadius')" v-model="avatarRadiusLocal" :fallback="previewTheme.radii.avatar" max="28" hardMin="0"/>
- <RangeInput name="avatarAltRadius" :label="$t('settings.avatarAltRadius')" v-model="avatarAltRadiusLocal" :fallback="previewTheme.radii.avatarAlt" max="28" hardMin="0"/>
- <RangeInput name="attachmentRadius" :label="$t('settings.attachmentRadius')" v-model="attachmentRadiusLocal" :fallback="previewTheme.radii.attachment" max="50" hardMin="0"/>
- <RangeInput name="tooltipRadius" :label="$t('settings.tooltipRadius')" v-model="tooltipRadiusLocal" :fallback="previewTheme.radii.tooltip" max="50" hardMin="0"/>
+ <div class="tab-header">
+ <p>{{$t('settings.radii_help')}}</p>
+ <button class="btn" @click="clearRoundness">{{$t('settings.style.switcher.clear_all')}}</button>
</div>
+ <RangeInput name="btnRadius" :label="$t('settings.btnRadius')" v-model="btnRadiusLocal" :fallback="previewTheme.radii.btn" max="16" hardMin="0"/>
+ <RangeInput name="inputRadius" :label="$t('settings.inputRadius')" v-model="inputRadiusLocal" :fallback="previewTheme.radii.input" max="9" hardMin="0"/>
+ <RangeInput name="checkboxRadius" :label="$t('settings.checkboxRadius')" v-model="checkboxRadiusLocal" :fallback="previewTheme.radii.checkbox" max="16" hardMin="0"/>
+ <RangeInput name="panelRadius" :label="$t('settings.panelRadius')" v-model="panelRadiusLocal" :fallback="previewTheme.radii.panel" max="50" hardMin="0"/>
+ <RangeInput name="avatarRadius" :label="$t('settings.avatarRadius')" v-model="avatarRadiusLocal" :fallback="previewTheme.radii.avatar" max="28" hardMin="0"/>
+ <RangeInput name="avatarAltRadius" :label="$t('settings.avatarAltRadius')" v-model="avatarAltRadiusLocal" :fallback="previewTheme.radii.avatarAlt" max="28" hardMin="0"/>
+ <RangeInput name="attachmentRadius" :label="$t('settings.attachmentRadius')" v-model="attachmentRadiusLocal" :fallback="previewTheme.radii.attachment" max="50" hardMin="0"/>
+ <RangeInput name="tooltipRadius" :label="$t('settings.tooltipRadius')" v-model="tooltipRadiusLocal" :fallback="previewTheme.radii.tooltip" max="50" hardMin="0"/>
</div>
<div :label="$t('settings.style.shadows._tab_label')" class="shadow-container">
<div class="tab-header shadow-selector">
@@ -214,6 +212,35 @@
</div>
<shadow-control :ready="!!currentShadowFallback" :fallback="currentShadowFallback" v-model="currentShadow"/>
</div>
+ <div :label="$t('settings.style.fonts._tab_label')" class="fonts-container">
+ <div class="tab-header">
+ <p>{{$t('settings.style.fonts.help')}}</p>
+ </div>
+ <FontControl
+ name="ui"
+ v-model="fontsLocal.interface"
+ :label="$t('settings.style.fonts.components.interface')"
+ :fallback="previewTheme.fonts.interface"
+ :options="['serif', 'sans-serif', 'monospace', 'custom']" />
+ <FontControl
+ name="input"
+ v-model="fontsLocal.input"
+ :label="$t('settings.style.fonts.components.input')"
+ :fallback="previewTheme.fonts.input"
+ :options="['serif', 'sans-serif', 'monospace', 'inherit', 'custom']" />
+ <FontControl
+ name="post"
+ v-model="fontsLocal.post"
+ :label="$t('settings.style.fonts.components.post')"
+ :fallback="previewTheme.fonts.post"
+ :options="['serif', 'sans-serif', 'monospace', 'inherit', 'custom']" />
+ <FontControl
+ name="postCode"
+ v-model="fontsLocal.postCode"
+ :label="$t('settings.style.fonts.components.postCode')"
+ :fallback="previewTheme.fonts.postCode"
+ :options="['serif', 'sans-serif', 'monospace', 'inherit', 'custom']" />
+ </div>
</tab-switcher>
</keep-alive>
diff --git a/src/i18n/en.json b/src/i18n/en.json
index 5bd1ddbb..6f439f65 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -236,6 +236,19 @@
"buttonPressedHover": "Button (pressed+hover)",
"input": "Input field"
}
+ },
+ "fonts": {
+ "_tab_label": "Fonts",
+ "help": "Select font to use for elements of UI. For \"custom\" you have to enter exact font name as it appears in system.",
+ "components": {
+ "interface": "Interface",
+ "input": "Input fields",
+ "post": "Post text",
+ "postCode": "Monospaced text in a post (rich text)"
+ },
+ "family": "Font name",
+ "size": "Size (in px)",
+ "weight": "Weight (boldness)"
}
}
},
diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js
index e11ee90c..f2c9c13e 100644
--- a/src/services/style_setter/style_setter.js
+++ b/src/services/style_setter/style_setter.js
@@ -85,6 +85,7 @@ const setColors = (input, commit) => {
styleSheet.insertRule(`body { ${rules.radii} }`, 'index-max')
styleSheet.insertRule(`body { ${rules.colors} }`, 'index-max')
styleSheet.insertRule(`body { ${rules.shadows} }`, 'index-max')
+ styleSheet.insertRule(`body { ${rules.fonts} }`, 'index-max')
body.style.display = 'initial'
// commit('setOption', { name: 'colors', value: htmlColors })
@@ -267,6 +268,41 @@ const generateRadii = (input) => {
}
}
+const generateFonts = (input) => {
+ const fonts = Object.entries(input.fonts || {}).filter(([k, v]) => v).reduce((acc, [k, v]) => {
+ acc[k] = Object.entries(v).filter(([k, v]) => v).reduce((acc, [k, v]) => {
+ acc[k] = v
+ return acc
+ }, acc[k])
+ return acc
+ }, {
+ interface: {
+ family: 'sans-serif'
+ },
+ input: {
+ family: 'inherit'
+ },
+ post: {
+ family: 'inherit'
+ },
+ postCode: {
+ family: 'monospace'
+ }
+ })
+
+ return {
+ rules: {
+ fonts: Object
+ .entries(fonts)
+ .filter(([k, v]) => v)
+ .map(([k, v]) => `--${k}Font: ${v.family}`).join(';')
+ },
+ theme: {
+ fonts
+ }
+ }
+}
+
const generateShadows = (input) => {
const border = (top, shadow) => ({
x: 0,
@@ -355,17 +391,19 @@ const generateShadows = (input) => {
}
}
-const composePreset = (colors, radii, shadows) => {
+const composePreset = (colors, radii, shadows, fonts) => {
return {
rules: {
...shadows.rules,
...colors.rules,
- ...radii.rules
+ ...radii.rules,
+ ...fonts.rules
},
theme: {
...shadows.theme,
...colors.theme,
- ...radii.theme
+ ...radii.theme,
+ ...fonts.theme
}
}
}
@@ -374,8 +412,9 @@ const generatePreset = (input) => {
const shadows = generateShadows(input)
const colors = generateColors(input)
const radii = generateRadii(input)
+ const fonts = generateFonts(input)
- return composePreset(colors, radii, shadows)
+ return composePreset(colors, radii, shadows, fonts)
}
const setPreset = (val, commit) => {
@@ -424,6 +463,7 @@ export {
generateColors,
generateRadii,
generateShadows,
+ generateFonts,
generatePreset,
composePreset,
getCssShadow