mirror of
https://github.com/aleksilassila/reiverr.git
synced 2026-04-26 18:55:12 +02:00
feat: server side continue watching before refactoring
This commit is contained in:
@@ -12,6 +12,7 @@ export enum MyListOrder {
|
||||
Name = 'name',
|
||||
FirstReleaseDate = 'first-release-date',
|
||||
LastReleaseDate = 'last-release-date',
|
||||
LastPlayed = 'last-played',
|
||||
}
|
||||
|
||||
export enum MyListStatusFilter {
|
||||
@@ -19,7 +20,7 @@ export enum MyListStatusFilter {
|
||||
Upcoming = 'upcoming',
|
||||
Unwatched = 'unwatched',
|
||||
Watched = 'watched',
|
||||
ContinueWatching = 'continueWatching',
|
||||
ContinueWatching = 'continue-watching',
|
||||
}
|
||||
|
||||
export enum MyListTypeFilter {
|
||||
|
||||
@@ -25,13 +25,17 @@ export class LibraryItem {
|
||||
id: string;
|
||||
|
||||
@ApiProperty({ required: true })
|
||||
@Column({ unique: true })
|
||||
@Column()
|
||||
tmdbId: string;
|
||||
|
||||
@ApiProperty({ required: true, enum: MediaType })
|
||||
@Column()
|
||||
mediaType: MediaType;
|
||||
|
||||
@ApiProperty({ type: 'string', required: false })
|
||||
@Column({ nullable: true })
|
||||
lastPlayedAt?: Date;
|
||||
|
||||
@ApiProperty({ required: false, type: MovieMetadata })
|
||||
@ManyToOne(() => MovieMetadata, {
|
||||
createForeignKeyConstraints: false,
|
||||
|
||||
@@ -57,66 +57,12 @@ export class LibraryService {
|
||||
direction = OrderDirection.Desc,
|
||||
} = options;
|
||||
|
||||
// const order = {
|
||||
// [MyListOrder.DateAdded]: { createdAt: directon } as const,
|
||||
// [MyListOrder.Name]: {
|
||||
// seriesMetadata: {
|
||||
// name: directon,
|
||||
// },
|
||||
// movieMetadata: {
|
||||
// name: directon,
|
||||
// },
|
||||
// } as const,
|
||||
// [MyListOrder.FirstReleaseDate]: {
|
||||
// movieMetadata: {
|
||||
// releaseDate: directon,
|
||||
// },
|
||||
// seriesMetadata: {
|
||||
// firstReleaseDate: directon,
|
||||
// },
|
||||
// } as const,
|
||||
// [MyListOrder.LastReleaseDate]: {
|
||||
// movieMetadata: {
|
||||
// releaseDate: directon,
|
||||
// },
|
||||
// seriesMetadata: {
|
||||
// lastReleaseDate: directon,
|
||||
// },
|
||||
// } as const,
|
||||
// }[sortBy];
|
||||
|
||||
const mediaType = type
|
||||
? type === MyListTypeFilter.Movies
|
||||
? MediaType.Movie
|
||||
: MediaType.Series
|
||||
: undefined;
|
||||
|
||||
// const [items, total] = await this.libraryRepository.findAndCount({
|
||||
// relations: {
|
||||
// playStates: true,
|
||||
// seriesMetadata: true,
|
||||
// movieMetadata: true,
|
||||
// },
|
||||
// select: {
|
||||
// seriesMetadata: {
|
||||
// firstReleaseDate: true,
|
||||
// lastReleaseDate: true,
|
||||
// name: true,
|
||||
// },
|
||||
// movieMetadata: {
|
||||
// releaseDate: true,
|
||||
// name: true,
|
||||
// },
|
||||
// },
|
||||
// where: {
|
||||
// userId,
|
||||
// ...(mediaType ? { mediaType } : {}),
|
||||
// },
|
||||
// order,
|
||||
// take: pagination.itemsPerPage,
|
||||
// skip: pagination.itemsPerPage * (pagination.page - 1),
|
||||
// });
|
||||
|
||||
let builder = this.libraryRepository
|
||||
.createQueryBuilder('libraryItem')
|
||||
.leftJoinAndSelect('libraryItem.playStates', 'playStates')
|
||||
@@ -176,7 +122,10 @@ export class LibraryService {
|
||||
builder = builder.andWhere(upcoming);
|
||||
} else if (status === MyListStatusFilter.Watched) {
|
||||
builder = builder.andWhere(watchedAndNotUpcoming);
|
||||
} else if (status === MyListStatusFilter.Unwatched) {
|
||||
} else if (
|
||||
status === MyListStatusFilter.Unwatched ||
|
||||
status === MyListStatusFilter.ContinueWatching
|
||||
) {
|
||||
builder = builder.andWhere(
|
||||
new Brackets((qb) =>
|
||||
qb
|
||||
@@ -210,6 +159,12 @@ export class LibraryService {
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
if (status === MyListStatusFilter.ContinueWatching) {
|
||||
builder = builder.andWhere(
|
||||
"libraryItem.lastPlayedAt IS NOT NULL AND libraryItem.lastPlayedAt > date('now', '-1 month')",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const DIRECTION = direction === OrderDirection.Asc ? 'ASC' : 'DESC';
|
||||
@@ -224,6 +179,8 @@ export class LibraryService {
|
||||
} else if (order === MyListOrder.LastReleaseDate) {
|
||||
builder.addOrderBy('movieMetadata.releaseDate', DIRECTION);
|
||||
builder.addOrderBy('seriesMetadata.lastReleaseDate', DIRECTION);
|
||||
} else if (order === MyListOrder.LastPlayed) {
|
||||
builder.addOrderBy('libraryItem.lastPlayedAt', DIRECTION);
|
||||
}
|
||||
|
||||
const [items, total] = await builder
|
||||
|
||||
@@ -2,10 +2,11 @@ import { Module } from '@nestjs/common';
|
||||
import { playStateProviders } from './play-state.providers';
|
||||
import { PlayStatesController } from './play-states.controller';
|
||||
import { PlayStatesService } from './play-states.service';
|
||||
import { libraryProviders } from '../library/library.providers';
|
||||
|
||||
@Module({
|
||||
imports: [],
|
||||
providers: [...playStateProviders, PlayStatesService],
|
||||
providers: [...playStateProviders, ...libraryProviders, PlayStatesService],
|
||||
controllers: [PlayStatesController],
|
||||
exports: [PlayStatesService],
|
||||
})
|
||||
|
||||
@@ -1,15 +1,19 @@
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { MediaTypeFull } from 'src/common/common.dto';
|
||||
import { Repository } from 'typeorm';
|
||||
import { BulkUpdatePlayStateDto, UpdatePlayStateDto } from './play-state.dto';
|
||||
import { UpdatePlayStateDto } from './play-state.dto';
|
||||
import { PlayState } from './play-state.entity';
|
||||
import { USER_PLAY_STATE_REPOSITORY } from './play-state.providers';
|
||||
import { USER_LIBRARY_REPOSITORY } from '../library/library.providers';
|
||||
import { LibraryItem } from '../library/library.entity';
|
||||
|
||||
@Injectable()
|
||||
export class PlayStatesService {
|
||||
constructor(
|
||||
@Inject(USER_PLAY_STATE_REPOSITORY)
|
||||
private readonly playStateRepository: Repository<PlayState>,
|
||||
@Inject(USER_LIBRARY_REPOSITORY)
|
||||
private readonly libraryRepository: Repository<LibraryItem>,
|
||||
) {}
|
||||
|
||||
async findMoviePlayState(userId: string, tmdbId: string) {
|
||||
@@ -106,7 +110,14 @@ export class PlayStatesService {
|
||||
if (playState.progress !== undefined) state.progress = playState.progress;
|
||||
if (playState.watched !== undefined) state.watched = playState.watched;
|
||||
|
||||
return this.playStateRepository.save(state);
|
||||
return this.playStateRepository.save(state).then(async (state) => {
|
||||
await this.libraryRepository.update(
|
||||
{ tmdbId, userId },
|
||||
{ lastPlayedAt: new Date() },
|
||||
);
|
||||
|
||||
return state;
|
||||
});
|
||||
}
|
||||
|
||||
async updateOrCreateEpisodePlayState(
|
||||
@@ -125,7 +136,14 @@ export class PlayStatesService {
|
||||
if (playState.progress !== undefined) state.progress = playState.progress;
|
||||
if (playState.watched !== undefined) state.watched = playState.watched;
|
||||
|
||||
return this.playStateRepository.save(state);
|
||||
return this.playStateRepository.save(state).then(async (state) => {
|
||||
await this.libraryRepository.update(
|
||||
{ tmdbId, userId },
|
||||
{ lastPlayedAt: new Date() },
|
||||
);
|
||||
|
||||
return state;
|
||||
});
|
||||
}
|
||||
|
||||
async deleteMoviePlayState(userId: string, tmdbId: string) {
|
||||
|
||||
Reference in New Issue
Block a user