logo

pleroma-fe

My custom branche(s) on git.pleroma.social/pleroma/pleroma-fe git clone https://hacktivis.me/git/pleroma-fe.git
commit: 0635a6c131804c2a6f2ce99c4888a0d3ee757570
parent d7f744d2819343eced508a589d6fad3842686a3e
Author: HJ <30-hj@users.noreply.git.pleroma.social>
Date:   Sat,  6 Apr 2024 14:53:53 +0000

Merge branch 'themes3-fixes' into 'develop'

Themes 3 fixes

Closes #1301 and #1303

See merge request pleroma/pleroma-fe!1906

Diffstat:

Achangelog.d/themes3-fixes.fix1+
Msrc/App.scss8++++++++
Msrc/App.vue1+
Msrc/boot/after_store.js1+
Msrc/components/color_input/color_input.scss32++++++++++++++++++++++++++------
Msrc/components/color_input/color_input.vue50+++++++++++++++++++++++++++++++-------------------
Msrc/components/conversation/conversation.vue4++--
Msrc/components/popover/popover.vue2++
Msrc/components/rich_content/rich_content.scss5+++++
Msrc/components/shout_panel/shout_panel.vue8++++----
Msrc/components/tab_switcher/tab_switcher.scss1+
Msrc/components/user_card/user_card.scss5+++++
Msrc/modules/instance.js1+
Msrc/modules/interface.js4++++
Msrc/services/style_setter/style_setter.js57++++++++++++++++++++++++++++++++++++++++++++-------------
Msrc/services/theme_data/theme2_keys.js6+++---
Msrc/services/theme_data/theme2_to_theme3.js2++
17 files changed, 141 insertions(+), 47 deletions(-)

