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: Selecting all emojis in Custom emoji is impossible
- Fix: PhotoSwipeによるメモリリークの修正
### Server
- Fix: APIのオフセットが壊れていたせいで「もっと見る」でもっと見れない問題を修正

View file

@ -58,7 +58,7 @@ async function getClientWidthWithCache(targetEl: HTMLElement, containerEl: HTMLE
</script>
<script lang="ts" setup>
import { onMounted, shallowRef } from 'vue';
import { onMounted, onUnmounted, shallowRef } from 'vue';
import * as misskey from 'misskey-js';
import PhotoSwipeLightbox from 'photoswipe/lightbox';
import PhotoSwipe from 'photoswipe';
@ -82,12 +82,19 @@ const gallery = shallowRef<HTMLDivElement>();
const pswpZIndex = os.claimZIndex('middle');
document.documentElement.style.setProperty('--mk-pswp-root-z-index', pswpZIndex.toString());
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に基づいていい感じに調整する
* aspect-ratioではなくheightを使う
*/
async function calcAspectRatio() {
async function calcAspectRatio() {
if (!gallery.value || !root.value) return;
let img = props.mediaList[0];
@ -137,7 +144,7 @@ const count = $computed(() => props.mediaList.filter(media => previewable(media)
onMounted(() => {
calcAspectRatio();
const lightbox = new PhotoSwipeLightbox({
lightbox = new PhotoSwipeLightbox({
dataSource: props.mediaList
.filter(media => {
if (media.type === 'image/svg+xml') return true; // svgwebpublicpngtrue
@ -221,12 +228,7 @@ onMounted(() => {
lightbox.init();
window.addEventListener('popstate', () => {
if (lightbox.pswp && lightbox.pswp.isOpen === true) {
lightbox.pswp.close();
return;
}
});
window.addEventListener('popstate', popstateHandler);
lightbox.on('beforeOpen', () => {
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 => {
if (file.type === 'image/svg+xml') return true; // svgwebpublic/thumbnailpngtrue
// FILE_TYPE_BROWSERSAFE