diff --git a/backend/src/user-data/library/library.module.ts b/backend/src/user-data/library/library.module.ts index 9867be3..0de3c87 100644 --- a/backend/src/user-data/library/library.module.ts +++ b/backend/src/user-data/library/library.module.ts @@ -5,10 +5,11 @@ import { libraryProviders } from './library.providers'; import { LibraryService } from './library.service'; import { UsersModule } from 'src/users/users.module'; import { SourceProvidersModule } from 'src/source-providers/source-providers.module'; +import { playStateProviders } from '../play-state/play-state.providers'; @Module({ imports: [UsersModule, MetadataModule, SourceProvidersModule], - providers: [...libraryProviders, LibraryService], + providers: [...libraryProviders, ...playStateProviders, LibraryService], controllers: [LibraryController], exports: [LibraryService], }) diff --git a/backend/src/user-data/library/library.service.ts b/backend/src/user-data/library/library.service.ts index 0ce6da0..8eb8125 100644 --- a/backend/src/user-data/library/library.service.ts +++ b/backend/src/user-data/library/library.service.ts @@ -18,12 +18,15 @@ import { } from './library.dto'; import { LibraryItem } from './library.entity'; import { USER_LIBRARY_REPOSITORY } from './library.providers'; +import { USER_PLAY_STATE_REPOSITORY } from '../play-state/play-state.providers'; @Injectable() export class LibraryService { constructor( @Inject(USER_LIBRARY_REPOSITORY) private readonly libraryRepository: Repository, + @Inject(USER_PLAY_STATE_REPOSITORY) + private readonly playStateRepository: Repository, private readonly metadataService: MetadataService, private readonly mediaSourceService: MediaSourcesService, ) { @@ -345,6 +348,23 @@ export class LibraryService { tmdbId, mediaType, }); + + const lastPlayedAt = await this.playStateRepository + .find({ + where: { + userId, + tmdbId, + }, + }) + .then((states) => + states.map((s) => new Date(s.lastPlayedAt).getTime() || 0), + ) + .then((dates) => Math.max(...dates)); + + if (lastPlayedAt) { + libraryItem.lastPlayedAt = new Date(lastPlayedAt); + } + await this.libraryRepository.save(libraryItem); } @@ -401,7 +421,7 @@ export class LibraryService { mediaType: mediaType === 'movie' ? MediaType.Movie : MediaType.Series, watched, playStates, - lastPlayState: playStates?.[0], + lastPlayState: playStates ? playStates[playStates.length - 1] : undefined, tmdbItem: { id: movieMetadata?.tmdbMovie.id ?? seriesMetadata?.tmdbSeries.id, poster_path: diff --git a/src/lib/apis/reiverr/reiverr.openapi.ts b/src/lib/apis/reiverr/reiverr.openapi.ts index 3fe148f..538c675 100644 --- a/src/lib/apis/reiverr/reiverr.openapi.ts +++ b/src/lib/apis/reiverr/reiverr.openapi.ts @@ -117,6 +117,7 @@ export interface LibraryItem { id?: string; tmdbId: string; mediaType: 'movie' | 'series'; + lastPlayedAt?: string; movieMetadata?: MovieMetadata; seriesMetadata?: SeriesMetadata; userId: string; @@ -577,6 +578,7 @@ export interface LibraryItemDto { mediaType: 'movie' | 'series'; playStates?: PlayStateDto[]; tmdbItem: TmdbItemDto; + lastPlayState?: PlayStateDto; watched?: boolean; } diff --git a/src/lib/components/CardGrid.svelte b/src/lib/components/CardGrid.svelte index f220596..9c93f0b 100644 --- a/src/lib/components/CardGrid.svelte +++ b/src/lib/components/CardGrid.svelte @@ -1,49 +1,14 @@ diff --git a/src/lib/components/Container.svelte b/src/lib/components/Container.svelte index 4fef0f2..c9b06fa 100644 --- a/src/lib/components/Container.svelte +++ b/src/lib/components/Container.svelte @@ -33,6 +33,7 @@ export let debugOutline: Required['debugOutline'] = false; export let focusOnClick: Required['focusOnClick'] = false; export let focusedChild: Required['focusedChild'] = false; + export let index: ContainerProps['index'] = undefined; export let disabled = false; @@ -105,6 +106,8 @@ export let tag: Required['tag'] = 'div'; + $: if (index !== undefined) selectable.updateIndex(index); + $: selectable.setIsDisabled(disabled); $: selectable.setGridColumns(gridCols); diff --git a/src/lib/components/Container.type.ts b/src/lib/components/Container.type.ts index 8738157..99d1c7b 100644 --- a/src/lib/components/Container.type.ts +++ b/src/lib/components/Container.type.ts @@ -22,4 +22,5 @@ export type ContainerProps = SvelteHTMLElements['div'] & { focusedChild?: boolean; disabled?: boolean; tag?: string; + index?: number | undefined; }; diff --git a/src/lib/pages/LibraryPage/CatalogueTab.svelte b/src/lib/pages/LibraryPage/CatalogueTab.svelte index e60d39d..63a7dc5 100644 --- a/src/lib/pages/LibraryPage/CatalogueTab.svelte +++ b/src/lib/pages/LibraryPage/CatalogueTab.svelte @@ -1,20 +1,25 @@ - + +

Source Catalogue

+ +
+ +
{#each filters ?? [] as filter} @@ -111,15 +121,24 @@ Options - - {#if $data.length} - - {#each $data.map((i) => i.tmdbItem) as item (item.id)} - - {/each} - -
- {/if} +
+ {#if $data.length} + + {#each $data.map((i) => i.tmdbItem) as item, index (item.id)} + + {/each} + +
+ {:else if $isLoading} + Loading... + {:else} + No items found + {/if} +