Skip to content

Commit 26b2f6f

Browse files
committed
chore(api): adds image cache busting in panels
1 parent d385af7 commit 26b2f6f

File tree

4 files changed

+47
-39
lines changed

4 files changed

+47
-39
lines changed

src/components/common/poster/PosterComponent.vue

+7-6
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,14 @@ const props = defineProps({
4343
required: false,
4444
default: 300,
4545
},
46+
force: {
47+
type: Boolean,
48+
required: false,
49+
default: false,
50+
},
4651
});
4752
48-
const { backdrop, poster, item, size, type } = toRefs(props);
53+
const { backdrop, poster, item, size, type, force } = toRefs(props);
4954
5055
// cache poster image to prevent flickering
5156
const cache = reactive<Record<string, ImageStoreMedias>>({});
@@ -122,18 +127,14 @@ const getPosters = async (
122127
transition.value = true;
123128
}, 100);
124129
try {
125-
const response = await getImageUrl({
126-
query,
127-
size: size.value,
128-
});
130+
const response = await getImageUrl({ query, size: size.value, force: force.value });
129131
if (!_item?.key || !response) return;
130132
const key = [item.value.key, backdrop.value, type?.value].filter(Boolean).join('-');
131133
cache[key] = response;
132134
} catch (error) {
133135
Logger.error('Failed to fetch poster', error);
134136
}
135137
};
136-
137138
watch([item, type, backdrop], () => getPosters(), { immediate: true, flush: 'pre' });
138139
139140
onBeforeUnmount(() => {

src/components/views/panel/PanelPoster.vue

+9-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
import { NFlex, NSkeleton } from 'naive-ui';
33
import { computed, type PropType, toRefs, Transition } from 'vue';
44
5+
import { useRoute } from 'vue-router';
6+
57
import type { PosterItem } from '~/models/poster.model';
68
import type { ImageQuery, ImageStoreTypes } from '~/stores/data/image.store';
79
@@ -81,6 +83,7 @@ const label = computed(() => {
8183
});
8284
8385
const { openTab } = useLinksStore();
86+
const route = useRoute();
8487
</script>
8588

8689
<template>
@@ -92,7 +95,12 @@ const { openTab } = useLinksStore();
9295
:title="label"
9396
@click="openTab(link)"
9497
>
95-
<PosterComponent :item="posterItem" :size="size" :backdrop="!portait" />
98+
<PosterComponent
99+
:item="posterItem"
100+
:size="size"
101+
:backdrop="!portait"
102+
:force="route.query.force === 'true'"
103+
/>
96104
</NFlex>
97105
</Transition>
98106
<NSkeleton

src/services/trakt.service.ts

+10-23
Original file line numberDiff line numberDiff line change
@@ -260,49 +260,36 @@ export class TraktService {
260260
}
261261

262262
static posters = {
263-
async movie(movie_id: string | number) {
264-
const response = await TraktService.tmdbClient.v3.movies.images.cached({
265-
movie_id,
266-
});
263+
async movie(movie_id: string | number, force?: boolean) {
264+
const response = await TraktService.tmdbClient.v3.movies.images.cached({ movie_id }, undefined, { force });
267265
const data = await response.json();
268266
if (imageResponseEmpty(data) && shouldEvict(response.cache)) response.cache?.evict?.();
269267
return data;
270268
},
271269

272-
async show(series_id: string | number) {
273-
const response = await TraktService.tmdbClient.v3.shows.images.cached({
274-
series_id,
275-
});
270+
async show(series_id: string | number, force?: boolean) {
271+
const response = await TraktService.tmdbClient.v3.shows.images.cached({ series_id }, undefined, { force });
276272
const data = await response.json();
277273
if (imageResponseEmpty(data) && shouldEvict(response.cache)) response.cache?.evict?.();
278274
return data;
279275
},
280276

281-
async season(series_id: string | number, season_number: number) {
282-
const response = await TraktService.tmdbClient.v3.seasons.images.cached({
283-
series_id,
284-
season_number,
285-
});
277+
async season(series_id: string | number, season_number: number, force?: boolean) {
278+
const response = await TraktService.tmdbClient.v3.seasons.images.cached({ series_id, season_number }, undefined, { force });
286279
const data = await response.json();
287280
if (imageResponseEmpty(data) && shouldEvict(response.cache)) response.cache?.evict?.();
288281
return data;
289282
},
290283

291-
async episode(series_id: string | number, season_number: number, episode_number: number) {
292-
const response = await TraktService.tmdbClient.v3.episodes.images.cached({
293-
series_id,
294-
season_number,
295-
episode_number,
296-
});
284+
async episode(series_id: string | number, season_number: number, episode_number: number, force?: boolean) {
285+
const response = await TraktService.tmdbClient.v3.episodes.images.cached({ series_id, season_number, episode_number }, undefined, { force });
297286
const data = await response.json();
298287
if (imageResponseEmpty(data) && shouldEvict(response.cache)) response.cache?.evict?.();
299288
return data;
300289
},
301290

302-
async person(person_id: string | number) {
303-
const response = await TraktService.tmdbClient.v3.people.images.cached({
304-
person_id,
305-
});
291+
async person(person_id: string | number, force?: boolean) {
292+
const response = await TraktService.tmdbClient.v3.people.images.cached({ person_id }, undefined, { force });
306293
const data = await response.json();
307294
if (imageResponseEmpty(data) && shouldEvict(response.cache)) response.cache?.evict?.();
308295
return data;

src/stores/data/image.store.ts

+21-9
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ export const useImageStore = defineStore(ImageStoreConstants.Store, () => {
147147
if (!(key in queue)) queue[key] = request();
148148
const response = await queue[key];
149149
delete imageErrors[type]?.[key];
150+
delete queue[key];
150151
return response;
151152
} catch (error) {
152153
if (error instanceof Response && error.status === 404) {
@@ -170,18 +171,19 @@ export const useImageStore = defineStore(ImageStoreConstants.Store, () => {
170171
const fetchImageUrl = async (
171172
key: string,
172173
{ id, season, episode, type }: ImageQuery,
174+
force?: boolean,
173175
): Promise<{ image: ImageStoreMedias; key: string; type: ImageQuery['type'] } | undefined> => {
174176
let payload: ImagePayload;
175177
if (type === 'movie') {
176-
payload = await queueRequest({ key, type }, () => TraktService.posters.movie(id));
178+
payload = await queueRequest({ key, type }, () => TraktService.posters.movie(id, force));
177179
} else if (type === 'person') {
178-
payload = await queueRequest({ key, type }, () => TraktService.posters.person(id));
180+
payload = await queueRequest({ key, type }, () => TraktService.posters.person(id, force));
179181
} else if (type === 'episode' && season !== undefined && episode !== undefined) {
180-
payload = await queueRequest({ key, type }, () => TraktService.posters.episode(id, season, episode));
182+
payload = await queueRequest({ key, type }, () => TraktService.posters.episode(id, season, episode, force));
181183
} else if (type === 'season' && season !== undefined) {
182-
payload = await queueRequest({ key, type }, () => TraktService.posters.season(id, season));
184+
payload = await queueRequest({ key, type }, () => TraktService.posters.season(id, season, force));
183185
} else if (type === 'show') {
184-
payload = await queueRequest({ key, type }, () => TraktService.posters.show(id));
186+
payload = await queueRequest({ key, type }, () => TraktService.posters.show(id, force));
185187
} else {
186188
Logger.error('Unsupported type or missing parameters for fetchImageUrl', { key, id, season, episode, type });
187189
throw new Error('Unsupported type or missing parameters for fetchImageUrl');
@@ -191,7 +193,7 @@ export const useImageStore = defineStore(ImageStoreConstants.Store, () => {
191193
const sType = 'show';
192194
const sKey = `${sType}-${id}`;
193195
if (images[sType][sKey]) return { image: images[sType][sKey], key: sKey, type: sType };
194-
return fetchImageUrl(sKey, { id, type: sType });
196+
return fetchImageUrl(sKey, { id, type: sType }, force);
195197
}
196198

197199
if (['movie', 'show'].includes(type)) {
@@ -270,15 +272,25 @@ export const useImageStore = defineStore(ImageStoreConstants.Store, () => {
270272
return { key, type, baseUrl, image: getResponseValue({ image, baseUrl, type, size }) };
271273
};
272274

273-
const getImageUrl = async ({ query, size = 300, fetch = true }: { query: ImageQuery; size?: number | 'original'; fetch?: boolean }) => {
275+
const getImageUrl = async ({
276+
query,
277+
size = 300,
278+
fetch = true,
279+
force,
280+
}: {
281+
query: ImageQuery;
282+
size?: number | 'original';
283+
fetch?: boolean;
284+
force?: boolean;
285+
}) => {
274286
if (!tmdbConfig.value) throw new Error('TmdbConfiguration not initialized');
275287
if (!tmdbConfig.value?.images?.secure_base_url) throw new Error('TmdbConfiguration missing secure_base_url');
276288

277289
const { image, key, type, baseUrl = tmdbConfig.value.images.secure_base_url } = getImageResponse({ query, size });
278290

279-
if (image || !fetch) return image;
291+
if (!force && (image || !fetch)) return image;
280292

281-
const result = await fetchImageUrl(key, query);
293+
const result = await fetchImageUrl(key, query, force);
282294
if (!result?.image) return undefined;
283295
return getResponseValue({ image: result.image, baseUrl, type, size });
284296
};

0 commit comments

Comments
 (0)