forked from mirrors/misskey
enhance(frontend): テーマ切り替えのアニメーションをView Transitionに変更 (#15974)
* enhance(frontend): テーマ切り替えのアニメーションをView Transitionに変更 * fix lint * fix: 切り替え時間を0.5sに
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import { ref } from 'vue';
|
||||
import { ref, nextTick } from 'vue';
|
||||
import tinycolor from 'tinycolor2';
|
||||
import lightTheme from '@@/themes/_light.json5';
|
||||
import darkTheme from '@@/themes/_dark.json5';
|
||||
@@ -88,20 +88,7 @@ export async function removeTheme(theme: Theme): Promise<void> {
|
||||
prefer.commit('themes', themes);
|
||||
}
|
||||
|
||||
let timeout: number | null = null;
|
||||
|
||||
export function applyTheme(theme: Theme, persist = true) {
|
||||
if (timeout) window.clearTimeout(timeout);
|
||||
|
||||
window.document.documentElement.classList.add('_themeChanging_');
|
||||
|
||||
timeout = window.setTimeout(() => {
|
||||
window.document.documentElement.classList.remove('_themeChanging_');
|
||||
|
||||
// 色計算など再度行えるようにクライアント全体に通知
|
||||
globalEvents.emit('themeChanged');
|
||||
}, 1000);
|
||||
|
||||
function applyThemeInternal(theme: Theme, persist: boolean) {
|
||||
const colorScheme = theme.base === 'dark' ? 'dark' : 'light';
|
||||
|
||||
window.document.documentElement.dataset.colorScheme = colorScheme;
|
||||
@@ -139,6 +126,37 @@ export function applyTheme(theme: Theme, persist = true) {
|
||||
globalEvents.emit('themeChanging');
|
||||
}
|
||||
|
||||
let timeout: number | null = null;
|
||||
|
||||
export function applyTheme(theme: Theme, persist = true) {
|
||||
if (timeout) {
|
||||
window.clearTimeout(timeout);
|
||||
timeout = null;
|
||||
}
|
||||
|
||||
if (window.document.startViewTransition != null && prefer.s.animation) {
|
||||
window.document.documentElement.classList.add('_themeChanging_');
|
||||
window.document.startViewTransition(async () => {
|
||||
applyThemeInternal(theme, persist);
|
||||
await nextTick();
|
||||
}).finished.then(() => {
|
||||
window.document.documentElement.classList.remove('_themeChanging_');
|
||||
// 色計算など再度行えるようにクライアント全体に通知
|
||||
globalEvents.emit('themeChanged');
|
||||
});
|
||||
} else {
|
||||
// TODO: ViewTransition API が主要ブラウザで対応したら消す
|
||||
window.document.documentElement.classList.add('_themeChangingFallback_');
|
||||
timeout = window.setTimeout(() => {
|
||||
window.document.documentElement.classList.remove('_themeChangingFallback_');
|
||||
// 色計算など再度行えるようにクライアント全体に通知
|
||||
globalEvents.emit('themeChanged');
|
||||
}, 500);
|
||||
|
||||
applyThemeInternal(theme, persist);
|
||||
}
|
||||
}
|
||||
|
||||
export function compile(theme: Theme): Record<string, string> {
|
||||
function getColor(val: string): tinycolor.Instance {
|
||||
if (val[0] === '@') { // ref (prop)
|
||||
|
||||
Reference in New Issue
Block a user