From e4a819a0e2ed9c57dc2191428d86a33bb5918862 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Wed, 22 May 2024 19:54:19 +0300 Subject: [PATCH 01/53] initial Appearance Tab implementation, added text size/UI scale option --- src/App.scss | 4 +- .../settings_modal/helpers/setting.js | 10 ++- .../settings_modal/helpers/unit_setting.js | 24 +++++-- .../settings_modal/helpers/unit_setting.vue | 2 +- .../settings_modal/settings_modal.js | 3 + .../settings_modal/settings_modal.vue | 12 ++++ .../settings_modal_user_content.js | 2 + .../settings_modal_user_content.vue | 7 ++ .../settings_modal/tabs/appearance_tab.js | 39 ++++++++++ .../settings_modal/tabs/appearance_tab.vue | 71 +++++++++++++++++++ .../settings_modal/tabs/general_tab.vue | 15 ---- src/i18n/en.json | 8 +++ src/modules/config.js | 33 ++++++++- src/modules/instance.js | 2 + src/modules/interface.js | 14 ++++ src/services/style_setter/style_setter.js | 16 ++++- 16 files changed, 236 insertions(+), 26 deletions(-) create mode 100644 src/components/settings_modal/tabs/appearance_tab.js create mode 100644 src/components/settings_modal/tabs/appearance_tab.vue diff --git a/src/App.scss b/src/App.scss index 6e0aabcaa..32ca91896 100644 --- a/src/App.scss +++ b/src/App.scss @@ -3,7 +3,7 @@ @import "./panel"; :root { - --font-size: 14px; + --fontSize: 14px; --status-margin: 0.75em; --navbar-height: 3.5rem; --post-line-height: 1.4; @@ -20,7 +20,7 @@ } html { - font-size: var(--font-size); + font-size: var(--textSize); // overflow-x: clip causes my browser's tab to crash with SIGILL lul } diff --git a/src/components/settings_modal/helpers/setting.js b/src/components/settings_modal/helpers/setting.js index abf9cfdf4..3b3e6268d 100644 --- a/src/components/settings_modal/helpers/setting.js +++ b/src/components/settings_modal/helpers/setting.js @@ -48,6 +48,10 @@ export default { draftMode: { type: Boolean, default: undefined + }, + timedApplyMode: { + type: Boolean, + default: false } }, inject: { @@ -161,7 +165,11 @@ export default { case 'admin': return (k, v) => this.$store.dispatch('pushAdminSetting', { path: k, value: v }) default: - return (k, v) => this.$store.dispatch('setOption', { name: k, value: v }) + if (this.timedApplyMode) { + return (k, v) => this.$store.dispatch('setOptionTemporarily', { name: k, value: v }) + } else { + return (k, v) => this.$store.dispatch('setOption', { name: k, value: v }) + } } }, defaultState () { diff --git a/src/components/settings_modal/helpers/unit_setting.js b/src/components/settings_modal/helpers/unit_setting.js index c9c23cb0b..daeddd813 100644 --- a/src/components/settings_modal/helpers/unit_setting.js +++ b/src/components/settings_modal/helpers/unit_setting.js @@ -21,15 +21,23 @@ export default { unitSet: { type: String, default: 'none' + }, + step: { + type: Number, + default: 1 + }, + resetDefault: { + type: Object, + default: null } }, computed: { ...Setting.computed, stateUnit () { - return this.state.replace(/\d+/, '') + return typeof this.state === 'string' ? this.state.replace(/[0-9,.]+/, '') : '' }, stateValue () { - return this.state.replace(/\D+/, '') + return typeof this.state === 'string' ? this.state.replace(/[^0-9,.]+/, '') : '' } }, methods: { @@ -39,10 +47,18 @@ export default { return this.$t(['settings', 'units', this.unitSet, value].join('.')) }, updateValue (e) { - this.configSink(this.path, parseInt(e.target.value) + this.stateUnit) + this.configSink(this.path, parseFloat(e.target.value) + this.stateUnit) }, updateUnit (e) { - this.configSink(this.path, this.stateValue + e.target.value) + let value = this.stateValue + const newUnit = e.target.value + if (this.resetDefault) { + const replaceValue = this.resetDefault[newUnit] + if (replaceValue != null) { + value = replaceValue + } + } + this.configSink(this.path, value + newUnit) } } } diff --git a/src/components/settings_modal/helpers/unit_setting.vue b/src/components/settings_modal/helpers/unit_setting.vue index 68f52b1cd..86798e04e 100644 --- a/src/components/settings_modal/helpers/unit_setting.vue +++ b/src/components/settings_modal/helpers/unit_setting.vue @@ -13,7 +13,7 @@ :id="path" class="input number-input" type="number" - step="1" + step="step" :disabled="disabled" :min="min || 0" :value="stateValue" diff --git a/src/components/settings_modal/settings_modal.js b/src/components/settings_modal/settings_modal.js index ff58f2c38..63c9b24a3 100644 --- a/src/components/settings_modal/settings_modal.js +++ b/src/components/settings_modal/settings_modal.js @@ -4,6 +4,7 @@ import AsyncComponentError from 'src/components/async_component_error/async_comp import getResettableAsyncComponent from 'src/services/resettable_async_component.js' import Popover from '../popover/popover.vue' import Checkbox from 'src/components/checkbox/checkbox.vue' +import ConfirmModal from 'src/components/confirm_modal/confirm_modal.vue' import { library } from '@fortawesome/fontawesome-svg-core' import { cloneDeep, isEqual } from 'lodash' import { @@ -53,6 +54,7 @@ const SettingsModal = { Modal, Popover, Checkbox, + ConfirmModal, SettingsModalUserContent: getResettableAsyncComponent( () => import('./settings_modal_user_content.vue'), { @@ -165,6 +167,7 @@ const SettingsModal = { }, computed: { currentSaveStateNotice () { + console.log(this.$store.state.interface.settings.currentSaveStateNotice) return this.$store.state.interface.settings.currentSaveStateNotice }, modalActivated () { diff --git a/src/components/settings_modal/settings_modal.vue b/src/components/settings_modal/settings_modal.vue index 50859c94c..90dbbde0a 100644 --- a/src/components/settings_modal/settings_modal.vue +++ b/src/components/settings_modal/settings_modal.vue @@ -147,6 +147,18 @@ + + + {{ $t('settings.confirm_new_question') }} + + diff --git a/src/components/settings_modal/settings_modal_user_content.js b/src/components/settings_modal/settings_modal_user_content.js index 9ac0301f6..ac1190068 100644 --- a/src/components/settings_modal/settings_modal_user_content.js +++ b/src/components/settings_modal/settings_modal_user_content.js @@ -7,6 +7,7 @@ import FilteringTab from './tabs/filtering_tab.vue' import SecurityTab from './tabs/security_tab/security_tab.vue' import ProfileTab from './tabs/profile_tab.vue' import GeneralTab from './tabs/general_tab.vue' +import AppearanceTab from './tabs/appearance_tab.vue' import VersionTab from './tabs/version_tab.vue' import ThemeTab from './tabs/theme_tab/theme_tab.vue' @@ -44,6 +45,7 @@ const SettingsModalContent = { SecurityTab, ProfileTab, GeneralTab, + AppearanceTab, VersionTab, ThemeTab }, diff --git a/src/components/settings_modal/settings_modal_user_content.vue b/src/components/settings_modal/settings_modal_user_content.vue index 0221cccb6..da99f340b 100644 --- a/src/components/settings_modal/settings_modal_user_content.vue +++ b/src/components/settings_modal/settings_modal_user_content.vue @@ -21,6 +21,13 @@ > +
+ +
+
+
+

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

+
    +
  • + + {{ $t('settings.hide_wallpaper') }} + +
  • +
  • + + {{ $t('settings.disable_sticky_headers') }} + +
  • +
  • + + {{ $t('settings.show_scrollbars') }} + +
  • +
  • + + {{ $t('settings.text_size') }} + +
    + + + px + rem + +
    + + 14px + +
    +
    +
  • +
+
+
+ + + + + diff --git a/src/components/settings_modal/tabs/general_tab.vue b/src/components/settings_modal/tabs/general_tab.vue index 208c49ee3..240c07626 100644 --- a/src/components/settings_modal/tabs/general_tab.vue +++ b/src/components/settings_modal/tabs/general_tab.vue @@ -15,11 +15,6 @@ {{ $t('settings.hide_isp') }} -
  • - - {{ $t('settings.hide_wallpaper') }} - -
  • {{ $t('settings.stop_gifs') }} @@ -101,16 +96,6 @@
  • {{ $t('settings.columns') }}

  • -
  • - - {{ $t('settings.disable_sticky_headers') }} - -
  • -
  • - - {{ $t('settings.show_scrollbars') }} - -
  • {{ $t('settings.right_sidebar') }} diff --git a/src/i18n/en.json b/src/i18n/en.json index f626e933d..0c3f26b9c 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -374,6 +374,14 @@ "enter_current_password_to_confirm": "Enter your current password to confirm your identity", "post_look_feel": "Posts Look & Feel", "mention_links": "Mention links", + "appearance": "Appearance", + "confirm_new_setting": "Confirm new setting?", + "confirm_new_question": "Does this look ok? Setting will be reverted in 10 seconds.", + "revert": "Revert", + "confirm": "Confirm", + "text_size": "Text and interface size", + "text_size_tip": "Use {0} for absolute values, {1} will scale with browser default text size.", + "text_size_tip2": "Values other than {0} might break some things and themes", "mfa": { "otp": "OTP", "setup_otp": "Setup OTP", diff --git a/src/modules/config.js b/src/modules/config.js index 8001b854b..4d5e8efca 100644 --- a/src/modules/config.js +++ b/src/modules/config.js @@ -115,7 +115,8 @@ export const defaultState = { sidebarColumnWidth: '25rem', contentColumnWidth: '45rem', notifsColumnWidth: '25rem', - emojiReactionsScale: 1.0, + emojiReactionsScale: undefined, + textSize: undefined, // instance default navbarColumnStretch: false, greentext: undefined, // instance default useAtIcon: undefined, // instance default @@ -173,6 +174,10 @@ const config = { } }, mutations: { + setOptionTemporarily (state, { name, value }) { + set(state, name, value) + applyConfig(state) + }, setOption (state, { name, value }) { set(state, name, value) }, @@ -203,6 +208,31 @@ const config = { setHighlight ({ commit, dispatch }, { user, color, type }) { commit('setHighlight', { user, color, type }) }, + setOptionTemporarily ({ commit, dispatch, state, rootState }, { name, value }) { + if (rootState.interface.temporaryChangesTimeoutId !== null) { + console.warn('Can\'t track more than one temporary change') + return + } + const oldValue = state[name] + + commit('setOptionTemporarily', { name, value }) + + const confirm = () => { + dispatch('setOption', { name, value }) + commit('clearTemporaryChanges') + } + + const revert = () => { + commit('setOptionTemporarily', { name, value: oldValue }) + commit('clearTemporaryChanges') + } + + commit('setTemporaryChanges', { + timeoutId: setTimeout(revert, 10000), + confirm, + revert + }) + }, setOption ({ commit, dispatch, state }, { name, value }) { const exceptions = new Set([ 'useStreamingApi' @@ -231,6 +261,7 @@ const config = { case 'sidebarColumnWidth': case 'contentColumnWidth': case 'notifsColumnWidth': + case 'textSize': case 'emojiReactionsScale': applyConfig(state) break diff --git a/src/modules/instance.js b/src/modules/instance.js index 0a5c1ae76..4a75d9487 100644 --- a/src/modules/instance.js +++ b/src/modules/instance.js @@ -98,6 +98,8 @@ const defaultState = { sidebarRight: false, subjectLineBehavior: 'email', theme: 'pleroma-dark', + emojiReactionsScale: 1.0, + textSize: '14px', virtualScrolling: true, sensitiveByDefault: false, conversationDisplay: 'linear', diff --git a/src/modules/interface.js b/src/modules/interface.js index 39242b9d6..e21b4204b 100644 --- a/src/modules/interface.js +++ b/src/modules/interface.js @@ -1,5 +1,8 @@ const defaultState = { themeApplied: false, + temporaryChangesTimeoutId: null, // used for temporary options that revert after a timeout + temporaryChangesConfirm: () => {}, // used for applying temporary options + temporaryChangesRevert: () => {}, // used for reverting temporary options settingsModalState: 'hidden', settingsModalLoadedUser: false, settingsModalLoadedAdmin: false, @@ -36,6 +39,17 @@ const interfaceMod = { state.settings.currentSaveStateNotice = { error: true, errorData: error } } }, + setTemporaryChanges (state, { timeoutId, confirm, revert }) { + state.temporaryChangesTimeoutId = timeoutId + state.temporaryChangesConfirm = confirm + state.temporaryChangesRevert = revert + }, + clearTemporaryChanges (state) { + clearTimeout(state.temporaryChangesTimeoutId) + state.temporaryChangesTimeoutId = null + state.temporaryChangesConfirm = () => {} + state.temporaryChangesRevert = () => {} + }, setThemeApplied (state) { state.themeApplied = true }, diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js index 369d2c9f1..a98456d30 100644 --- a/src/services/style_setter/style_setter.js +++ b/src/services/style_setter/style_setter.js @@ -148,8 +148,19 @@ export const applyTheme = async (input, onFinish = (data) => {}) => { return Promise.resolve() } -const configColumns = ({ sidebarColumnWidth, contentColumnWidth, notifsColumnWidth, emojiReactionsScale }) => - ({ sidebarColumnWidth, contentColumnWidth, notifsColumnWidth, emojiReactionsScale }) +const configColumns = ({ + sidebarColumnWidth, + contentColumnWidth, + notifsColumnWidth, + emojiReactionsScale, + textSize +}) => ({ + sidebarColumnWidth, + contentColumnWidth, + notifsColumnWidth, + emojiReactionsScale, + textSize +}) const defaultConfigColumns = configColumns(defaultState) @@ -175,6 +186,7 @@ export const applyConfig = (config) => { styleSheet.toString() styleSheet.insertRule(`:root { ${rules} }`, 'index-max') + body.classList.remove('hidden') } From 6142ac2bfcacec227e4035cac19f2c5d968e72d6 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Thu, 13 Jun 2024 01:28:34 +0300 Subject: [PATCH 02/53] fix mobile layout navbar height --- src/components/mobile_nav/mobile_nav.vue | 8 ++++---- src/components/navigation/navigation_pins.vue | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/components/mobile_nav/mobile_nav.vue b/src/components/mobile_nav/mobile_nav.vue index 6e134ef2b..624ff1d03 100644 --- a/src/components/mobile_nav/mobile_nav.vue +++ b/src/components/mobile_nav/mobile_nav.vue @@ -129,7 +129,7 @@ .mobile-nav { display: grid; line-height: var(--navbar-height); - grid-template-rows: 50px; + grid-template-rows: 1fr; grid-template-columns: 2fr auto; width: 100%; box-sizing: border-box; @@ -190,8 +190,8 @@ justify-content: space-between; z-index: calc(var(--ZI_navbar) + 100); width: 100%; - height: 50px; - line-height: 50px; + height: 3.5em; + line-height: 3.5em; position: absolute; box-shadow: var(--shadow); @@ -214,7 +214,7 @@ } .mobile-notifications { - margin-top: 50px; + margin-top: 3.5em; width: 100vw; height: calc(100vh - var(--navbar-height)); overflow-x: hidden; diff --git a/src/components/navigation/navigation_pins.vue b/src/components/navigation/navigation_pins.vue index 36eb1ebe2..decd1c04b 100644 --- a/src/components/navigation/navigation_pins.vue +++ b/src/components/navigation/navigation_pins.vue @@ -49,6 +49,7 @@ } &.toggled { + margin-bottom: -4px; border-bottom: 4px solid; } } From 6343b91abf7fbad1cdd8b4648d1fc825d8e9b03c Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Thu, 13 Jun 2024 02:22:47 +0300 Subject: [PATCH 03/53] more scaling options --- src/App.scss | 5 +- .../emoji_reactions/emoji_reactions.vue | 2 +- .../settings_modal/tabs/appearance_tab.js | 32 ++++- .../settings_modal/tabs/appearance_tab.vue | 116 +++++++++++++++--- .../settings_modal/tabs/general_tab.js | 33 +---- .../settings_modal/tabs/general_tab.vue | 60 --------- src/i18n/en.json | 4 + src/modules/config.js | 5 + src/modules/instance.js | 3 + src/panel.scss | 6 +- src/services/style_setter/style_setter.js | 20 ++- 11 files changed, 165 insertions(+), 121 deletions(-) diff --git a/src/App.scss b/src/App.scss index 32ca91896..a27104360 100644 --- a/src/App.scss +++ b/src/App.scss @@ -5,7 +5,7 @@ :root { --fontSize: 14px; --status-margin: 0.75em; - --navbar-height: 3.5rem; + --navbar-height: var(--navbarSize, 3.5rem); --post-line-height: 1.4; // Z-Index stuff --ZI_media_modal: 9000; @@ -21,6 +21,9 @@ html { font-size: var(--textSize); + + --navbar-height: var(--navbarSize, 3.5rem); + --emoji-size: var(--emojiSize, 32px); // overflow-x: clip causes my browser's tab to crash with SIGILL lul } diff --git a/src/components/emoji_reactions/emoji_reactions.vue b/src/components/emoji_reactions/emoji_reactions.vue index ad4a3c0bd..3ab4c125e 100644 --- a/src/components/emoji_reactions/emoji_reactions.vue +++ b/src/components/emoji_reactions/emoji_reactions.vue @@ -79,7 +79,7 @@ margin-top: 0.25em; flex-wrap: wrap; - --emoji-size: calc(1.25em * var(--emojiReactionsScale, 1)); + --emoji-size: calc(var(--emojiSize, 1.25em) * var(--emojiReactionsScale, 1)); .emoji-reaction-container { display: flex; diff --git a/src/components/settings_modal/tabs/appearance_tab.js b/src/components/settings_modal/tabs/appearance_tab.js index b96106bd6..542ab0c12 100644 --- a/src/components/settings_modal/tabs/appearance_tab.js +++ b/src/components/settings_modal/tabs/appearance_tab.js @@ -2,7 +2,7 @@ import BooleanSetting from '../helpers/boolean_setting.vue' import ChoiceSetting from '../helpers/choice_setting.vue' import IntegerSetting from '../helpers/integer_setting.vue' import FloatSetting from '../helpers/float_setting.vue' -import UnitSetting from '../helpers/unit_setting.vue' +import UnitSetting, { defaultHorizontalUnits } from '../helpers/unit_setting.vue' import SharedComputedObject from '../helpers/shared_computed_object.js' import ProfileSettingIndicator from '../helpers/profile_setting_indicator.vue' @@ -17,7 +17,13 @@ library.add( const AppearanceTab = { data () { - return {} + return { + thirdColumnModeOptions: ['none', 'notifications', 'postform'].map(mode => ({ + key: mode, + value: mode, + label: this.$t(`settings.third_column_mode_${mode}`) + })) + } }, components: { BooleanSetting, @@ -28,10 +34,32 @@ const AppearanceTab = { ProfileSettingIndicator }, computed: { + horizontalUnits () { + return defaultHorizontalUnits + }, + columns () { + const mode = this.$store.getters.mergedConfig.thirdColumnMode + + const notif = mode === 'none' ? [] : ['notifs'] + + if (this.$store.getters.mergedConfig.sidebarRight || mode === 'postform') { + return [...notif, 'content', 'sidebar'] + } else { + return ['sidebar', 'content', ...notif] + } + }, + instanceSpecificPanelPresent () { return this.$store.state.instance.showInstanceSpecificPanel }, instanceWallpaperUsed () { return this.$store.state.instance.background && !this.$store.state.users.currentUser.background_image }, + instanceShoutboxPresent () { return this.$store.state.instance.shoutAvailable }, + language: { + get: function () { return this.$store.getters.mergedConfig.interfaceLanguage }, + set: function (val) { + this.$store.dispatch('setOption', { name: 'interfaceLanguage', value: val }) + } + }, ...SharedComputedObject() } } diff --git a/src/components/settings_modal/tabs/appearance_tab.vue b/src/components/settings_modal/tabs/appearance_tab.vue index 7730b701d..75126df77 100644 --- a/src/components/settings_modal/tabs/appearance_tab.vue +++ b/src/components/settings_modal/tabs/appearance_tab.vue @@ -1,23 +1,8 @@ diff --git a/src/i18n/en.json b/src/i18n/en.json index 4b2161651..d995163a8 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 bee503c59..2ccfeef35 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) => { From 80cbf29bdf7c6cd3695d1e4cf49a8e38bff847ed Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Thu, 27 Jun 2024 00:59:24 +0300 Subject: [PATCH 20/53] fields for user font overrides --- src/components/font_control/font_control.js | 2 +- .../settings_modal/tabs/appearance_tab.js | 8 +++- .../settings_modal/tabs/appearance_tab.vue | 45 +++++++++++++++++++ src/i18n/en.json | 1 + src/modules/config.js | 2 + src/modules/instance.js | 1 + 6 files changed, 57 insertions(+), 2 deletions(-) diff --git a/src/components/font_control/font_control.js b/src/components/font_control/font_control.js index f6f45c8cc..08d0907e4 100644 --- a/src/components/font_control/font_control.js +++ b/src/components/font_control/font_control.js @@ -30,7 +30,7 @@ export default { emits: ['update:modelValue'], data () { return { - manualEntry: true, + manualEntry: false, availableOptions: [ this.noInherit ? '' : 'inherit', 'serif', diff --git a/src/components/settings_modal/tabs/appearance_tab.js b/src/components/settings_modal/tabs/appearance_tab.js index d9a0429ab..3776464aa 100644 --- a/src/components/settings_modal/tabs/appearance_tab.js +++ b/src/components/settings_modal/tabs/appearance_tab.js @@ -4,6 +4,8 @@ import IntegerSetting from '../helpers/integer_setting.vue' import FloatSetting from '../helpers/float_setting.vue' import UnitSetting, { defaultHorizontalUnits } from '../helpers/unit_setting.vue' +import FontControl from 'src/components/font_control/font_control.vue' + import SharedComputedObject from '../helpers/shared_computed_object.js' import ProfileSettingIndicator from '../helpers/profile_setting_indicator.vue' import { library } from '@fortawesome/fontawesome-svg-core' @@ -36,12 +38,16 @@ const AppearanceTab = { IntegerSetting, FloatSetting, UnitSetting, - ProfileSettingIndicator + ProfileSettingIndicator, + FontControl }, computed: { horizontalUnits () { return defaultHorizontalUnits }, + fontsOverride () { + return this.$store.getters.mergedConfig.fontsOverride + }, columns () { const mode = this.$store.getters.mergedConfig.thirdColumnMode diff --git a/src/components/settings_modal/tabs/appearance_tab.vue b/src/components/settings_modal/tabs/appearance_tab.vue index 5356292ec..fb24cc6b3 100644 --- a/src/components/settings_modal/tabs/appearance_tab.vue +++ b/src/components/settings_modal/tabs/appearance_tab.vue @@ -34,6 +34,51 @@
  • +
  • +

    {{ $t('settings.style.interface_font_user_override') }}

    +
      +
    • + +
    • +
    • + +
    • +
    • + +
    • +
    • + +
    • +
    +
  • Date: Thu, 4 Jul 2024 03:20:26 +0300 Subject: [PATCH 21/53] "fix" theme preview --- preview.style.js | 0 .../tabs/theme_tab/theme_tab.js | 87 ++++---- .../tabs/theme_tab/theme_tab.vue | 203 ++++++++++-------- src/i18n/en.json | 2 + src/services/style_setter/style_setter.js | 6 +- .../theme_data/theme_data_3.service.js | 10 +- 6 files changed, 175 insertions(+), 133 deletions(-) create mode 100644 preview.style.js diff --git a/preview.style.js b/preview.style.js new file mode 100644 index 000000000..e69de29bb diff --git a/src/components/settings_modal/tabs/theme_tab/theme_tab.js b/src/components/settings_modal/tabs/theme_tab/theme_tab.js index 11c90b034..72e2b625c 100644 --- a/src/components/settings_modal/tabs/theme_tab/theme_tab.js +++ b/src/components/settings_modal/tabs/theme_tab/theme_tab.js @@ -1,7 +1,8 @@ import { rgb2hex, hex2rgb, - getContrastRatioLayers + getContrastRatioLayers, + relativeLuminance } from 'src/services/color_convert/color_convert.js' import { getThemes @@ -23,10 +24,14 @@ import { generateShadows, generateRadii, generateFonts, - composePreset, shadows2to3, colors2to3 } from 'src/services/theme_data/theme_data.service.js' + +import { convertTheme2To3 } from 'src/services/theme_data/theme2_to_theme3.js' +import { init } from 'src/services/theme_data/theme_data_3.service.js' +import { getCssRules } from 'src/services/theme_data/css_utils.js' + import ColorInput from 'src/components/color_input/color_input.vue' import RangeInput from 'src/components/range_input/range_input.vue' import OpacityInput from 'src/components/opacity_input/opacity_input.vue' @@ -62,6 +67,7 @@ const colorConvert = (color) => { export default { data () { return { + themeV3Preview: [], themeImporter: newImporter({ validator: this.importValidator, onImport: this.onImport, @@ -78,10 +84,7 @@ export default { tempImportFile: undefined, engineVersion: 0, - previewShadows: {}, - previewColors: {}, - previewRadii: {}, - previewFonts: {}, + previewTheme: {}, shadowsInvalid: true, colorsInvalid: true, @@ -232,13 +235,6 @@ export default { chatMessage: this.chatMessageRadiusLocal } }, - preview () { - return composePreset(this.previewColors, this.previewRadii, this.previewShadows, this.previewFonts) - }, - previewTheme () { - if (!this.preview.theme.colors) return { colors: {}, opacity: {}, radii: {}, shadows: {}, fonts: {} } - return this.preview.theme - }, // This needs optimization maybe previewContrast () { try { @@ -306,14 +302,6 @@ export default { return {} } }, - previewRules () { - if (!this.preview.rules) return '' - return [ - ...Object.values(this.preview.rules), - 'color: var(--text)', - 'font-family: var(--interfaceFont, sans-serif)' - ].join(';') - }, shadowsAvailable () { return Object.keys(DEFAULT_SHADOWS).sort() }, @@ -532,16 +520,24 @@ export default { } }) }, - updatePreviewColorsAndShadows () { - this.previewColors = generateColors({ + updatePreviewColors () { + const result = generateColors({ opacity: this.currentOpacity, colors: this.currentColors }) - this.previewShadows = generateShadows( - { shadows: this.shadowsLocal, opacity: this.previewTheme.opacity, themeEngineVersion: this.engineVersion }, - this.previewColors.theme.colors, - this.previewColors.mod - ) + this.previewTheme.colors = result.theme.colors + this.previewTheme.opacity = result.theme.opacity + }, + updatePreviewShadows () { + this.previewTheme.shadows = generateShadows( + { + shadows: this.shadowsLocal, + opacity: this.previewTheme.opacity, + themeEngineVersion: this.engineVersion + }, + this.previewTheme.colors, + relativeLuminance(this.previewTheme.colors.bg) < 0.5 ? 1 : -1 + ).theme.shadows }, importTheme () { this.themeImporter.importData() }, exportTheme () { this.themeExporter.exportData() }, @@ -692,6 +688,8 @@ export default { } else { this.shadowsLocal = shadows } + this.updatePreviewColors() + this.updatePreviewShadows() this.shadowSelected = this.shadowsAvailable[0] } @@ -699,12 +697,32 @@ export default { this.clearFonts() this.fontsLocal = fonts } + }, + updateTheme3Preview () { + console.log(this.previewTheme) + const theme2 = convertTheme2To3(this.previewTheme) + const theme3 = init({ + extraRuleset: theme2, + ultimateBackgroundColor: '#000000', + liteMode: true + }) + this.themeV3Preview = getCssRules(theme3.eager) + .map(x => { + if (x.startsWith('html')) { + return x.replace('html', '#theme-preview') + } else if (x.startsWith('#content')) { + return x.replace('#content', '#theme-preview') + } else { + return '#theme-preview > ' + x + } + }) + .join('\n') } }, watch: { currentRadii () { try { - this.previewRadii = generateRadii({ radii: this.currentRadii }) + this.previewTheme.radii = generateRadii({ radii: this.currentRadii }).theme this.radiiInvalid = false } catch (e) { this.radiiInvalid = true @@ -713,9 +731,8 @@ export default { }, shadowsLocal: { handler () { - if (Object.getOwnPropertyNames(this.previewColors).length === 1) return try { - this.updatePreviewColorsAndShadows() + this.updatePreviewShadows() this.shadowsInvalid = false } catch (e) { this.shadowsInvalid = true @@ -727,7 +744,7 @@ export default { fontsLocal: { handler () { try { - this.previewFonts = generateFonts({ fonts: this.fontsLocal }) + this.previewTheme.fonts = generateFonts({ fonts: this.fontsLocal }).theme this.fontsInvalid = false } catch (e) { this.fontsInvalid = true @@ -738,18 +755,16 @@ export default { }, currentColors () { try { - this.updatePreviewColorsAndShadows() + this.updatePreviewColors() this.colorsInvalid = false - this.shadowsInvalid = false } catch (e) { this.colorsInvalid = true - this.shadowsInvalid = true console.warn(e) } }, currentOpacity () { try { - this.updatePreviewColorsAndShadows() + this.updatePreviewColors() } catch (e) { console.warn(e) } diff --git a/src/components/settings_modal/tabs/theme_tab/theme_tab.vue b/src/components/settings_modal/tabs/theme_tab/theme_tab.vue index ff2fece9c..dd23145c1 100644 --- a/src/components/settings_modal/tabs/theme_tab/theme_tab.vue +++ b/src/components/settings_modal/tabs/theme_tab/theme_tab.vue @@ -1,5 +1,8 @@