summaryrefslogtreecommitdiff
path: root/packages
diff options
context:
space:
mode:
authortamaina <tamaina@hotmail.co.jp>2023-07-25 19:44:52 +0900
committerGitHub <noreply@github.com>2023-07-25 19:44:52 +0900
commit81ba841fb8d2adf2d9fa7a68753daa93a3194778 (patch)
tree1189b6d7bb39b40710fb05c2c008f9bb243982f2 /packages
parentfix(backend): Change isPublic to correctly recognize as:Public term (#11347) (diff)
downloadmisskey-81ba841fb8d2adf2d9fa7a68753daa93a3194778.tar.gz
misskey-81ba841fb8d2adf2d9fa7a68753daa93a3194778.tar.bz2
misskey-81ba841fb8d2adf2d9fa7a68753daa93a3194778.zip
perf(frontend): MkMediaListのアスペクト比制限を調整 (#11377)
Diffstat (limited to 'packages')
-rw-r--r--packages/frontend/src/components/MkMediaList.vue63
-rw-r--r--packages/frontend/src/pages/settings/general.vue1
2 files changed, 45 insertions, 19 deletions
diff --git a/packages/frontend/src/components/MkMediaList.vue b/packages/frontend/src/components/MkMediaList.vue
index be0aed6524..65d3d529dd 100644
--- a/packages/frontend/src/components/MkMediaList.vue
+++ b/packages/frontend/src/components/MkMediaList.vue
@@ -1,5 +1,5 @@
<template>
-<div>
+<div ref="root">
<XBanner v-for="media in mediaList.filter(media => !previewable(media))" :key="media.id" :media="media"/>
<div v-if="mediaList.filter(media => previewable(media)).length > 0" :class="$style.container">
<div
@@ -23,7 +23,7 @@
</template>
<script lang="ts" setup>
-import { onMounted, watch, shallowRef } from 'vue';
+import { onMounted, shallowRef } from 'vue';
import * as misskey from 'misskey-js';
import PhotoSwipeLightbox from 'photoswipe/lightbox';
import PhotoSwipe from 'photoswipe';
@@ -34,19 +34,26 @@ import XVideo from '@/components/MkMediaVideo.vue';
import * as os from '@/os';
import { FILE_TYPE_BROWSERSAFE } from '@/const';
import { defaultStore } from '@/store';
+import { getScrollContainer, getBodyScrollHeight } from '@/scripts/scroll';
const props = defineProps<{
mediaList: misskey.entities.DriveFile[];
raw?: boolean;
}>();
+const root = shallowRef<HTMLDivElement>();
+const container = shallowRef<HTMLElement | null | undefined>(undefined);
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);
+/**
+ * アスペクト比をmediaListWithOneImageAppearanceに基づいていい感じに調整する
+ * aspect-ratioではなくheightを使う
+ */
function calcAspectRatio() {
- if (!gallery.value) return;
+ if (!gallery.value || !root.value) return;
let img = props.mediaList[0];
@@ -55,28 +62,46 @@ function calcAspectRatio() {
return;
}
- // アスペクト比上限設定では、横長の場合は高さを縮小させる
- const ratioMax = (ratio: number) => `${Math.max(ratio, img.properties.width / img.properties.height).toString()} / 1`;
+ const width = gallery.value.clientWidth;
+
+ const heightMin = (ratio: number) => {
+ const imgResizeRatio = width / img.properties.width;
+ const imgDrawHeight = img.properties.height * imgResizeRatio;
+ const maxHeight = width * ratio;
+ const height = Math.min(imgDrawHeight, maxHeight);
+ if (_DEV_) console.log('Image height calculated:', { width, properties: img.properties, imgResizeRatio, imgDrawHeight, maxHeight, height });
+ return `${height}px`;
+ };
switch (defaultStore.state.mediaListWithOneImageAppearance) {
case '16_9':
- gallery.value.style.aspectRatio = ratioMax(16 / 9);
+ gallery.value.style.height = heightMin(9 / 16);
break;
case '1_1':
- gallery.value.style.aspectRatio = ratioMax(1);
+ gallery.value.style.height = heightMin(1);
break;
case '2_3':
- gallery.value.style.aspectRatio = ratioMax(2 / 3);
+ gallery.value.style.height = heightMin(3 / 2);
break;
- default:
- gallery.value.style.aspectRatio = '';
+ default: {
+ if (!container.value) container.value = getScrollContainer(root.value);
+ const maxHeight = Math.max(64, (container.value ? container.value.clientHeight : getBodyScrollHeight()) * 0.5 || 360);
+ if (width === 0 || !maxHeight) return;
+ const imgResizeRatio = width / img.properties.width;
+ const imgDrawHeight = img.properties.height * imgResizeRatio;
+ gallery.value.style.height = `${Math.max(64, Math.min(imgDrawHeight, maxHeight))}px`;
+ gallery.value.style.minHeight = 'initial';
+ gallery.value.style.maxHeight = 'initial';
break;
+ }
}
-}
-watch([defaultStore.reactiveState.mediaListWithOneImageAppearance, gallery], () => calcAspectRatio());
+ gallery.value.style.aspectRatio = 'initial';
+}
onMounted(() => {
+ calcAspectRatio();
+
const lightbox = new PhotoSwipeLightbox({
dataSource: props.mediaList
.filter(media => {
@@ -203,7 +228,7 @@ const previewable = (file: misskey.entities.DriveFile): boolean => {
&.n1 {
grid-template-rows: 1fr;
- // default (expand)
+ // default but fallback (expand)
min-height: 64px;
max-height: clamp(
64px,
@@ -212,20 +237,20 @@ const previewable = (file: misskey.entities.DriveFile): boolean => {
);
&.n116_9 {
- min-height: none;
- max-height: none;
+ min-height: initial;
+ max-height: initial;
aspect-ratio: 16 / 9; // fallback
}
&.n11_1{
- min-height: none;
- max-height: none;
+ min-height: initial;
+ max-height: initial;
aspect-ratio: 1 / 1; // fallback
}
&.n12_3 {
- min-height: none;
- max-height: none;
+ min-height: initial;
+ max-height: initial;
aspect-ratio: 2 / 3; // fallback
}
}
diff --git a/packages/frontend/src/pages/settings/general.vue b/packages/frontend/src/pages/settings/general.vue
index cfe5cd31e7..31a288745e 100644
--- a/packages/frontend/src/pages/settings/general.vue
+++ b/packages/frontend/src/pages/settings/general.vue
@@ -258,6 +258,7 @@ watch([
showGapBetweenNotesInTimeline,
instanceTicker,
overridedDeviceKind,
+ mediaListWithOneImageAppearance,
], async () => {
await reloadAsk();
});