From eba3a43805b5777aebb677df88bf5c8533743ead Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Wed, 26 Jun 2024 14:17:22 +0300 Subject: better font control custom input --- src/components/font_control/font_control.vue | 101 +++++++++++++++------------ 1 file changed, 55 insertions(+), 46 deletions(-) (limited to 'src/components/font_control/font_control.vue') diff --git a/src/components/font_control/font_control.vue b/src/components/font_control/font_control.vue index d2d1b388..e73862a0 100644 --- a/src/components/font_control/font_control.vue +++ b/src/components/font_control/font_control.vue @@ -1,6 +1,6 @@ @@ -55,20 +71,13 @@ -- cgit v1.2.3-70-g09d2 From d5d37849ea6712fa00a077cb219800553b5689ab Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Wed, 26 Jun 2024 17:05:59 +0300 Subject: font selector with proper styles and functionality + local font selector --- src/App.scss | 35 ++++--- src/components/font_control/font_control.js | 61 +++++++++--- src/components/font_control/font_control.vue | 102 +++++++++++++++++---- .../settings_modal/tabs/theme_tab/theme_tab.scss | 4 + src/i18n/en.json | 9 +- src/modules/interface.js | 24 ++++- 6 files changed, 185 insertions(+), 50 deletions(-) (limited to 'src/components/font_control/font_control.vue') diff --git a/src/App.scss b/src/App.scss index 6b8875bf..9225075b 100644 --- a/src/App.scss +++ b/src/App.scss @@ -375,7 +375,6 @@ nav { user-select: none; color: var(--text); border: none; - border-radius: var(--roundness); cursor: pointer; background-color: var(--background); box-shadow: var(--shadow); @@ -511,7 +510,6 @@ textarea { --_padding: 0.5em; border: none; - border-radius: var(--roundness); background-color: var(--background); color: var(--text); box-shadow: var(--shadow); @@ -617,6 +615,17 @@ textarea { } } +.input, +.button-default { + --_roundness-left: var(--roundness); + --_roundness-right: var(--roundness); + + border-top-left-radius: var(--_roundness-left); + border-bottom-left-radius: var(--_roundness-left); + border-top-right-radius: var(--_roundness-right); + border-bottom-right-radius: var(--_roundness-right); +} + // Textareas should have stock line-height + vertical padding instead of huge line-height textarea.input { padding: var(--_padding); @@ -662,22 +671,20 @@ option { display: inline-flex; vertical-align: middle; - button, - .button-dropdown { + > * { + --_roundness-left: 0; + --_roundness-right: 0; + position: relative; flex: 1 1 auto; + } - &:not(:last-child), - &:not(:last-child) .button-default { - border-top-right-radius: 0; - border-bottom-right-radius: 0; - } + > *:first-child { + --_roundness-left: var(--roundness); + } - &:not(:first-child), - &:not(:first-child) .button-default { - border-top-left-radius: 0; - border-bottom-left-radius: 0; - } + > *:last-child { + --_roundness-right: var(--roundness); } } diff --git a/src/components/font_control/font_control.js b/src/components/font_control/font_control.js index 52c3e70a..1e33338f 100644 --- a/src/components/font_control/font_control.js +++ b/src/components/font_control/font_control.js @@ -1,13 +1,19 @@ -import { set } from 'lodash' +import { set, clone } from 'lodash' import Select from '../select/select.vue' import Checkbox from 'src/components/checkbox/checkbox.vue' import Popover from 'src/components/popover/popover.vue' import { library } from '@fortawesome/fontawesome-svg-core' -import { faExclamationTriangle } from '@fortawesome/free-solid-svg-icons' +import { + faExclamationTriangle, + faKeyboard, + faFont +} from '@fortawesome/free-solid-svg-icons' library.add( - faExclamationTriangle + faExclamationTriangle, + faKeyboard, + faFont ) const PRESET_FONTS = new Set(['serif', 'sans-serif', 'monospace', 'inherit']) @@ -24,20 +30,38 @@ export default { emits: ['update:modelValue'], data () { return { - localValue: this.modelValue, - customFamily: '', + manualEntry: true, + localValue: clone(this.modelValue), + familyCustomLocal: null, availableOptions: [ this.noInherit ? '' : 'inherit', - 'local', - ...(this.options || []), 'serif', + 'sans-serif', 'monospace', - 'sans-serif' + 'local', + ...(this.options || []) ].filter(_ => _) } }, beforeUpdate () { - this.localValue = this.modelValue + this.localValue = clone(this.modelValue) + if (this.familyCustomLocal === null && !this.isInvalidFamily(this.modelValue?.family)) { + this.familyCustomLocal = this.modelValue?.family + } + }, + methods: { + lookupLocalFonts () { + if (!this.fontsList) { + this.$store.dispatch('queryLocalFonts') + } + this.toggleManualEntry() + }, + isInvalidFamily (value) { + return PRESET_FONTS.has(value) || (value === '') + }, + toggleManualEntry () { + this.manualEntry = !this.manualEntry + } }, computed: { present () { @@ -46,32 +70,39 @@ export default { defaultValue () { return this.localValue || this.fallback || {} }, + fontsListCapable () { + return this.$store.state.interface.browserSupport.localFonts + }, + fontsList () { + return this.$store.state.interface.localFonts + }, family: { get () { return this.defaultValue.family }, set (v) { + this.familyCustomLocal = '' set(this.localValue, 'family', v) this.$emit('update:modelValue', this.localValue) } }, familyCustom: { get () { - return this.customFamily + return this.familyCustomLocal }, set (v) { - this.customFamily = v - if (!PRESET_FONTS.has(this.customFamily)) { + this.familyCustomLocal = v + if (!this.isInvalidFamily(v)) { set(this.localValue, 'family', v) - this.$emit('update:modelValue', this.customFamily) + this.$emit('update:modelValue', this.localValue) } } }, invalidCustom () { - return PRESET_FONTS.has(this.customFamily) + return this.isInvalidFamily(this.familyCustomLocal) }, isCustom () { - return !PRESET_FONTS.has(this.family) + return !PRESET_FONTS.has(this.defaultValue.family) }, preset: { get () { diff --git a/src/components/font_control/font_control.vue b/src/components/font_control/font_control.vue index e73862a0..f1b126be 100644 --- a/src/components/font_control/font_control.vue +++ b/src/components/font_control/font_control.vue @@ -10,15 +10,6 @@ > {{ label }} - {{ ' ' }} - - {{ $t('settings.style.themes3.define') }} -

+ {{ ' ' }} + + {{ $t('settings.style.themes3.define') }} +

-

- + + + {{ ' ' }} + + + + + + + + .font-control { - input.custom-font { - min-width: 12em; + .custom-font { + min-width: 20em; + max-width: 20em; } } diff --git a/src/components/settings_modal/tabs/theme_tab/theme_tab.scss b/src/components/settings_modal/tabs/theme_tab/theme_tab.scss index 5e633120..4cb37c1e 100644 --- a/src/components/settings_modal/tabs/theme_tab/theme_tab.scss +++ b/src/components/settings_modal/tabs/theme_tab/theme_tab.scss @@ -10,6 +10,10 @@ margin-right: 0.25em; } + .btn-group .btn { + margin: 0; + } + .style-control { display: flex; align-items: baseline; diff --git a/src/i18n/en.json b/src/i18n/en.json index bd18c6ef..4b216165 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -746,14 +746,19 @@ "more_settings": "More settings", "style": { "themes3": { - "define": "Include in theme", + "define": "Override", "font": { "local": "Local font (must be installed on computer)", "serif": "Serif (browser default)", "sans-serif": "Sans-serif (browser default)", "monospace": "Monospace (browser default)", "inherit": "Same as parent component", - "invalid_custom_reserved": "This is a reserved font name, it will not be saved as custom font - use dropdown instead" + "invalid_custom_reserved": "Empty or reserved font name, it will not be saved as custom font - use dropdown instead", + "font_list_unavailable": "Couldn't get locally installed fonts: {error}", + "lookup_local_fonts": "Load list of fonts installed on this computer", + "enter_manually": "Enter font name family manually", + "entry": "Font's {fontFamily}", + "select": "Select local font" } }, "switcher": { diff --git a/src/modules/interface.js b/src/modules/interface.js index e21b4204..bee503c5 100644 --- a/src/modules/interface.js +++ b/src/modules/interface.js @@ -1,4 +1,5 @@ const defaultState = { + localFonts: null, themeApplied: false, temporaryChangesTimeoutId: null, // used for temporary options that revert after a timeout temporaryChangesConfirm: () => {}, // used for applying temporary options @@ -17,7 +18,8 @@ const defaultState = { cssFilter: window.CSS && window.CSS.supports && ( window.CSS.supports('filter', 'drop-shadow(0 0)') || window.CSS.supports('-webkit-filter', 'drop-shadow(0 0)') - ) + ), + localFonts: typeof window.queryLocalFonts === 'function' }, layoutType: 'normal', globalNotices: [], @@ -104,6 +106,10 @@ const interfaceMod = { }, setLastTimeline (state, value) { state.lastTimeline = value + }, + setFontsList (state, value) { + console.log(value) + state.localFonts = new Set(value.map(font => font.family)) } }, actions: { @@ -178,6 +184,22 @@ const interfaceMod = { commit('setLayoutType', wideLayout ? 'wide' : normalOrMobile) } }, + queryLocalFonts ({ commit, dispatch }) { + window + .queryLocalFonts() + .then((fonts) => { + commit('setFontsList', fonts) + }) + .catch((e) => { + dispatch('pushGlobalNotice', { + messageKey: 'settings.style.themes3.font.font_list_unavailable', + messageArgs: { + error: e + }, + level: 'error' + }) + }) + }, setLastTimeline ({ commit }, value) { commit('setLastTimeline', value) } -- cgit v1.2.3-70-g09d2 From 925fd863fe2be2cd273507dbb2688efb2d0ae07e Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Thu, 27 Jun 2024 00:34:25 +0300 Subject: Massively simplify and improve font input component --- src/components/font_control/font_control.js | 77 ++------------ src/components/font_control/font_control.vue | 147 +++++++++++++-------------- src/i18n/en.json | 20 ++-- src/modules/interface.js | 9 +- 4 files changed, 99 insertions(+), 154 deletions(-) (limited to 'src/components/font_control/font_control.vue') diff --git a/src/components/font_control/font_control.js b/src/components/font_control/font_control.js index 1e33338f..f6f45c8c 100644 --- a/src/components/font_control/font_control.js +++ b/src/components/font_control/font_control.js @@ -1,4 +1,3 @@ -import { set, clone } from 'lodash' import Select from '../select/select.vue' import Checkbox from 'src/components/checkbox/checkbox.vue' import Popover from 'src/components/popover/popover.vue' @@ -16,8 +15,6 @@ library.add( faFont ) -const PRESET_FONTS = new Set(['serif', 'sans-serif', 'monospace', 'inherit']) - export default { components: { Select, @@ -27,94 +24,36 @@ export default { props: [ 'name', 'label', 'modelValue', 'fallback', 'options', 'no-inherit' ], + mounted () { + this.$store.dispatch('queryLocalFonts') + }, emits: ['update:modelValue'], data () { return { manualEntry: true, - localValue: clone(this.modelValue), - familyCustomLocal: null, availableOptions: [ this.noInherit ? '' : 'inherit', 'serif', 'sans-serif', 'monospace', - 'local', ...(this.options || []) ].filter(_ => _) } }, - beforeUpdate () { - this.localValue = clone(this.modelValue) - if (this.familyCustomLocal === null && !this.isInvalidFamily(this.modelValue?.family)) { - this.familyCustomLocal = this.modelValue?.family - } - }, methods: { - lookupLocalFonts () { - if (!this.fontsList) { - this.$store.dispatch('queryLocalFonts') - } - this.toggleManualEntry() - }, - isInvalidFamily (value) { - return PRESET_FONTS.has(value) || (value === '') - }, toggleManualEntry () { this.manualEntry = !this.manualEntry } }, computed: { present () { - return typeof this.localValue !== 'undefined' - }, - defaultValue () { - return this.localValue || this.fallback || {} - }, - fontsListCapable () { - return this.$store.state.interface.browserSupport.localFonts - }, - fontsList () { - return this.$store.state.interface.localFonts - }, - family: { - get () { - return this.defaultValue.family - }, - set (v) { - this.familyCustomLocal = '' - set(this.localValue, 'family', v) - this.$emit('update:modelValue', this.localValue) - } - }, - familyCustom: { - get () { - return this.familyCustomLocal - }, - set (v) { - this.familyCustomLocal = v - if (!this.isInvalidFamily(v)) { - set(this.localValue, 'family', v) - this.$emit('update:modelValue', this.localValue) - } - } - }, - invalidCustom () { - return this.isInvalidFamily(this.familyCustomLocal) + return typeof this.modelValue !== 'undefined' }, - isCustom () { - return !PRESET_FONTS.has(this.defaultValue.family) + localFontsList () { + return this.$store.state.interface.localFonts?.values() }, - preset: { - get () { - if (PRESET_FONTS.has(this.family)) { - return this.family - } else { - return 'local' - } - }, - set (v) { - this.family = v === 'local' ? '' : v - } + localFontsSize () { + return this.$store.state.interface.localFonts?.size } } } diff --git a/src/components/font_control/font_control.vue b/src/components/font_control/font_control.vue index f1b126be..f3ab41a2 100644 --- a/src/components/font_control/font_control.vue +++ b/src/components/font_control/font_control.vue @@ -10,42 +10,18 @@ > {{ label }} -

- - {{ ' ' }} - - {{ $t('settings.style.themes3.define') }} - -

-

- + {{ ' ' }} + + {{ $t('settings.style.themes3.define') }} + +

+ {{ ' ' }} - + - + - + - - - - - -

diff --git a/src/i18n/en.json b/src/i18n/en.json index 4b216165..d995163a 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -748,17 +748,21 @@ "themes3": { "define": "Override", "font": { - "local": "Local font (must be installed on computer)", - "serif": "Serif (browser default)", - "sans-serif": "Sans-serif (browser default)", - "monospace": "Monospace (browser default)", - "inherit": "Same as parent component", - "invalid_custom_reserved": "Empty or reserved font name, it will not be saved as custom font - use dropdown instead", + "group-builtin": "Browser default fonts", + "builtin" : { + "serif": "Serif", + "sans-serif": "Sans-serif", + "monospace": "Monospace", + "inherit": "Unchanged" + }, + "group-local": "Locally installed fonts", + "local-unavailable1": "List of locally installed fonts unavailalbe", + "local-unavailable2": "Use manual entry to specify custom font", "font_list_unavailable": "Couldn't get locally installed fonts: {error}", "lookup_local_fonts": "Load list of fonts installed on this computer", "enter_manually": "Enter font name family manually", - "entry": "Font's {fontFamily}", - "select": "Select local font" + "entry": "Enter {fontFamily}", + "select": "Select font" } }, "switcher": { diff --git a/src/modules/interface.js b/src/modules/interface.js index bee503c5..2ccfeef3 100644 --- a/src/modules/interface.js +++ b/src/modules/interface.js @@ -108,7 +108,6 @@ const interfaceMod = { state.lastTimeline = value }, setFontsList (state, value) { - console.log(value) state.localFonts = new Set(value.map(font => font.family)) } }, @@ -184,10 +183,16 @@ const interfaceMod = { commit('setLayoutType', wideLayout ? 'wide' : normalOrMobile) } }, - queryLocalFonts ({ commit, dispatch }) { + queryLocalFonts ({ commit, dispatch, state }) { + if (state.localFonts !== null) return + commit('setFontsList', []) + if (!state.browserSupport.localFonts) { + return + } window .queryLocalFonts() .then((fonts) => { + console.log(fonts) commit('setFontsList', fonts) }) .catch((e) => { -- cgit v1.2.3-70-g09d2 From 665faf892a418fa1e7aeda1d1c82d926a2ed4f3a Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Sun, 21 Jul 2024 23:27:11 +0300 Subject: font overrides + fixes for font component --- src/components/font_control/font_control.vue | 2 +- .../settings_modal/tabs/appearance_tab.js | 14 +++++++- .../settings_modal/tabs/appearance_tab.vue | 18 +++++----- src/modules/config.js | 9 +++-- src/modules/interface.js | 40 ++++++++++++++++++++++ 5 files changed, 70 insertions(+), 13 deletions(-) (limited to 'src/components/font_control/font_control.vue') diff --git a/src/components/font_control/font_control.vue b/src/components/font_control/font_control.vue index f3ab41a2..b5423a8c 100644 --- a/src/components/font_control/font_control.vue +++ b/src/components/font_control/font_control.vue @@ -84,7 +84,7 @@ :id="name + '-local-font-switcher'" :model-value="modelValue.family" class="custom-font" - @update:modelValue="$emit('update:modelValue', { ...(modelValue || {}), family: $event.target.value })" + @update:modelValue="v => $emit('update:modelValue', { ...(modelValue || {}), family: v })" >
  • diff --git a/src/modules/config.js b/src/modules/config.js index e54a883c..88e339cf 100644 --- a/src/modules/config.js +++ b/src/modules/config.js @@ -52,7 +52,13 @@ export const defaultState = { palette: null, // not used yet, will be used for V3 theme3hacks: { // Hacks, user overrides that are independent of theme used underlay: 'none', - badgeColor: null + badgeColor: null, + fonts: { + interface: undefined, + input: undefined, + post: undefined, + monospace: undefined + } }, hideISP: false, @@ -147,7 +153,6 @@ export const defaultState = { navbarSize: undefined, // instance default panelHeaderSize: undefined, // instance default forcedRoundness: undefined, // instance default - fontsOverride: undefined, // instance default navbarColumnStretch: false, greentext: undefined, // instance default useAtIcon: undefined, // instance default diff --git a/src/modules/interface.js b/src/modules/interface.js index 38ee88db..206c68a7 100644 --- a/src/modules/interface.js +++ b/src/modules/interface.js @@ -274,6 +274,46 @@ const interfaceMod = { Object.entries(theme3hacks).forEach(([key, value]) => { switch (key) { + case 'fonts': { + Object.entries(theme3hacks.fonts).forEach(([fontKey, font]) => { + if (!font?.family) return + switch (fontKey) { + case 'interface': + hacks.push({ + component: 'Root', + directives: { + '--font': 'generic | ' + font.family + } + }) + break + case 'input': + hacks.push({ + component: 'Input', + directives: { + '--font': 'generic | ' + font.family + } + }) + break + case 'post': + hacks.push({ + component: 'RichContent', + directives: { + '--font': 'generic | ' + font.family + } + }) + break + case 'monospace': + hacks.push({ + component: 'Root', + directives: { + '--monoFont': 'generic | ' + font.family + } + }) + break + } + }) + break + } case 'underlay': { if (value !== 'none') { const newRule = { -- cgit v1.2.3-70-g09d2 From 4d3d07515163bfba4304bd22f9ed7f90d32cea28 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Sun, 21 Jul 2024 23:45:21 +0300 Subject: fix font selector losing list of local fonts when selecting one --- src/components/font_control/font_control.js | 5 +++-- src/components/font_control/font_control.vue | 2 +- src/modules/interface.js | 3 ++- 3 files changed, 6 insertions(+), 4 deletions(-) (limited to 'src/components/font_control/font_control.vue') diff --git a/src/components/font_control/font_control.js b/src/components/font_control/font_control.js index 08d0907e..13daa095 100644 --- a/src/components/font_control/font_control.js +++ b/src/components/font_control/font_control.js @@ -50,10 +50,11 @@ export default { return typeof this.modelValue !== 'undefined' }, localFontsList () { - return this.$store.state.interface.localFonts?.values() + console.log('FONTLIST', this.$store.state.interface.localFonts?.values()) + return this.$store.state.interface.localFonts }, localFontsSize () { - return this.$store.state.interface.localFonts?.size + return this.$store.state.interface.localFonts?.length } } } diff --git a/src/components/font_control/font_control.vue b/src/components/font_control/font_control.vue index b5423a8c..fca3b360 100644 --- a/src/components/font_control/font_control.vue +++ b/src/components/font_control/font_control.vue @@ -82,7 +82,7 @@