From 6b209077ef27c7ddb89e2a3e7810ed522ea5c4bc Mon Sep 17 00:00:00 2001 From: Sergey Elpashev Date: Sat, 20 Jul 2024 00:59:00 +0300 Subject: [PATCH] feat: started popular titles on main page --- apps/NwaifuAnime/src/app/app.config.ts | 5 ++ .../app/components/home/home.component.html | 8 +++ .../src/app/components/home/home.component.ts | 55 ++++++++++++++--- .../src/app/services/parsers/enums/parser.ts | 4 ++ .../src/app/services/parsers/parser.ts | 2 + .../rulib/lib.social.parser.service.ts | 20 ++++++ .../parsers/rulib/rulib.popular.dto.ts | 61 +++++++++++++++++++ .../parsers/rulib/slashlib.parser.service.ts | 10 +++ .../src/app/services/parsers/urls.ts | 1 + .../src/app/services/search.service.ts | 25 ++++++-- 10 files changed, 180 insertions(+), 11 deletions(-) create mode 100644 apps/NwaifuAnime/src/app/services/parsers/enums/parser.ts create mode 100644 apps/NwaifuAnime/src/app/services/parsers/rulib/rulib.popular.dto.ts create mode 100644 apps/NwaifuAnime/src/app/services/parsers/rulib/slashlib.parser.service.ts diff --git a/apps/NwaifuAnime/src/app/app.config.ts b/apps/NwaifuAnime/src/app/app.config.ts index 05a04f4..1ba75e8 100644 --- a/apps/NwaifuAnime/src/app/app.config.ts +++ b/apps/NwaifuAnime/src/app/app.config.ts @@ -3,6 +3,9 @@ import { ApplicationConfig, isDevMode, provideZoneChangeDetection } from "@angul import { provideRouter } from "@angular/router"; import { provideServiceWorker } from "@angular/service-worker"; import { appRoutes } from "./app.routes"; +import { Parser } from "./services/parsers/parser"; +import { MangalibParserService } from "./services/parsers/rulib/mangalib.parser.service"; +import { SlashlibParserService } from "./services/parsers/rulib/slashlib.parser.service"; export const appConfig: ApplicationConfig = { providers: [ @@ -13,5 +16,7 @@ export const appConfig: ApplicationConfig = { registrationStrategy: "registerWhenStable:30000", }), provideHttpClient(withFetch()), + { provide: Parser, multi: true, useClass: MangalibParserService }, + { provide: Parser, multi: true, useClass: SlashlibParserService }, ], }; diff --git a/apps/NwaifuAnime/src/app/components/home/home.component.html b/apps/NwaifuAnime/src/app/components/home/home.component.html index fe14cb8..cd94647 100644 --- a/apps/NwaifuAnime/src/app/components/home/home.component.html +++ b/apps/NwaifuAnime/src/app/components/home/home.component.html @@ -1,4 +1,12 @@

It's home component

