diff --git a/package-lock.json b/package-lock.json index 13a5c9c..f983c75 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3722,6 +3722,11 @@ "whatwg-url": "^7.0.0" } }, + "date-fns": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.13.0.tgz", + "integrity": "sha512-xm0c61mevGF7f0XpCGtDTGpzEFC/1fpLXHbmFpxZZQJuvByIK2ozm6cSYuU+nxFYOPh2EuCfzUwlTEFwKG+h5w==" + }, "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", diff --git a/package.json b/package.json index 3278181..6beaf8a 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,7 @@ "@nestjs/typeorm": "^7.0.0", "class-transformer": "^0.2.3", "class-validator": "^0.12.2", + "date-fns": "^2.13.0", "nestjs-typeorm-paginate": "^2.0.3", "passport": "^0.4.1", "passport-jwt": "^4.0.0", diff --git a/src/listens/dto/get-listens.dto.ts b/src/listens/dto/get-listens.dto.ts index cdd6865..6d45a96 100644 --- a/src/listens/dto/get-listens.dto.ts +++ b/src/listens/dto/get-listens.dto.ts @@ -1,5 +1,26 @@ +import { IsOptional, ValidateNested, IsISO8601 } from "class-validator"; import { User } from "src/users/user.entity"; -export interface GetListensDto { - user: User; +// tslint:disable-next-line: max-classes-per-file +export class GetListensFilterTimeDto { + @IsISO8601() + start: string; + @IsISO8601() + end: string; +} + +// tslint:disable-next-line: max-classes-per-file +export class GetListensFilterDto { + @IsOptional() + @ValidateNested() + time?: GetListensFilterTimeDto; +} + +// tslint:disable-next-line: max-classes-per-file +export class GetListensDto { + user: User; + + @IsOptional() + @ValidateNested() + filter?: GetListensFilterDto; } diff --git a/src/listens/listens.controller.ts b/src/listens/listens.controller.ts index e5d8bba..d52fe06 100644 --- a/src/listens/listens.controller.ts +++ b/src/listens/listens.controller.ts @@ -3,6 +3,7 @@ import { Pagination } from "nestjs-typeorm-paginate"; import { Auth } from "../auth/decorators/auth.decorator"; import { ReqUser } from "../auth/decorators/req-user.decorator"; import { User } from "../users/user.entity"; +import { GetListensFilterDto } from "./dto/get-listens.dto"; import { Listen } from "./listen.entity"; import { ListensService } from "./listens.service"; @@ -15,10 +16,11 @@ export class ListensController { async getRecentlyPlayed( @Query("page") page: number = 1, @Query("limit") limit: number = 10, + @Query("filter") filter: GetListensFilterDto, @ReqUser() user: User ): Promise> { limit = limit > 100 ? 100 : limit; - return this.listensService.getListens({ page, limit, user }); + return this.listensService.getListens({ page, limit, user, filter }); } } diff --git a/src/listens/listens.service.ts b/src/listens/listens.service.ts index 66627fa..2aa3332 100644 --- a/src/listens/listens.service.ts +++ b/src/listens/listens.service.ts @@ -1,13 +1,14 @@ import { Injectable } from "@nestjs/common"; +import { getTime, parseISO, getUnixTime } from "date-fns"; import { IPaginationOptions, paginate, Pagination, } from "nestjs-typeorm-paginate"; import { CreateListenDto } from "./dto/create-listen.dto"; +import { GetListensDto } from "./dto/get-listens.dto"; import { Listen } from "./listen.entity"; import { ListenRepository } from "./listen.repository"; -import { GetListensDto } from "./dto/get-listens.dto"; @Injectable() export class ListensService { @@ -42,9 +43,9 @@ export class ListensService { async getListens( options: GetListensDto & IPaginationOptions ): Promise> { - const { page, limit, user } = options; + const { page, limit, user, filter } = options; - const queryBuilder = this.listenRepository + let queryBuilder = this.listenRepository .createQueryBuilder("l") .leftJoin("l.user", "user") .where("user.id = :userID", { userID: user.id }) @@ -54,6 +55,18 @@ export class ListensService { .leftJoinAndSelect("album.artists", "albumArtists") .orderBy("l.playedAt", "DESC"); + if (filter) { + if (filter.time) { + queryBuilder = queryBuilder.andWhere( + "l.playedAt BETWEEN :timeStart AND :timeEnd", + { + timeStart: parseISO(filter.time.start), + timeEnd: parseISO(filter.time.end), + } + ); + } + } + return paginate(queryBuilder, { page, limit,