From 454aa695ab067f0e94a344bb5110cda410d69001 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Thu, 14 Nov 2024 21:42:45 +0200 Subject: [PATCH] User palette editor --- .../palette_editor/palette_editor.vue | 80 +++++++++++++++---- .../settings_modal/tabs/appearance_tab.js | 25 ++++-- .../settings_modal/tabs/appearance_tab.scss | 4 +- .../settings_modal/tabs/appearance_tab.vue | 21 ++--- src/i18n/en.json | 8 +- 5 files changed, 102 insertions(+), 36 deletions(-) diff --git a/src/components/palette_editor/palette_editor.vue b/src/components/palette_editor/palette_editor.vue index 9dd8d868..be5dee44 100644 --- a/src/components/palette_editor/palette_editor.vue +++ b/src/components/palette_editor/palette_editor.vue @@ -1,5 +1,8 @@ @@ -43,12 +53,34 @@ library.add( faFileExport ) -const props = defineProps(['modelValue']) -const emit = defineEmits(['update:modelValue']) +const paletteKeys = [ + 'bg', + 'fg', + 'text', + 'link', + 'accent', + 'cRed', + 'cBlue', + 'cGreen', + 'cOrange', + 'wallpaper' +] + +const props = defineProps(['modelValue', 'compact', 'apply']) +const emit = defineEmits(['update:modelValue', 'applyPalette']) +const getExportedObject = () => paletteKeys.reduce((acc, key) => { + const value = props.modelValue[key] + if (value == null) { + return acc + } else { + return { ...acc, [key]: props.modelValue[key] } + } +}, {}) + const paletteExporter = newExporter({ filename: 'pleroma_palette', extension: 'json', - getExportedObject: () => props.modelValue + getExportedObject }) const paletteImporter = newImporter({ accept: '.json', @@ -65,18 +97,9 @@ const importPalette = () => { paletteImporter.importData() } -const paletteKeys = [ - 'bg', - 'fg', - 'text', - 'link', - 'accent', - 'cRed', - 'cBlue', - 'cGreen', - 'cOrange', - 'wallpaper' -] +const applyPalette = (data) => { + emit('applyPalette', getExportedObject()) +} const fallback = (key) => { if (key === 'accent') { @@ -118,8 +141,33 @@ const updatePalette = (paletteKey, value) => { grid-column: 3 / span 2; } + .palette-apply-button { + grid-column: 1 / span 2; + } + .color-input.style-control { margin: 0; } + + &.-compact { + grid-template-columns: repeat(2, 1fr); + grid-template-rows: repeat(5, 1fr) auto; + + .palette-import-button { + grid-column: 1; + } + + .palette-export-button { + grid-column: 2; + } + + &.-apply { + grid-template-rows: repeat(5, 1fr) auto auto; + + .palette-apply-button { + grid-column: 1 / span 2; + } + } + } } diff --git a/src/components/settings_modal/tabs/appearance_tab.js b/src/components/settings_modal/tabs/appearance_tab.js index 1e8f596f..03026198 100644 --- a/src/components/settings_modal/tabs/appearance_tab.js +++ b/src/components/settings_modal/tabs/appearance_tab.js @@ -3,6 +3,7 @@ import ChoiceSetting from '../helpers/choice_setting.vue' import IntegerSetting from '../helpers/integer_setting.vue' import FloatSetting from '../helpers/float_setting.vue' import UnitSetting, { defaultHorizontalUnits } from '../helpers/unit_setting.vue' +import PaletteEditor from 'src/components/palette_editor/palette_editor.vue' import FontControl from 'src/components/font_control/font_control.vue' @@ -50,6 +51,7 @@ const AppearanceTab = { 'cBlue', 'cOrange' ], + userPalette: {}, intersectionObserver: null, thirdColumnModeOptions: ['none', 'notifications', 'postform'].map(mode => ({ key: mode, @@ -76,7 +78,8 @@ const AppearanceTab = { UnitSetting, ProfileSettingIndicator, FontControl, - Preview + Preview, + PaletteEditor }, mounted () { const updateIndex = (resource) => { @@ -105,6 +108,7 @@ const AppearanceTab = { updateIndex('palette').then(bundledPalettes => { bundledPalettes.forEach(([key, palettePromise]) => palettePromise.then(v => { + let palette if (Array.isArray(v)) { const [ name, @@ -117,9 +121,15 @@ const AppearanceTab = { cBlue = '#0000FF', cOrange = '#E3FF00' ] = v - this.bundledPalettes.push({ key, name, bg, fg, text, link, cRed, cBlue, cGreen, cOrange }) + palette = { key, name, bg, fg, text, link, cRed, cBlue, cGreen, cOrange } + this.bundledPalettes.push() } else { - this.bundledPalettes.push({ key, ...v }) + palette = { key, ...v } + } + this.bundledPalettes.push(palette) + + if (this.isPaletteActive(key)) { + this.userPalette = palette } })) }) @@ -292,15 +302,18 @@ const AppearanceTab = { this.$store.dispatch('setTheme', name) this.$store.dispatch('applyTheme') }, - setPalette (name) { + setPalette (name, data) { this.$store.dispatch('resetThemeV2') this.$store.dispatch('setPalette', name) this.$store.dispatch('applyTheme') + this.userPalette = data }, - setPaletteCustom (p) { + setPaletteCustom (data) { + console.log('APPLY CUSTOM', data) this.$store.dispatch('resetThemeV2') - this.$store.dispatch('setPaletteCustom', p) + this.$store.dispatch('setPaletteCustom', data) this.$store.dispatch('applyTheme') + this.userPalette = data }, resetTheming (name) { this.$store.dispatch('resetThemeV2') diff --git a/src/components/settings_modal/tabs/appearance_tab.scss b/src/components/settings_modal/tabs/appearance_tab.scss index c78b4acc..ede4b342 100644 --- a/src/components/settings_modal/tabs/appearance_tab.scss +++ b/src/components/settings_modal/tabs/appearance_tab.scss @@ -26,7 +26,8 @@ grid-gap: 0.5em; h4, - .unsupported-theme-v2 { + .unsupported-theme-v2, + .userPalette { grid-column: 1 / span 2; } } @@ -71,6 +72,7 @@ border-radius: var(--roundness); border: 1px solid var(--border); padding: 0; + margin-bottom: 1em; .theme-preview { font-size: 1rem; // fix for firefox diff --git a/src/components/settings_modal/tabs/appearance_tab.vue b/src/components/settings_modal/tabs/appearance_tab.vue index 2853cd40..6ec84eb2 100644 --- a/src/components/settings_modal/tabs/appearance_tab.vue +++ b/src/components/settings_modal/tabs/appearance_tab.vue @@ -5,15 +5,6 @@ >

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

- -
-