@@ -14,6 +14,10 @@ const props = defineProps({
14
14
type: Object as PropType <PosterItem >,
15
15
required: true ,
16
16
},
17
+ type: {
18
+ type: String as PropType <PosterItem [' type' ]>,
19
+ required: false ,
20
+ },
17
21
poster: {
18
22
type: String ,
19
23
required: false ,
@@ -30,7 +34,7 @@ const props = defineProps({
30
34
},
31
35
});
32
36
33
- const { backdrop, poster, item, size } = toRefs (props );
37
+ const { backdrop, poster, item, size, type } = toRefs (props );
34
38
35
39
// Local poster is used when the item has no poster ref of its own.
36
40
const localPoster = ref <ImageStoreMedias >();
@@ -48,20 +52,31 @@ const resolvedPoster = computed(() => {
48
52
}
49
53
if (! image ) return ;
50
54
if (typeof image === ' string' ) return image ;
51
- if (backdrop .value && ' backdrop' in image ) return image .backdrop ;
52
- return image .poster ;
55
+ if (backdrop .value && ' backdrop' in image ) return image .backdrop ?? image . poster ;
56
+ return image .poster ?? image . backdrop ;
53
57
});
54
58
55
- const objectFit = computed (() =>
56
- resolvedPoster .value === PosterPlaceholder ? ' contain' : ' cover' ,
57
- );
58
-
59
59
const transition = ref (false );
60
60
61
61
const imgLoaded = ref (false );
62
62
const loading = computed (() => ! imgLoaded .value || ! resolvedPoster .value );
63
63
64
+ const imageRef = ref <typeof NImage >();
65
+ const dimensions = ref <{ width: number ; height: number ; ratio: number }>();
66
+ const portrait = computed (() => dimensions .value ?.ratio && dimensions .value .ratio < 1 );
67
+
68
+ const objectFit = computed (() =>
69
+ resolvedPoster .value === PosterPlaceholder ? ' contain' : ' cover' ,
70
+ );
71
+
64
72
const onLoad = () => {
73
+ const { naturalWidth, naturalHeight }: HTMLImageElement =
74
+ imageRef .value ?.$el ?.firstElementChild ?? {};
75
+ dimensions .value = {
76
+ width: naturalWidth ,
77
+ height: naturalHeight ,
78
+ ratio: Math .round ((naturalWidth / naturalHeight ) * 100 ) / 100 ,
79
+ };
65
80
imgLoaded .value = true ;
66
81
};
67
82
@@ -73,9 +88,10 @@ const getPosters = async (_item: PosterItem) => {
73
88
74
89
const query = _item .getPosterQuery ?.();
75
90
if (! query ) return ;
76
- if (! backdrop .value && _item .type === ' episode' ) {
77
- query .type = ' show' ;
78
- delete query .episode ;
91
+ if (type ?.value && type .value !== _item .type ) {
92
+ query .type = type .value ;
93
+ if (_item .type === ' episode' ) delete query .episode ;
94
+ if (_item .type === ' season' ) delete query .season ;
79
95
}
80
96
// If the image is not loaded after 100ms, show transition
81
97
clearTimeout (timeout .value );
@@ -103,9 +119,11 @@ onBeforeUnmount(() => {
103
119
104
120
<template >
105
121
<NImage
122
+ ref =" imageRef"
106
123
alt =" poster-image"
107
124
class =" poster"
108
125
:class =" {
126
+ portrait,
109
127
backdrop,
110
128
loading,
111
129
transition,
@@ -121,7 +139,10 @@ onBeforeUnmount(() => {
121
139
<NImage
122
140
alt =" poster-image-fallback"
123
141
class =" poster placeholder"
124
- :class =" { backdrop }"
142
+ :class =" {
143
+ portrait,
144
+ backdrop,
145
+ }"
125
146
object-fit =" contain"
126
147
width =" 100%"
127
148
lazy
0 commit comments