feat: range of font size (#1376)
This commit is contained in:
parent
85be61a316
commit
1a577343da
@ -4,13 +4,66 @@ import type { FontSize } from '~/composables/settings'
|
|||||||
|
|
||||||
const userSettings = useUserSettings()
|
const userSettings = useUserSettings()
|
||||||
|
|
||||||
const sizes = ['xs', 'sm', 'md', 'lg', 'xl'] as FontSize[]
|
const sizes = (new Array(11)).fill(0).map((x, i) => `${10 + i}px`) as FontSize[]
|
||||||
|
|
||||||
|
const setFontSize = (e: Event) => {
|
||||||
|
if (e.target && 'valueAsNumber' in e.target)
|
||||||
|
userSettings.value.fontSize = sizes[e.target.valueAsNumber as number]
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<select v-model="userSettings.fontSize">
|
<div flex items-center space-x-4>
|
||||||
<option v-for="size in sizes" :key="size" :value="size" :selected="userSettings.fontSize === size">
|
<span text-xs text-secondary>Aa</span>
|
||||||
{{ `${$t(`settings.interface.size_label.${size}`)}${size === DEFAULT_FONT_SIZE ? $t('settings.interface.default') : ''}` }}
|
<div flex-1 relative flex items-center>
|
||||||
</option>
|
<input
|
||||||
</select>
|
:value="sizes.indexOf(userSettings.fontSize)"
|
||||||
|
:aria-valuetext="`${userSettings.fontSize}${userSettings.fontSize === DEFAULT_FONT_SIZE ? ` ${$t('settings.interface.default')}` : ''}`"
|
||||||
|
:min="0"
|
||||||
|
:max="sizes.length - 1"
|
||||||
|
:step="1"
|
||||||
|
type="range"
|
||||||
|
focus:outline-none
|
||||||
|
appearance-none bg-transparent
|
||||||
|
w-full cursor-pointer
|
||||||
|
@change="setFontSize"
|
||||||
|
>
|
||||||
|
<div flex items-center justify-between absolute w-full pointer-events-none>
|
||||||
|
<div
|
||||||
|
v-for="i in sizes.length" :key="i"
|
||||||
|
h-3 w-3
|
||||||
|
rounded-full bg-secondary-light
|
||||||
|
relative
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
v-if="(sizes.indexOf(userSettings.fontSize)) === i - 1"
|
||||||
|
absolute rounded-full class="-top-1 -left-1"
|
||||||
|
bg-primary h-5 w-5
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<span text-xl text-secondary>Aa</span>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
input[type=range]::-webkit-slider-runnable-track {
|
||||||
|
--at-apply: bg-secondary-light rounded-full h1 op60;
|
||||||
|
}
|
||||||
|
input[type=range]:focus:-webkit-slider-runnable-track {
|
||||||
|
--at-apply: outline-2 outline-red;
|
||||||
|
}
|
||||||
|
input[type=range]::-webkit-slider-thumb {
|
||||||
|
--at-apply: w3 h3 bg-primary -mt-1 outline outline-3 outline-primary rounded-full cursor-pointer appearance-none;
|
||||||
|
}
|
||||||
|
input[type=range]::-moz-range-track {
|
||||||
|
--at-apply: bg-secondary-light rounded-full h1 op60;
|
||||||
|
}
|
||||||
|
input[type=range]:focus::-moz-range-track {
|
||||||
|
--at-apply: outline-2 outline-red;
|
||||||
|
}
|
||||||
|
input[type=range]::-moz-range-thumb {
|
||||||
|
--at-apply: w3 h3 bg-primary -mt-1 outline outline-3 outline-primary rounded-full cursor-pointer appearance-none border-none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
import { DEFAULT_FONT_SIZE } from '~/constants'
|
import { DEFAULT_FONT_SIZE } from '~/constants'
|
||||||
|
|
||||||
export type FontSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl'
|
export type FontSize = `${number}px`
|
||||||
|
|
||||||
|
// Temporary type for backward compatibility
|
||||||
|
export type OldFontSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl'
|
||||||
|
|
||||||
export type ColorMode = 'light' | 'dark' | 'system'
|
export type ColorMode = 'light' | 'dark' | 'system'
|
||||||
|
|
||||||
export interface PreferencesSettings {
|
export interface PreferencesSettings {
|
||||||
|
@ -1,14 +1,21 @@
|
|||||||
import type { Ref } from 'vue'
|
import type { Ref } from 'vue'
|
||||||
import type { VueI18n } from 'vue-i18n'
|
import type { VueI18n } from 'vue-i18n'
|
||||||
import type { LocaleObject } from 'vue-i18n-routing'
|
import type { LocaleObject } from 'vue-i18n-routing'
|
||||||
import type { PreferencesSettings, UserSettings } from './definition'
|
import type { FontSize, OldFontSize, PreferencesSettings, UserSettings } from './definition'
|
||||||
import { STORAGE_KEY_SETTINGS } from '~/constants'
|
import { STORAGE_KEY_SETTINGS } from '~/constants'
|
||||||
|
import { oldFontSizeMap } from '~~/constants/options'
|
||||||
|
|
||||||
export function useUserSettings() {
|
export function useUserSettings() {
|
||||||
const i18n = useNuxtApp().vueApp.config.globalProperties.$i18n as VueI18n
|
const i18n = useNuxtApp().vueApp.config.globalProperties.$i18n as VueI18n
|
||||||
const { locales } = i18n
|
const { locales } = i18n
|
||||||
const supportLanguages = (locales as LocaleObject[]).map(locale => locale.code)
|
const supportLanguages = (locales as LocaleObject[]).map(locale => locale.code)
|
||||||
return useUserLocalStorage<UserSettings>(STORAGE_KEY_SETTINGS, () => getDefaultUserSettings(supportLanguages))
|
const settingsStorage = useUserLocalStorage<UserSettings>(STORAGE_KEY_SETTINGS, () => getDefaultUserSettings(supportLanguages))
|
||||||
|
|
||||||
|
// Backward compatibility, font size was xs, sm, md, lg, xl before
|
||||||
|
if (settingsStorage.value.fontSize && !settingsStorage.value.fontSize.includes('px'))
|
||||||
|
settingsStorage.value.fontSize = oldFontSizeMap[settingsStorage.value.fontSize as OldFontSize] as FontSize
|
||||||
|
|
||||||
|
return settingsStorage
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: refactor & simplify this
|
// TODO: refactor & simplify this
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
export const APP_NAME = 'Elk'
|
export const APP_NAME = 'Elk'
|
||||||
|
|
||||||
export const DEFAULT_POST_CHARS_LIMIT = 500
|
export const DEFAULT_POST_CHARS_LIMIT = 500
|
||||||
export const DEFAULT_FONT_SIZE = 'md'
|
export const DEFAULT_FONT_SIZE = '15px'
|
||||||
|
|
||||||
export const STORAGE_KEY_DRAFTS = 'elk-drafts'
|
export const STORAGE_KEY_DRAFTS = 'elk-drafts'
|
||||||
export const STORAGE_KEY_USERS = 'elk-users'
|
export const STORAGE_KEY_USERS = 'elk-users'
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
export const fontSizeMap = {
|
export const oldFontSizeMap = {
|
||||||
xs: '13px',
|
xs: '13px',
|
||||||
sm: '14px',
|
sm: '14px',
|
||||||
md: '15px',
|
md: '15px',
|
||||||
|
@ -260,13 +260,6 @@
|
|||||||
"font_size": "حجم الخط",
|
"font_size": "حجم الخط",
|
||||||
"label": "واجهه المستخدم",
|
"label": "واجهه المستخدم",
|
||||||
"light_mode": "وضع الضوء",
|
"light_mode": "وضع الضوء",
|
||||||
"size_label": {
|
|
||||||
"lg": "كبير",
|
|
||||||
"md": "متوسط",
|
|
||||||
"sm": "صغير",
|
|
||||||
"xl": "ضخم",
|
|
||||||
"xs": "صغير جدا"
|
|
||||||
},
|
|
||||||
"system_mode": "النظام"
|
"system_mode": "النظام"
|
||||||
},
|
},
|
||||||
"language": {
|
"language": {
|
||||||
|
@ -266,13 +266,6 @@
|
|||||||
"font_size": "Schriftgröße",
|
"font_size": "Schriftgröße",
|
||||||
"label": "Oberfläche",
|
"label": "Oberfläche",
|
||||||
"light_mode": "Helles Farbschema",
|
"light_mode": "Helles Farbschema",
|
||||||
"size_label": {
|
|
||||||
"lg": "Groß",
|
|
||||||
"md": "Mittel",
|
|
||||||
"sm": "Klein",
|
|
||||||
"xl": "Extra groß",
|
|
||||||
"xs": "Extra klein"
|
|
||||||
},
|
|
||||||
"system_mode": "System"
|
"system_mode": "System"
|
||||||
},
|
},
|
||||||
"language": {
|
"language": {
|
||||||
|
@ -301,13 +301,6 @@
|
|||||||
"font_size": "Font Size",
|
"font_size": "Font Size",
|
||||||
"label": "Interface",
|
"label": "Interface",
|
||||||
"light_mode": "Light",
|
"light_mode": "Light",
|
||||||
"size_label": {
|
|
||||||
"lg": "Large",
|
|
||||||
"md": "Medium",
|
|
||||||
"sm": "Small",
|
|
||||||
"xl": "Extra large",
|
|
||||||
"xs": "Extra small"
|
|
||||||
},
|
|
||||||
"system_mode": "System",
|
"system_mode": "System",
|
||||||
"theme_color": "Theme Color"
|
"theme_color": "Theme Color"
|
||||||
},
|
},
|
||||||
|
@ -255,14 +255,7 @@
|
|||||||
"default": " (por defecto)",
|
"default": " (por defecto)",
|
||||||
"font_size": "Tamaño de Letra",
|
"font_size": "Tamaño de Letra",
|
||||||
"label": "Interfaz",
|
"label": "Interfaz",
|
||||||
"light_mode": "Modo claro",
|
"light_mode": "Modo claro"
|
||||||
"size_label": {
|
|
||||||
"lg": "Grande",
|
|
||||||
"md": "Mediana",
|
|
||||||
"sm": "Pequeña",
|
|
||||||
"xl": "Extra grande",
|
|
||||||
"xs": "Extra pequeña"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"language": {
|
"language": {
|
||||||
"display_language": "Idioma de pantalla",
|
"display_language": "Idioma de pantalla",
|
||||||
|
@ -306,13 +306,6 @@
|
|||||||
"font_size": "Taille de police",
|
"font_size": "Taille de police",
|
||||||
"label": "Interface",
|
"label": "Interface",
|
||||||
"light_mode": "Mode lumineux",
|
"light_mode": "Mode lumineux",
|
||||||
"size_label": {
|
|
||||||
"lg": "Grande",
|
|
||||||
"md": "Moyenne",
|
|
||||||
"sm": "Petite",
|
|
||||||
"xl": "Très grande",
|
|
||||||
"xs": "Très petite"
|
|
||||||
},
|
|
||||||
"system_mode": "Système",
|
"system_mode": "Système",
|
||||||
"theme_color": "Couleur du thème"
|
"theme_color": "Couleur du thème"
|
||||||
},
|
},
|
||||||
|
@ -304,13 +304,6 @@
|
|||||||
"font_size": "Ukuran huruf",
|
"font_size": "Ukuran huruf",
|
||||||
"label": "Antarmuka",
|
"label": "Antarmuka",
|
||||||
"light_mode": "Terang",
|
"light_mode": "Terang",
|
||||||
"size_label": {
|
|
||||||
"lg": "Besar",
|
|
||||||
"md": "Medium",
|
|
||||||
"sm": "Kecil",
|
|
||||||
"xl": "Ekstra besar",
|
|
||||||
"xs": "Ekstra kecil"
|
|
||||||
},
|
|
||||||
"system_mode": "Sistem",
|
"system_mode": "Sistem",
|
||||||
"theme_color": "Warna Tema"
|
"theme_color": "Warna Tema"
|
||||||
},
|
},
|
||||||
|
@ -301,13 +301,6 @@
|
|||||||
"font_size": "フォントサイズ",
|
"font_size": "フォントサイズ",
|
||||||
"label": "インターフェイス",
|
"label": "インターフェイス",
|
||||||
"light_mode": "ライトモード",
|
"light_mode": "ライトモード",
|
||||||
"size_label": {
|
|
||||||
"lg": "大",
|
|
||||||
"md": "中",
|
|
||||||
"sm": "小",
|
|
||||||
"xl": "極大",
|
|
||||||
"xs": "極小"
|
|
||||||
},
|
|
||||||
"system_mode": "システム",
|
"system_mode": "システム",
|
||||||
"theme_color": "テーマカラー"
|
"theme_color": "テーマカラー"
|
||||||
},
|
},
|
||||||
|
@ -301,13 +301,6 @@
|
|||||||
"font_size": "Tamanho da fonte",
|
"font_size": "Tamanho da fonte",
|
||||||
"label": "Apresentação",
|
"label": "Apresentação",
|
||||||
"light_mode": "Modo Claro",
|
"light_mode": "Modo Claro",
|
||||||
"size_label": {
|
|
||||||
"lg": "Grande",
|
|
||||||
"md": "Médio",
|
|
||||||
"sm": "Pequeno",
|
|
||||||
"xl": "Extra grande",
|
|
||||||
"xs": "Extra pequeno"
|
|
||||||
},
|
|
||||||
"system_mode": "Sistema",
|
"system_mode": "Sistema",
|
||||||
"theme_color": "Cor to Tema"
|
"theme_color": "Cor to Tema"
|
||||||
},
|
},
|
||||||
|
@ -256,13 +256,6 @@
|
|||||||
"font_size": "Font Boyutu",
|
"font_size": "Font Boyutu",
|
||||||
"label": "Arayüz",
|
"label": "Arayüz",
|
||||||
"light_mode": "Aydınlık Mod",
|
"light_mode": "Aydınlık Mod",
|
||||||
"size_label": {
|
|
||||||
"lg": "Büyük",
|
|
||||||
"md": "Orta",
|
|
||||||
"sm": "Küçük",
|
|
||||||
"xl": "Çok büyük",
|
|
||||||
"xs": "Çok küçük"
|
|
||||||
},
|
|
||||||
"system_mode": "Sistem"
|
"system_mode": "Sistem"
|
||||||
},
|
},
|
||||||
"language": {
|
"language": {
|
||||||
|
@ -226,14 +226,7 @@
|
|||||||
"default": " (за замовчуванням)",
|
"default": " (за замовчуванням)",
|
||||||
"font_size": "Розмір шрифта",
|
"font_size": "Розмір шрифта",
|
||||||
"label": "Інтерфейс",
|
"label": "Інтерфейс",
|
||||||
"light_mode": "Світла",
|
"light_mode": "Світла"
|
||||||
"size_label": {
|
|
||||||
"lg": "Великий",
|
|
||||||
"md": "Середній",
|
|
||||||
"sm": "Малий",
|
|
||||||
"xl": "Дуже великий",
|
|
||||||
"xs": "Дуже малий"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"language": {
|
"language": {
|
||||||
"display_language": "Мова інтерфейсу",
|
"display_language": "Мова інтерфейсу",
|
||||||
|
@ -274,13 +274,6 @@
|
|||||||
"font_size": "字号",
|
"font_size": "字号",
|
||||||
"label": "外观",
|
"label": "外观",
|
||||||
"light_mode": "浅色",
|
"light_mode": "浅色",
|
||||||
"size_label": {
|
|
||||||
"lg": "大",
|
|
||||||
"md": "中",
|
|
||||||
"sm": "小",
|
|
||||||
"xl": "特大",
|
|
||||||
"xs": "特小"
|
|
||||||
},
|
|
||||||
"system_mode": "跟随系统"
|
"system_mode": "跟随系统"
|
||||||
},
|
},
|
||||||
"language": {
|
"language": {
|
||||||
|
@ -284,13 +284,6 @@
|
|||||||
"font_size": "字體大小",
|
"font_size": "字體大小",
|
||||||
"label": "外觀",
|
"label": "外觀",
|
||||||
"light_mode": "淺色",
|
"light_mode": "淺色",
|
||||||
"size_label": {
|
|
||||||
"lg": "大",
|
|
||||||
"md": "中",
|
|
||||||
"sm": "小",
|
|
||||||
"xl": "特大",
|
|
||||||
"xs": "特小"
|
|
||||||
},
|
|
||||||
"system_mode": "系統預設",
|
"system_mode": "系統預設",
|
||||||
"theme_color": "主題色"
|
"theme_color": "主題色"
|
||||||
},
|
},
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
import { fontSizeMap } from '~/constants/options'
|
import type { OldFontSize } from '~/composables/settings'
|
||||||
|
import { oldFontSizeMap } from '~/constants/options'
|
||||||
import { DEFAULT_FONT_SIZE } from '~/constants'
|
import { DEFAULT_FONT_SIZE } from '~/constants'
|
||||||
|
|
||||||
export default defineNuxtPlugin(() => {
|
export default defineNuxtPlugin(() => {
|
||||||
const userSettings = useUserSettings()
|
const userSettings = useUserSettings()
|
||||||
const html = document.documentElement
|
const html = document.documentElement
|
||||||
watchEffect(() => {
|
watchEffect(() => {
|
||||||
html.style.setProperty('--font-size', fontSizeMap[userSettings.value.fontSize || DEFAULT_FONT_SIZE])
|
const { fontSize } = userSettings.value
|
||||||
|
html.style.setProperty('--font-size', fontSize ? (oldFontSizeMap[fontSize as OldFontSize] ?? fontSize) : DEFAULT_FONT_SIZE)
|
||||||
})
|
})
|
||||||
watchEffect(() => {
|
watchEffect(() => {
|
||||||
html.classList.toggle('zen', userSettings.value.zenMode)
|
html.classList.toggle('zen', userSettings.value.zenMode)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { STORAGE_KEY_CURRENT_USER_HANDLE, STORAGE_KEY_SETTINGS } from '~/constants'
|
import { STORAGE_KEY_CURRENT_USER_HANDLE, STORAGE_KEY_SETTINGS } from '~/constants'
|
||||||
import { fontSizeMap } from '~/constants/options'
|
import { oldFontSizeMap } from '~/constants/options'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Injecting scripts before renders
|
* Injecting scripts before renders
|
||||||
@ -19,8 +19,8 @@ export default defineNuxtPlugin(() => {
|
|||||||
${process.dev ? 'console.log({ settings })' : ''}
|
${process.dev ? 'console.log({ settings })' : ''}
|
||||||
|
|
||||||
if (settings.fontSize) {
|
if (settings.fontSize) {
|
||||||
const fontSizeMap = ${JSON.stringify(fontSizeMap)}
|
const oldFontSizeMap = ${JSON.stringify(oldFontSizeMap)}
|
||||||
html.style.setProperty('--font-size', fontSizeMap[settings.fontSize])
|
html.style.setProperty('--font-size', oldFontSizeMap[settings.fontSize] || settings.fontSize)
|
||||||
}
|
}
|
||||||
if (settings.language) {
|
if (settings.language) {
|
||||||
html.setAttribute('lang', settings.language)
|
html.setAttribute('lang', settings.language)
|
||||||
|
@ -22,6 +22,8 @@ export default defineConfig({
|
|||||||
'bg-base': 'bg-$c-bg-base',
|
'bg-base': 'bg-$c-bg-base',
|
||||||
'bg-border': 'bg-$c-border',
|
'bg-border': 'bg-$c-border',
|
||||||
'bg-active': 'bg-$c-bg-active',
|
'bg-active': 'bg-$c-bg-active',
|
||||||
|
'bg-secondary': 'bg-$c-text-secondary',
|
||||||
|
'bg-secondary-light': 'bg-$c-text-secondary-light',
|
||||||
'bg-primary-light': 'bg-$c-primary-light',
|
'bg-primary-light': 'bg-$c-primary-light',
|
||||||
'bg-primary-fade': 'bg-$c-primary-fade',
|
'bg-primary-fade': 'bg-$c-primary-fade',
|
||||||
'bg-card': 'bg-$c-bg-card',
|
'bg-card': 'bg-$c-bg-card',
|
||||||
|
Loading…
Reference in New Issue
Block a user