diff --git a/changelog.d/themes3-fixes.fix b/changelog.d/themes3-fixes.fix @@ -0,0 +1 @@ +fix color inputs and some in-development themes3 issues diff --git a/src/App.scss b/src/App.scss @@ -14,6 +14,9 @@ --ZI_navbar_popovers: 7500; --ZI_navbar: 7000; --ZI_popovers: 6000; + + // Fallback for when stuff is loading + --background: var(--bg); } html { @@ -370,6 +373,7 @@ nav { border: none; border-radius: var(--roundness); cursor: pointer; + background-color: var(--background); box-shadow: var(--shadow); font-size: 1em; font-family: sans-serif; @@ -406,6 +410,7 @@ nav { width: 100%; line-height: var(--__line-height); padding: var(--__vertical-gap) var(--__horizontal-gap); + background: transparent; --__line-height: 1.5em; --__horizontal-gap: 0.75em; @@ -470,6 +475,7 @@ nav { font-size: 100%; font-family: inherit; box-shadow: var(--shadow); + background-color: transparent; padding: 0; line-height: unset; cursor: pointer; @@ -502,6 +508,8 @@ textarea { border: none; border-radius: var(--roundness); + background-color: var(--background); + color: var(--text); box-shadow: var(--shadow); font-family: var(--font); font-size: 1em; diff --git a/src/App.vue b/src/App.vue @@ -1,5 +1,6 @@ <template> <div + v-show="$store.state.interface.themeApplied" id="app-loaded" :style="bgStyle" > diff --git a/src/boot/after_store.js b/src/boot/after_store.js @@ -363,6 +363,7 @@ const afterStoreSetup = async ({ store, i18n }) => { } else { applyTheme(customTheme) } + store.commit('setThemeApplied') } else if (theme) { // do nothing, it will load asynchronously } else { diff --git a/src/components/color_input/color_input.scss b/src/components/color_input/color_input.scss @@ -9,6 +9,7 @@ padding: 0.2em 8px; input { + color: var(--text); background: none; border: none; padding: 0; @@ -19,21 +20,38 @@ min-width: 3em; padding: 0; } + } + + .nativeColor { + cursor: pointer; + flex: 0 0 auto; - &.nativeColor { - flex: 0 0 2em; - min-width: 2em; - align-self: stretch; - min-height: 100%; + input { + appearance: none; + max-width: 0; + min-width: 0; + max-height: 0; + /* stylelint-disable-next-line declaration-no-important */ + opacity: 0 !important; } } .computedIndicator, + .validIndicator, + .invalidIndicator, .transparentIndicator { flex: 0 0 2em; + margin: 0 0.5em; min-width: 2em; align-self: stretch; - min-height: 100%; + min-height: 1.5em; + border-radius: var(--roundness); + } + + .invalidIndicator { + background: transparent; + box-sizing: border-box; + border: 2px solid var(--cRed); } .transparentIndicator { @@ -54,11 +72,13 @@ &::after { top: 0; left: 0; + border-top-left-radius: var(--roundness); } &::before { bottom: 0; right: 0; + border-bottom-right-radius: var(--roundness); } } } diff --git a/src/components/color_input/color_input.vue b/src/components/color_input/color_input.vue @@ -25,30 +25,51 @@ :disabled="!present || disabled" @input="$emit('update:modelValue', $event.target.value)" > - <input + <div v-if="validColor" - :id="name" - class="nativeColor unstyled" - type="color" - :value="modelValue || fallback" - :disabled="!present || disabled" - @input="$emit('update:modelValue', $event.target.value)" - > + class="validIndicator" + :style="{backgroundColor: modelValue || fallback}" + /> <div - v-if="transparentColor" + v-else-if="transparentColor" class="transparentIndicator" /> <div - v-if="computedColor" + v-else-if="computedColor" class="computedIndicator" :style="{backgroundColor: fallback}" /> + <div + v-else + class="invalidIndicator" + /> + <label class="nativeColor"> + <FAIcon icon="eye-dropper" /> + <input + :id="name" + class="unstyled" + type="color" + :value="modelValue || fallback" + :disabled="!present || disabled" + @input="$emit('update:modelValue', $event.target.value)" + > + </label> </div> </div> </template> <script> import Checkbox from '../checkbox/checkbox.vue' import { hex2rgb } from '../../services/color_convert/color_convert.js' + +import { library } from '@fortawesome/fontawesome-svg-core' +import { + faEyeDropper +} from '@fortawesome/free-solid-svg-icons' + +library.add( + faEyeDropper +) + export default { components: { Checkbox @@ -108,12 +129,3 @@ export default { } </script> <style lang="scss" src="./color_input.scss"></style> - -<style lang="scss"> -.color-control { - input.text-input { - max-width: 7em; - flex: 1; - } -} -</style> diff --git a/src/components/conversation/conversation.vue b/src/components/conversation/conversation.vue @@ -81,7 +81,7 @@ :replies="getReplies(status.id)" :in-profile="inProfile" :profile-user-id="profileUserId" - class="conversation-status status-fadein" + class="conversation-status status-fadein panel-body" :simple-tree="treeViewIsSimple" :toggle-thread-display="toggleThreadDisplay" @@ -186,7 +186,7 @@ :replies="getReplies(status.id)" :in-profile="inProfile" :profile-user-id="profileUserId" - class="conversation-status status-fadein" + class="conversation-status status-fadein panel-body" :toggle-thread-display="toggleThreadDisplay" :thread-display-status="threadDisplayStatus" diff --git a/src/components/popover/popover.vue b/src/components/popover/popover.vue @@ -71,6 +71,7 @@ border-color: var(--border); border-style: solid; border-width: 1px; + background-color: var(--background); } .dropdown-menu { @@ -82,6 +83,7 @@ max-width: 100vw; z-index: var(--ZI_popover_override, var(--ZI_popovers)); white-space: nowrap; + background-color: var(--background); .dropdown-divider { height: 0; diff --git a/src/components/rich_content/rich_content.scss b/src/components/rich_content/rich_content.scss @@ -83,3 +83,8 @@ color: var(--funtextCyantext); } } + +a .RichContent { + /* stylelint-disable-next-line declaration-no-important */ + color: var(--link) !important; +} diff --git a/src/components/shout_panel/shout_panel.vue b/src/components/shout_panel/shout_panel.vue @@ -5,7 +5,7 @@ > <div class="panel panel-default"> <div - class="panel-heading timeline-heading" + class="panel-heading" :class="{ 'shout-heading': floating }" @click.stop.prevent="togglePanel" > @@ -18,7 +18,7 @@ /> </div> </div> - <div class="shout-window"> + <div class="panel-body shout-window"> <div v-for="message in messages" :key="message.id" @@ -41,10 +41,10 @@ </div> </div> </div> - <div class="shout-input"> + <div class="panel-body shout-input"> <textarea v-model="currentMessage" - class="shout-input-textarea" + class="shout-input-textarea input" rows="1" @keyup.enter="submit(currentMessage)" /> diff --git a/src/components/tab_switcher/tab_switcher.scss b/src/components/tab_switcher/tab_switcher.scss @@ -174,6 +174,7 @@ font-size: 1em; font-family: var(--font); border-radius: var(--roundness); + background-color: var(--background); position: relative; white-space: nowrap; padding: 6px 1em; diff --git a/src/components/user_card/user_card.scss b/src/components/user_card/user_card.scss @@ -204,6 +204,11 @@ --emoji-size: 1.7em; + .RichContent { + /* stylelint-disable-next-line declaration-no-important */ + --link: var(--text) !important; + } + .top-line, .bottom-line { display: flex; diff --git a/src/modules/instance.js b/src/modules/instance.js @@ -386,6 +386,7 @@ const instance = { } else { applyTheme(themeData.theme) } + commit('setThemeApplied') }) }, fetchEmoji ({ dispatch, state }) { diff --git a/src/modules/interface.js b/src/modules/interface.js @@ -1,4 +1,5 @@ const defaultState = { + themeApplied: false, settingsModalState: 'hidden', settingsModalLoadedUser: false, settingsModalLoadedAdmin: false, @@ -35,6 +36,9 @@ const interfaceMod = { state.settings.currentSaveStateNotice = { error: true, errorData: error } } }, + setThemeApplied (state) { + state.themeApplied = true + }, setNotificationPermission (state, permission) { state.notificationPermission = permission }, diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js @@ -6,7 +6,13 @@ import { getCssRules } from '../theme_data/css_utils.js' import { defaultState } from '../../modules/config.js' import { chunk } from 'lodash' -export const applyTheme = async (input) => { +export const generateTheme = async (input, callbacks) => { + const { + onNewRule = (rule, isLazy) => {}, + onLazyFinished = () => {}, + onEagerFinished = () => {} + } = callbacks + let extraRules if (input.themeFileVersion === 1) { extraRules = convertTheme2To3(input) @@ -17,11 +23,6 @@ export const applyTheme = async (input) => { // Assuming that "worst case scenario background" is panel background since it's the most likely one const themes3 = init(extraRules, extraRules[0].directives['--bg'].split('|')[1].trim()) - const body = document.body - - const styleSheet = new CSSStyleSheet() - document.adoptedStyleSheets = [styleSheet] - body.classList.add('hidden') getCssRules(themes3.eager, themes3.staticVars).forEach(rule => { // Hacks to support multiple selectors on same component @@ -37,13 +38,12 @@ export const applyTheme = async (input) => { parts[1], '}' ].join('') - styleSheet.insertRule(newRule, 'index-max') + onNewRule(newRule, false) } else { - styleSheet.insertRule(rule, 'index-max') + onNewRule(rule, false) } }) - - body.classList.remove('hidden') + onEagerFinished() // Optimization - instead of processing all lazy rules in one go, process them in small chunks // so that UI can do other things and be somewhat responsive while less important rules are being @@ -61,13 +61,15 @@ export const applyTheme = async (input) => { parts[0], ', ', parts[0].replace(/\.modal-view/, '#modal'), + ', ', + parts[0].replace(/\.modal-view/, '.shout-panel'), ' {', parts[1], '}' ].join('') - styleSheet.insertRule(newRule, 'index-max') + onNewRule(newRule, true) } else { - styleSheet.insertRule(rule, 'index-max') + onNewRule(rule, true) } }) // const t1 = performance.now() @@ -76,10 +78,39 @@ export const applyTheme = async (input) => { counter += 1 if (counter < chunks.length) { setTimeout(processChunk, 0) + } else { + onLazyFinished() } }) } - setTimeout(processChunk, 0) + + return { lazyProcessFunc: processChunk } +} + +export const applyTheme = async (input) => { + const styleSheet = new CSSStyleSheet() + const lazyStyleSheet = new CSSStyleSheet() + + const { lazyProcessFunc } = await generateTheme( + input, + { + onNewRule (rule, isLazy) { + if (isLazy) { + lazyStyleSheet.insertRule(rule, 'index-max') + } else { + styleSheet.insertRule(rule, 'index-max') + } + }, + onEagerFinished () { + document.adoptedStyleSheets = [styleSheet] + }, + onLazyFinished () { + document.adoptedStyleSheets = [styleSheet, lazyStyleSheet] + } + } + ) + + setTimeout(lazyProcessFunc, 0) return Promise.resolve() } diff --git a/src/services/theme_data/theme2_keys.js b/src/services/theme_data/theme2_keys.js @@ -158,12 +158,12 @@ export default [ 'alertPopupNeutral', 'alertPopupNeutralText', - 'badgeNotification', - 'badgeNotificationText', - 'badgeNeutral', 'badgeNeutralText', + 'badgeNotification', + 'badgeNotificationText', + 'chatBg', 'chatMessageIncomingBg', diff --git a/src/services/theme_data/theme2_to_theme3.js b/src/services/theme_data/theme2_to_theme3.js @@ -517,6 +517,8 @@ export const convertTheme2To3 = (data) => { } else if (newRule.component === 'Badge') { if (newRule.variant === 'notification') { return [newRule, { component: 'Root', directives: { '--badgeNotification': 'color | ' + newRule.directives.background } }] + } else if (newRule.variant === 'neutral') { + return [{ ...newRule, variant: 'normal' }] } else { return [newRule] }