diff --git a/package-lock.json b/package-lock.json index f4cfac0..0dec6ba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7709,6 +7709,11 @@ "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", "dev": true }, + "nestjs-typeorm-paginate": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/nestjs-typeorm-paginate/-/nestjs-typeorm-paginate-2.0.3.tgz", + "integrity": "sha512-cGIVwdIrZuDO5kHSVTcYRyFAjyxbg2dn/YFp9l+/xhsQl9XZkvcfXtqoo32T/h5bUmztdS4GJMoUYwo7TF30Eg==" + }, "next-tick": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", diff --git a/package.json b/package.json index 5bd38d3..d5067d5 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "@nestjs/typeorm": "^7.0.0", "class-transformer": "^0.2.3", "class-validator": "^0.12.2", + "nestjs-typeorm-paginate": "^2.0.3", "passport": "^0.4.1", "passport-jwt": "^4.0.0", "passport-spotify": "^1.1.0", diff --git a/src/listens/dto/get-listens.dto.ts b/src/listens/dto/get-listens.dto.ts new file mode 100644 index 0000000..cdd6865 --- /dev/null +++ b/src/listens/dto/get-listens.dto.ts @@ -0,0 +1,5 @@ +import { User } from "src/users/user.entity"; + +export interface GetListensDto { + user: User; +} diff --git a/src/listens/listens.controller.spec.ts b/src/listens/listens.controller.spec.ts new file mode 100644 index 0000000..7255712 --- /dev/null +++ b/src/listens/listens.controller.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from "@nestjs/testing"; +import { ListensController } from "./listens.controller"; + +describe("Listens Controller", () => { + let controller: ListensController; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [ListensController], + }).compile(); + + controller = module.get(ListensController); + }); + + it("should be defined", () => { + expect(controller).toBeDefined(); + }); +}); diff --git a/src/listens/listens.controller.ts b/src/listens/listens.controller.ts new file mode 100644 index 0000000..e5d8bba --- /dev/null +++ b/src/listens/listens.controller.ts @@ -0,0 +1,24 @@ +import { Controller, Get, Query } from "@nestjs/common"; +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 { Listen } from "./listen.entity"; +import { ListensService } from "./listens.service"; + +@Controller("api/v1/listens") +export class ListensController { + constructor(private readonly listensService: ListensService) {} + + @Get() + @Auth() + async getRecentlyPlayed( + @Query("page") page: number = 1, + @Query("limit") limit: number = 10, + @ReqUser() user: User + ): Promise> { + limit = limit > 100 ? 100 : limit; + + return this.listensService.getListens({ page, limit, user }); + } +} diff --git a/src/listens/listens.module.ts b/src/listens/listens.module.ts index b98112b..7d5b837 100644 --- a/src/listens/listens.module.ts +++ b/src/listens/listens.module.ts @@ -2,10 +2,12 @@ import { Module } from "@nestjs/common"; import { ListensService } from "./listens.service"; import { TypeOrmModule } from "@nestjs/typeorm"; import { ListenRepository } from "./listen.repository"; +import { ListensController } from "./listens.controller"; @Module({ imports: [TypeOrmModule.forFeature([ListenRepository])], providers: [ListensService], exports: [ListensService], + controllers: [ListensController], }) export class ListensModule {} diff --git a/src/listens/listens.service.ts b/src/listens/listens.service.ts index 21ab4ad..66627fa 100644 --- a/src/listens/listens.service.ts +++ b/src/listens/listens.service.ts @@ -1,7 +1,13 @@ import { Injectable } from "@nestjs/common"; +import { + IPaginationOptions, + paginate, + Pagination, +} from "nestjs-typeorm-paginate"; +import { CreateListenDto } from "./dto/create-listen.dto"; import { Listen } from "./listen.entity"; import { ListenRepository } from "./listen.repository"; -import { CreateListenDto } from "./dto/create-listen.dto"; +import { GetListensDto } from "./dto/get-listens.dto"; @Injectable() export class ListensService { @@ -32,4 +38,25 @@ export class ListensService { return listen; } + + async getListens( + options: GetListensDto & IPaginationOptions + ): Promise> { + const { page, limit, user } = options; + + const queryBuilder = this.listenRepository + .createQueryBuilder("l") + .leftJoin("l.user", "user") + .where("user.id = :userID", { userID: user.id }) + .leftJoinAndSelect("l.track", "track") + .leftJoinAndSelect("track.artists", "artists") + .leftJoinAndSelect("track.album", "album") + .leftJoinAndSelect("album.artists", "albumArtists") + .orderBy("l.playedAt", "DESC"); + + return paginate(queryBuilder, { + page, + limit, + }); + } }