+
}
diff --git a/apps/NwaifuAnime/src/app/components/reader/reader.component.html b/apps/NwaifuAnime/src/app/components/reader/reader.component.html
new file mode 100644
index 0000000..d33d132
--- /dev/null
+++ b/apps/NwaifuAnime/src/app/components/reader/reader.component.html
@@ -0,0 +1,6 @@
+
It's reader page
+
+ @for (page of pages; track $index) {
+
![]()
+ }
+
diff --git a/apps/NwaifuAnime/src/app/components/reader/reader.component.less b/apps/NwaifuAnime/src/app/components/reader/reader.component.less
new file mode 100644
index 0000000..e69de29
diff --git a/apps/NwaifuAnime/src/app/components/reader/reader.component.ts b/apps/NwaifuAnime/src/app/components/reader/reader.component.ts
new file mode 100644
index 0000000..c9c1e17
--- /dev/null
+++ b/apps/NwaifuAnime/src/app/components/reader/reader.component.ts
@@ -0,0 +1,38 @@
+import { CommonModule } from "@angular/common";
+import { AfterViewInit, Component } from "@angular/core";
+import { ActivatedRoute, Router } from "@angular/router";
+import { Page } from "../../services/parsers/rulib/rulib.chapter.dto";
+import { SearchService } from "../../services/search.service";
+
+@Component({
+ selector: "app-reader",
+ templateUrl: "./reader.component.html",
+ styleUrls: ["./reader.component.less"],
+ standalone: true,
+ imports: [CommonModule],
+})
+export class ReaderComponent implements AfterViewInit {
+ pages: Page[] = [];
+ constructor(
+ private route: ActivatedRoute,
+ private router: Router,
+ private searchService: SearchService,
+ ) {}
+
+ ngAfterViewInit(): void {
+ this.route.queryParams.subscribe((params) => {
+ const url = params["url"];
+ const chapter = params["chapter"];
+ const volume = params["volume"];
+ if (url && chapter && volume) {
+ this.searchService.getChapter(url, chapter, volume).subscribe((data) => {
+ this.pages = data.data.pages.map((page) => {
+ return { ...page, url: this.searchService.getImageServer() + page.url };
+ });
+ });
+ } else {
+ this.router.navigate(["/"]);
+ }
+ });
+ }
+}
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 b1ac197..d50c2a2 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
@@ -2,6 +2,8 @@ import { HttpClient } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { Observable, catchError, map, throwError } from "rxjs";
import { ESiteUrls } from "../urls";
+import { IRulibChapterResult } from "./rulib.chapter.dto";
+import { IRulibChaptersResult } from "./rulib.chapters.dto";
import { IRulibDetailResult } from "./rulib.detail.dto";
import { IRulibSearchResult } from "./rulib.search.dto";
@@ -13,6 +15,10 @@ export class LibSocialParserService {
private readonly url = ESiteUrls.LIB_SOCIAL;
constructor(private readonly http: HttpClient) {}
+ get imageServer() {
+ return "https://img33.imgslib.link";
+ }
+
searchManga(query: string): Observable
{
return this.http
.get(`${this.url}/api/manga?fields[]=rate_avg&fields[]=rate&q=${query}&site_id[]=1`)
@@ -40,4 +46,24 @@ export class LibSocialParserService {
}),
);
}
+
+ getChapters(url: string): Observable {
+ return this.http.get(`${this.url}/api/manga/${url}/chapters`).pipe(
+ map((data) => {
+ return data as IRulibChaptersResult;
+ }),
+ catchError((error) => {
+ return throwError(() => `Now found ${error}`);
+ }),
+ );
+ }
+
+ getChapter(url: string, chapter: string, volume: string): Observable {
+ return this.http
+ .get(`${this.url}/api/manga/${url}/chapter?number=${chapter}&volume=${volume}`)
+ .pipe(
+ map((data) => data as IRulibChapterResult),
+ catchError((error) => throwError(() => `Now found ${error}`)),
+ );
+ }
}
diff --git a/apps/NwaifuAnime/src/app/services/parsers/rulib/rulib.chapter.dto.ts b/apps/NwaifuAnime/src/app/services/parsers/rulib/rulib.chapter.dto.ts
new file mode 100644
index 0000000..eff79a6
--- /dev/null
+++ b/apps/NwaifuAnime/src/app/services/parsers/rulib/rulib.chapter.dto.ts
@@ -0,0 +1,62 @@
+export interface IRulibChapterResult {
+ data: Chapter;
+}
+
+export interface Chapter {
+ id: number;
+ type: string;
+ volume: string;
+ number: string;
+ number_secondary: string;
+ name: string;
+ slug: string;
+ branch_id: null;
+ manga_id: number;
+ created_at: Date;
+ moderated: Moderated;
+ likes_count: number;
+ teams: Team[];
+ pages: Page[];
+}
+
+export interface Moderated {
+ id: number;
+ label: string;
+}
+
+export interface Page {
+ id: number;
+ image: string;
+ slug: number;
+ external: number;
+ chunks: number;
+ chapter_id: number;
+ created_at: Date;
+ updated_at: UpdatedAt;
+ height: number;
+ width: number;
+ url: string;
+ ratio: string;
+}
+
+export enum UpdatedAt {
+ The0000011130T000000000000Z = "-000001-11-30T00:00:00.000000Z",
+}
+
+export interface Team {
+ id: number;
+ slug: string;
+ slug_url: string;
+ model: string;
+ name: string;
+ cover: Cover;
+ vk: null;
+ discord: null;
+}
+
+export interface Cover {
+ filename: null;
+ thumbnail: string;
+ default: string;
+ md: string;
+}
diff --git a/apps/NwaifuAnime/src/app/services/parsers/rulib/rulib.chapters.dto.ts b/apps/NwaifuAnime/src/app/services/parsers/rulib/rulib.chapters.dto.ts
new file mode 100644
index 0000000..ef486ea
--- /dev/null
+++ b/apps/NwaifuAnime/src/app/services/parsers/rulib/rulib.chapters.dto.ts
@@ -0,0 +1,85 @@
+export interface IRulibChaptersResult {
+ data: IRulibChapter[];
+}
+
+export interface IRulibChapter {
+ id: number;
+ index: number;
+ item_number: number;
+ volume: string;
+ number: string;
+ number_secondary: string;
+ name: string;
+ branches_count: number;
+ branches: Branch[];
+}
+
+export interface Branch {
+ id: number;
+ branch_id: null;
+ created_at: Date;
+ teams: Team[];
+ user: User;
+}
+
+export interface Team {
+ id: number;
+ slug: Slug;
+ slug_url: SlugURL;
+ model: Model;
+ name: Name;
+ cover: Cover;
+}
+
+export interface Cover {
+ filename: null | string;
+ thumbnail: Thumbnail;
+ default: Default;
+ md: Default;
+}
+
+export enum Default {
+ StaticImagesPlaceholdersUserAvatarPNG = "/static/images/placeholders/user_avatar.png",
+ UploadsTeamAnyasyavaCoverJSazXO7JdAKV250X350Jpg = "/uploads/team/anyasyava/cover/jSazXO7JdAKV_250x350.jpg",
+}
+
+export enum Thumbnail {
+ StaticImagesPlaceholdersUserAvatarPNG = "/static/images/placeholders/user_avatar.png",
+ UploadsTeamAnyasyavaCoverJSazXO7JdAKVThumbJpg = "/uploads/team/anyasyava/cover/jSazXO7JdAKV_thumb.jpg",
+}
+
+export enum Model {
+ Team = "team",
+}
+
+export enum Name {
+ Abame = "abame",
+ Anyasyava = "ANYASYAVA",
+ Cabel = "Cabel",
+ Deadvm = "deadvm",
+}
+
+export enum Slug {
+ Abame = "abame",
+ Anyasyava = "anyasyava",
+ Cabel = "cabel",
+ Deadvm = "deadvm",
+}
+
+export enum SlugURL {
+ The13801Anyasyava = "13801--anyasyava",
+ The33106Abame = "33106--abame",
+ The42374Cabel = "42374--cabel",
+ The45635Deadvm = "45635--deadvm",
+}
+
+export interface User {
+ username: Username;
+ id: number;
+}
+
+export enum Username {
+ Deadvm = "deadvm",
+ Gjunyaa = "gjunyaa ❤️\ud83e\ude79",
+ Oksas = "oksas",
+}
diff --git a/apps/NwaifuAnime/src/app/services/search.service.ts b/apps/NwaifuAnime/src/app/services/search.service.ts
index 1636d56..8682415 100644
--- a/apps/NwaifuAnime/src/app/services/search.service.ts
+++ b/apps/NwaifuAnime/src/app/services/search.service.ts
@@ -1,6 +1,8 @@
import { Injectable } from "@angular/core";
import { BehaviorSubject, Observable, map } from "rxjs";
import { LibSocialParserService } from "./parsers/rulib/lib.social.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";
import { Datum } from "./parsers/rulib/rulib.search.dto";
@@ -23,4 +25,24 @@ export class SearchService {
}),
);
}
+
+ getChapters(url: string): Observable {
+ return this.parser.getChapters(url).pipe(
+ map((data) => {
+ return data;
+ }),
+ );
+ }
+
+ getChapter(url: string, chapter: string, volume: string): Observable {
+ return this.parser.getChapter(url, chapter, volume).pipe(
+ map((data) => {
+ return data;
+ }),
+ );
+ }
+
+ getImageServer() {
+ return this.parser.imageServer;
+ }
}