Skip to content

Commit 358caf4

Browse files
committed
fix(images): clear cache on empty staled request & fix cache eviction
1 parent 3963251 commit 358caf4

File tree

4 files changed

+57
-20
lines changed

4 files changed

+57
-20
lines changed

src/components/views/settings/SettingsCache.vue

+7-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import SettingsFormItem from '~/components/views/settings/SettingsFormItem.vue';
99
1010
import { NotificationService } from '~/services/notification.service';
1111
import { TraktService } from '~/services/trakt.service';
12+
import { useImageStore } from '~/stores/data/image.store';
1213
import { useExtensionSettingsStoreRefs } from '~/stores/settings/extension.store';
1314
import { logger } from '~/stores/settings/log.store';
1415
import { useI18n } from '~/utils/i18n.utils';
@@ -38,8 +39,13 @@ const onClick = async (fn: () => unknown, index: number) => {
3839
}
3940
};
4041
42+
const { clearState: clearImageStore } = useImageStore();
43+
4144
const evictScopes = [
42-
{ label: i18n('evict_images'), click: TraktService.evict.tmdb },
45+
{
46+
label: i18n('evict_images'),
47+
click: () => Promise.all([clearImageStore(), TraktService.evict.tmdb()]),
48+
},
4349
{
4450
label: i18n('evict_progress'),
4551
click: () =>

src/models/poster.model.ts

+8
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type { TmdbImage } from '@dvcol/tmdb-http-client/models';
12
import type { Ref } from 'vue';
23
import type { ImageQuery, ImageStoreMedias, ImageStoreTypes } from '~/stores/data/image.store';
34

@@ -8,3 +9,10 @@ export type PosterItem = {
89
posterRef?: Ref<ImageStoreMedias | undefined>;
910
getPosterQuery?: () => ImageQuery | undefined;
1011
};
12+
13+
export type ImagePayload = {
14+
posters?: TmdbImage[]; // movie, show, season
15+
backdrops?: TmdbImage[]; // movie or shows
16+
stills?: TmdbImage[]; // episodes
17+
profiles?: TmdbImage[]; // profiles
18+
};

src/services/trakt.service.ts

+28-11
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import type {
3939
} from '@dvcol/trakt-http-client/models';
4040

4141
import type { TvdbApiResponse } from '@dvcol/tvdb-http-client/models';
42+
import type { ImagePayload } from '~/models/poster.model';
4243
import type { ProgressItem } from '~/models/progress.model';
4344
import type { SettingsAuth, UserSetting } from '~/models/trakt-service.model';
4445

@@ -55,7 +56,7 @@ import { useUserSettingsStore } from '~/stores/settings/user.store';
5556
import { createTab } from '~/utils/browser/browser.utils';
5657
import { CachePrefix, ChromeCacheStore } from '~/utils/cache.utils';
5758

58-
export const shouldEvict = (date?: string | number | Date, cache?: CacheResponse<unknown>): boolean => {
59+
const shouldEvict = (cache?: CacheResponse<unknown>, date?: string | number | Date): boolean => {
5960
// no cache skip
6061
if (!cache?.evict) return false;
6162
// cached today skip
@@ -70,6 +71,12 @@ export const shouldEvict = (date?: string | number | Date, cache?: CacheResponse
7071
return new Date(date) > new Date();
7172
};
7273

74+
const imageResponseEmpty = (payload: ImagePayload) => {
75+
return Object.values(payload)
76+
.filter(Array.isArray)
77+
.every(v => !v?.length);
78+
};
79+
7380
export class TraktService {
7481
private static traktClient: TraktClient;
7582
private static tmdbClient: TmdbClient;
@@ -240,22 +247,28 @@ export class TraktService {
240247
const response = await TraktService.tmdbClient.v3.movies.images.cached({
241248
movie_id,
242249
});
243-
return response.json();
250+
const data = await response.json();
251+
if (imageResponseEmpty(data) && shouldEvict(response.cache)) response.cache?.evict?.();
252+
return data;
244253
},
245254

246255
async show(series_id: string | number) {
247256
const response = await TraktService.tmdbClient.v3.shows.images.cached({
248257
series_id,
249258
});
250-
return response.json();
259+
const data = await response.json();
260+
if (imageResponseEmpty(data) && shouldEvict(response.cache)) response.cache?.evict?.();
261+
return data;
251262
},
252263

253264
async season(series_id: string | number, season_number: number) {
254265
const response = await TraktService.tmdbClient.v3.seasons.images.cached({
255266
series_id,
256267
season_number,
257268
});
258-
return response.json();
269+
const data = await response.json();
270+
if (imageResponseEmpty(data) && shouldEvict(response.cache)) response.cache?.evict?.();
271+
return data;
259272
},
260273

261274
async episode(series_id: string | number, season_number: number, episode_number: number) {
@@ -264,14 +277,18 @@ export class TraktService {
264277
season_number,
265278
episode_number,
266279
});
267-
return response.json();
280+
const data = await response.json();
281+
if (imageResponseEmpty(data) && shouldEvict(response.cache)) response.cache?.evict?.();
282+
return data;
268283
},
269284

270285
async person(person_id: string | number) {
271286
const response = await TraktService.tmdbClient.v3.people.images.cached({
272287
person_id,
273288
});
274-
return response.json();
289+
const data = await response.json();
290+
if (imageResponseEmpty(data) && shouldEvict(response.cache)) response.cache?.evict?.();
291+
return data;
275292
},
276293
};
277294

@@ -414,36 +431,36 @@ export class TraktService {
414431
async summary(id: string | number) {
415432
const response = await TraktService.traktClient.shows.summary.cached({ id, extended: 'full' });
416433
const data = await response.json();
417-
if (shouldEvict(data?.first_aired, response?.cache)) response.cache?.evict?.();
434+
if (shouldEvict(response?.cache, data?.first_aired)) response.cache?.evict?.();
418435
return data as TraktShowExtended;
419436
},
420437

421438
async season(id: string | number, season: number) {
422439
const response = await TraktService.traktClient.seasons.season.cached({ id, season });
423440
const data = await response.json();
424-
if (data.some(e => shouldEvict(e?.first_aired, response?.cache))) response.cache?.evict?.();
441+
if (data.some(e => shouldEvict(response?.cache, e?.first_aired))) response.cache?.evict?.();
425442
return data as TraktEpisodeShort[];
426443
},
427444

428445
async seasons(id: string | number) {
429446
const response = await TraktService.traktClient.seasons.summary.cached({ id, extended: 'full' });
430447
const data = await response.json();
431-
if (data.some(s => shouldEvict(s?.first_aired, response?.cache))) response.cache?.evict?.();
448+
if (data.some(s => shouldEvict(response?.cache, s?.first_aired))) response.cache?.evict?.();
432449
return data as TraktSeasonExtended[];
433450
},
434451

435452
async episode({ id, season, episode }: { id: string | number; season: number; episode: number }) {
436453
const response = await TraktService.traktClient.episodes.summary.cached({ id, season, episode, extended: 'full' });
437454
const data = await response.json();
438-
if (shouldEvict(data?.first_aired, response?.cache)) response.cache?.evict?.();
455+
if (shouldEvict(response?.cache, data?.first_aired)) response.cache?.evict?.();
439456
return data as TraktEpisodeExtended;
440457
},
441458
};
442459

443460
static async movie(id: string | number) {
444461
const response = await this.traktClient.movies.summary.cached({ id, extended: 'full' });
445462
const data = await response.json();
446-
if (shouldEvict(data?.released, response?.cache)) response.cache?.evict?.();
463+
if (shouldEvict(response?.cache, data?.released)) response.cache?.evict?.();
447464
return data as TraktMovieExtended;
448465
}
449466

src/stores/data/image.store.ts

+14-8
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import { computed, reactive, type Ref, ref } from 'vue';
55

66
import type { TmdbConfiguration, TmdbImage } from '@dvcol/tmdb-http-client/models';
77

8+
import type { ImagePayload } from '~/models/poster.model';
9+
810
import { ErrorService } from '~/services/error.service';
911
import { TraktService } from '~/services/trakt.service';
1012
import { logger } from '~/stores/settings/log.store';
@@ -13,6 +15,7 @@ import { getShortLocale } from '~/utils/browser/browser.utils';
1315
import { CachePrefix } from '~/utils/cache.utils';
1416
import { debounce } from '~/utils/debounce.utils';
1517
import { ErrorCount, type ErrorDictionary } from '~/utils/retry.utils';
18+
import { clearProxy } from '~/utils/vue.utils';
1619

1720
type ImageStoreMedia = {
1821
poster?: string;
@@ -55,13 +58,6 @@ export type ImageQuery = {
5558
type: ImageStoreTypes;
5659
};
5760

58-
type ImagePayload = {
59-
posters?: TmdbImage[]; // movie, show, season
60-
backdrops?: TmdbImage[]; // movie or shows
61-
stills?: TmdbImage[]; // episodes
62-
profiles?: TmdbImage[]; // profiles
63-
};
64-
6561
const emptyImageStore = {
6662
movie: {},
6763
show: {},
@@ -123,6 +119,16 @@ export const useImageStore = defineStore(ImageStoreConstants.Store, () => {
123119
if (person) Object.assign(images.person, person);
124120
};
125121

122+
const clearState = async () => {
123+
clearProxy(images.movie);
124+
clearProxy(images.show);
125+
clearProxy(images.season);
126+
clearProxy(images.episode);
127+
clearProxy(images.person);
128+
clearProxy(imageErrors);
129+
return saveState().catch(err => logger.error('Failed to save image store', err));
130+
};
131+
126132
const initImageStore = async (config?: TmdbConfiguration) => {
127133
if (!config) config = await TraktService.tmdbConfiguration();
128134
tmdbConfig.value = config;
@@ -249,7 +255,7 @@ export const useImageStore = defineStore(ImageStoreConstants.Store, () => {
249255
return setResponseValue({ image: result.image, baseUrl, type, size }, response);
250256
};
251257

252-
return { initImageStore, getImageUrl, imageSizes };
258+
return { initImageStore, getImageUrl, imageSizes, clearState };
253259
});
254260

255261
export const useImageStoreRefs = () => storeToRefs(useImageStore());

0 commit comments

Comments
 (0)