diff --git a/src/App.scss b/src/App.scss index ceb0bb873d..45491fd2b4 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 0000000000..424f6259b7 --- /dev/null +++ b/src/components/font_control/font_control.vue @@ -0,0 +1,93 @@ + + + + + diff --git a/src/components/shadow_control/shadow_control.vue b/src/components/shadow_control/shadow_control.vue index 85346e1745..744925d4f1 100644 --- a/src/components/shadow_control/shadow_control.vue +++ b/src/components/shadow_control/shadow_control.vue @@ -124,9 +124,9 @@ -
+

{{$t('settings.style.shadows.hint')}} -

+

@@ -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 57faa61b7f..bbd28bdceb 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 ad20385642..9c4f4ecd04 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 5e9af19e6f..f64bda3f2a 100644 --- a/src/components/style_switcher/style_switcher.vue +++ b/src/components/style_switcher/style_switcher.vue @@ -75,7 +75,7 @@
-

{{$t('settings.theme_help')}}

+

{{$t('settings.theme_help')}}

@@ -169,20 +169,18 @@
-
-
-

{{$t('settings.radii_help')}}

- -
- - - - - - - - +
+

{{$t('settings.radii_help')}}

+
+ + + + + + + +
@@ -214,6 +212,35 @@
+
+
+

{{$t('settings.style.fonts.help')}}

+
+ + + + +
diff --git a/src/i18n/en.json b/src/i18n/en.json index 5bd1ddbb09..6f439f6508 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 e11ee90caa..f2c9c13e75 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