mirror of
https://github.com/aleksilassila/reiverr.git
synced 2026-04-26 18:55:12 +02:00
feat: library page sections, sorting, view options
fix: tmdb library items not being cached
This commit is contained in:
@@ -37,7 +37,7 @@ export class LibraryController {
|
||||
): Promise<PaginatedResponseDto<LibraryItemDto>> {
|
||||
// const user = await this.userService.findOne(userId);
|
||||
|
||||
const items = await this.libraryService.getLibraryItemsWithMetadata(
|
||||
const items = await this.libraryService.getLibraryItemDtos(
|
||||
userId,
|
||||
pagination,
|
||||
);
|
||||
|
||||
@@ -1,22 +1,20 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { ApiProperty, PickType } from '@nestjs/swagger';
|
||||
import { MovieDto } from 'src/metadata/metadata.dto';
|
||||
import { PlayStateDto } from '../play-state/play-state.dto';
|
||||
import { MediaType } from 'src/common/common.dto';
|
||||
import { Series } from 'src/metadata/metadata.entity';
|
||||
import { LibraryItem } from './library.entity';
|
||||
|
||||
export class LibraryItemDto {
|
||||
@ApiProperty()
|
||||
tmdbId: string;
|
||||
|
||||
@ApiProperty({ enum: MediaType })
|
||||
mediaType: MediaType;
|
||||
|
||||
@ApiProperty({ type: [PlayStateDto], required: false })
|
||||
playStates?: PlayStateDto[];
|
||||
|
||||
export class LibraryItemDto extends PickType(LibraryItem, [
|
||||
'tmdbId',
|
||||
'mediaType',
|
||||
'playStates',
|
||||
'createdAt',
|
||||
]) {
|
||||
@ApiProperty({ type: MovieDto, required: false })
|
||||
movieMetadata?: MovieDto;
|
||||
|
||||
@ApiProperty({ type: Series, required: false })
|
||||
seriesMetadata?: Series;
|
||||
|
||||
@ApiProperty({ required: false })
|
||||
watched?: boolean;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import { MediaType } from 'src/common/common.dto';
|
||||
import { User } from 'src/users/user.entity';
|
||||
import {
|
||||
Column,
|
||||
CreateDateColumn,
|
||||
Entity,
|
||||
JoinColumn,
|
||||
ManyToOne,
|
||||
@@ -10,8 +11,10 @@ import {
|
||||
PrimaryColumn,
|
||||
PrimaryGeneratedColumn,
|
||||
Unique,
|
||||
UpdateDateColumn,
|
||||
} from 'typeorm';
|
||||
import { PlayState } from '../play-state/play-state.entity';
|
||||
import { PlayStateDto } from '../play-state/play-state.dto';
|
||||
|
||||
@Entity()
|
||||
@Unique(['tmdbId', 'userId'])
|
||||
@@ -20,7 +23,7 @@ export class LibraryItem {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id: string;
|
||||
|
||||
@ApiProperty({ required: true, type: 'number' })
|
||||
@ApiProperty({ required: true })
|
||||
@Column({ unique: true })
|
||||
tmdbId: string;
|
||||
|
||||
@@ -37,6 +40,16 @@ export class LibraryItem {
|
||||
@JoinColumn({ name: 'userId' })
|
||||
user: User;
|
||||
|
||||
@ApiProperty({ type: [PlayStateDto], required: false })
|
||||
@OneToMany(() => PlayState, (playState) => playState.libraryItem)
|
||||
playStates?: PlayState[];
|
||||
|
||||
/** @deprecated */
|
||||
@ApiProperty({ type: 'string' })
|
||||
@UpdateDateColumn({ default: () => 'CURRENT_TIMESTAMP' })
|
||||
updatedAt: Date;
|
||||
|
||||
@ApiProperty({ type: 'string' })
|
||||
@CreateDateColumn({ default: () => 'CURRENT_TIMESTAMP' })
|
||||
createdAt: Date;
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ export class LibraryService {
|
||||
private readonly metadataService: MetadataService,
|
||||
) {}
|
||||
|
||||
async getLibraryItemsWithMetadata(
|
||||
async getLibraryItemDtos(
|
||||
userId: string,
|
||||
pagination: PaginationParamsDto,
|
||||
): Promise<LibraryItemDto[]> {
|
||||
@@ -22,16 +22,37 @@ export class LibraryService {
|
||||
|
||||
return Promise.all(
|
||||
items.map(async (item) => {
|
||||
const seriesMetadata =
|
||||
item.mediaType === MediaType.Series
|
||||
? await this.metadataService.getSeriesByTmdbId(item.tmdbId)
|
||||
: undefined;
|
||||
let watched = false;
|
||||
|
||||
if (item.mediaType === MediaType.Movie) {
|
||||
watched = item.playStates?.some((state) => state.watched) ?? false;
|
||||
} else if (
|
||||
item.mediaType === MediaType.Series &&
|
||||
seriesMetadata.tmdbSeries?.last_episode_to_air
|
||||
) {
|
||||
const { season_number: season, episode_number: episode } =
|
||||
seriesMetadata.tmdbSeries.last_episode_to_air;
|
||||
watched =
|
||||
item.playStates?.some(
|
||||
(state) =>
|
||||
state.season === season &&
|
||||
state.episode === episode &&
|
||||
state.watched,
|
||||
) ?? false;
|
||||
}
|
||||
|
||||
return {
|
||||
...item,
|
||||
watched,
|
||||
movieMetadata:
|
||||
item.mediaType === MediaType.Movie
|
||||
? await this.metadataService.getMovieByTmdbId(item.tmdbId)
|
||||
: undefined,
|
||||
seriesMetadata:
|
||||
item.mediaType === MediaType.Series
|
||||
? await this.metadataService.getSeriesByTmdbId(item.tmdbId)
|
||||
: undefined,
|
||||
seriesMetadata,
|
||||
};
|
||||
}),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user