fix: PhotoSwipeによるクライアントのメモリリークの解消 (#11395)

* Destroy PhotoSwipe on unmounted

* Update CHANGELOG.md
This commit is contained in:
kabo2468 2023-07-27 06:44:16 +09:00 committed by GitHub
parent 090253c2d2
commit 71b016b293
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 18 additions and 9 deletions

View File

@ -19,6 +19,7 @@
- Fix: モバイル表示のときページ下部がナビゲーションバーに隠れる問題を修正 - Fix: モバイル表示のときページ下部がナビゲーションバーに隠れる問題を修正
- Fix: 一部モーダルダイアログでスクロールできない問題を修正 - Fix: 一部モーダルダイアログでスクロールできない問題を修正
- Fix: Selecting all emojis in Custom emoji is impossible - Fix: Selecting all emojis in Custom emoji is impossible
- Fix: PhotoSwipeによるメモリリークの修正
### Server ### Server
- Fix: APIのオフセットが壊れていたせいで「もっと見る」でもっと見れない問題を修正 - Fix: APIのオフセットが壊れていたせいで「もっと見る」でもっと見れない問題を修正

View File

@ -58,7 +58,7 @@ async function getClientWidthWithCache(targetEl: HTMLElement, containerEl: HTMLE
</script> </script>
<script lang="ts" setup> <script lang="ts" setup>
import { onMounted, shallowRef } from 'vue'; import { onMounted, onUnmounted, shallowRef } from 'vue';
import * as misskey from 'misskey-js'; import * as misskey from 'misskey-js';
import PhotoSwipeLightbox from 'photoswipe/lightbox'; import PhotoSwipeLightbox from 'photoswipe/lightbox';
import PhotoSwipe from 'photoswipe'; import PhotoSwipe from 'photoswipe';
@ -82,6 +82,13 @@ const gallery = shallowRef<HTMLDivElement>();
const pswpZIndex = os.claimZIndex('middle'); const pswpZIndex = os.claimZIndex('middle');
document.documentElement.style.setProperty('--mk-pswp-root-z-index', pswpZIndex.toString()); document.documentElement.style.setProperty('--mk-pswp-root-z-index', pswpZIndex.toString());
const count = $computed(() => props.mediaList.filter(media => previewable(media)).length); const count = $computed(() => props.mediaList.filter(media => previewable(media)).length);
let lightbox: PhotoSwipeLightbox | null;
const popstateHandler = (): void => {
if (lightbox.pswp && lightbox.pswp.isOpen === true) {
lightbox.pswp.close();
}
};
/** /**
* アスペクト比をmediaListWithOneImageAppearanceに基づいていい感じに調整する * アスペクト比をmediaListWithOneImageAppearanceに基づいていい感じに調整する
@ -137,7 +144,7 @@ const count = $computed(() => props.mediaList.filter(media => previewable(media)
onMounted(() => { onMounted(() => {
calcAspectRatio(); calcAspectRatio();
const lightbox = new PhotoSwipeLightbox({ lightbox = new PhotoSwipeLightbox({
dataSource: props.mediaList dataSource: props.mediaList
.filter(media => { .filter(media => {
if (media.type === 'image/svg+xml') return true; // svgwebpublicpngtrue if (media.type === 'image/svg+xml') return true; // svgwebpublicpngtrue
@ -221,12 +228,7 @@ onMounted(() => {
lightbox.init(); lightbox.init();
window.addEventListener('popstate', () => { window.addEventListener('popstate', popstateHandler);
if (lightbox.pswp && lightbox.pswp.isOpen === true) {
lightbox.pswp.close();
return;
}
});
lightbox.on('beforeOpen', () => { lightbox.on('beforeOpen', () => {
history.pushState(null, '', '#pswp'); history.pushState(null, '', '#pswp');
@ -239,6 +241,12 @@ onMounted(() => {
}); });
}); });
onUnmounted(() => {
window.removeEventListener('popstate', popstateHandler);
lightbox?.destroy();
lightbox = null;
});
const previewable = (file: misskey.entities.DriveFile): boolean => { const previewable = (file: misskey.entities.DriveFile): boolean => {
if (file.type === 'image/svg+xml') return true; // svgwebpublic/thumbnailpngtrue if (file.type === 'image/svg+xml') return true; // svgwebpublic/thumbnailpngtrue
// FILE_TYPE_BROWSERSAFE // FILE_TYPE_BROWSERSAFE