fix: PhotoSwipeによるクライアントのメモリリークの解消 (#11395)
* Destroy PhotoSwipe on unmounted * Update CHANGELOG.md
This commit is contained in:
parent
090253c2d2
commit
71b016b293
@ -19,6 +19,7 @@
|
||||
- Fix: モバイル表示のときページ下部がナビゲーションバーに隠れる問題を修正
|
||||
- Fix: 一部モーダルダイアログでスクロールできない問題を修正
|
||||
- Fix: Selecting all emojis in Custom emoji is impossible
|
||||
- Fix: PhotoSwipeによるメモリリークの修正
|
||||
|
||||
### Server
|
||||
- Fix: APIのオフセットが壊れていたせいで「もっと見る」でもっと見れない問題を修正
|
||||
|
@ -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; // svgのwebpublicはpngなのでtrue
|
||||
@ -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; // svgのwebpublic/thumbnailはpngなのでtrue
|
||||
// FILE_TYPE_BROWSERSAFEに適合しないものはブラウザで表示するのに不適切
|
||||
|
Loading…
Reference in New Issue
Block a user