enhance(frontend): KeepAliveのページキャッシュを削除できるように (#13180)

* enhance(frontend): 内部のページキャッシュを削除できるように

* Update Changelog
This commit is contained in:
かっこかり 2024-02-06 16:26:03 +09:00 committed by GitHub
parent 16eccad492
commit edb39a089d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 49 additions and 7 deletions

View File

@ -66,6 +66,7 @@
- Fix: 画像をクロップするとクロップ後の解像度が異様に低くなる問題の修正
- Fix: 画像をクロップ時、正常に完了できない問題の修正
- Fix: キャプションが空の画像をクロップするとキャプションにnullという文字列が入ってしまう問題の修正
- Fix: プロフィールを編集してもリロードするまで反映されない問題を修正
### Server
- Enhance: 連合先のレートリミットに引っかかった際にリトライするようになりました

View File

@ -4,7 +4,10 @@ SPDX-License-Identifier: AGPL-3.0-only
-->
<template>
<KeepAlive :max="defaultStore.state.numberOfPageCache">
<KeepAlive
:max="defaultStore.state.numberOfPageCache"
:exclude="pageCacheController"
>
<Suspense :timeout="0">
<component :is="currentPageComponent" :key="key" v-bind="Object.fromEntries(currentPageProps)"/>
@ -16,9 +19,11 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { inject, onBeforeUnmount, provide, ref, shallowRef } from 'vue';
import { IRouter, Resolved } from '@/nirax.js';
import { inject, onBeforeUnmount, provide, ref, shallowRef, computed, nextTick } from 'vue';
import { IRouter, Resolved, RouteDef } from '@/nirax.js';
import { defaultStore } from '@/store.js';
import { globalEvents } from '@/events.js';
import MkLoadingPage from '@/pages/_loading_.vue';
const props = defineProps<{
router?: IRouter;
@ -46,20 +51,47 @@ function resolveNested(current: Resolved, d = 0): Resolved | null {
}
const current = resolveNested(router.current)!;
const currentPageComponent = shallowRef(current.route.component);
const currentPageComponent = shallowRef('component' in current.route ? current.route.component : MkLoadingPage);
const currentPageProps = ref(current.props);
const key = ref(current.route.path + JSON.stringify(Object.fromEntries(current.props)));
function onChange({ resolved, key: newKey }) {
const current = resolveNested(resolved);
if (current == null) return;
if (current == null || 'redirect' in current.route) return;
currentPageComponent.value = current.route.component;
currentPageProps.value = current.props;
key.value = current.route.path + JSON.stringify(Object.fromEntries(current.props));
nextTick(() => {
//
if (clearCacheRequested.value) {
clearCacheRequested.value = false;
}
});
}
router.addListener('change', onChange);
// #region
/**
* キャッシュクリアが有効になったら全キャッシュをクリアする
*
* keepAlive側にwatcherがあるのですぐ消えるとはおもうけど念のためページ遷移完了まではキャッシュを無効化しておく
* キャッシュ有効時向けにexcludeを使いたい場合はpageCacheControllerに並列に突っ込むのではなく下に追記すること
*/
const pageCacheController = computed(() => clearCacheRequested.value ? /.*/ : undefined);
const clearCacheRequested = ref(false);
globalEvents.on('requestClearPageCache', () => {
if (_DEV_) console.log('clear page cache requested');
if (!clearCacheRequested.value) {
clearCacheRequested.value = true;
}
});
// #endregion
onBeforeUnmount(() => {
router.removeListener('change', onChange);
});

View File

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

View File

@ -125,6 +125,7 @@ import { langmap } from '@/scripts/langmap.js';
import { definePageMetadata } from '@/scripts/page-metadata.js';
import { claimAchievement } from '@/scripts/achievements.js';
import { defaultStore } from '@/store.js';
import { globalEvents } from '@/events.js';
import MkInfo from '@/components/MkInfo.vue';
import MkTextarea from '@/components/MkTextarea.vue';
@ -173,6 +174,7 @@ function saveFields() {
os.apiWithDialog('i/update', {
fields: fields.value.filter(field => field.name !== '' && field.value !== '').map(field => ({ name: field.name, value: field.value })),
});
globalEvents.emit('requestClearPageCache');
}
function save() {
@ -191,6 +193,7 @@ function save() {
isBot: !!profile.isBot,
isCat: !!profile.isCat,
});
globalEvents.emit('requestClearPageCache');
claimAchievement('profileFilled');
if (profile.name === 'syuilo' || profile.name === 'しゅいろ') {
claimAchievement('setNameToSyuilo');
@ -222,6 +225,7 @@ function changeAvatar(ev) {
});
$i.avatarId = i.avatarId;
$i.avatarUrl = i.avatarUrl;
globalEvents.emit('requestClearPageCache');
claimAchievement('profileFilled');
});
}
@ -248,6 +252,7 @@ function changeBanner(ev) {
});
$i.bannerId = i.bannerId;
$i.bannerUrl = i.bannerUrl;
globalEvents.emit('requestClearPageCache');
});
}