+@if (!search) { + @for (popular of popularItems; track popular[0]) { +

{{ popular[0] }}

+ @for (popularTitle of popular[1]; track popularTitle.id) { +

{{ popularTitle.rus_name }}

+ } + } +}
@if (loading) {

Loading...

diff --git a/apps/NwaifuAnime/src/app/components/home/home.component.ts b/apps/NwaifuAnime/src/app/components/home/home.component.ts index 6058714..3a4b8b6 100644 --- a/apps/NwaifuAnime/src/app/components/home/home.component.ts +++ b/apps/NwaifuAnime/src/app/components/home/home.component.ts @@ -1,7 +1,8 @@ import { CommonModule } from "@angular/common"; import { Component, Input, OnDestroy, OnInit } from "@angular/core"; import { ActivatedRoute, RouterLink } from "@angular/router"; -import { Subject, takeUntil } from "rxjs"; +import { map, Subject, Subscription, takeUntil } from "rxjs"; +import { IRuLIBPopular } from "../../services/parsers/rulib/rulib.popular.dto"; import { Datum } from "../../services/parsers/rulib/rulib.search.dto"; import { SearchService } from "../../services/search.service"; @@ -16,33 +17,73 @@ export class HomeComponent implements OnDestroy, OnInit { @Input() items: Datum[] = []; loading = false; notFound = false; + search: string = ""; + popularItemsMap: Map = new Map(); private destroy$ = new Subject(); + private popularSubscription = new Subscription(); constructor( private searchService: SearchService, private route: ActivatedRoute, - ) {} + ) { + this.searchService.setMangalibParser(); + } ngOnDestroy(): void { this.destroy$.next(); this.destroy$.complete(); + this.popularSubscription.unsubscribe(); + } + + private getPopular() { + if (!this.popularSubscription.closed) this.popularSubscription.unsubscribe(); + this.popularSubscription = this.searchService + .getPopular() + .pipe(map((data) => data as IRuLIBPopular[])) + .subscribe({ + next: (data) => { + this.popularItemsMap.set(this.searchService.getRuLibName(), data); + console.log(this.popularItemsMap); + }, + error: (error) => { + console.error(error); + }, + }); + } + + getPopularMangalib() { + this.searchService.setMangalibParser(); + this.getPopular(); + } + + getPopularSlashlib() { + this.searchService.setSlashlibParser(); + this.getPopular(); + } + + get popularItems() { + return this.popularItemsMap.entries(); } ngOnInit(): void { - this.route.queryParams.subscribe((params) => { - const search = params["search"]; - if (search) { - this.searchService.setMangalibParser(); + this.route.queryParams.pipe(takeUntil(this.destroy$)).subscribe((params) => { + this.search = params["search"] ?? ""; + this.items = []; + if (this.search) { this.loading = true; + this.searchService.setMangalibParser(); this.searchService - .search(search) + .search(this.search) .pipe(takeUntil(this.destroy$)) .subscribe((data) => { this.loading = false; this.items = data.data; this.notFound = this.items.length === 0; }); + } else { + this.getPopularMangalib(); + this.getPopularSlashlib(); } }); } diff --git a/apps/NwaifuAnime/src/app/services/parsers/enums/parser.ts b/apps/NwaifuAnime/src/app/services/parsers/enums/parser.ts new file mode 100644 index 0000000..87aa692 --- /dev/null +++ b/apps/NwaifuAnime/src/app/services/parsers/enums/parser.ts @@ -0,0 +1,4 @@ +export enum EParser { + MangaLib = 0, + SlashLib = 1, +} diff --git a/apps/NwaifuAnime/src/app/services/parsers/parser.ts b/apps/NwaifuAnime/src/app/services/parsers/parser.ts index 0a751cf..0793eba 100644 --- a/apps/NwaifuAnime/src/app/services/parsers/parser.ts +++ b/apps/NwaifuAnime/src/app/services/parsers/parser.ts @@ -15,4 +15,6 @@ export abstract class Parser { abstract getChapters(url: string): Observable; abstract getChapter(url: string, chapter: string, volume: string): Observable; + + abstract getPopular(): Observable; } diff --git a/apps/NwaifuAnime/src/app/services/parsers/rulib/lib.social.parser.service.ts b/apps/NwaifuAnime/src/app/services/parsers/rulib/lib.social.parser.service.ts index 2f4076d..2e89fcc 100644 --- a/apps/NwaifuAnime/src/app/services/parsers/rulib/lib.social.parser.service.ts +++ b/apps/NwaifuAnime/src/app/services/parsers/rulib/lib.social.parser.service.ts @@ -6,6 +6,7 @@ import { RulibAuthService } from "./rulib.auth.service"; import { IRulibChapterResult } from "./rulib.chapter.dto"; import { IRulibChaptersResult } from "./rulib.chapters.dto"; import { IRulibDetailResult } from "./rulib.detail.dto"; +import { IRuLIBPopular } from "./rulib.popular.dto"; import { IRulibSearchResult } from "./rulib.search.dto"; //TODO: Make abstract classes @@ -98,4 +99,23 @@ export class LibSocialParserService extends Parser { catchError((error) => throwError(() => `Now found ${error}`)), ); } + + getPopular(): Observable { + //TODO: мб сделать ассинхрон + return this.http + .get<{ data: { popular: [] } }>(`${this.url}/api/`, { + headers: { + Authorization: "Bearer " + this.rulibAuthService.getToken(), + "Site-Id": this.site_id, + }, + }) + .pipe( + map((data) => { + const res = data.data.popular as IRuLIBPopular[]; + console.log(res); + return res; + }), + catchError((error) => throwError(() => `Now found ${error}`)), + ); + } } diff --git a/apps/NwaifuAnime/src/app/services/parsers/rulib/rulib.popular.dto.ts b/apps/NwaifuAnime/src/app/services/parsers/rulib/rulib.popular.dto.ts new file mode 100644 index 0000000..1dcbcae --- /dev/null +++ b/apps/NwaifuAnime/src/app/services/parsers/rulib/rulib.popular.dto.ts @@ -0,0 +1,61 @@ +export interface IRuLIBPopular { + id: number; + name: string; + rus_name: string; + eng_name: string; + slug: string; + slug_url: string; + cover: Cover; + ageRestriction: AgeRestriction; + site: number; + type: AgeRestriction; + rating: Rating; + last_item_at: Date; + metadata: Metadata; + model: Model; + status: AgeRestriction; + releaseDateString: string; +} + +export interface AgeRestriction { + id: number; + label: string; +} + +export interface Cover { + filename: string; + thumbnail: string; + default: string; + md: string; +} + +export interface Metadata { + last_item: LastItem; +} + +export interface LastItem { + id: number; + number: string; + volume: number | string; + name: string; + branch_id: number | null; + status?: null; + type?: string; + number_secondary?: string; + slug?: number; + manga_id?: null; + created_at?: Date; + likes_count?: null; +} + +export enum Model { + Manga = "manga", +} + +export interface Rating { + average: string; + averageFormated: string; + votes: number; + votesFormated: string; + user: number; +} diff --git a/apps/NwaifuAnime/src/app/services/parsers/rulib/slashlib.parser.service.ts b/apps/NwaifuAnime/src/app/services/parsers/rulib/slashlib.parser.service.ts new file mode 100644 index 0000000..8b539cc --- /dev/null +++ b/apps/NwaifuAnime/src/app/services/parsers/rulib/slashlib.parser.service.ts @@ -0,0 +1,10 @@ +import { Injectable } from "@angular/core"; +import { ParserDecorator } from "../decorators/parser.decorator"; +import { ESiteUrls } from "../urls"; +import { LibSocialParserService } from "./lib.social.parser.service"; + +@Injectable({ + providedIn: "root", +}) +@ParserDecorator({ site_name: "Slashlib", url: ESiteUrls.LIB_SOCIAL, site_id: 2 }) +export class SlashlibParserService extends LibSocialParserService {} diff --git a/apps/NwaifuAnime/src/app/services/parsers/urls.ts b/apps/NwaifuAnime/src/app/services/parsers/urls.ts index bcf757c..25288af 100644 --- a/apps/NwaifuAnime/src/app/services/parsers/urls.ts +++ b/apps/NwaifuAnime/src/app/services/parsers/urls.ts @@ -1,4 +1,5 @@ export enum ESiteUrls { LIB_SOCIAL = "https://api.lib.social", MANGALIB = "https://api.mangalib.me", + SLASHLIB = "https://api.slashlib.me", } diff --git a/apps/NwaifuAnime/src/app/services/search.service.ts b/apps/NwaifuAnime/src/app/services/search.service.ts index afcc4da..fbd64e9 100644 --- a/apps/NwaifuAnime/src/app/services/search.service.ts +++ b/apps/NwaifuAnime/src/app/services/search.service.ts @@ -1,8 +1,8 @@ import { HttpClient } from "@angular/common/http"; -import { Injectable } from "@angular/core"; +import { Inject, Injectable } from "@angular/core"; import { Observable, map } from "rxjs"; +import { EParser } from "./parsers/enums/parser"; import { Parser } from "./parsers/parser"; -import { MangalibParserService } from "./parsers/rulib/mangalib.parser.service"; import { IRulibChapterResult } from "./parsers/rulib/rulib.chapter.dto"; import { IRulibChaptersResult } from "./parsers/rulib/rulib.chapters.dto"; import { IRulibDetailResult } from "./parsers/rulib/rulib.detail.dto"; @@ -13,11 +13,19 @@ export class SearchService { private parser!: Parser; constructor( private http: HttpClient, - private mangalibParser: MangalibParserService, + @Inject(Parser) private parsers: Parser[], ) {} setMangalibParser() { - this.parser = this.mangalibParser; + this.setParser(EParser.MangaLib); + } + + setSlashlibParser() { + this.setParser(EParser.SlashLib); + } + + private setParser(parser: EParser) { + this.parser = this.parsers[parser]; } search(query: string): Observable { @@ -69,4 +77,13 @@ export class SearchService { // eslint-disable-next-line @typescript-eslint/no-explicit-any return (this.parser as any).isManhwa(url); } + + getPopular(): Observable { + return this.parser.getPopular(); + } + + getRuLibName(): string { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + return (this.parser as any).site_name; + } }