fix(frontend): テーマ切り替え時に一部の色が変わらない問題を修正

This commit is contained in:
syuilo 2025-03-10 10:05:50 +09:00
parent 6419af2179
commit 4df9083bf0
6 changed files with 35 additions and 15 deletions

View File

@ -7,6 +7,7 @@
- Feat: 設定の管理が強化されました - Feat: 設定の管理が強化されました
- 自動でバックアップされるように - 自動でバックアップされるように
- Enhance: プラグインの管理が強化されました - Enhance: プラグインの管理が強化されました
- Fix: テーマ切り替え時に一部の色が変わらない問題を修正
### Server ### Server
- Fix: プロフィール追加情報で無効なURLに入力された場合に照会エラーを出るのを修正 - Fix: プロフィール追加情報で無効なURLに入力された場合に照会エラーを出るのを修正

View File

@ -43,14 +43,14 @@ SPDX-License-Identifier: AGPL-3.0-only
<script lang="ts" setup> <script lang="ts" setup>
import { onMounted, onUnmounted, ref, inject, shallowRef, computed } from 'vue'; import { onMounted, onUnmounted, ref, inject, shallowRef, computed } from 'vue';
import tinycolor from 'tinycolor2'; import tinycolor from 'tinycolor2';
import { scrollToTop } from '@@/js/scroll.js';
import XTabs from './MkPageHeader.tabs.vue'; import XTabs from './MkPageHeader.tabs.vue';
import type { Tab } from './MkPageHeader.tabs.vue'; import type { Tab } from './MkPageHeader.tabs.vue';
import { scrollToTop } from '@@/js/scroll.js'; import type { PageHeaderItem } from '@/types/page-header.js';
import type { PageMetadata } from '@/utility/page-metadata.js';
import { globalEvents } from '@/events.js'; import { globalEvents } from '@/events.js';
import { injectReactiveMetadata } from '@/utility/page-metadata.js'; import { injectReactiveMetadata } from '@/utility/page-metadata.js';
import { $i, openAccountMenu as openAccountMenu_ } from '@/account.js'; import { $i, openAccountMenu as openAccountMenu_ } from '@/account.js';
import type { PageHeaderItem } from '@/types/page-header.js';
import type { PageMetadata } from '@/utility/page-metadata.js';
const props = withDefaults(defineProps<{ const props = withDefaults(defineProps<{
overridePageMetadata?: PageMetadata; overridePageMetadata?: PageMetadata;
@ -114,7 +114,7 @@ let ro: ResizeObserver | null;
onMounted(() => { onMounted(() => {
calcBg(); calcBg();
globalEvents.on('themeChanged', calcBg); globalEvents.on('themeChanging', calcBg);
if (el.value && el.value.parentElement) { if (el.value && el.value.parentElement) {
narrow.value = el.value.parentElement.offsetWidth < 500; narrow.value = el.value.parentElement.offsetWidth < 500;
@ -128,7 +128,7 @@ onMounted(() => {
}); });
onUnmounted(() => { onUnmounted(() => {
globalEvents.off('themeChanged', calcBg); globalEvents.off('themeChanging', calcBg);
if (ro) ro.disconnect(); if (ro) ro.disconnect();
}); });
</script> </script>

View File

@ -5,17 +5,32 @@
import type { Directive } from 'vue'; import type { Directive } from 'vue';
import { getBgColor } from '@/utility/get-bg-color.js'; import { getBgColor } from '@/utility/get-bg-color.js';
import { globalEvents } from '@/events.js';
const handlerMap = new WeakMap<any, any>();
export default { export default {
mounted(src, binding, vn) { mounted(src, binding, vn) {
const parentBg = getBgColor(src.parentElement) ?? 'transparent'; function calc() {
const parentBg = getBgColor(src.parentElement) ?? 'transparent';
const myBg = window.getComputedStyle(src).backgroundColor; const myBg = window.getComputedStyle(src).backgroundColor;
if (parentBg === myBg) { if (parentBg === myBg) {
src.style.borderColor = 'var(--MI_THEME-divider)'; src.style.borderColor = 'var(--MI_THEME-divider)';
} else { } else {
src.style.borderColor = myBg; src.style.borderColor = myBg;
}
} }
handlerMap.set(src, calc);
calc();
globalEvents.on('themeChanged', calc);
},
unmounted(src, binding, vn) {
globalEvents.off('themeChanged', handlerMap.get(src));
}, },
} as Directive; } as Directive;

View File

@ -7,6 +7,7 @@ import { EventEmitter } from 'eventemitter3';
import * as Misskey from 'misskey-js'; import * as Misskey from 'misskey-js';
export const globalEvents = new EventEmitter<{ export const globalEvents = new EventEmitter<{
themeChanging: () => void;
themeChanged: () => void; themeChanged: () => void;
clientNotification: (notification: Misskey.entities.Notification) => void; clientNotification: (notification: Misskey.entities.Notification) => void;
requestClearPageCache: () => void; requestClearPageCache: () => void;

View File

@ -35,8 +35,8 @@ SPDX-License-Identifier: AGPL-3.0-only
<script lang="ts" setup> <script lang="ts" setup>
import { computed, onMounted, onUnmounted, ref, shallowRef, watch, nextTick } from 'vue'; import { computed, onMounted, onUnmounted, ref, shallowRef, watch, nextTick } from 'vue';
import tinycolor from 'tinycolor2'; import tinycolor from 'tinycolor2';
import { popupMenu } from '@/os.js';
import { scrollToTop } from '@@/js/scroll.js'; import { scrollToTop } from '@@/js/scroll.js';
import { popupMenu } from '@/os.js';
import MkButton from '@/components/MkButton.vue'; import MkButton from '@/components/MkButton.vue';
import { globalEvents } from '@/events.js'; import { globalEvents } from '@/events.js';
import { injectReactiveMetadata } from '@/utility/page-metadata.js'; import { injectReactiveMetadata } from '@/utility/page-metadata.js';
@ -127,7 +127,7 @@ const calcBg = () => {
onMounted(() => { onMounted(() => {
calcBg(); calcBg();
globalEvents.on('themeChanged', calcBg); globalEvents.on('themeChanging', calcBg);
watch(() => [props.tab, props.tabs], () => { watch(() => [props.tab, props.tabs], () => {
nextTick(() => { nextTick(() => {
@ -147,7 +147,7 @@ onMounted(() => {
}); });
onUnmounted(() => { onUnmounted(() => {
globalEvents.off('themeChanged', calcBg); globalEvents.off('themeChanging', calcBg);
}); });
</script> </script>

View File

@ -72,6 +72,9 @@ export function applyTheme(theme: Theme, persist = true) {
timeout = window.setTimeout(() => { timeout = window.setTimeout(() => {
document.documentElement.classList.remove('_themeChanging_'); document.documentElement.classList.remove('_themeChanging_');
// 色計算など再度行えるようにクライアント全体に通知
globalEvents.emit('themeChanged');
}, 1000); }, 1000);
const colorScheme = theme.base === 'dark' ? 'dark' : 'light'; const colorScheme = theme.base === 'dark' ? 'dark' : 'light';
@ -108,7 +111,7 @@ export function applyTheme(theme: Theme, persist = true) {
} }
// 色計算など再度行えるようにクライアント全体に通知 // 色計算など再度行えるようにクライアント全体に通知
globalEvents.emit('themeChanged'); globalEvents.emit('themeChanging');
} }
function compile(theme: Theme): Record<string, string> { function compile(theme: Theme): Record<string, string> {