Skip to content

Commit 84393ab

Browse files
committed
fixup! fix: スケルトンを設定してレイアウトシフトを抑制
1 parent 774a043 commit 84393ab

6 files changed

Lines changed: 54 additions & 36 deletions

File tree

src/components/Main/MainView/MessageElement/Embeddings/MessageFileListImage.vue

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,16 @@
44
<SkeletonImage
55
:src="fileThumbnailPath"
66
:alt="name"
7+
:class="$style.image"
8+
fixed
79
:height="fileThumbnailSize.height"
810
:width="fileThumbnailSize.width"
911
>
1012
<PlayIcon v-if="isAnimatedImage" :class="$style.playIcon" />
1113
</SkeletonImage>
1214
</router-link>
1315
<router-link v-else :to="fileLink" :class="$style.container">
14-
<SkeletonImage
15-
:src="fileThumbnailPath"
16-
:alt="name"
17-
:width="240"
18-
:height="160"
19-
>
16+
<SkeletonImage :src="fileThumbnailPath" :alt="name">
2017
<PlayIcon v-if="isAnimatedImage" :class="$style.playIcon" />
2118
</SkeletonImage>
2219
</router-link>
@@ -85,16 +82,18 @@ const {
8582
color: $theme-background-secondary-border;
8683
}
8784
max-width: 100%;
88-
img {
89-
height: auto;
90-
width: auto;
91-
max-height: 450px;
92-
max-width: min(600px, 100%);
93-
min-width: 100px;
94-
object-fit: contain;
95-
cursor: pointer;
96-
}
9785
}
86+
87+
.image {
88+
height: auto;
89+
width: auto;
90+
max-height: 450px;
91+
max-width: min(600px, 100%);
92+
min-width: 100px;
93+
object-fit: contain;
94+
cursor: pointer;
95+
}
96+
9897
.playIcon {
9998
position: absolute;
10099
top: 0;

src/components/Main/MainView/MessageElement/Embeddings/MessageFileSummaryImage.vue

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
<template>
22
<RouterLink :to="fileLink" :class="$style.container" @click.stop>
3-
<SkeletonImage :src="fileThumbnailPath" :class="$style.image" background />
3+
<SkeletonImage
4+
:src="fileThumbnailPath"
5+
fixed
6+
width="9rem"
7+
height="6rem"
8+
:class="$style.image"
9+
background
10+
/>
411
<PlayIcon v-if="isAnimatedImage" :class="$style.playIcon" />
512
</RouterLink>
613
</template>
@@ -27,8 +34,6 @@ const { fileLink, fileThumbnailPath, isAnimatedImage } = useFileThumbnail(props)
2734
.image {
2835
border: 2px solid $theme-background-secondary-border;
2936
border-radius: 6px;
30-
height: 6rem;
31-
width: 9rem;
3237
overflow: hidden;
3338
background: {
3439
position: center;

src/components/Main/MainView/MessageElement/Embeddings/MessageOgpContentVideo.vue

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
<div :class="$style.container">
33
<MessageOgpEmbed
44
:preview-url="previewUrl"
5+
:preview-width="previewWidth"
6+
:preview-height="previewHeight"
57
:embedded-url="embeddedUrl"
68
show-play-icon
79
@click.prevent.stop=""
@@ -29,6 +31,8 @@ withDefaults(
2931
defineProps<{
3032
url: string
3133
previewUrl: string
34+
previewWidth?: number
35+
previewHeight?: number
3236
embeddedUrl: string
3337
title?: string
3438
description?: string

src/components/Main/MainView/MessageElement/Embeddings/MessageOgpEmbed.vue

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,39 +7,43 @@
77
allowfullscreen
88
allow="fullscreen; autoplay; encrypted-media; picture-in-picture"
99
/>
10-
<template v-else>
11-
<img :src="previewUrl" :class="$style.image" />
10+
<SkeletonImage v-else fixed :src="previewUrl" :class="$style.image">
1211
<div :class="$style.icon">
1312
<AIcon v-if="showPlayIcon" mdi name="play" :size="32" />
1413
</div>
15-
</template>
14+
</SkeletonImage>
1615
</div>
1716
</template>
1817

1918
<script lang="ts" setup>
2019
import { computed } from 'vue'
2120
2221
import AIcon from '/@/components/UI/AIcon.vue'
22+
import SkeletonImage from '/@/components/UI/SkeletonImage.vue'
2323
import useToggle from '/@/composables/utils/useToggle'
2424
2525
const props = withDefaults(
2626
defineProps<{
2727
previewUrl?: string
28+
previewWidth?: number
29+
previewHeight?: number
2830
embeddedUrl: string
2931
showPlayIcon?: boolean
3032
aspectRatio?: number
3133
}>(),
3234
{
33-
showPlayIcon: false,
34-
aspectRatio: 9 / 16
35+
showPlayIcon: false
3536
}
3637
)
3738
3839
const { value: isContentShown, open: showContent } = useToggle()
3940
4041
const containerStyle = computed(() => ({
41-
// TODO: Safariが15以降で aspect-ratio に対応している
42-
paddingTop: `${props.aspectRatio * 100}%`
42+
aspectRatio:
43+
props.aspectRatio ??
44+
(props.previewWidth && props.previewHeight
45+
? `${props.previewWidth} / ${props.previewHeight}`
46+
: '16 / 9')
4347
}))
4448
</script>
4549

src/components/Main/MainView/MessageElement/Embeddings/MessageOgpListItem.vue

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
:title="ogpData.title"
77
:description="ogpData.description"
88
:preview-url="imageUrl"
9+
:preview-width="imageWidth"
10+
:preview-height="imageHeight"
911
:embedded-url="videoUrl"
1012
/>
1113
<MessageOgpContentWebsite

src/components/UI/SkeletonImage.vue

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
<template>
2-
<div :class="$style.container" :style="containerStyle">
2+
<div
3+
v-if="background"
4+
v-bind="$attrs"
5+
:style="[skeletonStyle, backgroundStyle]"
6+
>
7+
<slot />
8+
</div>
9+
<template v-else>
310
<span
411
v-if="!src || !isImageLoaded"
512
:class="$style.skeleton"
@@ -8,18 +15,17 @@
815
/>
916
<img
1017
v-show="isImageLoaded"
11-
v-if="src"
18+
v-if="src && !background"
1219
:src="src"
1320
v-bind="$attrs"
14-
:class="{ [$style.hidden]: !isImageLoaded }"
1521
@load="onImageLoad"
1622
/>
1723
<slot />
18-
</div>
24+
</template>
1925
</template>
2026

2127
<script lang="ts" setup>
22-
import { computed, ref, watch } from 'vue'
28+
import { computed, ref, watch, watchEffect } from 'vue'
2329
2430
import { isNumber } from '/@/lib/basic/arithmetic'
2531
@@ -71,8 +77,7 @@ watch(
7177
{ immediate: true }
7278
)
7379
74-
const containerStyle = computed(() => {
75-
if (!props.background) return {}
80+
const backgroundStyle = computed(() => {
7681
return {
7782
backgroundImage: isImageLoaded.value ? `url(${props.src})` : 'none'
7883
}
@@ -90,6 +95,9 @@ const skeletonStyle = computed(() => {
9095
}
9196
}
9297
})
98+
watchEffect(() => {
99+
console.log(skeletonStyle.value)
100+
})
93101
</script>
94102

95103
<style lang="scss" module>
@@ -112,10 +120,6 @@ const skeletonStyle = computed(() => {
112120
border-radius: 4px;
113121
}
114122
115-
.hidden {
116-
display: none;
117-
}
118-
119123
@keyframes skeleton-loading {
120124
0% {
121125
background-position: 200% 0;

0 commit comments

Comments
 (0)